Skip to content

Commit

Permalink
Add Fragment Support for Search Terms (#5847)
Browse files Browse the repository at this point in the history
* add fragment support for search engine

* refactor and re indent file

* add test case of fragment usage for search term
  • Loading branch information
Mustafa Hastürk authored and garvankeeley committed Dec 11, 2019
1 parent a81b35b commit ce33cb5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 21 deletions.
11 changes: 11 additions & 0 deletions Client/Assets/Search/SearchPlugins/yaani.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- 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/. -->

<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Yaani</ShortName>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/png;base64,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</Image>
<Url type="text/html" method="GET" template="https://tr.yaani.com.tr/?src=1#q={searchTerms}">
</Url>
</SearchPlugin>
48 changes: 32 additions & 16 deletions Client/Frontend/Browser/OpenSearch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class OpenSearchEngine: NSObject, NSCoding {
// http://stackoverflow.com/a/40034694
let isCustomEngine = aDecoder.decodeAsBool(forKey: "isCustomEngine")
guard let searchTemplate = aDecoder.decodeObject(forKey: "searchTemplate") as? String,
let shortName = aDecoder.decodeObject(forKey: "shortName") as? String,
let image = aDecoder.decodeObject(forKey: "image") as? UIImage else {
let shortName = aDecoder.decodeObject(forKey: "shortName") as? String,
let image = aDecoder.decodeObject(forKey: "image") as? UIImage else {
assertionFailure()
return nil
}
Expand Down Expand Up @@ -78,14 +78,25 @@ class OpenSearchEngine: NSObject, NSCoding {
// and have to do flaky pattern matching instead.
let placeholder = "PLACEHOLDER"
let template = searchTemplate.replacingOccurrences(of: SearchTermComponent, with: placeholder)
let components = URLComponents(string: template)
let searchTerm = components?.queryItems?.filter { item in
var components = URLComponents(string: template)

if let retVal = extractQueryArg(in: components?.queryItems, for: placeholder) {
return retVal
} else {
// Query arg may be exist inside fragment
components = URLComponents()
components?.query = URL(string: template)?.fragment
return extractQueryArg(in: components?.queryItems, for: placeholder)
}
}

fileprivate func extractQueryArg(in queryItems: [URLQueryItem]?, for placeholder: String) -> String? {
let searchTerm = queryItems?.filter { item in
return item.value == placeholder
}
guard let term = searchTerm, !term.isEmpty else { return nil }
return term[0].name
return searchTerm?.first?.name
}

/**
* check that the URL host contains the name of the search engine somewhere inside it
**/
Expand All @@ -100,13 +111,18 @@ class OpenSearchEngine: NSObject, NSCoding {
* Returns the query that was used to construct a given search URL
**/
func queryForSearchURL(_ url: URL?) -> String? {
if isSearchURLForEngine(url) {
if let key = searchQueryComponentKey,
let value = url?.getQuery()[key] {
return value.replacingOccurrences(of: "+", with: " ").removingPercentEncoding
}
guard isSearchURLForEngine(url), let key = searchQueryComponentKey else { return nil }

if let value = url?.getQuery()[key] {
return value.replacingOccurrences(of: "+", with: " ").removingPercentEncoding
} else {
// If search term could not found in query, it may be exist inside fragment
var components = URLComponents()
components.query = url?.fragment?.removingPercentEncoding

guard let value = components.url?.getQuery()[key] else { return nil }
return value.replacingOccurrences(of: "+", with: " ").removingPercentEncoding
}
return nil
}

/**
Expand Down Expand Up @@ -266,9 +282,9 @@ class OpenSearchParser {

let uiImage: UIImage
if let imageElement = largestImageElement,
let imageURL = URL(string: imageElement.stringValue),
let imageData = try? Data(contentsOf: imageURL),
let image = UIImage.imageFromDataThreadSafe(imageData) {
let imageURL = URL(string: imageElement.stringValue),
let imageData = try? Data(contentsOf: imageURL),
let image = UIImage.imageFromDataThreadSafe(imageData) {
uiImage = image
} else {
print("Error: Invalid search image data")
Expand Down
16 changes: 11 additions & 5 deletions ClientTests/SearchTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class SearchTests: XCTestCase {
func testSuggestClient() {
let webServerBase = startMockSuggestServer()
let engine = OpenSearchEngine(engineID: "mock", shortName: "Mock engine", image: UIImage(), searchTemplate: "", suggestTemplate: "\(webServerBase)?q={searchTerms}",
isCustomEngine: false)
isCustomEngine: false)
let client = SearchSuggestClient(searchEngine: engine, userAgent: "Fx-testSuggestClient")

let query1 = self.expectation(description: "foo query")
Expand Down Expand Up @@ -100,15 +100,16 @@ class SearchTests: XCTestCase {

func testExtractingOfSearchTermsFromURL() {
let parser = OpenSearchParser(pluginMode: true)
var file = Bundle.main.path(forResource: "google-b-m", ofType: "xml", inDirectory: "SearchPlugins/")
let googleEngine: OpenSearchEngine! = parser.parse(file!, engineID: "google")
var file = Bundle.main.path(forResource: "google-b-m", ofType: "xml", inDirectory: "SearchPlugins/")!
let googleEngine: OpenSearchEngine! = parser.parse(file, engineID: "google")

// create URL
let searchTerm = "Foo Bar"
let encodedSeachTerm = searchTerm.replacingOccurrences(of: " ", with: "+")
let googleSearchURL = URL(string: "https://www.google.com/search?q=\(encodedSeachTerm)&ie=utf-8&oe=utf-8&gws_rd=cr&ei=I0UyVp_qK4HtUoytjagM")
let duckDuckGoSearchURL = URL(string: "https://duckduckgo.com/?q=\(encodedSeachTerm)&ia=about")
let invalidSearchURL = URL(string: "https://www.google.co.uk")
let yaaniSearchURL = URL(string: "https://tr.yaani.com.tr/?src=1#q=\(encodedSeachTerm)")

// check it correctly matches google search term given google config
XCTAssertEqual(searchTerm, googleEngine.queryForSearchURL(googleSearchURL))
Expand All @@ -117,15 +118,20 @@ class SearchTests: XCTestCase {
XCTAssertNil(googleEngine.queryForSearchURL(invalidSearchURL))

// check that it matches given a different configuration
file = Bundle.main.path(forResource: "duckduckgo", ofType: "xml", inDirectory: "SearchPlugins/")
let duckDuckGoEngine: OpenSearchEngine! = parser.parse(file!, engineID: "duckduckgo")
file = Bundle.main.path(forResource: "duckduckgo", ofType: "xml", inDirectory: "SearchPlugins/")!
let duckDuckGoEngine: OpenSearchEngine! = parser.parse(file, engineID: "duckduckgo")
XCTAssertEqual(searchTerm, duckDuckGoEngine.queryForSearchURL(duckDuckGoSearchURL))

// check it doesn't match search URLs for different configurations
XCTAssertNil(duckDuckGoEngine.queryForSearchURL(googleSearchURL))

// check that if you pass in a nil URL that everything works
XCTAssertNil(duckDuckGoEngine.queryForSearchURL(nil))

// check that if search engine that uses fragment matches search term
file = Bundle.main.path(forResource: "yaani", ofType: "xml", inDirectory: "SearchPlugins/")!
let yaaniEngine: OpenSearchEngine = parser.parse(file, engineID: "Yaani")!
XCTAssertEqual(searchTerm, yaaniEngine.queryForSearchURL(yaaniSearchURL))
}

fileprivate func startMockSuggestServer() -> String {
Expand Down

0 comments on commit ce33cb5

Please sign in to comment.