/*
 * License: AGPL-3
 * Copyright 2016, Internet Archive
 */
var VERSION = "1.5.4";

/**
 * Header callback
 */
chrome.webRequest.onCompleted.addListener(function(details) {
  function tabIsReady(isIncognito) {
    if (isIncognito === false &&
        details.statusCode === 404 &&
        details.frameId === 0 &&
        !details.url.startsWith("http://web.archive.org/web/") &&
        !details.url.startsWith("https://web.archive.org/web/")) {
      wmAvailabilityCheck(details.url, function(wayback_url, url) {
        chrome.tabs.executeScript(details.tabId, {
          file: "scripts/client.js"
        }, function() {
          chrome.tabs.sendMessage(details.tabId, {
            type: "SHOW_BANNER",
            wayback_url: wayback_url
          });
        });
      }, function() {
        telemetry.none();
      });
    }
  }
  chrome.tabs.get(details.tabId, function(tab) {
    tabIsReady(tab.incognito);
  });
}, {urls: ["<all_urls>"], types: ["main_frame"]});

/**
 * Checks Wayback Machine API for url snapshot
 */
function wmAvailabilityCheck(url, onsuccess, onfail) {
  var xhr = new XMLHttpRequest();
  var requestUrl = "https://archive.org/wayback/available";
  var requestParams = "url=" + encodeURI(url);
  xhr.open("POST", requestUrl, true);
  xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr.setRequestHeader("User-Agent", navigator.userAgent + " Wayback_Machine_Firefox/" + VERSION);
  xhr.setRequestHeader("Wayback-Api-Version", 2);
  xhr.onload = function() {
    var response = JSON.parse(xhr.responseText);
    var wayback_url = getWaybackUrlFromResponse(response);
    if (wayback_url !== null) {
      onsuccess(wayback_url, url);
    } else if (onfail) {
      onfail();
    }
  };
  xhr.send(requestParams);
}

/**
 * @param response {object}
 * @return {string or null}
 */
function getWaybackUrlFromResponse(response) {
  if (response.results &&
      response.results[0] &&
      response.results[0].archived_snapshots &&
      response.results[0].archived_snapshots.closest &&
      response.results[0].archived_snapshots.closest.available &&
      response.results[0].archived_snapshots.closest.available === true &&
      response.results[0].archived_snapshots.closest.status.indexOf("2") === 0 &&
      isValidSnapshotUrl(response.results[0].archived_snapshots.closest.url)) {
    return response.results[0].archived_snapshots.closest.url;
  } else {
    return null;
  }
}

/**
 * Makes sure response is a valid URL to prevent code injection
 * @param url {string}
 * @return {bool}
 */
function isValidSnapshotUrl(url) {
  return ((typeof url) === "string" &&
    (url.indexOf("http://") === 0 || url.indexOf("https://") === 0));
}

/**
 * Helper generaters a telemetry function. Each action can only be sent once.
 * @param action {string}
 * @return {function}
 */
function telemetryGenerator(action) {
  var TESTPILOT_TELEMETRY_CHANNEL = "testpilot-telemetry";
  var testpilotPingChannel = new BroadcastChannel(TESTPILOT_TELEMETRY_CHANNEL);
  var actionAlreadySent = false;
  return function() {
    if (actionAlreadySent === false) {
      testpilotPingChannel.postMessage({
        "test": "No More 404s",
        "agent": navigator.userAgent,
        "payload": {
          "action": action,
          "version": VERSION
        }
      });
    } else {
      actionAlreadySent = true;
    }
  }
}

var telemetry = {
  // 'viewed': the user clicked through to the archived version
  viewed: telemetryGenerator("viewed"),
  // 'dismissed': the user dismissed the prompt
  dismissed: telemetryGenerator("dismissed"),
  // 'ignored': the user ignored the prompt
  ignored: telemetryGenerator("ignored"),
  // 'none': will be 'none' if there isn't an archive available
  none: telemetryGenerator("none"),
};

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.action in telemetry) {
    telemetry[request.action]();
    sendResponse(true);
  } else {
    sendResponse(false);
  }
});

@@ -79,16 +79,341 @@
 .5.4%22;%0A%0A
+var excluded_urls = %5B%0A  %22web.archive.org/web/%22,%0A  %22localhost%22,%0A  %220.0.0.0%22,%0A  %22127.0.0.1%22%0A%5D;%0A%0Afunction isValidUrl(url) %7B%0A  for (var i = 0; i %3C excluded_urls.length; i++) %7B%0A    if (url.startsWith(%22http://%22 + excluded_urls%5Bi%5D) %7C%7C url.startsWith(%22https://%22 + excluded_urls%5Bi%5D)) %7B%0A      return false;%0A    %7D%0A  %7D%0A  return true;%0A%7D%0A%0A
 /**%0A * H
@@ -646,128 +646,30 @@
     
-!details.url.startsWith(%22http://web.archive.org/web/%22) &&%0A        !details.url.startsWith(%22https://web.archive.org/web/%22
+isValidUrl(details.url
 )) %7B

Update exclusion policy and add localhost domains