tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

UrlbarProviderHistoryUrlHeuristic.sys.mjs (3838B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /**
      6 * This module exports a provider that provides a heuristic result. The result
      7 * will be provided if the query requests the URL and the URL is in Places with
      8 * the page title.
      9 */
     10 
     11 import {
     12  UrlbarProvider,
     13  UrlbarUtils,
     14 } from "moz-src:///browser/components/urlbar/UrlbarUtils.sys.mjs";
     15 
     16 const lazy = {};
     17 
     18 ChromeUtils.defineESModuleGetters(lazy, {
     19  PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
     20  UrlbarResult: "moz-src:///browser/components/urlbar/UrlbarResult.sys.mjs",
     21 });
     22 
     23 /**
     24 * Class used to create the provider.
     25 */
     26 export class UrlbarProviderHistoryUrlHeuristic extends UrlbarProvider {
     27  /**
     28   * @returns {Values<typeof UrlbarUtils.PROVIDER_TYPE>}
     29   */
     30  get type() {
     31    return UrlbarUtils.PROVIDER_TYPE.HEURISTIC;
     32  }
     33 
     34  /**
     35   * Whether this provider should be invoked for the given context.
     36   * If this method returns false, the providers manager won't start a query
     37   * with this provider, to save on resources.
     38   *
     39   * @param {UrlbarQueryContext} queryContext The query context object
     40   */
     41  async isActive(queryContext) {
     42    // For better performance, this provider tries to return a result only when
     43    // the input value can become a URL of the http(s) protocol and its length
     44    // is less than `MAX_TEXT_LENGTH`. That way its SQL query avoids calling
     45    // `hash()` on atypical or very long URLs.
     46    return (
     47      queryContext.fixupInfo?.href &&
     48      !queryContext.fixupInfo.isSearch &&
     49      queryContext.fixupInfo.scheme.startsWith("http") &&
     50      queryContext.fixupInfo.href.length <= UrlbarUtils.MAX_TEXT_LENGTH
     51    );
     52  }
     53 
     54  /**
     55   * Starts querying.
     56   *
     57   * @param {UrlbarQueryContext} queryContext
     58   * @param {(provider: UrlbarProvider, result: UrlbarResult) => void} addCallback
     59   *   Callback invoked by the provider to add a new result.
     60   */
     61  async startQuery(queryContext, addCallback) {
     62    const instance = this.queryInstance;
     63    const result = await this.#getResult(queryContext);
     64    if (result && instance === this.queryInstance) {
     65      addCallback(this, result);
     66    }
     67  }
     68 
     69  async #getResult(queryContext) {
     70    const inputedURL = queryContext.fixupInfo.href;
     71    const [strippedURL] = UrlbarUtils.stripPrefixAndTrim(inputedURL, {
     72      stripHttp: true,
     73      stripHttps: true,
     74      stripWww: true,
     75      trimEmptyQuery: true,
     76    });
     77    const connection = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
     78    const resultSet = await connection.executeCached(
     79      `
     80      SELECT url, IIF(last_visit_date NOTNULL, h.title, b.title) AS _title, frecency
     81      FROM moz_places h
     82      LEFT JOIN moz_bookmarks b ON b.fk = h.id
     83      WHERE
     84        url_hash IN (
     85          hash('https://' || :strippedURL),
     86          hash('https://www.' || :strippedURL),
     87          hash('http://' || :strippedURL),
     88          hash('http://www.' || :strippedURL)
     89        )
     90        AND frecency <> 0
     91      ORDER BY
     92        _title NOTNULL DESC,
     93        _title || '/' <> :strippedURL DESC,
     94        h.url = :inputedURL DESC,
     95        h.frecency DESC,
     96        h.id DESC
     97      LIMIT 1
     98      `,
     99      { inputedURL, strippedURL }
    100    );
    101 
    102    if (!resultSet.length) {
    103      return null;
    104    }
    105 
    106    const title = resultSet[0].getResultByName("_title");
    107    if (!title) {
    108      return null;
    109    }
    110 
    111    return new lazy.UrlbarResult({
    112      type: UrlbarUtils.RESULT_TYPE.URL,
    113      source: UrlbarUtils.RESULT_SOURCE.HISTORY,
    114      heuristic: true,
    115      payload: {
    116        url: inputedURL,
    117        title,
    118        icon: UrlbarUtils.getIconForUrl(resultSet[0].getResultByName("url")),
    119      },
    120      highlights: {
    121        url: UrlbarUtils.HIGHLIGHT.TYPED,
    122      },
    123    });
    124  }
    125 }