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 233003 320dd3495026132dda46ca14cae852070787209e
parent 233002 e1ae6cb6c6b131aadcf10ac9b3486694757bb576
child 233004 433cb9e553e117c9d3c46c43774a2b819866788a
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbnicholson
bugs1063193
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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>