diff --git a/Client/Frontend/Browser/OpenSearch.swift b/Client/Frontend/Browser/OpenSearch.swift index 3f7f889d6f64..3505e9986ecb 100644 --- a/Client/Frontend/Browser/OpenSearch.swift +++ b/Client/Frontend/Browser/OpenSearch.swift @@ -5,6 +5,8 @@ import Foundation import UIKit +private let TypeSearch = "text/html" + private class OpenSearchURL { let template: String let type: String @@ -19,34 +21,28 @@ class OpenSearchEngine { let shortName: String let description: String? let image: UIImage? - private let urls: [OpenSearchURL] + private let searchURL: OpenSearchURL - private init(shortName: String, description: String?, urls: [OpenSearchURL], image: UIImage?) { + private init(shortName: String, description: String?, image: UIImage?, searchURL: OpenSearchURL) { self.shortName = shortName self.description = description - self.urls = urls self.image = image + self.searchURL = searchURL } /** * Returns the search URL for the given query. - * - * The element with the "text/html" type is used for the template. */ - func urlForQuery(query: String) -> NSURL? { - for url in urls { - if url.type == "text/html" { - let escapedQuery = query.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) - if escapedQuery == nil { - return nil - } + func searchURLForQuery(query: String) -> NSURL? { + return getURLFromTemplate(searchURL, query: query) + } - let urlString = url.template.stringByReplacingOccurrencesOfString("{searchTerms}", withString: escapedQuery!, options: NSStringCompareOptions.LiteralSearch, range: nil) - return NSURL(string: urlString) - } + private func getURLFromTemplate(openSearchURL: OpenSearchURL, query: String) -> NSURL? { + if let escapedQuery = query.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) { + let urlString = openSearchURL.template.stringByReplacingOccurrencesOfString("{searchTerms}", withString: escapedQuery, options: NSStringCompareOptions.LiteralSearch, range: nil) + return NSURL(string: urlString) } - println("Error: search engine does not support text/html searches") return nil } } @@ -107,20 +103,26 @@ class OpenSearchParser { return nil } + var searchURL: OpenSearchURL! var searchURLs = [OpenSearchURL]() for url in urls! { - var template = url.attributes["template"] - if template == nil { - println("Url element requires a template attribute") - return nil - } - let type = url.attributes["type"] if type == nil { println("Url element requires a type attribute") return nil } + if type != TypeSearch { + // Not a supported search type. + continue + } + + var template = url.attributes["template"] + if template == nil { + println("Url element requires a template attribute") + return nil + } + if pluginMode { var params = url.elements["Param"] @@ -145,8 +147,15 @@ class OpenSearchParser { } } - let searchURL = OpenSearchURL(template: template!, type: type!) - searchURLs.append(searchURL) + let url = OpenSearchURL(template: template!, type: type!) + if type == TypeSearch { + searchURL = url + } + } + + if searchURL == nil { + println("Search engine must have a text/html type") + return nil } var uiImage: UIImage? @@ -182,6 +191,6 @@ class OpenSearchParser { } } - return OpenSearchEngine(shortName: shortName!, description: description, urls: searchURLs, image: uiImage) + return OpenSearchEngine(shortName: shortName!, description: description, image: uiImage, searchURL: searchURL) } } \ No newline at end of file diff --git a/Client/Frontend/TabBar/SearchViewController.swift b/Client/Frontend/TabBar/SearchViewController.swift index 4303c6cd6185..612ad1bb9e45 100644 --- a/Client/Frontend/TabBar/SearchViewController.swift +++ b/Client/Frontend/TabBar/SearchViewController.swift @@ -82,7 +82,7 @@ extension SearchViewController: UITableViewDataSource { extension SearchViewController: UITableViewDelegate { func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let engine = sortedEngines[indexPath.row] - let url = engine.urlForQuery(searchQuery) + let url = engine.searchURLForQuery(searchQuery) if let url = url { delegate?.didClickSearchResult(url) } diff --git a/Client/Frontend/TabBar/TabBarViewController.swift b/Client/Frontend/TabBar/TabBarViewController.swift index 5e6e847f0f24..8a0ce9377a48 100644 --- a/Client/Frontend/TabBar/TabBarViewController.swift +++ b/Client/Frontend/TabBar/TabBarViewController.swift @@ -247,7 +247,7 @@ class TabBarViewController: UIViewController, UITextFieldDelegate, SearchViewCon // If we can't make a valid URL, do a search query. if url == nil { - url = profile.searchEngines.defaultEngine.urlForQuery(text) + url = profile.searchEngines.defaultEngine.searchURLForQuery(text) } // If we still don't have a valid URL, something is broken. Give up. diff --git a/ClientTests/SearchTests.swift b/ClientTests/SearchTests.swift index 2631a4b226ed..04ad80b4a611 100644 --- a/ClientTests/SearchTests.swift +++ b/ClientTests/SearchTests.swift @@ -20,7 +20,7 @@ class SearchTests: XCTestCase { XCTAssertNil(engine.description) // Test regular search queries. - XCTAssertEqual(engine.urlForQuery("foobar")!.absoluteString!, "https://www.google.com/search?q=foobar&ie=utf-8&oe=utf-8") + XCTAssertEqual(engine.searchURLForQuery("foobar")!.absoluteString!, "https://www.google.com/search?q=foobar&ie=utf-8&oe=utf-8") } func testSearchEngines() {