<commit_before>/* 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/. */
"use strict";

const { classes: Cc, interfaces: Ci, utils: Cu } = Components;

Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SharedPreferences.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");

XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
  "resource://gre/modules/LightweightThemeManager.jsm");

XPCOMUtils.defineLazyGetter(this, "CrashReporter", function() {
  try {
    return Cc["@mozilla.org/xre/app-info;1"].getService(Ci["nsICrashReporter"]);
  } catch (e) {
    // Fennec may not be built with the crash reporter, so just return an empty
    // object instead of throwing an exception.
    return {};
  }
});

XPCOMUtils.defineLazyGetter(this, "JNI", function() {
  // Check to see if the public domain JNI.jsm is available in the tree (Firefox 34+).
  let scope = {};
  Cu.import("resource://gre/modules/JNI.jsm", scope);
  if (scope.JNI.GetForThread) {
    return scope.JNI;
  }

  // Othwerwise, fall back to import our own.
  Cu.import("chrome://privacycoach/content/JNI.jsm", scope);
  return scope.JNI;
});

XPCOMUtils.defineLazyGetter(this, "Strings", function() {
  return Services.strings.createBundle("chrome://privacycoach/locale/privacycoach.properties");
});

// Prefix for prefs to store original user prefs.
let PREF_PREFIX = "extensions.privacycoach.";

// JSON array of search engines that we won't warn about.
let PREF_DONT_WARN_ENGINES = "extensions.privacycoach.dontWarnEngines";

// Prefs that the add-on sets.
let PREFS = [
  {
    type: "bool",
    key: "privacy.donottrackheader.enabled",
    value: true
  },
  {
    type: "int",
    key: "privacy.donottrackheader.value",
    value: 1 // "Do not track me."" This will be deprecated in Fx35 with bug 1042135.
  },
  {
    type: "int",
    key: "network.cookie.cookieBehavior",
    value: 1 // "Enabled, excluding 3rd party"
  },
  {
    type: "bool",
    key: "toolkit.telemetry.enabled",
    value: false
  },
  {
    key: "datareporting.crashreporter.submitEnabled",
    value: false
  },
  {
    type: "sp-bool",
    key: "android.not_a_preference.healthreport.uploadEnabled",
    value: false
  },
  {
    type: "sp-bool",
    key: "android.not_a_preference.app.geo.reportdata",
    value: false
  }
];

let THEME = {
  id: "540624",
  name: "13fox",
  author: "<NAME>",
  version: "1.0",
  headerURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/header.png?1411165085",
  footerURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/footer.png?1411165085",
  iconURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/icon.png?1411165085",
  previewURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/preview.png?1411165085",
  detailURL: "https://addons.mozilla.org/en-US/addon/13fox/",
  updateURL: "https://versioncheck.addons.mozilla.org/en-US/themes/update-check/540624",
  textcolor: "#FFFFFF",
  accentcolor: "#363B40"
};

/**
 * Observes "browser-search-engine-modified" notification.
 */
function observeSearchEngineModified(subject, topic, data) {
  if (data == "engine-default") {
    let engine = subject.QueryInterface(Ci.nsISearchEngine);
    let submission = engine.getSubmission("");
    if (submission.uri.scheme !== "https") {
      let window = Services.wm.getMostRecentWindow("navigator:browser");
      let message = Strings.formatStringFromName("defaultWarning.message", [engine.name], 1);
      window.NativeWindow.toast.show(message, "long");
    }
  }
}

/**
 * Prompt the user before performing non-https searches.
 * @param window
 * @param name Search engine name.
 *
 * @return Whether or not we should perform the serach.
 */
function confirmSearch(window, name) {
  let dontWarnEngines;
  try {
    dontWarnEngines = JSON.parse(Services.prefs.getCharPref(PREF_DONT_WARN_ENGINES));
  } catch(e) {
    dontWarnEngines = [];
  }

  if (dontWarnEngines.indexOf(name) != -1) {
    return true;
  }

  let engine = Services.search.getEngineByName(name);
  if (!engine) {
    return true;
  }

  let submission = engine.getSubmission("");
  if (submission.uri.scheme === "https") {
    return true;
  }

  let title = Strings.GetStringFromName("prompt.title");
  let message = Strings.formatStringFromName("httpsWarning.message", [name], 1);
  let dontAsk = Strings.formatStringFromName("httpsWarning.dontAsk", [name], 1);
  let checkState = { value: false };
  let shouldContinue = Services.prompt.confirmCheck(window, title, message, dontAsk, checkState);

  // Set a pref if the user doesn't want to be asked again.
  if (shouldContinue && checkState.value) {
    dontWarnEngines.push(name);
    Services.prefs.setCharPref(PREF_DONT_WARN_ENGINES, JSON.stringify(dontWarnEngines));
  }

  return shouldContinue;
}

