BearND has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/171512

Change subject: Disambiguation and page issues dialog comes up from bottom
......................................................................

Disambiguation and page issues dialog comes up from bottom

Change-Id: If216e2b73cfc94184fca64c384575a5d1d903add
---
M wikipedia/assets/bundle.js
M wikipedia/assets/preview.js
A wikipedia/res/layout/dialog_page_info.xml
M wikipedia/res/layout/item_issue.xml
M wikipedia/res/values/colors.xml
M wikipedia/res/values/strings.xml
M wikipedia/res/values/styles.xml
A wikipedia/src/main/java/org/wikipedia/page/BottomDialog.java
D wikipedia/src/main/java/org/wikipedia/page/DisambigHandler.java
A wikipedia/src/main/java/org/wikipedia/page/DisambigListAdapter.java
D wikipedia/src/main/java/org/wikipedia/page/IssuesHandler.java
A wikipedia/src/main/java/org/wikipedia/page/IssuesListAdapter.java
A wikipedia/src/main/java/org/wikipedia/page/PageInfo.java
A wikipedia/src/main/java/org/wikipedia/page/PageInfoDialog.java
A wikipedia/src/main/java/org/wikipedia/page/PageInfoHandler.java
M wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
M wikipedia/src/main/java/org/wikipedia/page/ReferenceDialog.java
M www/js/actions.js
18 files changed, 578 insertions(+), 356 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/12/171512/1

diff --git a/wikipedia/assets/bundle.js b/wikipedia/assets/bundle.js
index 04b7957..bf925e2 100644
--- a/wikipedia/assets/bundle.js
+++ b/wikipedia/assets/bundle.js
@@ -66,30 +66,6 @@
         curNode = curNode.parentNode;
     }
 
