/*
 * This Source Code is subject to the terms of the Mozilla Public License
 * version 2.0 (the "License"). You can obtain a copy of the License at
 * http://mozilla.org/MPL/2.0/.
 */

window.addEventListener("mousedown", saveLinkTarget, true);
window.addEventListener("mousedown", restoreLinkTarget, false);
window.addEventListener("click", interceptEvent, true);
window.addEventListener("keydown", interceptEvent, true);

function detach()
{
  try
  {
    window.removeEventListener("mousedown", saveLinkTarget, true);
    window.removeEventListener("mousedown", restoreLinkTarget, false);
    window.removeEventListener("click", interceptEvent, true);
    window.removeEventListener("keydown", interceptEvent, true);
  }
  catch (e)
  {
    // Ignore, likely "permission denied" because window has been unloaded
  }
}

let currentLink = null;
let currentLinkHref = null;

let hosts = {
  "groups.google.com": "google-groups",
  "yandex.com": "yandex",
  "yandex.com.tr": "yandex",
  "yandex.by": "yandex",
  "yandex.fr": "yandex",
  "yandex.kz": "yandex",
  "yandex.ru": "yandex",
  "yandex.ua": "yandex",
};

let containerAttr = {
  "google": "#search,.gsc-wrapper",
  "google-groups": "[role=main]",
  "google-images": "[data-cid^=GRID]",
};

function isSearchPage(window)
{
  try
  {
    let host = window.location.host;
    if (hosts.hasOwnProperty(host))
      return hosts[host];

    host = host.replace(/^.*?\./, "");
    if (hosts.hasOwnProperty(host))
      return hosts[host];
  }
  catch (e)
  {
    // Getting host could throw on special pages
  }

  for (let type of ["google", "google-images"])
    if (document instanceof HTMLDocument && document.querySelector(containerAttr[type]))
      return type;

  if (document.readyState == "complete")
    detach();
  return null;
}

function isSearchResult(link)
{
  let type = isSearchPage(link.ownerDocument.defaultView);
  if (type === null)
    return false;

  if (containerAttr.hasOwnProperty(type))
  {
    let selector = containerAttr[type];
    for (let parent = link; parent; parent = parent.parentNode)
      if ("matches" in parent && parent.matches(selector))
        return true;
  }
  return false;
}

function saveLinkTarget(event)
{
  let type = isSearchPage(event.target.ownerDocument.defaultView);
  if (!type)
    return;

  for (currentLink = event.target; currentLink; currentLink = currentLink.parentNode)
    if (currentLink.localName == "a")
      break;

  currentLinkHref = (currentLink ? currentLink.href : null);

  if (type == "yandex" && currentLink)
    currentLink.removeAttribute("data-counter");

  // Just in case event propagation is canceled
  setTimeout(restoreLinkTarget, 0);
}

function restoreLinkTarget(event)
{
  try
  {
    if (currentLink && currentLink.href != currentLinkHref)
      currentLink.href = currentLinkHref;
  }
  catch (e)
  {
    // Ignore, likely "can't access dead object" (currentLink has been garbage collected)
  }

  currentLink = currentLinkHref = null;
}

function interceptEvent(event)
{
  if (event.type == "keydown" && event.keyCode != event.DOM_VK_RETURN)
    return;

  let link = null;
  for (link = event.target; link; link = link.parentNode)
    if (link.localName == "a" || link.localName == "img")
      break;

  if (link && link.localName == "a" && isSearchResult(link) &&
      /^\s*https?:/i.test(link.getAttribute("href")))
  {
    event.stopPropagation();
  }
}