1 /* -*- mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 ChromeUtils.defineESModuleGetters(lazy, {
9 PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
12 export var KeywordUtils = {
14 * Replaces %s or %S in the provided url or postData with the given parameter,
15 * acccording to the best charset for the given url.
17 * @return [url, postData]
18 * @throws if nor url nor postData accept a param, but a param was provided.
20 async parseUrlAndPostData(url, postData, param) {
21 let hasGETParam = /%s/i.test(url);
22 let decodedPostData = postData ? unescape(postData) : "";
23 let hasPOSTParam = /%s/i.test(decodedPostData);
25 if (!hasGETParam && !hasPOSTParam) {
27 // If nor the url, nor postData contain parameters, but a parameter was
28 // provided, return the original input.
30 "A param was provided but there's nothing to bind it to"
33 return [url, postData];
37 const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/;
38 let matches = url.match(re);
40 [, url, charset] = matches;
42 // Try to fetch a charset from History.
44 // Will return an empty string if character-set is not found.
45 let pageInfo = await lazy.PlacesUtils.history.fetch(url, {
46 includeAnnotations: true,
50 pageInfo.annotations.has(lazy.PlacesUtils.CHARSET_ANNO)
52 charset = pageInfo.annotations.get(lazy.PlacesUtils.CHARSET_ANNO);
55 // makeURI() throws if url is invalid.
60 // encodeURIComponent produces UTF-8, and cannot be used for other charsets.
61 // escape() works in those cases, but it doesn't uri-encode +, @, and /.
62 // Therefore we need to manually replace these ASCII characters by their
63 // encodeURIComponent result, to match the behavior of nsEscape() with
65 let encodedParam = "";
66 if (charset && charset != "UTF-8") {
69 "@mozilla.org/intl/scriptableunicodeconverter"
70 ].createInstance(Ci.nsIScriptableUnicodeConverter);
71 converter.charset = charset;
72 encodedParam = converter.ConvertFromUnicode(param) + converter.Finish();
76 encodedParam = escape(encodedParam).replace(
81 // Default charset is UTF-8
82 encodedParam = encodeURIComponent(param);
85 url = url.replace(/%s/g, encodedParam).replace(/%S/g, param);
87 postData = decodedPostData
88 .replace(/%s/g, encodedParam)
89 .replace(/%S/g, param);
91 return [url, postData];
95 * Returns a set of parameters if a keyword is registered and the search
96 * string can be bound to it.
98 * @param {string} keyword The typed keyword.
99 * @param {string} searchString The full search string, including the keyword.
100 * @returns { entry, url, postData }
102 async getBindableKeyword(keyword, searchString) {
103 let entry = await lazy.PlacesUtils.keywords.fetch(keyword);
109 let [url, postData] = await this.parseUrlAndPostData(
114 return { entry, url, postData };