-    function collectIssues( sourceNode ) {
-        var res = [];
-        var issues = sourceNode.parentNode.querySelectorAll( 'table.ambox' );
-        var i = 0,
-            len = issues.length;
-        for (; i < len; i++) {
-            // .ambox- is used e.g. on eswiki
-            res.push( issues[i].querySelector( '.mbox-text, .ambox-text' 
).innerHTML );
-        }
-
-        bridge.sendMessage( 'issuesClicked', { "issues": res } );
-    }
-
-    function handleDisambig( sourceNode ) {
-        var res = [];
-        var hatnotes = sourceNode.parentNode.querySelectorAll( 'div.hatnote' );
-        var i = 0,
-            len = hatnotes.length;
-        for (; i < len; i++) {
-            res.push( hatnotes[i].innerHTML );
-        }
-        bridge.sendMessage( 'disambigClicked', { "hatnotes": res } );
-    }
-
     if (sourceNode) {
         if ( sourceNode.hasAttribute( "data-action" ) ) {
             var action = sourceNode.getAttribute( "data-action" );
@@ -101,10 +77,10 @@
             var href = sourceNode.getAttribute( "href" );
             if ( href[0] === "#" ) {
                 var targetId = href.slice(1);
-                if ("issues" === targetId) {
-                    collectIssues(sourceNode);
-                } else if ("disambig" === targetId) {
-                    handleDisambig(sourceNode);
+                if ( "issues" === targetId ) {
+                    issuesClicked( sourceNode );
+                } else if ( "disambig" === targetId ) {
+                    disambigClicked( sourceNode );
                 } else {
                     handleReference( targetId, ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
                 }
@@ -116,6 +92,41 @@
     }
 };
 
+function issuesClicked( sourceNode ) {
+    var issues = collectIssues( sourceNode.parentNode );
+    var disambig = collectDisambig( document ); // the other node is not a 
child of sourceNode
+    bridge.sendMessage( 'issuesClicked', { "hatnotes": disambig, "issues": 
issues } );
+}
+
+function disambigClicked( sourceNode ) {
+    var disambig = collectDisambig( sourceNode.parentNode );
+    var issues = collectIssues( document ); // the other node is not a child 
of sourceNode
+    bridge.sendMessage( 'disambigClicked', { "hatnotes": disambig, "issues": 
issues } );
+}
+
+function collectDisambig( sourceNode ) {
+    var res = [];
+    var hatnotes = sourceNode.querySelectorAll( 'div.hatnote' );
+    var i = 0,
+        len = hatnotes.length;
+    for (; i < len; i++) {
+        res.push( hatnotes[i].innerHTML );
+    }
+    return res;
+}
+
+function collectIssues( sourceNode ) {
+    var res = [];
+    var issues = sourceNode.querySelectorAll( 'table.ambox' );
+    var i = 0,
+        len = issues.length;
+    for (; i < len; i++) {
+        // .ambox- is used e.g. on eswiki
+        res.push( issues[i].querySelector( '.mbox-text, .ambox-text' 
).innerHTML );
+    }
+    return res;
+}
+
 module.exports = new ActionsHandler();
 
 },{"./bridge":2}],2:[function(require,module,exports){
diff --git a/wikipedia/assets/preview.js b/wikipedia/assets/preview.js
index d173794..4c2d353 100644
--- a/wikipedia/assets/preview.js
+++ b/wikipedia/assets/preview.js
@@ -66,30 +66,6 @@
         curNode = curNode.parentNode;
     }
 
-    function collectIssues( sourceNode ) {
-        var res = [];
-        var issues = sourceNode.parentNode.querySelectorAll( 'table.ambox' );
-        var i = 0,
-            len = issues.length;
-        for (; i < len; i++) {
-            // .ambox- is used e.g. on eswiki
-            res.push( issues[i].querySelector( '.mbox-text, .ambox-text' 
).innerHTML );
-        }
-
-        bridge.sendMessage( 'issuesClicked', { "issues": res } );
-    }
-
-    function handleDisambig( sourceNode ) {
-        var res = [];
-        var hatnotes = sourceNode.parentNode.querySelectorAll( 'div.hatnote' );
-        var i = 0,
-            len = hatnotes.length;
-        for (; i < len; i++) {
-            res.push( hatnotes[i].innerHTML );
-        }
-        bridge.sendMessage( 'disambigClicked', { "hatnotes": res } );
-    }
-
     if (sourceNode) {
         if ( sourceNode.hasAttribute( "data-action" ) ) {
             var action = sourceNode.getAttribute( "data-action" );
@@ -101,10 +77,10 @@
             var href = sourceNode.getAttribute( "href" );
             if ( href[0] === "#" ) {
                 var targetId = href.slice(1);
-                if ("issues" === targetId) {
-                    collectIssues(sourceNode);
-                } else if ("disambig" === targetId) {
-                    handleDisambig(sourceNode);
+                if ( "issues" === targetId ) {
+                    issuesClicked( sourceNode );
+                } else if ( "disambig" === targetId ) {
+                    disambigClicked( sourceNode );
                 } else {
                     handleReference( targetId, ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
                 }
@@ -116,6 +92,41 @@
     }
 };
 
+function issuesClicked( sourceNode ) {
+    var issues = collectIssues( sourceNode.parentNode );
+    var disambig = collectDisambig( document ); // the other node is not a 
child of sourceNode
+    bridge.sendMessage( 'issuesClicked', { "hatnotes": disambig, "issues": 
issues } );
+}
+
+function disambigClicked( sourceNode ) {
+    var disambig = collectDisambig( sourceNode.parentNode );
+    var issues = collectIssues( document ); // the other node is not a child 
of sourceNode
+    bridge.sendMessage( 'disambigClicked', { "hatnotes": disambig, "issues": 
issues } );
+}
+
+function collectDisambig( sourceNode ) {
+    var res = [];
+    var hatnotes = sourceNode.querySelectorAll( 'div.hatnote' );
+    var i = 0,
+        len = hatnotes.length;
+    for (; i < len; i++) {
+        res.push( hatnotes[i].innerHTML );
+    }
+    return res;
+}
+
+function collectIssues( sourceNode ) {
+    var res = [];
+    var issues = sourceNode.querySelectorAll( 'table.ambox' );
+    var i = 0,
+        len = issues.length;
+    for (; i < len; i++) {
+        // .ambox- is used e.g. on eswiki
+        res.push( issues[i].querySelector( '.mbox-text, .ambox-text' 
).innerHTML );
+    }
+    return res;
+}
+
 module.exports = new ActionsHandler();
 
 },{"./bridge":2}],2:[function(require,module,exports){
diff --git a/wikipedia/res/layout/dialog_page_info.xml 
b/wikipedia/res/layout/dialog_page_info.xml
new file mode 100644
index 0000000..40faa47
--- /dev/null
+++ b/wikipedia/res/layout/dialog_page_info.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android";
+    xmlns:tools="http://schemas.android.com/tools";
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:background="?attr/page_background_color"
+    >
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0.5dp"
+        android:background="@color/nav_border" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="8dp"
+        >
+
+        <TextView
+            android:id="@+id/page_info_similar_titles_heading"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"
+            style="@style/text_heading_gray"
+            android:text="@string/page_similar_titles" />
+
+        <TextView
+            android:id="@+id/page_info_heading_separator"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="8dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginLeft="7dp"
+            android:layout_marginRight="7dp"
+            style="@style/text_heading_gray"
+            android:text="|"
+            tools:ignore="HardcodedText" />
+
+        <TextView
+            android:id="@+id/page_info_page_issues_heading"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"
+            style="@style/text_heading_gray"
+            android:text="@string/dialog_page_issues" />
+
+    </LinearLayout>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="?android:listDivider" />
+
+    <ListView
+        android:id="@+id/page_info_list"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:paddingBottom="0dp"
+        android:paddingLeft="16dp"
+        android:paddingRight="16dp"
+        android:paddingTop="0dp"
+        />
+
+</LinearLayout>
diff --git a/wikipedia/res/layout/item_issue.xml 
b/wikipedia/res/layout/item_issue.xml
index cc92f7b..029802d 100644
--- a/wikipedia/res/layout/item_issue.xml
+++ b/wikipedia/res/layout/item_issue.xml
@@ -11,7 +11,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="8dp"
-        android:layout_marginLeft="8dp"
         android:src="@drawable/ic_flag" />
 
     <LinearLayout
@@ -21,17 +20,17 @@
         android:padding="8dp">
         <TextView
             android:id="@+id/issue_text"
-            style="?android:textAppearanceMedium"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center" />
-        <TextView
-            android:id="@+id/issue_subtext"
-            style="?android:textAppearanceSmall"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
-            android:layout_marginTop="8dp"
+            android:textSize="16sp" />
+        <TextView
+            android:id="@+id/issue_subtext"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginTop="2dp"
+            android:textSize="12sp"
             android:textColor="@color/issues_subtext"
             android:textAllCaps="true"/>
 
diff --git a/wikipedia/res/values/colors.xml b/wikipedia/res/values/colors.xml
index 1159f25..be9d50d 100644
--- a/wikipedia/res/values/colors.xml
+++ b/wikipedia/res/values/colors.xml
@@ -28,6 +28,7 @@
     <color name="fulltext_search_highlight">#00AF89</color>
     <color name="announcement_background">#0C0C0C</color>
     <color name="announcement_text">#AAAAAA</color>
+    <color name="page_info_heading">#555555</color>
 
     <color name="link_light">#ff347BFF</color>
     <color name="button_light">#ff777777</color>
diff --git a/wikipedia/res/values/strings.xml b/wikipedia/res/values/strings.xml
index f5d84cf..2843485 100644
--- a/wikipedia/res/values/strings.xml
+++ b/wikipedia/res/values/strings.xml
@@ -239,7 +239,7 @@
     <string name="color_theme_select">Theme</string>
     <string name="color_theme_light">Light</string>
     <string name="color_theme_dark">Dark</string>
-    <string name="page_similar_titles">Similar pages</string>
+    <string name="page_similar_titles">Other meanings</string>
     <string name="search_within_pages">Search within pages…</string>
     <string name="search_no_results">No results found for \"%s\".</string>
     <string name="search_did_you_mean">Did you mean \"%s\"?</string>
diff --git a/wikipedia/res/values/styles.xml b/wikipedia/res/values/styles.xml
index 87fc704..582a0b4 100644
--- a/wikipedia/res/values/styles.xml
+++ b/wikipedia/res/values/styles.xml
@@ -33,4 +33,9 @@
         <item name="android:background">@drawable/button_selector_gray</item>
     </style>
 
+    <style name="text_heading_gray" 
parent="@android:style/TextAppearance.Medium">
+        <item name="android:textSize">16sp</item>
+        <item name="android:textColor">@color/page_info_heading</item>
+    </style>
+
 </resources>
diff --git a/wikipedia/src/main/java/org/wikipedia/page/BottomDialog.java 
b/wikipedia/src/main/java/org/wikipedia/page/BottomDialog.java
new file mode 100644
index 0000000..6002864
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/page/BottomDialog.java
@@ -0,0 +1,42 @@
+package org.wikipedia.page;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Build;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+
+/**
+ * A dialog that appears at the bottom of the page.
+ */
+public class BottomDialog extends Dialog {
+    private View dialogLayout;
+
+    public BottomDialog(Context context, int dialogLayoutResId) {
+        super(context);
+
+        LayoutInflater inflater = (LayoutInflater) 
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        dialogLayout = inflater.inflate(dialogLayoutResId, null);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            getWindow().setDimAmount(0.0f);
+        }
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        setContentView(dialogLayout);
+
+        getWindow().setBackgroundDrawable(null);
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
+        lp.copyFrom(getWindow().getAttributes());
+        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
+        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        lp.gravity = Gravity.BOTTOM;
+        getWindow().setAttributes(lp);
+    }
+
+    protected View getDialogLayout() {
+        return dialogLayout;
+    }
+}
diff --git a/wikipedia/src/main/java/org/wikipedia/page/DisambigHandler.java 
b/wikipedia/src/main/java/org/wikipedia/page/DisambigHandler.java
deleted file mode 100644
index 8c2d507..0000000
--- a/wikipedia/src/main/java/org/wikipedia/page/DisambigHandler.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.wikipedia.page;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.text.Html;
-import android.text.Spannable;
-import android.text.TextPaint;
-import android.text.style.URLSpan;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.wikipedia.R;
-import org.wikipedia.Utils;
-import org.wikipedia.WikipediaApp;
-import org.wikipedia.bridge.CommunicationBridge;
-
-/**
- * Handles the #disambig links coming from a {@link 
org.wikipedia.page.PageViewFragment}.
- * Automatically goes to the disambiguation page for the selected item.
- */
-public abstract class DisambigHandler implements 
CommunicationBridge.JSEventListener {
-    private final Activity activity;
-    private Dialog dlg;
-
-    public DisambigHandler(Activity activity, CommunicationBridge bridge) {
-        this.activity = activity;
-        bridge.addListener("disambigClicked", this);
-    }
-
-    // message from JS bridge:
-    @Override
-    public void onMessage(String messageType, JSONObject messagePayload) {
-        try {
-            
show(Utils.jsonArrayToStringArray(messagePayload.getJSONArray("hatnotes")));
-        } catch (JSONException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void show(final String[] items) {
-        final WikipediaApp app = (WikipediaApp) 
activity.getApplicationContext();
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
-        ListAdapter adapter = new ArrayAdapter<String>(activity, 0, items) {
-            private ViewHolder holder;
-
-            class ViewHolder {
-                private ImageView icon;
-                private TextView text;
-            }
-
-            @Override
-            public boolean isEnabled(int position) {
-                return false; // don't make it appear clickable
-            }
-
-            public View getView(int position, View convertView, ViewGroup 
parent) {
-                LayoutInflater inflater = activity.getLayoutInflater();
-                if (convertView == null) {
-                    convertView = inflater.inflate(R.layout.item_disambig, 
null);
-                    holder = new ViewHolder();
-                    holder.icon = (ImageView) 
convertView.findViewById(R.id.disambig_icon);
-                    holder.text = (TextView) 
convertView.findViewById(R.id.disambig_text);
-                    convertView.setTag(holder);
-                } else {
-                    // view already defined, retrieve view holder
-                    holder = (ViewHolder) convertView.getTag();
-                }
-
-                holder.text.setText(Html.fromHtml(items[position]));
-                holder.text.setMovementMethod(new 
LinkMovementMethodExt(getLinkHandler()) {
-                    @Override
-                    public boolean onTouchEvent(final TextView widget, final 
Spannable buffer, final MotionEvent event) {
-                        boolean ret = super.onTouchEvent(widget, buffer, 
event);
-                        if (ret && event.getAction() == MotionEvent.ACTION_UP 
&& dlg != null) {
-                            dlg.dismiss();
-                        }
-                        return ret;
-                    }
-                });
-                stripUnderlines(holder.text);
-                app.adjustLinkDrawableToTheme(holder.icon.getDrawable());
-                return convertView;
-            }
-
-            private void stripUnderlines(TextView textView) {
-                Spannable s = (Spannable)textView.getText();
-                URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
-                for (URLSpan span: spans) {
-                    int start = s.getSpanStart(span);
-                    int end = s.getSpanEnd(span);
-                    s.removeSpan(span);
-                    span = new URLSpan(span.getURL()) {
-                        @Override
-                        public void updateDrawState(TextPaint ds) {
-                            super.updateDrawState(ds);
-                            ds.setUnderlineText(false);
-                        }
-                    };
-                    s.setSpan(span, start, end, 0);
-                }
-                textView.setText(s);
-            }
-        };
-
-        builder.setAdapter(adapter, null);
-        builder.setTitle(R.string.page_similar_titles);
-        dlg = builder.create();
-        dlg.show();
-    }
-
-    public abstract LinkHandler getLinkHandler();
-
-}
diff --git 
a/wikipedia/src/main/java/org/wikipedia/page/DisambigListAdapter.java 
b/wikipedia/src/main/java/org/wikipedia/page/DisambigListAdapter.java
new file mode 100644
index 0000000..ed27f5b
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/page/DisambigListAdapter.java
@@ -0,0 +1,87 @@
+package org.wikipedia.page;
+
+import org.wikipedia.R;
+import org.wikipedia.WikipediaApp;
+import android.app.Activity;
+import android.text.Html;
+import android.text.Spannable;
+import android.text.TextPaint;
+import android.text.style.URLSpan;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ *
+ */
+class DisambigListAdapter extends ArrayAdapter<String> {
+    private final Activity activity;
+    private final String[] items;
+    private LinkMovementMethodExt movementMethod;
+
+    /**
+     * Constructor
+     * @param activity The current activity.
+     * @param items The objects to represent in the ListView.
+     */
+    public DisambigListAdapter(Activity activity, String[] items, 
LinkMovementMethodExt movementMethod) {
+        super(activity, 0, items);
+        this.activity = activity;
+        this.items = items;
+        this.movementMethod = movementMethod;
+    }
+
+    class ViewHolder {
+        private ImageView icon;
+        private TextView text;
+    }
+
+    @Override
+    public boolean isEnabled(int position) {
+        return false; // don't make it appear clickable
+    }
+
+    public View getView(int position, View convertView, ViewGroup parent) {
+        LayoutInflater inflater = activity.getLayoutInflater();
+        ViewHolder holder;
+        if (convertView == null) {
+            convertView = inflater.inflate(R.layout.item_disambig, null);
+            holder = new ViewHolder();
+            holder.icon = (ImageView) 
convertView.findViewById(R.id.disambig_icon);
+            holder.text = (TextView) 
convertView.findViewById(R.id.disambig_text);
+            convertView.setTag(holder);
+        } else {
+            // view already defined, retrieve view holder
+            holder = (ViewHolder) convertView.getTag();
+        }
+
+        holder.text.setText(Html.fromHtml(items[position]));
+        holder.text.setMovementMethod(movementMethod);
+        stripUnderlines(holder.text);
+        final WikipediaApp app = (WikipediaApp) 
activity.getApplicationContext();
+        app.adjustLinkDrawableToTheme(holder.icon.getDrawable());
+        return convertView;
+    }
+
+    private void stripUnderlines(TextView textView) {
+        Spannable s = (Spannable)textView.getText();
+        URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
+        for (URLSpan span: spans) {
+            int start = s.getSpanStart(span);
+            int end = s.getSpanEnd(span);
+            s.removeSpan(span);
+            span = new URLSpan(span.getURL()) {
+                @Override
+                public void updateDrawState(TextPaint ds) {
+                    super.updateDrawState(ds);
+                    ds.setUnderlineText(false);
+                }
+            };
+            s.setSpan(span, start, end, 0);
+        }
+        textView.setText(s);
+    }
+}
diff --git a/wikipedia/src/main/java/org/wikipedia/page/IssuesHandler.java 
b/wikipedia/src/main/java/org/wikipedia/page/IssuesHandler.java
deleted file mode 100644
index 6e5747d..0000000
--- a/wikipedia/src/main/java/org/wikipedia/page/IssuesHandler.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package org.wikipedia.page;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.text.Html;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.wikipedia.R;
-import org.wikipedia.Utils;
-import org.wikipedia.WikipediaApp;
-import org.wikipedia.bridge.CommunicationBridge;
-
-/**
- * Handles the #issues links coming from a {@link 
org.wikipedia.page.PageViewFragment}.
- * Shows a dialog with a list of issues when the issues link is clicked.
- */
-public class IssuesHandler implements CommunicationBridge.JSEventListener {
-    private static final String SEPARATOR = "<small><i>(";
-    private static final String SEPARATOR_END = ")</i></small>";
-
-    private final Activity activity;
-
-    public IssuesHandler(final Activity activity, CommunicationBridge bridge) {
-        this.activity = activity;
-        bridge.addListener("issuesClicked", this);
-    }
-
-    // message from JS bridge:
-    @Override
-    public void onMessage(String messageType, JSONObject messagePayload) {
-        try {
-            
show(Utils.jsonArrayToStringArray(messagePayload.getJSONArray("issues")));
-        } catch (JSONException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void show(final String[] items) {
-        final WikipediaApp app = (WikipediaApp) 
activity.getApplicationContext();
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
-        ListAdapter adapter = new ArrayAdapter<String>(activity, 0, items) {
-            private ViewHolder holder;
-
-            class ViewHolder {
-                private ImageView icon;
-                private TextView text;
-                private TextView subText;
-            }
-
-            @Override
-            public boolean isEnabled(int position) {
-                return false; // don't make it appear clickable
-            }
-
-            public View getView(int position, View convertView, ViewGroup 
parent) {
-                LayoutInflater inflater = activity.getLayoutInflater();
-                if (convertView == null) {
-                    convertView = inflater.inflate(R.layout.item_issue, null);
-                    holder = new ViewHolder();
-                    holder.icon = (ImageView) 
convertView.findViewById(R.id.issue_icon);
-                    holder.text = (TextView) 
convertView.findViewById(R.id.issue_text);
-                    holder.subText = (TextView) 
convertView.findViewById(R.id.issue_subtext);
-                    convertView.setTag(holder);
-                } else {
-                    // view already defined, retrieve view holder
-                    holder = (ViewHolder) convertView.getTag();
-                }
-
-                updateText(position);
-                app.adjustLinkDrawableToTheme(holder.icon.getDrawable());
-                return convertView;
-            }
-
-            private void updateText(int position) {
-                String fullText = items[position].replaceAll(" href\\s*=", " 
x="); // disable links
-                int end = fullText.lastIndexOf(SEPARATOR_END);
-                int start = fullText.lastIndexOf(SEPARATOR, end);
-                if (start != -1 && end != -1) {
-                    String text1 = fullText.substring(0, start);
-                    String text2 = fullText.substring(start + 
SEPARATOR.length(), end);
-                    holder.text.setText(Html.fromHtml(text1));
-                    holder.subText.setText(Html.fromHtml(text2));
-                    holder.subText.setVisibility(View.VISIBLE);
-                } else {
-                    holder.text.setText(Html.fromHtml(fullText));
-                    holder.subText.setVisibility(View.GONE);
-                }
-            }
-        };
-
-        builder.setAdapter(adapter, null);
-        builder.setTitle(R.string.dialog_page_issues);
-
-        builder.create().show();
-    }
-}
diff --git a/wikipedia/src/main/java/org/wikipedia/page/IssuesListAdapter.java 
b/wikipedia/src/main/java/org/wikipedia/page/IssuesListAdapter.java
new file mode 100644
index 0000000..624dff3
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/page/IssuesListAdapter.java
@@ -0,0 +1,81 @@
+package org.wikipedia.page;
+
+import org.wikipedia.R;
+import org.wikipedia.WikipediaApp;
+import android.app.Activity;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ *
+ */
+class IssuesListAdapter extends ArrayAdapter<String> {
+    private static final String SEPARATOR = "<small><i>(";
+    private static final String SEPARATOR_END = ")</i></small>";
+    private final Activity activity;
+    private final String[] items;
+
+    private ViewHolder holder;
+
+    /**
+     * Constructor
+     * @param activity The current activity.
+     * @param items The objects to represent in the ListView.
+     */
+    public IssuesListAdapter(Activity activity, String[] items) {
+        super(activity, 0, items);
+        this.activity = activity;
+        this.items = items;
+    }
+
+    class ViewHolder {
+        private ImageView icon;
+        private TextView text;
+        private TextView subText;
+    }
+
+    @Override
+    public boolean isEnabled(int position) {
+        return false; // don't make it appear clickable
+    }
+
+    public View getView(int position, View convertView, ViewGroup parent) {
+        LayoutInflater inflater = activity.getLayoutInflater();
+        if (convertView == null) {
+            convertView = inflater.inflate(R.layout.item_issue, null);
+            holder = new ViewHolder();
+            holder.icon = (ImageView) 
convertView.findViewById(R.id.issue_icon);
+            holder.text = (TextView) convertView.findViewById(R.id.issue_text);
+            holder.subText = (TextView) 
convertView.findViewById(R.id.issue_subtext);
+            convertView.setTag(holder);
+        } else {
+            // view already defined, retrieve view holder
+            holder = (ViewHolder) convertView.getTag();
+        }
+
+        updateText(position);
+        ((WikipediaApp) 
activity.getApplicationContext()).adjustLinkDrawableToTheme(holder.icon.getDrawable());
+        return convertView;
+    }
+
+    private void updateText(int position) {
+        String fullText = items[position].replaceAll(" href\\s*=", " x="); // 
disable links
+        int end = fullText.lastIndexOf(SEPARATOR_END);
+        int start = fullText.lastIndexOf(SEPARATOR, end);
+        if (start != -1 && end != -1) {
+            String text1 = fullText.substring(0, start);
+            String text2 = fullText.substring(start + SEPARATOR.length(), end);
+            holder.text.setText(Html.fromHtml(text1));
+            holder.subText.setText(Html.fromHtml(text2));
+            holder.subText.setVisibility(View.VISIBLE);
+        } else {
+            holder.text.setText(Html.fromHtml(fullText));
+            holder.subText.setVisibility(View.GONE);
+        }
+    }
+}
diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageInfo.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageInfo.java
new file mode 100644
index 0000000..31f12c7
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageInfo.java
@@ -0,0 +1,22 @@
+package org.wikipedia.page;
+
+/**
+ *
+ */
+public class PageInfo {
+    private final String[] disambigs;
+    private final String[] issues;
+
+    public PageInfo(String[] disambigs, String[] issues) {
+        this.disambigs = disambigs;
+        this.issues = issues;
+    }
+
+    public String[] getDisambigs() {
+        return disambigs;
+    }
+
+    public String[] getIssues() {
+        return issues;
+    }
+}
diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageInfoDialog.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageInfoDialog.java
new file mode 100644
index 0000000..eddb743
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageInfoDialog.java
@@ -0,0 +1,69 @@
+package org.wikipedia.page;
+
+import org.wikipedia.R;
+import android.app.Activity;
+import android.graphics.Typeface;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TextView;
+
+/**
+ * A dialog to host page issues and disambig information.
+ */
+class PageInfoDialog extends BottomDialog {
+    private final Activity activity;
+    private final PageInfo info;
+    private final LinkMovementMethodExt movementMethod;
+    private ListView list;
+    private TextView disambigHeading;
+    private TextView issuesHeading;
+
+    PageInfoDialog(Activity activity, PageInfo pageInfo, int height, 
LinkMovementMethodExt movementMethod) {
+        super(activity, R.layout.dialog_page_info);
+        this.activity = activity;
+        info = pageInfo;
+        this.movementMethod = movementMethod;
+
+        View parentView = getDialogLayout();
+        list = (ListView) parentView.findViewById(R.id.page_info_list);
+        disambigHeading = (TextView) 
parentView.findViewById(R.id.page_info_similar_titles_heading);
+        issuesHeading = (TextView) 
parentView.findViewById(R.id.page_info_page_issues_heading);
+        View separatorHeading = 
parentView.findViewById(R.id.page_info_heading_separator);
+
+        parentView.setMinimumHeight(height);
+        if (pageInfo.getDisambigs().length > 0) {
+            disambigHeading.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    showDisambig();
+                }
+            });
+        } else {
+            disambigHeading.setVisibility(View.GONE);
+            separatorHeading.setVisibility(View.GONE);
+        }
+        if (pageInfo.getIssues().length > 0) {
+            issuesHeading.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    showIssues();
+                }
+            });
+        } else {
+            issuesHeading.setVisibility(View.GONE);
+            separatorHeading.setVisibility(View.GONE);
+        }
+    }
+
+    void showDisambig() {
+        list.setAdapter(new DisambigListAdapter(activity, info.getDisambigs(), 
movementMethod));
+        disambigHeading.setTypeface(null, Typeface.BOLD);
+        issuesHeading.setTypeface(null, Typeface.NORMAL);
+    }
+
+    void showIssues() {
+        list.setAdapter(new IssuesListAdapter(activity, info.getIssues()));
+        disambigHeading.setTypeface(null, Typeface.NORMAL);
+        issuesHeading.setTypeface(null, Typeface.BOLD);
+    }
+}
diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageInfoHandler.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageInfoHandler.java
new file mode 100644
index 0000000..ece0850
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageInfoHandler.java
@@ -0,0 +1,59 @@
+package org.wikipedia.page;
+
+import org.wikipedia.Utils;
+import org.wikipedia.bridge.CommunicationBridge;
+import org.json.JSONException;
+import org.json.JSONObject;
+import android.app.Activity;
+import android.text.Spannable;
+import android.view.MotionEvent;
+import android.widget.TextView;
+
+/**
+ * A handler for both disambiguation and page issues information.
+ * It listens to disambig and page issues link clicks from the WebView.
+ * When clicked it shows the PageInfoDialog with the respective list.
+ */
+abstract class PageInfoHandler implements CommunicationBridge.JSEventListener {
+    private final Activity activity;
+    private PageInfoDialog dialog;
+
+    PageInfoHandler(Activity activity, CommunicationBridge bridge) {
+        this.activity = activity;
+        bridge.addListener("disambigClicked", this);
+        bridge.addListener("issuesClicked", this);
+    }
+
+    private LinkMovementMethodExt movementMethod = new 
LinkMovementMethodExt(getLinkHandler()) {
+        @Override
+        public boolean onTouchEvent(final TextView widget, final Spannable 
buffer, final MotionEvent event) {
+            boolean ret = super.onTouchEvent(widget, buffer, event);
+            if (ret && event.getAction() == MotionEvent.ACTION_UP) {
+                dialog.dismiss();
+            }
+            return ret;
+        }
+    };
+
+    // message from JS bridge:
+    @Override
+    public void onMessage(String messageType, JSONObject messagePayload) {
+        try {
+            PageInfo info = new 
PageInfo(Utils.jsonArrayToStringArray(messagePayload.getJSONArray("hatnotes")),
+                                         
Utils.jsonArrayToStringArray(messagePayload.getJSONArray("issues")));
+            dialog = new PageInfoDialog(activity, info, getDialogHeight(), 
movementMethod);
+            dialog.show();
+            if ("disambigClicked".equals(messageType)) {
+                dialog.showDisambig();
+            } else if ("issuesClicked".equals(messageType)) {
+                dialog.showIssues();
+            }
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    abstract LinkHandler getLinkHandler();
+
+    abstract int getDialogHeight();
+}
diff --git 
a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
index d2e03bd..0d48321 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
@@ -105,6 +105,7 @@
     private PageTitle title;
     private PageTitle titleOriginal;
     private View contentsContainer;
+    private ViewGroup imagesContainer;
     private LeadImagesHandler leadImagesHandler;
     private ObservableWebView webView;
     private View networkError;
@@ -346,12 +347,16 @@
             }
         };
 
-        new IssuesHandler(getActivity(), bridge);
-
-        new DisambigHandler(getActivity(), bridge){
+        new PageInfoHandler(getActivity(), bridge) {
             @Override
-            public LinkHandler getLinkHandler() {
+            LinkHandler getLinkHandler() {
                 return linkHandler;
+            }
+
+            @Override
+            int getDialogHeight() {
+                // could have scrolled up a bit but the page info links must 
still be visible else they couldn't have been clicked
+                return webView.getHeight() + webView.getScrollY() - 
imagesContainer.getHeight();
             }
         };
 
@@ -379,8 +384,8 @@
         editHandler = new EditHandler(parentFragment, bridge);
 
         new SearchBarHideHandler(webView, getActivity());
-        leadImagesHandler = new LeadImagesHandler(parentFragment, bridge, 
webView,
-                
(ViewGroup)parentFragment.getView().findViewById(R.id.page_images_container));
+        imagesContainer = (ViewGroup) 
parentFragment.getView().findViewById(R.id.page_images_container);
+        leadImagesHandler = new LeadImagesHandler(parentFragment, bridge, 
webView, imagesContainer);
 
         //is this page in cache??
         if (PAGE_CACHE.has(titleOriginal)) {
diff --git a/wikipedia/src/main/java/org/wikipedia/page/ReferenceDialog.java 
b/wikipedia/src/main/java/org/wikipedia/page/ReferenceDialog.java
index 58b639a..e9ad170 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/ReferenceDialog.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/ReferenceDialog.java
@@ -1,45 +1,22 @@
 package org.wikipedia.page;
 
-import android.app.Dialog;
+import org.wikipedia.R;
 import android.content.Context;
-import android.os.Build;
 import android.text.Html;
 import android.text.Spanned;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
 import android.widget.TextView;
-import org.wikipedia.R;
 
-/** Display the currently clicked reference */
-public class ReferenceDialog extends Dialog {
+/**
+ * A dialog that displays the currently clicked reference.
+ */
+public class ReferenceDialog extends BottomDialog {
     private final LinkHandler linkHandler;
     private final TextView referenceText;
 
     public ReferenceDialog(Context context, LinkHandler linkHandler) {
-        super(context);
+        super(context, R.layout.dialog_reference);
         this.linkHandler = linkHandler;
-
-        LayoutInflater inflater = (LayoutInflater) 
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View dlgLayout = inflater.inflate(R.layout.dialog_reference, null);
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            getWindow().setDimAmount(0.0f);
-        }
-        requestWindowFeature(Window.FEATURE_NO_TITLE);
-        setContentView(dlgLayout);
-
-        getWindow().setBackgroundDrawable(null);
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
-        lp.copyFrom(getWindow().getAttributes());
-        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
-        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
-        lp.gravity = Gravity.BOTTOM;
-        getWindow().setAttributes(lp);
-
-        referenceText = (TextView) dlgLayout.findViewById(R.id.reference_text);
+        referenceText = (TextView) 
getDialogLayout().findViewById(R.id.reference_text);
     }
 
     void updateReference(String refHtml) {
diff --git a/www/js/actions.js b/www/js/actions.js
index cb1a786..1ba8269 100644
--- a/www/js/actions.js
+++ b/www/js/actions.js
@@ -65,30 +65,6 @@
         curNode = curNode.parentNode;
     }
 
-    function collectIssues( sourceNode ) {
-        var res = [];
-        var issues = sourceNode.parentNode.querySelectorAll( 'table.ambox' );
-        var i = 0,
-            len = issues.length;
-        for (; i < len; i++) {
-            // .ambox- is used e.g. on eswiki
-            res.push( issues[i].querySelector( '.mbox-text, .ambox-text' 
).innerHTML );
-        }
-
-        bridge.sendMessage( 'issuesClicked', { "issues": res } );
-    }
-
-    function handleDisambig( sourceNode ) {
-        var res = [];
-        var hatnotes = sourceNode.parentNode.querySelectorAll( 'div.hatnote' );
-        var i = 0,
-            len = hatnotes.length;
-        for (; i < len; i++) {
-            res.push( hatnotes[i].innerHTML );
-        }
-        bridge.sendMessage( 'disambigClicked', { "hatnotes": res } );
-    }
-
     if (sourceNode) {
         if ( sourceNode.hasAttribute( "data-action" ) ) {
             var action = sourceNode.getAttribute( "data-action" );
@@ -100,10 +76,10 @@
             var href = sourceNode.getAttribute( "href" );
             if ( href[0] === "#" ) {
                 var targetId = href.slice(1);
-                if ("issues" === targetId) {
-                    collectIssues(sourceNode);
-                } else if ("disambig" === targetId) {
-                    handleDisambig(sourceNode);
+                if ( "issues" === targetId ) {
+                    issuesClicked( sourceNode );
+                } else if ( "disambig" === targetId ) {
+                    disambigClicked( sourceNode );
                 } else {
                     handleReference( targetId, ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
                 }
@@ -115,4 +91,39 @@
     }
 };
 
+function issuesClicked( sourceNode ) {
+    var issues = collectIssues( sourceNode.parentNode );
+    var disambig = collectDisambig( document ); // the other node is not a 
child of sourceNode
+    bridge.sendMessage( 'issuesClicked', { "hatnotes": disambig, "issues": 
issues } );
+}
+
+function disambigClicked( sourceNode ) {
+    var disambig = collectDisambig( sourceNode.parentNode );
+    var issues = collectIssues( document ); // the other node is not a child 
of sourceNode
+    bridge.sendMessage( 'disambigClicked', { "hatnotes": disambig, "issues": 
issues } );
+}
+
+function collectDisambig( sourceNode ) {
+    var res = [];
+    var hatnotes = sourceNode.querySelectorAll( 'div.hatnote' );
+    var i = 0,
+        len = hatnotes.length;
+    for (; i < len; i++) {
+        res.push( hatnotes[i].innerHTML );
+    }
+    return res;
+}
+
+function collectIssues( sourceNode ) {
+    var res = [];
+    var issues = sourceNode.querySelectorAll( 'table.ambox' );
+    var i = 0,
+        len = issues.length;
+    for (; i < len; i++) {
+        // .ambox- is used e.g. on eswiki
+        res.push( issues[i].querySelector( '.mbox-text, .ambox-text' 
).innerHTML );
+    }
+    return res;
+}
+
 module.exports = new ActionsHandler();

-- 
To view, visit https://gerrit.wikimedia.org/r/171512
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If216e2b73cfc94184fca64c384575a5d1d903add
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: BearND <bsitzm...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to