Bug 1063193 - Add mobile-specific URL to wikipedia search plugin. r=bnicholson
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Fri, 10 Oct 2014 10:24:30 -0400
changeset 209788 320dd3495026132dda46ca14cae852070787209e
parent 209787 e1ae6cb6c6b131aadcf10ac9b3486694757bb576
child 209789 433cb9e553e117c9d3c46c43774a2b819866788a
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbnicholson
bugs1063193
milestone35.0a1
Bug 1063193 - Add mobile-specific URL to wikipedia search plugin. r=bnicholson
mobile/android/search/java/org/mozilla/search/providers/SearchEngine.java
mobile/locales/en-US/searchplugins/wikipedia.xml
--- a/mobile/android/search/java/org/mozilla/search/providers/SearchEngine.java
+++ b/mobile/android/search/java/org/mozilla/search/providers/SearchEngine.java
@@ -8,29 +8,33 @@ import android.net.Uri;
 import android.util.Log;
 import android.util.Xml;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
 /**
  * Extend this class to add a new search engine to
  * the search activity.
  */
 public class SearchEngine {
     private static final String LOG_TAG = "SearchEngine";
 
     private static final String URLTYPE_SUGGEST_JSON = "application/x-suggestions+json";
     private static final String URLTYPE_SEARCH_HTML  = "text/html";
 
+    private static final String URL_REL_MOBILE = "mobile";
+
     // Parameters copied from nsSearchService.js
     private static final String MOZ_PARAM_LOCALE = "\\{moz:locale\\}";
     private static final String MOZ_PARAM_DIST_ID = "\\{moz:distributionID\\}";
     private static final String MOZ_PARAM_OFFICIAL = "\\{moz:official\\}";
 
     // Supported OpenSearch parameters
     // See http://opensearch.a9.com/spec/1.1/querysyntax/#core
     private static final String OS_PARAM_USER_DEFINED = "\\{searchTerms\\??\\}";
@@ -47,18 +51,18 @@ public class SearchEngine {
                     "tag.type='text/css';" +
                     "document.getElementsByTagName('head')[0].appendChild(tag);" +
                     "tag.innerText='%s'})();";
 
     private String identifier;
     private String shortName;
     private String iconURL;
 
-    // TODO: Make something more robust (like EngineURL in nsSearchService.js)
-    private Uri resultsUri;
+    // Ordered list of preferred results URIs.
+    private final List<Uri> resultsUris = new ArrayList<Uri>();
     private Uri suggestUri;
 
     /**
      *
      * @param in InputStream of open search plugin XML
      */
     public SearchEngine(String identifier, InputStream in) throws IOException, XmlPullParserException {
         this.identifier = identifier;
@@ -97,16 +101,17 @@ public class SearchEngine {
         }
     }
 
     private void readUrl(XmlPullParser parser) throws XmlPullParserException, IOException {
         parser.require(XmlPullParser.START_TAG, null, "Url");
 
         final String type = parser.getAttributeValue(null, "type");
         final String template = parser.getAttributeValue(null, "template");
+        final String rel = parser.getAttributeValue(null, "rel");
 
         Uri uri = Uri.parse(template);
 
         while (parser.next() != XmlPullParser.END_TAG) {
             if (parser.getEventType() != XmlPullParser.START_TAG) {
                 continue;
             }
 
@@ -120,17 +125,22 @@ public class SearchEngine {
             // TODO: Support for other tags
             //} else if (tag.equals("MozParam")) {
             } else {
                 skip(parser);
             }
         }
 
         if (type.equals(URLTYPE_SEARCH_HTML)) {
-            resultsUri = uri;
+            // Prefer mobile URIs.
+            if (rel != null && rel.equals(URL_REL_MOBILE)) {
+                resultsUris.add(0, uri);
+            } else {
+                resultsUris.add(uri);
+            }
         } else if (type.equals(URLTYPE_SUGGEST_JSON)) {
             suggestUri = uri;
         }
     }
 
     private void readImage(XmlPullParser parser) throws XmlPullParserException, IOException {
         parser.require(XmlPullParser.START_TAG, null, "Image");
 
@@ -195,41 +205,43 @@ public class SearchEngine {
         return iconURL;
     }
 
     /**
      * Determine whether a particular url belongs to this search engine. If not,
      * the url will be sent to Fennec.
      */
     public boolean isSearchResultsPage(String url) {
-        return resultsUri.getAuthority().equalsIgnoreCase(Uri.parse(url).getAuthority());
+        return getResultsUri().getAuthority().equalsIgnoreCase(Uri.parse(url).getAuthority());
     }
 
     /**
      * Finds the search query encoded in a given results URL.
      *
      * @param url Current results URL.
      * @return The search query, or an empty string if a query couldn't be found.
      */
     public String queryForResultsUrl(String url) {
+        final Uri resultsUri = getResultsUri();
         final Set<String> names = resultsUri.getQueryParameterNames();
         for (String name : names) {
             if (resultsUri.getQueryParameter(name).matches(OS_PARAM_USER_DEFINED)) {
                 return Uri.parse(url).getQueryParameter(name);
             }
         }
         return "";
     }
 
     /**
      * Create a uri string that can be used to fetch the results page.
      *
      * @param query The user's query. This method will escape and encode the query.
      */
     public String resultsUriForQuery(String query) {
+        final Uri resultsUri = getResultsUri();
         if (resultsUri == null) {
             Log.e(LOG_TAG, "No results URL for search engine: " + identifier);
             return "";
         }
         final String template = Uri.decode(resultsUri.toString());
         return paramSubstitution(template, Uri.encode(query));
     }
 
@@ -243,16 +255,26 @@ public class SearchEngine {
             Log.e(LOG_TAG, "No suggestions template for search engine: " + identifier);
             return "";
         }
         final String template = Uri.decode(suggestUri.toString());
         return paramSubstitution(template, Uri.encode(query));
     }
 
     /**
+     * @return Preferred results URI.
+     */
+    private Uri getResultsUri() {
+        if (resultsUris.isEmpty()) {
+            return null;
+        }
+        return resultsUris.get(0);
+    }
+
+    /**
      * Formats template string with proper parameters. Modeled after
      * ParamSubstitution in nsSearchService.js
      *
      * @param template
      * @param query
      * @return
      */
     private String paramSubstitution(String template, String query) {
--- a/mobile/locales/en-US/searchplugins/wikipedia.xml
+++ b/mobile/locales/en-US/searchplugins/wikipedia.xml
@@ -9,10 +9,14 @@
 <Url type="application/x-suggestions+json" method="GET" template="https://en.wikipedia.org/w/api.php">
   <Param name="action" value="opensearch"/>
   <Param name="search" value="{searchTerms}"/>
 </Url>
 <Url type="text/html" method="GET" template="https://en.wikipedia.org/wiki/Special:Search">
   <Param name="search" value="{searchTerms}"/>
   <Param name="sourceid" value="Mozilla-search"/>
 </Url>
+<Url type="text/html" method="GET" rel="mobile" template="https://en.m.wikipedia.org/wiki/Special:Search">
+  <Param name="search" value="{searchTerms}"/>
+  <Param name="sourceid" value="Mozilla-search"/>
+</Url>
 <SearchForm>https://en.wikipedia.org/wiki/Special:Search</SearchForm>
 </SearchPlugin>