dom/tests/mochitest/bugs/utils_bug260264.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/tests/mochitest/bugs/utils_bug260264.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,140 @@
     1.4 +/**
     1.5 + * Dispatches |handler| to |element|, as if fired in response to |event|.
     1.6 + */
     1.7 +function send(element, event, handler) {
     1.8 +  function unique_handler() { return handler.apply(this, arguments) }
     1.9 +  element.addEventListener(event, unique_handler, false);
    1.10 +  try { sendMouseEvent({ type: event }, element.id) }
    1.11 +  finally { element.removeEventListener(event, unique_handler, false) }
    1.12 +}
    1.13 +
    1.14 +/**
    1.15 + * Because it's not nice to leave popup windows open after the tests are
    1.16 + * finished, we need a foolproof way to close some/all window.opened windows.
    1.17 + */
    1.18 +(function(originalOpen) {
    1.19 +  var wins = [];
    1.20 +  (window.open = function() {
    1.21 +    var win = originalOpen.apply(window, arguments);
    1.22 +    if (win)
    1.23 +      wins[wins.length] = win;
    1.24 +    return win;
    1.25 +  }).close = function(n) {
    1.26 +    if (arguments.length < 1)
    1.27 +      n = wins.length;
    1.28 +    while (n --> 0) {
    1.29 +      var win = wins.pop();
    1.30 +      if (win) win.close();
    1.31 +      else break;
    1.32 +    }
    1.33 +  };
    1.34 +})(window.open);
    1.35 +
    1.36 +function _alter_helper(uri, fn) {
    1.37 +  var hash_splat = uri.split("#"),
    1.38 +      splat = hash_splat.shift().split("/");
    1.39 +  fn(splat);
    1.40 +  hash_splat.unshift(splat.join("/"));
    1.41 +  return hash_splat.join("#");
    1.42 +}
    1.43 +
    1.44 +function alter_host(uri, host) {
    1.45 +  return _alter_helper(uri, function(splat) {
    1.46 +    splat.splice(2, 1, host);
    1.47 +  });
    1.48 +}
    1.49 +
    1.50 +function alter_file(uri, file) {
    1.51 +  return _alter_helper(uri, function(splat) {
    1.52 +    splat[splat.length - 1] = file;
    1.53 +  });
    1.54 +}
    1.55 +
    1.56 +(function() {
    1.57 +
    1.58 +  var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
    1.59 +                              .getService(SpecialPowers.Ci.nsIPrefService),
    1.60 +      pm = SpecialPowers.Cc["@mozilla.org/permissionmanager;1"]
    1.61 +                     .getService(SpecialPowers.Ci.nsIPermissionManager),
    1.62 +      ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
    1.63 +                            .getService(SpecialPowers.Ci.nsIIOService);
    1.64 +
    1.65 +  ALLOW_ACTION = pm.ALLOW_ACTION;
    1.66 +  DENY_ACTION = pm.DENY_ACTION;
    1.67 +  UNKNOWN_ACTION = pm.UNKNOWN_ACTION;
    1.68 +
    1.69 +  /**
    1.70 +   * This ridiculously over-engineered function makes an accessor function from
    1.71 +   * any given preference string.  Such accessors may be passed as the first
    1.72 +   * parameter to the |hold| function defined below.
    1.73 +   */
    1.74 +  makePrefAccessor = function(pref) {
    1.75 +    var splat = pref.split('.'),
    1.76 +        basePref = splat.pop(),
    1.77 +        branch, kind;
    1.78 +
    1.79 +    try {
    1.80 +      branch = prefService.getBranch(splat.join('.') + '.');
    1.81 +    } catch (x) {
    1.82 +      alert("Calling prefService.getBranch failed: " + 
    1.83 +        "did you forget to enable UniversalXPConnect?");
    1.84 +      throw x;
    1.85 +    }
    1.86 +
    1.87 +    switch (branch.getPrefType(basePref)) {
    1.88 +    case branch.PREF_STRING:  kind = "CharPref"; break;
    1.89 +    case branch.PREF_INT:     kind = "IntPref"; break;
    1.90 +    case branch.PREF_BOOL:    kind = "BoolPref"; break;
    1.91 +    case branch.PREF_INVALID: kind = "ComplexValue";
    1.92 +    }
    1.93 +
    1.94 +    return function(value) {
    1.95 +      var oldValue = branch['get' + kind](basePref);
    1.96 +      if (arguments.length > 0)
    1.97 +        branch['set' + kind](basePref, value);
    1.98 +      return oldValue;
    1.99 +    };
   1.100 +  };
   1.101 +
   1.102 +  makePopupPrivAccessor = function(uri) {
   1.103 +    uri = ioService.newURI(uri, null, null);
   1.104 +    var principal = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
   1.105 +                      .getService(SpecialPowers.Ci.nsIScriptSecurityManager)
   1.106 +                      .getNoAppCodebasePrincipal(uri);
   1.107 +
   1.108 +    return function(permission) {
   1.109 +      var old = pm.testPermissionFromPrincipal(principal, "popup");
   1.110 +      if (arguments.length) {
   1.111 +        pm.removeFromPrincipal(principal, "popup");
   1.112 +        pm.addFromPrincipal(principal, "popup", permission);
   1.113 +      }
   1.114 +      return old;
   1.115 +    };
   1.116 +  };
   1.117 +
   1.118 +})();
   1.119 +
   1.120 +/**
   1.121 + * This function takes an accessor function, a new value, and a callback
   1.122 + * function.  It assigns the new value to the accessor, saving the old value,
   1.123 + * then calls the callback function with the new and old values.  Before
   1.124 + * returning, |hold| sets the accessor back to the old value, even if the
   1.125 + * callback function misbehaved (i.e., threw).
   1.126 + *
   1.127 + * For sanity's sake, |hold| also ensures that the accessor still has the new
   1.128 + * value at the time the old value is reassigned.  The accessor's value might
   1.129 + * have changed to something entirely different during the execution of the
   1.130 + * callback function, but it must have changed back.
   1.131 + *
   1.132 + * Without such a mechanism it would be very difficult to verify that these
   1.133 + * tests leave the browser's preferences/privileges as they were originally.
   1.134 + */
   1.135 +function hold(accessor, value, body) {
   1.136 +  var old_value = accessor(value);
   1.137 +  try { return body(value, old_value) }
   1.138 +  finally {
   1.139 +    old_value = accessor(old_value);
   1.140 +    if (old_value !== value)
   1.141 +      throw [accessor, value, old_value];
   1.142 +  }
   1.143 +}

mercurial