// Stores a reference to the original BrowserApp.observe function.
let originalObserve;

function loadIntoWindow(window) {
  originalObserve = window.BrowserApp.observe;

  // Intercept the original function call.
  window.BrowserApp.observe = function(subject, topic, data) {
    let shouldContinue = true;

    if (topic === "Tab:Load") {
      let d = JSON.parse(data);
      if (d.engine) {
        shouldContinue = confirmSearch(window, d.engine);
      }
    }

    // Then call the original function.
    if (shouldContinue) {
      originalObserve.call(window.BrowserApp, subject, topic, data);
    }
  }
}

function unloadFromWindow(window) {
  window.BrowserApp.observe = originalObserve;
}

/**
 * bootstrap.js API
 */
let windowListener = {
  onOpenWindow: function(window) {
    // Wait for the window to finish loading
    let domWindow = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
    domWindow.addEventListener("load", function() {
      domWindow.removeEventListener("load", arguments.callee, false);
      loadIntoWindow(domWindow);<commit_msg>prompt users when adding a non-https engine<commit_after>/* 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/. */
"use strict";

const { classes: Cc, interfaces: Ci, utils: Cu } = Components;

Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SharedPreferences.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");

XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
  "resource://gre/modules/LightweightThemeManager.jsm");

XPCOMUtils.defineLazyGetter(this, "CrashReporter", function() {
  try {
    return Cc["@mozilla.org/xre/app-info;1"].getService(Ci["nsICrashReporter"]);
  } catch (e) {
    // Fennec may not be built with the crash reporter, so just return an empty
    // object instead of throwing an exception.
    return {};
  }
});

XPCOMUtils.defineLazyGetter(this, "JNI", function() {
  // Check to see if the public domain JNI.jsm is available in the tree (Firefox 34+).
  let scope = {};
  Cu.import("resource://gre/modules/JNI.jsm", scope);
  if (scope.JNI.GetForThread) {
    return scope.JNI;
  }

  // Othwerwise, fall back to import our own.
  Cu.import("chrome://privacycoach/content/JNI.jsm", scope);
  return scope.JNI;
});

XPCOMUtils.defineLazyGetter(this, "Strings", function() {
  return Services.strings.createBundle("chrome://privacycoach/locale/privacycoach.properties");
});

// Prefix for prefs to store original user prefs.
let PREF_PREFIX = "extensions.privacycoach.";

// JSON array of search engines that we won't warn about.
let PREF_DONT_WARN_ENGINES = "extensions.privacycoach.dontWarnEngines";

// Prefs that the add-on sets.
let PREFS = [
  {
    type: "bool",
    key: "privacy.donottrackheader.enabled",
    value: true
  },
  {
    type: "int",
    key: "privacy.donottrackheader.value",
    value: 1 // "Do not track me."" This will be deprecated in Fx35 with bug 1042135.
  },
  {
    type: "int",
    key: "network.cookie.cookieBehavior",
    value: 1 // "Enabled, excluding 3rd party"
  },
  {
    type: "bool",
    key: "toolkit.telemetry.enabled",
    value: false
  },
  {
    key: "datareporting.crashreporter.submitEnabled",
    value: false
  },
  {
    type: "sp-bool",
    key: "android.not_a_preference.healthreport.uploadEnabled",
    value: false
  },
  {
    type: "sp-bool",
    key: "android.not_a_preference.app.geo.reportdata",
    value: false
  }
];

let THEME = {
  id: "540624",
  name: "13fox",
  author: "<NAME>",
  version: "1.0",
  headerURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/header.png?1411165085",
  footerURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/footer.png?1411165085",
  iconURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/icon.png?1411165085",
  previewURL: "https://addons.cdn.mozilla.net/user-media/addons/540624/preview.png?1411165085",
  detailURL: "https://addons.mozilla.org/en-US/addon/13fox/",
  updateURL: "https://versioncheck.addons.mozilla.org/en-US/themes/update-check/540624",
  textcolor: "#FFFFFF",
  accentcolor: "#363B40"
};

/**
 * Observes "browser-search-engine-modified" notification.
 */
function observeSearchEngineModified(subject, topic, data) {
  if (data == "engine-default") {
    let engine = subject.QueryInterface(Ci.nsISearchEngine);
    let submission = engine.getSubmission("");
    if (submission.uri.scheme !== "https") {
      let window = Services.wm.getMostRecentWindow("navigator:browser");
      let message = Strings.formatStringFromName("defaultWarning.message", [engine.name], 1);
      window.NativeWindow.toast.show(message, "long");
    }
  }
}

/**
 * Prompt the user before performing non-https searches.
 * @param window
 * @param name Search engine name.
 *
 * @return Whether or not we should perform the serach.
 */
function confirmSearch(window, name) {
  let dontWarnEngines;
  try {
    dontWarnEngines = JSON.parse(Services.prefs.getCharPref(PREF_DONT_WARN_ENGINES));
  } catch(e) {
    dontWarnEngines = [];
  }

  if (dontWarnEngines.indexOf(name) != -1) {
    return true;
  }

  let engine = Services.search.getEngineByName(name);
  if (!engine) {
    return true;
  }

  let submission = engine.getSubmission("");
  if (submission.uri.scheme === "https") {
    return true;
  }

  let title = Strings.GetStringFromName("prompt.title");
  let message = Strings.formatStringFromName("httpsWarning.message", [name], 1);
  let dontAsk = Strings.formatStringFromName("httpsWarning.dontAsk", [name], 1);
  let checkState = { value: false };
  let shouldContinue = Services.prompt.confirmCheck(window, title, message, dontAsk, checkState);

  // Set a pref if the user doesn't want to be asked again.
  if (shouldContinue && checkState.value) {
    dontWarnEngines.push(name);
    Services.prefs.setCharPref(PREF_DONT_WARN_ENGINES, JSON.stringify(dontWarnEngines));
  }

  return shouldContinue;
}

// Stores a reference to the original BrowserApp.observe function.
let originalObserve;

// Stored a reference to the original SearchEngines.addOpenSearchEngine.
let originalAddOpenSearchEngine;

// Monkey-patching madness.
function loadIntoWindow(window) {
  originalObserve = window.BrowserApp.observe;
  window.BrowserApp.observe = function(subject, topic, data) {
    let shouldContinue = true;

    if (topic === "Tab:Load") {
      let d = JSON.parse(data);
      if (d.engine) {
        shouldContinue = confirmSearch(window, d.engine);
      }
    }

    // Then call the original function.
    if (shouldContinue) {
      originalObserve.call(window.BrowserApp, subject, topic, data);
    }
  }

  originalAddOpenSearchEngine = window.SearchEngines.addOpenSearchEngine;
  window.SearchEngines.addOpenSearchEngine = function(engine) {
    let shouldContinue = true;

    if (!engine.url.startsWith("https://")) {
      let title = Strings.GetStringFromName("prompt.title");
      let message = Strings.formatStringFromName("httpsWarning.message", [engine.title], 1);
      shouldContinue = Services.prompt.confirm(window, title, message);
    }

    if (shouldContinue) {
      originalAddOpenSearchEngine.call(window.SearchEngines, engine);
    }
  }
}

function unloadFromWindow(window) {
  window.BrowserApp.observe = originalObserve;
  window.SearchEngines.addOpenSearchEngine = originalAddOpenSearchEngine;
}

/**
 * bootstrap.js API
 */
let windowListener = {
  onOpenWindow: function(window) {
    // Wait for the window to finish loading
    let domWindow = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
    domWindow.addEventListener("load", function() {
      domWindow.removeEventListener("load", arguments.callee, false);
      loadIntoWindow(domWindow);
{'fraction_non_alphanumeric': 0.1375009683166783, 'fraction_numerical': 0.017119838872104734, 'mean_word_length': 3.8753776435045317, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 13, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2699177', 'n_tokens_mistral': 4427, 'n_tokens_neox': 4230, 'n_words': 912}