about:startup - merge with trunk
authorDaniel Brooks <db48x@db48x.net>
Sun, 01 Aug 2010 05:24:42 -0500
changeset 58821 c286d24e60a48fbb9a42ceacff3ddaab571452de
parent 58820 24a2838d65eb31c2dbf6d9ed1c87b610f9caf679 (current diff)
parent 48660 b91faba6e48f6e66a210fb84a9d4374478a8c9d1 (diff)
child 58822 10c264df4a89afcbbd4d0a7618c42650c162e373
push idunknown
push userunknown
push dateunknown
milestone2.0b3pre
about:startup - merge with trunk
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
browser/themes/pinstripe/browser/places/livemarkFolder.png
intl/chardet/public/nsMetaCharsetCID.h
js/src/builtins.tbl
js/src/jsops.cpp
js/src/tests/js1_4/Eval/regress-531037.js
js/src/trace-test/tests/basic/bug531037.js
toolkit/components/ctypes/Module.cpp
toolkit/components/ctypes/Module.h
toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl
toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin
toolkit/xre/nsAppRunner.cpp
xpcom/system/nsIXULRuntime.idl
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
@@ -366,17 +366,28 @@ var TestPilotXulWindow = {
       if (task.status >= TaskConstants.STATUS_SUBMITTED) {
         if (task.taskType == TaskConstants.TYPE_RESULTS) {
           let maintask = TestPilotSetup.getTaskById(task.relatedStudyId);
           if (maintask && maintask.status >= TaskConstants.STATUS_SUBMITTED) {
             this.addThanksMessage(statusVbox);
           }
         } else {
           if (task.status == TaskConstants.STATUS_MISSED) {
-            // TODO use Sean's icon for missed studies
+            // Icon for missed studies
+            let hbox = document.createElement("hbox");
+            newRow.setAttribute("class", "tp-opted-out");
+            statusVbox.appendChild(this.makeSpacer());
+            statusVbox.appendChild(hbox);
+            this.addLabel(
+              statusVbox,
+              this._stringBundle.getString("testpilot.studiesWindow.missedStudy"));
+            statusVbox.appendChild(this.makeSpacer());
+            hbox.appendChild(this.makeSpacer());
+            this.addImg(hbox, "study-missed");
+            hbox.appendChild(this.makeSpacer());
           } else {
             this.addThanksMessage(statusVbox);
             numFinishedStudies ++;
           }
         }
       }
       let spacer = document.createElement("spacer");
       spacer.setAttribute("flex", "1");
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/browser.css
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/browser.css
@@ -95,16 +95,23 @@ image.study-submitted {
 
 image.study-canceled {
   list-style-image: url("chrome://testpilot/skin/status-ejected.png");
   height: 32px;
   width: 64px;
   margin-right: 8px;
 }
 
+image.study-missed {
+  list-style-image: url("chrome://testpilot/skin/status-missed.png");
+  height: 32px;
+  width: 64px;
+  margin-right: 8px;
+}
+
 image.new-study {
   list-style-image: url("chrome://testpilot/skin/tp-study-48x48.png");
   height: 48px;
   width: 48px;
   margin-right: 8px;
 }
 
 image.new-results {
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/install.rdf
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/install.rdf
@@ -1,24 +1,24 @@
 <?xml version="1.0"?>
 
 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
   <Description about="urn:mozilla:install-manifest">
     <em:id>testpilot@labs.mozilla.com</em:id>
-    <em:version>1.0</em:version>
+    <em:version>1.0.1</em:version>
     <em:type>2</em:type>
 
     <!-- Target Application this extension can install into, 
          with minimum and maximum supported versions. --> 
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>3.5</em:minVersion>
-        <em:maxVersion>4.0b2</em:maxVersion>
+        <em:maxVersion>4.0b3</em:maxVersion>
       </Description>
     </em:targetApplication>
    
     <!-- Front End MetaData -->
     <em:name>Feedback</em:name>
     <em:description>Help make Firefox better by giving feedback.</em:description>
     <em:creator>Mozilla Corporation</em:creator>
     <em:homepageURL>http://testpilot.mozillalabs.com/</em:homepageURL>
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/jar-code-store.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/jar-code-store.js
@@ -125,48 +125,52 @@ JarStore.prototype = {
     // s now contains your hash in hex
 
     return (s == expectedHash);
   },
 
   saveJarFile: function( filename, rawData, expectedHash ) {
     console.info("Saving a JAR file as " + filename + " hash = " + expectedHash);
     // rawData is a string of binary data representing a jar file
+    let jarFile;
     try {
-    let jarFile = this._baseDir.clone();
+      jarFile = this._baseDir.clone();
       // filename may have directories in it; use just the last part
       jarFile.append(filename.split("/").pop());
 
       // If a file of that name already exists, remove it!
       if (jarFile.exists()) {
         jarFile.remove(false);
       }
-    // From https://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO#Getting_special_files
-    jarFile.create( Ci.nsIFile.NORMAL_FILE_TYPE, 600);
-    let stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
-                    createInstance(Ci.nsIFileOutputStream);
-    stream.init(jarFile, 0x04 | 0x08 | 0x20, 0600, 0); // readwrite, create, truncate
-
-    stream.write(rawData, rawData.length);
-    if (stream instanceof Ci.nsISafeOutputStream) {
-      stream.finish();
-    } else {
-      stream.close();
-    }
-    // Verify hash; if it's good, index and set last modified time.
-    // If not good, remove it.
-    if (this._verifyJar(jarFile, expectedHash)) {
-      this._indexJar(jarFile);
-      this._lastModified[jarFile.leafName] = jarFile.lastModifiedTime;
-    } else {
-      console.warn("Bad JAR file, doesn't match hash: " + expectedHash);
-      jarFile.remove(false);
-    }
+      // From https://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO#Getting_special_files
+      jarFile.create( Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
+      let stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+                      createInstance(Ci.nsIFileOutputStream);
+      stream.init(jarFile, 0x04 | 0x08 | 0x20, 0600, 0); // readwrite, create, truncate
+      stream.write(rawData, rawData.length);
+      if (stream instanceof Ci.nsISafeOutputStream) {
+        stream.finish();
+      } else {
+        stream.close();
+      }
+      // Verify hash; if it's good, index and set last modified time.
+      // If not good, remove it.
+      if (this._verifyJar(jarFile, expectedHash)) {
+        this._indexJar(jarFile);
+        this._lastModified[jarFile.leafName] = jarFile.lastModifiedTime;
+      } else {
+        console.warn("Bad JAR file, doesn't match hash: " + expectedHash);
+        jarFile.remove(false);
+      }
     } catch(e) {
       console.warn("Error in saving jar file: " + e);
+      // Remove any partially saved file
+      if (jarFile.exists()) {
+        jarFile.remove(false);
+      }
     }
   },
 
   resolveModule: function(root, path) {
     // Root will be null if require() was done by absolute path.
     if (root != null) {
       // TODO I don't think we need to do anything special here.
     }
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/remote-experiment-loader.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/remote-experiment-loader.js
@@ -242,83 +242,226 @@ exports.RemoteExperimentLoader.prototype
       if(set["default"]) {
         studiesToLoad.push(set["default"]);
       }
       // If none of those are there, load nothing.
     }
     return studiesToLoad;
   },
 
+  _executeFreshIndexFile: function(data, callback) {
+    try {
+      data = JSON.parse(data);
+    } catch (e) {
+      this._logger.warn("Error parsing index.json: " + e );
+      callback(false);
+      return;
+    }
+
+    // Cache study results and legacy studies.
+    this._studyResults = data.results;
+    this._legacyStudies = data.legacy;
+
+    /* Go through each record indicated in index.json for our locale;
+     * download the specified .jar file (replacing any version on disk)
+     */
+    let jarFiles = this.getLocalizedStudyInfo(data.new_experiments);
+    let numFilesToDload = jarFiles.length;
+    let self = this;
+
+    for each (let j in jarFiles) {
+      let filename = j.jarfile;
+      let hash = j.hash;
+      if (j.studyfile) {
+        this._experimentFileNames.push(j.studyfile);
+      }
+      this._logger.trace("I'm gonna go try to get the code for " + filename);
+      let modDate = this._jarStore.getFileModifiedDate(filename);
+
+      this._fileGetter(resolveUrl(this._baseUrl, filename),
+      function onDone(code) {
+        // code will be non-null if there is actually new code to download.
+        if (code) {
+          self._logger.info("Downloaded jar file " + filename);
+          self._jarStore.saveJarFile(filename, code, hash);
+          self._logger.trace("Saved code for: " + filename);
+        } else {
+          self._logger.info("Nothing to download for " + filename);
+        }
+        numFilesToDload--;
+        if (numFilesToDload == 0) {
+          self._logger.trace("Calling callback.");
+          callback(true);
+        }
+      }, modDate);
+    }
+  },
+
+  _executeCachedIndexFile: function(data) {
+    /* Working with a cached index file = follow its instructions except
+     * don't try to download anything - just work with the jar files already
+     * on disk. There's a lot of shared code between this and _executeFreshIndexFile;
+     * refactor?*/
+    try {
+      data = JSON.parse(data);
+    } catch (e) {
+      this._logger.warn("Error parsing index.json: " + e );
+      return false;
+    }
+    // Read study results and legacy studies from index.
+    this._studyResults = data.results;
+    this._legacyStudies = data.legacy;
+
+    // Read names of experiment modules from index.
+    let jarFiles = this.getLocalizedStudyInfo(data.new_experiments);
+    for each (let j in jarFiles) {
+      let filename = j.jarfile;
+      let hash = j.hash;
+      if (j.studyfile) {
+        this._experimentFileNames.push(j.studyfile);
+      }
+    }
+    return true;
+  },
+
+  // TODO a bad thing that can go wrong: If we have a net connection but the index file
+  // has not changed, we currently don't try to download anything...
+
+  // Another bad thing: If there's a jar download that's corrupt or unreadable or has
+    // the wrong permissions or something, we need to kill it and download a new one.
+
+  // WTF every jar file I'm downloading appears as 0 bytes with __x__x___ permissions!
+
+  _cachedIndexNsiFile: null,
+  get cachedIndexNsiFile() {
+    if (!this._cachedIndexNsiFile) {
+      try {
+        let file = Cc["@mozilla.org/file/directory_service;1"].
+                         getService(Ci.nsIProperties).
+                         get("ProfD", Ci.nsIFile);
+        file.append("TestPilotExperimentFiles"); // TODO this name should go in pref?
+        // Make sure there's a directory with this name; delete any non-directory
+        // file that's in the way.
+        if (file.exists() && !file.isDirectory()) {
+          file.remove(false);
+        }
+        if (!file.exists()) {
+          file.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
+        }
+        file.append("index.json");
+        this._cachedIndexNsiFile = file;
+      } catch(e) {
+        console.warn("Error creating directory for cached index file: " + e);
+      }
+    }
+    return this._cachedIndexNsiFile;
+  },
+
+  _cacheIndexFile: function(data) {
+    // write data to disk as basedir/index.json
+    try {
+      let file = this.cachedIndexNsiFile;
+      if (file == null) {
+        console.warn("Can't cache index file because directory does not exist.");
+        return;
+      }
+      if (file.exists()) {
+        file.remove(false);
+      }
+      file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
+      // file is nsIFile, data is a string
+      let foStream = Cc["@mozilla.org/network/file-output-stream;1"].
+                               createInstance(Ci.nsIFileOutputStream);
+
+      foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
+      // write, create, truncate
+      let converter = Cc["@mozilla.org/intl/converter-output-stream;1"].
+                                createInstance(Ci.nsIConverterOutputStream);
+      converter.init(foStream, "UTF-8", 0, 0);
+      converter.writeString(data);
+      converter.close(); // this closes foStream too
+    } catch(e) {
+      console.warn("Error cacheing index file: " + e);
+    }
+  },
+
+  // https://developer.mozilla.org/en/Table_Of_Errors
+  _loadCachedIndexFile: function() {
+    // If basedir/index.json exists, read it and return its data
+    // Otherwise, return false
+    let file = this.cachedIndexNsiFile;
+    if (file == null) {
+      console.warn("Can't load cached index file because directory does not exist.");
+      return false;
+    }
+    if (file.exists()) {
+      try {
+        let data = "";
+        let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
+                          createInstance(Ci.nsIFileInputStream);
+        let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
+                          createInstance(Ci.nsIConverterInputStream);
+        fstream.init(file, -1, 0, 0);
+        cstream.init(fstream, "UTF-8", 0, 0);
+        let str = {};
+        while (cstream.readString(4096, str) != 0) {
+          data += str.value;
+        }
+        cstream.close(); // this closes fstream too
+        return data;
+      } catch(e) {
+        console.warn("Error occured in reading cached index file: " + e);
+        return false;
+      }
+    } else {
+      console.warn("Trying to load cached index file but it does not exist.");
+      return false;
+    }
+  },
+
   checkForUpdates: function(callback) {
+    // Check for surveys and studies.  Entry point for all download and execution of
+    // remote code.
     /* Callback will be called with true or false
      * to let us know whether there are any updates, so that client code can
      * restart any experiment whose code has changed. */
     let prefs = require("preferences-service");
     let indexFileName = prefs.get("extensions.testpilot.indexFileName",
                                   "index.json");
     let self = this;
     // Unload everything before checking for updates, to be sure we
     // get the newest stuff.
     this._logger.info("Unloading everything to prepare to check for updates.");
     this._refreshLoader();
 
-    // Check for surveys and studies
+    let modDate = 0;
+    if (this.cachedIndexNsiFile) {
+      if (this.cachedIndexNsiFile.exists()) {
+        modDate = this.cachedIndexNsiFile.lastModifiedTime;
+      }
+    }
     let url = resolveUrl(self._baseUrl, indexFileName);
     self._fileGetter(url, function onDone(data) {
       if (data) {
-        try {
-          data = JSON.parse(data);
-        } catch (e) {
-          self._logger.warn("Error parsing index.json: " + e );
+        self._executeFreshIndexFile(data, callback);
+        // cache index file contents so we can read them later if we can't get online.
+        self._cacheIndexFile(data);
+      } else {
+        self._logger.info("Could not download index.json, using cached version.");
+        let data = self._loadCachedIndexFile();
+        if (data) {
+          let success = self._executeCachedIndexFile(data);
+          callback(success);
+        } else {
+          self._logger.warn("Could not download index.json and no cached version.");
+          // TODO Should display an error message to the user in this case.
           callback(false);
-          return;
         }
-
-        // Cache study results and legacy studies.
-        self._studyResults = data.results;
-        self._legacyStudies = data.legacy;
-
-        /* Go through each record indicated in index.json for our locale;
-         * download the specified .jar file (replacing any version on disk)
-         */
-        let jarFiles = self.getLocalizedStudyInfo(data.new_experiments);
-        let numFilesToDload = jarFiles.length;
-
-        for each (let j in jarFiles) {
-          let filename = j.jarfile;
-          let hash = j.hash;
-          if (j.studyfile) {
-            self._experimentFileNames.push(j.studyfile);
-          }
-          self._logger.trace("I'm gonna go try to get the code for " + filename);
-          let modDate = self._jarStore.getFileModifiedDate(filename);
-
-          self._fileGetter(resolveUrl(self._baseUrl, filename),
-            function onDone(code) {
-              // code will be non-null if there is actually new code to download.
-              if (code) {
-                self._logger.info("Downloaded jar file " + filename);
-                self._jarStore.saveJarFile(filename, code, hash);
-                self._logger.trace("Saved code for: " + filename);
-              } else {
-                self._logger.info("Nothing to download for " + filename);
-              }
-              numFilesToDload--;
-              if (numFilesToDload == 0) {
-                self._logger.trace("Calling callback.");
-                callback(true);
-              }
-            }, modDate);
-        }
-
-      } else {
-        self._logger.warn("Could not download index.json from test pilot server.");
-        callback(false);
       }
-    });
+    }, modDate);
   },
 
   getExperiments: function() {
     /* Load up and return all studies/surveys (not libraries)
      * already stored in codeStorage.  Returns a dict with key =
      * the module name and value = the module object. */
     this._logger.trace("GetExperiments called.");
     let remoteExperiments = {};
@@ -341,27 +484,15 @@ exports.RemoteExperimentLoader.prototype
 
   getLegacyStudies: function() {
     return this._legacyStudies;
   }
 };
 
 // TODO purge the pref store of anybody who has one.
 
-// TODO i realized that right now there is no way for experiments
-// on disk to get loaded if the index file is not accessible for
-// any reason. getExperiments needs to be able to return names of
-// experiment modules on disk even if connection to server fails.  But
-// we can't just load everything; some modules in the jar are not
-// experiments.  Right now the information as to which modules are
-// experiments lives ONLY in index.json.  What if we put it into the .jar
-// file itself somehow?  Like calling one of the files "study.js".  Or
-// "survey.js"  Hey, that would be neat - one .jar file containing both
-// the study.js and the survey.js.  Or there could be a mini-manifest in the
-// jar telling which files are experiments.
-
 // TODO Also, if user has a study id foo that is not expired yet, and
 // a LegacyStudy appears with the same id, they should keep their "real"
 // version of id foo and not load the LegacyStudy version.
 
 // TODO but once the study is expired, should delete the jar for it and
 // just load the LegacyStudy version.
 
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
@@ -284,22 +284,48 @@ function testRemoteLoader() {
 
 function testRemotelyLoadTabsExperiment() {
 
   // TODO: Stub out the function downloadFile in remote-experiment-loader with
   // something that will give us the files from the local repo on the disk.
   // (~/testpilot/website/testcases/tab-open-close/tabs_experiment.js)
 }
 
+function testRemoteLoaderIndexCache() {
+  var Cuddlefish = {};
+  Cu.import("resource://testpilot/modules/lib/cuddlefish.js",
+                          Cuddlefish);
+  let cfl = new Cuddlefish.Loader({rootPaths: ["resource://testpilot/modules/",
+                                               "resource://testpilot/modules/lib/"]});
+  let remoteLoaderModule = cfl.require("remote-experiment-loader");
+
+  let getFileFunc = function(url, callback) {
+    callback(null);
+  };
+
+  let stubLogger = {
+    getLogger: function() { return {trace: function() {},
+                                    warn: function() {},
+                                    info: function() {},
+                                    debug: function() {}};}
+  };
+
+  let remoteLoader = new remoteLoaderModule.RemoteExperimentLoader(stubLogger, getFileFunc);
+  let data = "Foo bar baz quux";
+  remoteLoader._cacheIndexFile(data);
+  cheapAssertEqual(remoteLoader._loadCachedIndexFile(), data);
+}
+
 function runAllTests() {
   testTheDataStore();
   testFirefoxVersionCheck();
   testStringSanitizer();
   //testTheCuddlefishPreferencesFilesystem();
   //testRemoteLoader();
+  testRemoteLoaderIndexCache();
   dump("TESTING COMPLETE.  " + testsPassed + " out of " + testsRun +
        " tests passed.");
 }
 
 //exports.runAllTests = runAllTests;
 
 
 // Test that observers get installed on any windows that are already open.
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -638,19 +638,22 @@ const gXPInstallObserver = {
                    .getInterface(Components.interfaces.nsIWebNavigation)
                    .QueryInterface(Components.interfaces.nsIDocShell);
     var browser = this._getBrowser(shell);
     if (!browser)
       return;
     const anchorID = "addons-notification-icon";
     var messageString, action;
     var brandShortName = brandBundle.getString("brandShortName");
-    var host = installInfo.originatingURI ? installInfo.originatingURI.host : browser.currentURI.host;
 
     var notificationID = aTopic;
+    // Make notifications persist a minimum of 30 seconds
+    var options = {
+      timeout: Date.now() + 30000
+    };
 
     switch (aTopic) {
     case "addon-install-blocked":
       var enabled = true;
       try {
         enabled = gPrefService.getBoolPref("xpinstall.enabled");
       }
       catch (e) {
@@ -661,66 +664,72 @@ const gXPInstallObserver = {
         if (PopupNotifications.getNotification(notificationID, browser))
           return;
 
         if (gPrefService.prefIsLocked("xpinstall.enabled")) {
           messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
           buttons = [];
         }
         else {
-          messageString = gNavigatorBundle.getFormattedString("xpinstallDisabledMessage",
-                                                              [brandShortName, host]);
+          messageString = gNavigatorBundle.getString("xpinstallDisabledMessage");
 
           action = {
             label: gNavigatorBundle.getString("xpinstallDisabledButton"),
             accessKey: gNavigatorBundle.getString("xpinstallDisabledButton.accesskey"),
             callback: function editPrefs() {
               gPrefService.setBoolPref("xpinstall.enabled", true);
             }
           };
         }
       }
       else {
         if (PopupNotifications.getNotification(notificationID, browser))
           return;
 
         messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
-                                                            [brandShortName, host]);
+                          [brandShortName, installInfo.originatingURI.host]);
 
         action = {
           label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
           accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
           callback: function() {
             installInfo.install();
           }
         };
       }
 
       PopupNotifications.show(browser, notificationID, messageString, anchorID,
-                              action);
+                              action, null, options);
       break;
     case "addon-install-failed":
       // TODO This isn't terribly ideal for the multiple failure case
       installInfo.installs.forEach(function(aInstall) {
-        var error = "addonError";
+        var host = (installInfo.originatingURI instanceof Ci.nsIStandardURL) &&
+                   installInfo.originatingURI.host;
+        if (!host)
+          host = (aInstall.sourceURI instanceof Ci.nsIStandardURL) &&
+                 aInstall.sourceURI.host;
+
+        var error = (host || aInstall.error == 0) ? "addonError" : "addonLocalError";
         if (aInstall.error != 0)
           error += aInstall.error;
         else if (aInstall.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
           error += "Blocklisted";
         else
           error += "Incompatible";
 
         messageString = gNavigatorBundle.getString(error);
         messageString = messageString.replace("#1", aInstall.name);
-        messageString = messageString.replace("#2", host);
+        if (host)
+          messageString = messageString.replace("#2", host);
         messageString = messageString.replace("#3", brandShortName);
         messageString = messageString.replace("#4", Services.appinfo.version);
 
         PopupNotifications.show(browser, notificationID, messageString, anchorID,
-                                action);
+                                action, null, options);
       });
       break;
     case "addon-install-complete":
       var notification = PopupNotifications.getNotification(notificationID, browser);
       if (notification)
         PopupNotifications.remove(notification);
 
       var needsRestart = installInfo.installs.some(function(i) {
@@ -762,17 +771,17 @@ const gXPInstallObserver = {
       }
 
       messageString = PluralForm.get(installInfo.installs.length, messageString);
       messageString = messageString.replace("#1", installInfo.installs[0].name);
       messageString = messageString.replace("#2", installInfo.installs.length);
       messageString = messageString.replace("#3", brandShortName);
 
       PopupNotifications.show(browser, notificationID, messageString, anchorID,
-                              action);
+                              action, null, options);
       break;
     }
   }
 };
 
 // Simple gestures support
 //
 // As per bug #412486, web content must not be allowed to receive any
@@ -7761,23 +7770,21 @@ var TabContextMenu = {
     document.getElementById("context_closeTab").disabled =
       disabled && gBrowser.tabContainer._closeWindowWithLastTab;
 
     var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
     for (var i = 0; i < menuItems.length; i++)
       menuItems[i].disabled = disabled;
 
     // Session store
-    // XXXzeniko should't we just disable this item as we disable
-    // the tabbrowser-multiple items above - for consistency?
-    document.getElementById("context_undoCloseTab").hidden =
+    document.getElementById("context_undoCloseTab").disabled =
       Cc["@mozilla.org/browser/sessionstore;1"].
       getService(Ci.nsISessionStore).
       getClosedTabCount(window) == 0;
-      
+
     // Only one of pin/unpin should be visible
     document.getElementById("context_pinTab").hidden = this.contextTab.pinned;
     document.getElementById("context_unpinTab").hidden = !this.contextTab.pinned;
 
     // Disable "Close other Tabs" if there is only one unpinned tab and
     // hide it when the user rightclicked on a pinned tab.
     var unpinnedTabs = gBrowser.tabs.length - gBrowser._numPinnedTabs;
     document.getElementById("context_closeOtherTabs").disabled = unpinnedTabs <= 1;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -29,16 +29,17 @@
 #   Joe Hewitt <hewitt@netscape.com>
 #   Pierre Chanial <chanial@noos.fr>
 #   Dean Tessman <dean_tessman@hotmail.com>
 #   Johnathan Nightingale <johnath@mozilla.com>
 #   Dão Gottwald <dao@mozilla.com>
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #   Robert Strong <robert.bugzilla@gmail.com>
 #   Rob Campbell <rcampbell@mozilla.com>
+#   Patrick Walton <pcwalton@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -135,17 +136,17 @@
                 accesskey="&bookmarkAllTabs.accesskey;"
                 command="Browser:BookmarkAllTabs"/>
       <menuseparator/>
       <menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
                 oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
       <menuitem id="context_undoCloseTab"
                 label="&undoCloseTab.label;"
                 accesskey="&undoCloseTab.accesskey;"
-                command="History:UndoCloseTab"/>
+                observes="History:UndoCloseTab"/>
       <menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
                 oncommand="gBrowser.removeTab(TabContextMenu.contextTab);"/>
     </menupopup>
 
     <menupopup id="backForwardMenu"
                onpopupshowing="return FillHistoryMenu(event.target);"
                oncommand="gotoHistoryIndex(event);"
                onclick="checkForMiddleClick(this, event);"/>
@@ -224,17 +225,19 @@
            onmousemove="InspectorUI.highlighter.handleMouseMove(event);"/>
 
     <panel id="inspector-panel"
            orient="vertical"
            hidden="true"
            ignorekeys="true"
            noautofocus="true"
            noautohide="true"
-           level="top">
+           level="top"
+           titlebar="normal"
+           label="&inspectPanelTitle.label;">
       <toolbar id="inspector-toolbar"
                nowindowdrag="true">
         <toolbarbutton id="inspector-inspect-toolbutton"
                        label="&inspectButton.label;"
                        accesskey="&inspectButton.accesskey;"
                        class="toolbarbutton-text"
                        command="Inspector:Inspect"/>
         <toolbarbutton id="inspector-previous-toolbutton"
@@ -274,21 +277,19 @@
     </panel>
 
     <panel id="inspector-style-panel"
            hidden="true"
            orient="vertical"
            ignorekeys="true"
            noautofocus="true"
            noautohide="true"
-           level="top">
-        <toolbar id="inspector-style-toolbar"
-                 nowindowdrag="true">
-          <label>&inspectStylePanelTitle.label;</label>
-        </toolbar>
+           level="top"
+           titlebar="normal"
+           label="&inspectStylePanelTitle.label;">
         <listbox id="inspector-style-listbox" flex="1"/>
         <hbox align="end">
           <spacer flex="1" />
           <resizer dir="bottomend" />
         </hbox>
     </panel>
 
     <menupopup id="toolbar-context-menu"
@@ -319,17 +320,22 @@
                 oncommand="FullScreen.setAutohide();"/>
       <menuseparator/>
       <menuitem label="&fullScreenExit.label;"
                 accesskey="&fullScreenExit.accesskey;"
                 oncommand="BrowserFullScreen();"/>
     </menupopup>
 
     <menupopup id="contentAreaContextMenu"
-               onpopupshowing="if (event.target != this) return true; updateEditUIVisibility(); gContextMenu = new nsContextMenu(this, window.getBrowser()); return gContextMenu.shouldDisplay;"
+               onpopupshowing="if (event.target != this)
+                                 return true;
+                               gContextMenu = new nsContextMenu(this, gBrowser);
+                               if (gContextMenu.shouldDisplay)
+                                 updateEditUIVisibility();
+                               return gContextMenu.shouldDisplay;"
                onpopuphiding="if (event.target == this) { gContextMenu = null; updateEditUIVisibility(); }">
 #include browser-context.inc
     </menupopup>
 
     <menupopup id="placesContext"/>
 
     <panel id="notification-popup" position="after_start" noautofocus="true" hidden="true"/>
 
@@ -485,16 +491,32 @@
             <menuitem id="appmenu_showAllHistory"
                       label="&showAllHistoryCmd2.label;"
                       key="showAllHistoryKb"
                       command="Browser:ShowAllHistory"/>
             <menuseparator class="hide-if-empty-places-result"/>
           </menupopup>
         </menu>
         <menuseparator/>
+        <menu id="appmenu_developer"
+              label="&developerMenu.label;">
+          <menupopup id="appmenu_developer_popup">
+            <menuitem id="appmenu_pageSource"
+                      label="&pageSourceCmd.label;"
+                      command="View:PageSource"/>
+            <menuseparator/>
+            <menuitem id="appmenu_pageInspect"
+                      label="&inspectMenu.label;"
+                      command="Tools:Inspect"/>
+            <menuitem id="appmenu_webConsole"
+                      label="&webConsoleCmd.label;"
+                      oncommand="HUDConsoleUI.toggleHUD();"/>
+          </menupopup>
+        </menu>
+        <menuseparator/>
         <menu id="appmenu_customize"
               label="&appMenuCustomize.label;">
           <menupopup id="appmenu_customizeMenu"
                      onpopupshowing="onViewToolbarsPopupShowing(event);">
             <menuseparator/>
             <menuitem command="cmd_ToggleTabsOnTop"
                       type="checkbox"
                       label="&viewTabsOnTop.label;"/>
--- a/browser/base/content/inspector.js
+++ b/browser/base/content/inspector.js
@@ -18,16 +18,17 @@
  *
  * The Initial Developer of the Original Code is
  * The Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2010
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Rob Campbell <rcampbell@mozilla.com> (original author)
+ *   Mihai Șucan <mihai.sucan@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -255,17 +256,18 @@ PanelHighlighter.prototype = {
     let b = {
       x: clientRect.right - browserRect.left,
       y: clientRect.bottom - browserRect.top
     };
 
     // Get midpoint of diagonal line.
     let midpoint = this.midPoint(a, b);
 
-    return this.win.document.elementFromPoint(midpoint.x, midpoint.y);
+    return InspectorUI.elementFromPoint(this.win.document, midpoint.x,
+      midpoint.y);
   },
 
   /**
    * Is this.node highlightable?
    *
    * @returns boolean
    */
   isNodeHighlightable: function PanelHighlighter_isNodeHighlightable()
@@ -307,18 +309,18 @@ PanelHighlighter.prototype = {
    *        The MouseEvent triggering the method.
    */
   handleMouseMove: function PanelHighlighter_handleMouseMove(aEvent)
   {
     if (!InspectorUI.inspecting) {
       return;
     }
     let browserRect = this.browser.getBoundingClientRect();
-    let element = this.win.document.elementFromPoint(aEvent.clientX -
-      browserRect.left, aEvent.clientY - browserRect.top);
+    let element = InspectorUI.elementFromPoint(this.win.document,
+      aEvent.clientX - browserRect.left, aEvent.clientY - browserRect.top);
     if (element && element != this.node) {
       InspectorUI.inspectNode(element);
     }
   },
 };
 
 ///////////////////////////////////////////////////////////////////////////
 //// InspectorTreeView
@@ -852,18 +854,18 @@ var InspectorUI = {
         switch (event.keyCode) {
           case KeyEvent.DOM_VK_RETURN:
           case KeyEvent.DOM_VK_ESCAPE:
             this.stopInspecting();
             break;
         }
         break;
       case "mousemove":
-        let element = this.win.document.elementFromPoint(event.clientX,
-          event.clientY);
+        let element = this.elementFromPoint(event.target.ownerDocument,
+          event.clientX, event.clientY);
         if (element && element != this.node) {
           this.inspectNode(element);
         }
         break;
       case "click":
         this.stopInspecting();
         break;
       case "scroll":
@@ -926,16 +928,45 @@ var InspectorUI = {
   {
     this.highlighter.highlightNode(aNode);
     this.selectEventsSuppressed = true;
     this.treeView.selectedNode = aNode;
     this.selectEventsSuppressed = false;
     this.updateStylePanel(aNode);
   },
 
+  /**
+   * Find an element from the given coordinates. This method descends through 
+   * frames to find the element the user clicked inside frames.
+   *
+   * @param DOMDocument aDocument the document to look into.
+   * @param integer aX
+   * @param integer aY
+   * @returns Node|null the element node found at the given coordinates.
+   */
+  elementFromPoint: function IUI_elementFromPoint(aDocument, aX, aY)
+  {
+    let node = aDocument.elementFromPoint(aX, aY);
+    if (node && node.contentDocument) {
+      switch (node.nodeName.toLowerCase()) {
+        case "iframe":
+          let rect = node.getBoundingClientRect();
+          aX -= rect.left;
+          aY -= rect.top;
+
+        case "frame":
+          let subnode = this.elementFromPoint(node.contentDocument, aX, aY);
+          if (subnode) {
+            node = subnode;
+          }
+      }
+    }
+    return node;
+  },
+
   ///////////////////////////////////////////////////////////////////////////
   //// Utility functions
 
   /**
    * debug logging facility
    * @param msg
    *        text message to send to the log
    */
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -56,66 +56,36 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 function nsContextMenu(aXulMenu, aBrowser) {
-  this.target            = null;
-  this.browser           = null;
-  this.menu              = null;
-  this.isFrameImage      = false;
-  this.onTextInput       = false;
-  this.onKeywordField    = false;
-  this.onImage           = false;
-  this.onLoadedImage     = false;
-  this.onCompletedImage  = false;
-  this.onCanvas          = false;
-  this.onVideo           = false;
-  this.onAudio           = false;
-  this.onLink            = false;
-  this.onMailtoLink      = false;
-  this.onSaveableLink    = false;
-  this.onMathML          = false;
-  this.link              = false;
-  this.linkURL           = "";
-  this.linkURI           = null;
-  this.linkProtocol      = null;
-  this.inFrame           = false;
-  this.hasBGImage        = false;
-  this.isTextSelected    = false;
-  this.isContentSelected = false;
-  this.shouldDisplay     = true;
-  this.isDesignMode      = false;
-  this.onEditableArea = false;
-  this.ellipsis = "\u2026";
-  try {
-    this.ellipsis = gPrefService.getComplexValue("intl.ellipsis",
-                                                 Ci.nsIPrefLocalizedString).data;
-  } catch (e) { }
-
-  // Initialize new menu.
-  this.initMenu(aXulMenu, aBrowser);
+  this.shouldDisplay = true;
+  this.initMenu(aBrowser);
 }
 
 // Prototype for nsContextMenu "class."
 nsContextMenu.prototype = {
-  // Initialize context menu.
-  initMenu: function CM_initMenu(aPopup, aBrowser) {
-    this.menu = aPopup;
-    this.browser = aBrowser;
-
-    this.isFrameImage = document.getElementById("isFrameImage");
-
+  initMenu: function CM_initMenu(aBrowser) {
     // Get contextual info.
     this.setTarget(document.popupNode, document.popupRangeParent,
                    document.popupRangeOffset);
+    if (!this.shouldDisplay)
+      return;
 
+    this.browser = aBrowser;
+    this.isFrameImage = document.getElementById("isFrameImage");
+    this.ellipsis = "\u2026";
+    try {
+      this.ellipsis = gPrefService.getComplexValue("intl.ellipsis",
+                                                   Ci.nsIPrefLocalizedString).data;
+    } catch (e) { }
     this.isTextSelected = this.isTextSelection();
     this.isContentSelected = this.isContentSelection();
 
     // Initialize (disable/remove) menu items.
     this.initItems();
   },
 
   initItems: function CM_initItems() {
@@ -343,20 +313,21 @@ nsContextMenu.prototype = {
               .setAttribute("checked", InlineSpellCheckerUI.enabled);
     }
 
     this.showItem("spell-add-to-dictionary", onMisspelling);
 
     // suggestion list
     this.showItem("spell-suggestions-separator", onMisspelling);
     if (onMisspelling) {
-      var menu = document.getElementById("contentAreaContextMenu");
       var suggestionsSeparator =
         document.getElementById("spell-add-to-dictionary");
-      var numsug = InlineSpellCheckerUI.addSuggestionsToMenu(menu, suggestionsSeparator, 5);
+      var numsug =
+        InlineSpellCheckerUI.addSuggestionsToMenu(suggestionsSeparator.parentNode,
+                                                  suggestionsSeparator, 5);
       this.showItem("spell-no-suggestions", numsug == 0);
     }
     else
       this.showItem("spell-no-suggestions", false);
 
     // dictionary list
     this.showItem("spell-dictionaries", InlineSpellCheckerUI.enabled);
     if (canSpell) {
@@ -447,38 +418,43 @@ nsContextMenu.prototype = {
   },
 
   // Set various context menu attributes based on the state of the world.
   setTarget: function (aNode, aRangeParent, aRangeOffset) {
     const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     if (aNode.namespaceURI == xulNS ||
         this.isTargetAFormControl(aNode)) {
       this.shouldDisplay = false;
+      return;
     }
 
     // Initialize contextual info.
     this.onImage           = false;
     this.onLoadedImage     = false;
     this.onCompletedImage  = false;
     this.onStandaloneImage = false;
     this.onCanvas          = false;
     this.onVideo           = false;
     this.onAudio           = false;
     this.onTextInput       = false;
     this.onKeywordField    = false;
     this.mediaURL          = "";
     this.onLink            = false;
+    this.onMailtoLink      = false;
+    this.onSaveableLink    = false;
+    this.link              = null;
     this.linkURL           = "";
     this.linkURI           = null;
     this.linkProtocol      = "";
     this.onMathML          = false;
     this.inFrame           = false;
     this.hasBGImage        = false;
     this.bgImageURL        = "";
-    this.onEditableArea = false;
+    this.onEditableArea    = false;
+    this.isDesignMode      = false;
 
     // Clear any old spellchecking items from the menu, this used to
     // be in the menu hiding code but wasn't getting called in all
     // situations. Here, we can ensure it gets cleaned up any time the
     // menu is shown. Note: must be before uninit because that clears the
     // internal vars
     InlineSpellCheckerUI.clearSuggestionsFromMenu();
     InlineSpellCheckerUI.clearDictionaryListFromMenu();
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1454,28 +1454,41 @@
 
               // update tab close buttons state
               this.tabContainer.adjustTabstrip();
             }
 
             // update first-tab/last-tab/beforeselected/afterselected attributes
             this.selectedTab._selected = true;
 
+            // Removing the panel requires fixing up selectedPanel immediately
+            // (see below), which would be hindered by the potentially expensive
+            // browser removal. So we remove the browser and the panel in two
+            // steps.
+            var panel = browser.parentNode;
+
             // This will unload the document. An unload handler could remove
             // dependant tabs, so it's important that the tabbrowser is now in
             // a consistent state (tab removed, tab positions updated, etc.).
-            // Also, it's important that another tab has been selected before
-            // the panel is removed; otherwise, a random sibling panel can flash.
-            this.mPanelContainer.removeChild(browser.parentNode);
-
-            // As the panel is removed, the removal of a dependent document can
+            panel.removeChild(browser);
+
+            // As the browser is removed, the removal of a dependent document can
             // cause the whole window to close. So at this point, it's possible
             // that the binding is destructed.
-            if (this.mTabBox)
-              this.mTabBox.selectedPanel = this.getBrowserForTab(this.mCurrentTab).parentNode;
+            if (this.mTabBox) {
+              let selectedPanel = this.mTabBox.selectedPanel;
+
+              this.mPanelContainer.removeChild(panel);
+
+              // Under the hood, a selectedIndex attribute controls which panel
+              // is displayed. Removing a panel A which precedes the selected
+              // panel B makes selectedIndex point to the panel next to B. We
+              // need to explicitly preserve B as the selected panel.
+              this.mTabBox.selectedPanel = selectedPanel;
+            }
 
             if (aCloseWindow)
               this._windowIsClosing = closeWindow(true);
           ]]>
         </body>
       </method>
 
       <method name="_blurTab">
@@ -2869,21 +2882,16 @@
           }
           else {
             let tabRect = this.childNodes[newIndex].getBoundingClientRect();
             if (ltr)
               newMargin = tabRect.left - rect.left;
             else
               newMargin = rect.right - tabRect.right;
           }
-          // ensure we never place the drop indicator beyond our limits
-          if (newMargin < minMargin)
-            newMargin = minMargin;
-          else if (newMargin > maxMargin)
-            newMargin = maxMargin;
         }
 
         ind.collapsed = false;
 
         newMargin += ind.clientWidth / 2;
         if (!ltr)
           newMargin *= -1;
 
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -132,26 +132,28 @@ endif
                  browser_bug550565.js \
                  browser_bug553455.js \
                  browser_bug555224.js \
                  browser_bug555767.js \
                  browser_bug556061.js \
                  browser_bug562649.js \
                  browser_bug563588.js \
                  browser_bug577121.js \
+                 browser_bug580956.js \
                  browser_contextSearchTabPosition.js \
                  browser_ctrlTab.js \
                  browser_discovery.js \
                  browser_drag.js \
                  browser_gestureSupport.js \
                  browser_getshortcutoruri.js \
                  browser_inspector_initialization.js \
                  browser_inspector_treeSelection.js \
                  browser_inspector_highlighter.js \
                  browser_inspector_stylePanel.js \
+                 browser_inspector_iframeTest.js \
                  browser_pageInfo.js \
                  browser_page_style_menu.js \
                  browser_pinnedTabs.js \
                  browser_plainTextLinks.js \
                  browser_pluginnotification.js \
                  browser_popupUI.js \
                  browser_relatedTabs.js \
                  browser_sanitize-passwordDisabledHosts.js \
--- a/browser/base/content/test/browser_bug553455.js
+++ b/browser/base/content/test/browser_bug553455.js
@@ -1,15 +1,20 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const TESTROOT = "http://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
+const TESTROOT2 = "http://example.org/browser/toolkit/mozapps/extensions/test/xpinstall/";
+const CHROMEROOT = "chrome://mochikit/content/browser/toolkit/mozapps/extensions/test/xpinstall/";
 const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 
+var gApp = document.getElementById("bundle_brand").getString("brandShortName");
+var gVersion = Services.appinfo.version;
+
 function wait_for_notification(aCallback) {
   PopupNotifications.panel.addEventListener("popupshown", function() {
     PopupNotifications.panel.removeEventListener("popupshown", arguments.callee, false);
     aCallback(PopupNotifications.panel);
   }, false);
 }
 
 function wait_for_install_dialog(aCallback) {
@@ -51,29 +56,36 @@ function test_blocked_install() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the blocked notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-blocked", "Should have seen the install blocked");
     is(notification.button.label, "Allow", "Should have seen the right button");
+    is(notification.getAttribute("label"),
+       gApp + " prevented this site (example.com) from asking you to install " +
+       "software on your computer.",
+       "Should have seen the right message");
 
     // Click on Allow
     EventUtils.synthesizeMouse(notification.button, 20, 10, {});
 
     // Wait for the install confirmation dialog
     wait_for_install_dialog(function(aWindow) {
       aWindow.document.documentElement.acceptDialog();
 
       // Wait for the complete notification
       wait_for_notification(function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.id, "addon-install-complete", "Should have seen the install complete");
         is(notification.button.label, "Restart Now", "Should have seen the right button");
+        is(notification.getAttribute("label"), 
+           "XPI Test will be installed after you restart " + gApp + ".",
+           "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
 
           gBrowser.removeTab(gBrowser.selectedTab);
           runNextTest();
         });
@@ -96,16 +108,19 @@ function test_whitelisted_install() {
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.id, "addon-install-complete", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
         aInstalls[0].cancel();
 
         gBrowser.removeTab(gBrowser.selectedTab);
         Services.perms.remove("example.com", "install");
         runNextTest();
@@ -123,16 +138,20 @@ function test_failed_download() {
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "The add-on could not be downloaded because of a connection failure " +
+       "on example.com.",
+       "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
   });
 },
 
 function test_corrupt_file() {
@@ -144,16 +163,20 @@ function test_corrupt_file() {
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "The add-on downloaded from example.com could not be installed " +
+       "because it appears to be corrupt.",
+       "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
   });
 },
 
 function test_incompatible() {
@@ -165,16 +188,20 @@ function test_incompatible() {
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "XPI Test could not be installed because it is not compatible with " +
+       gApp + " " + gVersion + ".",
+       "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
   });
 },
 
 function test_restartless() {
@@ -191,16 +218,19 @@ function test_restartless() {
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.id, "addon-install-complete", "Should have seen the install complete");
       is(notification.button.label, "Open Add-ons Manager", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test has been installed successfully.",
+         "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 0, "Should be no pending installs");
 
         AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(aAddon) {
           aAddon.uninstall();
 
           gBrowser.removeTab(gBrowser.selectedTab);
@@ -227,44 +257,178 @@ function test_multiple() {
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.id, "addon-install-complete", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "2 add-ons will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
         aInstalls[0].cancel();
 
         AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(aAddon) {
           aAddon.uninstall();
 
           gBrowser.removeTab(gBrowser.selectedTab);
           Services.perms.remove("example.com", "install");
           runNextTest();
         });
       });
     });
   });
+},
+
+function test_url() {
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(TESTROOT + "unsigned.xpi");
+
+  // Wait for the install confirmation dialog
+  wait_for_install_dialog(function(aWindow) {
+    aWindow.document.documentElement.acceptDialog();
+
+    // Wait for the complete notification
+    wait_for_notification(function(aPanel) {
+      let notification = aPanel.childNodes[0];
+      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
+
+      AddonManager.getAllInstalls(function(aInstalls) {
+        is(aInstalls.length, 1, "Should be one pending install");
+        aInstalls[0].cancel();
+
+        gBrowser.removeTab(gBrowser.selectedTab);
+        runNextTest();
+      });
+    });
+  });
+},
+
+function test_localfile() {
+  var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Components.interfaces.nsIChromeRegistry);
+  var path = cr.convertChromeURL(makeURI(CHROMEROOT + "corrupt.xpi")).spec;
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(path);
+
+  // Wait for the complete notification
+  wait_for_notification(function(aPanel) {
+    let notification = aPanel.childNodes[0];
+    is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "This add-on could not be installed because it appears to be corrupt.",
+       "Should have seen the right message");
+
+    gBrowser.removeTab(gBrowser.selectedTab);
+    runNextTest();
+  });
+},
+
+function test_wronghost() {
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.addEventListener("load", function() {
+    if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
+      return;
+
+    gBrowser.removeEventListener("load", arguments.callee, true);
+
+    gBrowser.loadURI(TESTROOT + "corrupt.xpi");
+
+    // Wait for the complete notification
+    wait_for_notification(function(aPanel) {
+      let notification = aPanel.childNodes[0];
+      is(notification.id, "addon-install-failed", "Should have seen the install fail");
+      is(notification.getAttribute("label"),
+         "The add-on downloaded from example.com could not be installed " +
+         "because it appears to be corrupt.",
+         "Should have seen the right message");
+
+      gBrowser.removeTab(gBrowser.selectedTab);
+      runNextTest();
+    });
+  }, true);
+  gBrowser.loadURI(TESTROOT2 + "enabled.html");
+},
+
+function test_reload() {
+  var pm = Services.perms;
+  pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
+
+  var triggers = encodeURIComponent(JSON.stringify({
+    "Unsigned XPI": "unsigned.xpi"
+  }));
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
+
+  // Wait for the install confirmation dialog
+  wait_for_install_dialog(function(aWindow) {
+    aWindow.document.documentElement.acceptDialog();
+
+    // Wait for the complete notification
+    wait_for_notification(function(aPanel) {
+      let notification = aPanel.childNodes[0];
+      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
+
+      function test_fail() {
+        ok(false, "Reloading should not have hidden the notification");
+      }
+
+      PopupNotifications.panel.addEventListener("popuphiding", test_fail, false);
+
+      gBrowser.addEventListener("load", function() {
+        if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
+          return;
+
+        gBrowser.removeEventListener("load", arguments.callee, true);
+
+        PopupNotifications.panel.removeEventListener("popuphiding", test_fail, false);
+
+        AddonManager.getAllInstalls(function(aInstalls) {
+          is(aInstalls.length, 1, "Should be one pending install");
+          aInstalls[0].cancel();
+
+          gBrowser.removeTab(gBrowser.selectedTab);
+          Services.perms.remove("example.com", "install");
+          runNextTest();
+        });
+      }, true);
+      gBrowser.loadURI(TESTROOT2 + "enabled.html");
+    });
+  });
 }
 ];
 
 function runNextTest() {
   AddonManager.getAllInstalls(function(aInstalls) {
     is(aInstalls.length, 0, "Should be no active installs");
 
     if (TESTS.length == 0) {
+      Services.prefs.setBoolPref("extensions.logging.enabled", false);
+
       finish();
       return;
     }
 
+    info("Running " + TESTS[0].name);
     TESTS.shift()();
   });
-}
+};
 
 function test() {
   waitForExplicitFinish();
 
+  Services.prefs.setBoolPref("extensions.logging.enabled", true);
+
   runNextTest();
 }
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug580956.js
@@ -0,0 +1,27 @@
+function numClosedTabs()
+  Cc["@mozilla.org/browser/sessionstore;1"].
+    getService(Ci.nsISessionStore).
+    getClosedTabCount(window);
+
+function isUndoCloseEnabled() {
+  document.popupNode = gBrowser.tabs[0];
+  TabContextMenu.updateContextMenu(document.getElementById("tabContextMenu"));
+  return !document.getElementById("context_undoCloseTab").disabled;
+}
+
+function test() {
+  waitForExplicitFinish();
+
+  gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", 0);
+  gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
+  is(numClosedTabs(), 0, "There should be 0 closed tabs.");
+  ok(!isUndoCloseEnabled(), "Undo Close Tab should be disabled.");
+
+  var tab = gBrowser.addTab("http://mochi.test:8888/");
+  var browser = gBrowser.getBrowserForTab(tab);
+  browser.addEventListener("load", function() {
+    gBrowser.removeTab(tab);
+    ok(isUndoCloseEnabled(), "Undo Close Tab should be enabled.");
+    finish();
+  }, true);
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_inspector_iframeTest.js
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Inspector iframe Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Campbell <rcampbell@mozilla.com>
+ *   Mihai Șucan <mihai.sucan@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let doc;
+let div1;
+let div2;
+let iframe1;
+let iframe2;
+
+function createDocument()
+{
+  doc.title = "Inspector iframe Tests";
+
+  iframe1 = doc.createElement('iframe');
+
+  iframe1.addEventListener("load", function () {
+    iframe1.removeEventListener("load", arguments.callee, false);
+
+    div1 = iframe1.contentDocument.createElement('div');
+    div1.textContent = 'little div';
+    iframe1.contentDocument.body.appendChild(div1);
+
+    iframe2 = iframe1.contentDocument.createElement('iframe');
+
+    iframe2.addEventListener('load', function () {
+      iframe2.removeEventListener("load", arguments.callee, false);
+
+      div2 = iframe2.contentDocument.createElement('div');
+      div2.textContent = 'nested div';
+      iframe2.contentDocument.body.appendChild(div2);
+
+      setupIframeTests();
+    }, false);
+
+    iframe2.src = 'data:text/html,nested iframe';
+    iframe1.contentDocument.body.appendChild(iframe2);
+  }, false);
+
+  iframe1.src = 'data:text/html,little iframe';
+  doc.body.appendChild(iframe1);
+}
+
+function setupIframeTests()
+{
+  document.addEventListener("popupshown", runIframeTests, false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function runIframeTests(evt)
+{
+  if (evt.target.id != "inspector-panel")
+    return true;
+
+  document.removeEventListener("popupshown", runIframeTests, false);
+  document.addEventListener("popupshown", performTestComparisons1, false);
+
+  EventUtils.synthesizeMouse(div1, 2, 2, {type: "mousemove"},
+    iframe1.contentWindow);
+}
+
+function performTestComparisons1(evt)
+{
+  if (evt.target.id != "highlighter-panel")
+    return true;
+
+  document.removeEventListener("popupshown", performTestComparisons1, false);
+
+  is(InspectorUI.treeView.selectedNode, div1, "selection matches div1 node");
+  is(InspectorUI.highlighter.highlitNode, div1, "highlighter matches selection");
+
+  document.addEventListener("popupshown", performTestComparisons2, false);
+
+  EventUtils.synthesizeMouse(div2, 2, 2, {type: "mousemove"},
+    iframe2.contentWindow);
+}
+
+function performTestComparisons2(evt)
+{
+  if (evt.target.id != "highlighter-panel")
+    return true;
+
+  document.removeEventListener("popupshown", performTestComparisons2, false);
+
+  is(InspectorUI.treeView.selectedNode, div2, "selection matches div2 node");
+  is(InspectorUI.highlighter.highlitNode, div2, "highlighter matches selection");
+
+  executeSoon(finishUp);
+}
+
+function finishUp() {
+  InspectorUI.closeInspectorUI();
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    doc = content.document;
+    waitForFocus(createDocument, content);
+  }, true);
+  
+  content.location = "data:text/html,iframe tests for inspector";
+}
+
--- a/browser/base/content/test/browser_popupNotification.js
+++ b/browser/base/content/test/browser_popupNotification.js
@@ -339,25 +339,100 @@ var tests = [
       isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
             "geo anchor should be visible");
       dismissNotification(popup);
     },
     onHidden: function (popup) {
       this.notification.remove();
     }
   },
+  // Test that persistence allows the notification to persist across reloads
+  { // Test #12
+    run: function () {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+
+      let self = this;
+      loadURI("http://example.com/", function() {
+        self.notifyObj = new basicNotification();
+        self.notifyObj.options = {
+          persistence: 2
+        };
+        self.notification = showNotification(self.notifyObj);
+      });
+    },
+    onShown: function (popup) {
+      this.complete = false;
+
+      let self = this;
+      loadURI("http://example.org/", function() {
+        loadURI("http://example.com/", function() {
+
+          // Next load will hide the notification
+          self.complete = true;
+
+          loadURI("http://example.org/");
+        });
+      });
+    },
+    onHidden: function (popup) {
+      ok(this.complete, "Should only have hidden the notification after 3 page loads");
+      this.notification.remove();
+      gBrowser.removeTab(gBrowser.selectedTab);
+      gBrowser.selectedTab = this.oldSelectedTab;
+    }
+  },
+  // Test that a timeout allows the notification to persist across reloads
+  { // Test #13
+    run: function () {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+
+      let self = this;
+      loadURI("http://example.com/", function() {
+        self.notifyObj = new basicNotification();
+        // Set a timeout of 10 minutes that should never be hit
+        self.notifyObj.options = {
+          timeout: Date.now() + 600000
+        };
+        self.notification = showNotification(self.notifyObj);
+      });
+    },
+    onShown: function (popup) {
+      this.complete = false;
+
+      let self = this;
+      loadURI("http://example.org/", function() {
+        loadURI("http://example.com/", function() {
+
+          // Next load will hide the notification
+          self.notification.options.timeout = Date.now() - 1;
+          self.complete = true;
+
+          loadURI("http://example.org/");
+        });
+      });
+    },
+    onHidden: function (popup) {
+      ok(this.complete, "Should only have hidden the notification after the timeout was passed");
+      this.notification.remove();
+      gBrowser.removeTab(gBrowser.selectedTab);
+      gBrowser.selectedTab = this.oldSelectedTab;
+    }
+  },
 ];
 
 function showNotification(notifyObj) {
   return PopupNotifications.show(notifyObj.browser,
                                  notifyObj.id,
                                  notifyObj.message,
                                  notifyObj.anchorID,
                                  notifyObj.mainAction,
-                                 notifyObj.secondaryActions);
+                                 notifyObj.secondaryActions,
+                                 notifyObj.options);
 }
 
 function checkPopup(popup, notificationObj) {
   info("[Test #" + gTestIndex + "] checking popup");
   let notifications = popup.childNodes;
 
   is(notifications.length, 1, "only one notification displayed");
   let notification = notifications[0];
@@ -404,14 +479,27 @@ function triggerSecondaryCommand(popup, 
     // Activate
     EventUtils.synthesizeKey("VK_ENTER", {});
   }, false);
 
   // One down event to open the popup
   EventUtils.synthesizeKey("VK_DOWN", { altKey: (navigator.platform.indexOf("Mac") == -1) });
 }
 
+function loadURI(uri, callback) {
+  gBrowser.addEventListener("load", function() {
+    // Ignore the about:blank load
+    if (gBrowser.currentURI.spec != uri)
+      return;
+
+    gBrowser.removeEventListener("load", arguments.callee, true);
+
+    callback();
+  }, true);
+  gBrowser.loadURI(uri);
+}
+
 function dismissNotification(popup) {
   info("[Test #" + gTestIndex + "] dismissing notification");
   executeSoon(function () {
     EventUtils.synthesizeKey("VK_ESCAPE", {});
   });
 }
--- a/browser/components/preferences/tabs.js
+++ b/browser/components/preferences/tabs.js
@@ -55,18 +55,37 @@ var gTabsPane = {
    * - true if display should switch to a new tab which has been opened from a
    *   link, false if display shouldn't switch
    * browser.tabs.warnOnClose
    * - true if when closing a window with multiple tabs the user is warned and
    *   allowed to cancel the action, false to just close the window
    * browser.tabs.warnOnOpen
    * - true if the user should be warned if he attempts to open a lot of tabs at
    *   once (e.g. a large folder of bookmarks), false otherwise
+   * browser.taskbar.previews.enable
+   * - true if tabs are to be shown in the Windows 7 taskbar
    */
 
+#ifdef XP_WIN
+  /**
+   * Initialize any platform-specific UI.
+   */
+  init: function () {
+    const Cc = Components.classes;
+    const Ci = Components.interfaces;
+    try {
+      let sysInfo = Cc["@mozilla.org/system-info;1"].
+                    getService(Ci.nsIPropertyBag2);
+      let ver = parseFloat(sysInfo.getProperty("version"));
+      let showTabsInTaskbar = document.getElementById("showTabsInTaskbar");
+      showTabsInTaskbar.hidden = ver < 6.1;
+    } catch (ex) {}
+  },
+#endif
+
   /**
    * Determines where a link which opens a new window will open.
    *
    * @returns |true| if such links should be opened in new tabs
    */
   readLinkTarget: function() {
     var openNewWindow = document.getElementById("browser.link.open_newwindow");
     return openNewWindow.value != 2;
--- a/browser/components/preferences/tabs.xul
+++ b/browser/components/preferences/tabs.xul
@@ -45,24 +45,30 @@
 <!ENTITY % tabsDTD SYSTEM "chrome://browser/locale/preferences/tabs.dtd">
 %tabsDTD;
 ]>
 
 <overlay id="TabsPaneOverlay"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <prefpane id="paneTabs"
+#ifdef XP_WIN
+            onpaneload="gTabsPane.init();"
+#endif
             helpTopic="prefs-tabs">
 
     <preferences id="tabsPreferences">
       <preference id="browser.link.open_newwindow"     name="browser.link.open_newwindow"     type="int"/>
       <preference id="browser.tabs.autoHide"           name="browser.tabs.autoHide"           type="bool" inverted="true"/>
       <preference id="browser.tabs.loadInBackground"   name="browser.tabs.loadInBackground"   type="bool" inverted="true"/>
       <preference id="browser.tabs.warnOnClose"        name="browser.tabs.warnOnClose"        type="bool"/>
       <preference id="browser.tabs.warnOnOpen"         name="browser.tabs.warnOnOpen"         type="bool"/>
+#ifdef XP_WIN
+      <preference id="browser.taskbar.previews.enable" name="browser.taskbar.previews.enable" type="bool"/>
+#endif
     </preferences>
     
     <script type="application/javascript" src="chrome://browser/content/preferences/tabs.js"/>
 
     <!-- XXX flex below is a hack because wrapping checkboxes don't reflow
              properly; see bug 349098 -->
     <vbox id="tabPrefsBox" align="start" flex="1">
       <checkbox id="linkTargeting" label="&newWindowsAsTabs.label;"
@@ -77,13 +83,18 @@
                 accesskey="&warnOpenManyTabs.accesskey;"
                 preference="browser.tabs.warnOnOpen"/>
       <checkbox id="showTabBar" label="&showTabBar.label;"
                 accesskey="&showTabBar.accesskey;"
                 preference="browser.tabs.autoHide"/>
       <checkbox id="switchToNewTabs" label="&switchToNewTabs.label;"
                 accesskey="&switchToNewTabs.accesskey;"
                 preference="browser.tabs.loadInBackground"/>
+#ifdef XP_WIN
+      <checkbox id="showTabsInTaskbar" label="&showTabsInTaskbar.label;"
+                accesskey="&showTabsInTaskbar.accesskey;"
+                preference="browser.taskbar.previews.enable"/>
+#endif
     </vbox>
 
   </prefpane>
 
 </overlay>
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -41,17 +41,18 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/components/privatebrowsing/test/browser
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES =  \
 		browser_console_clear.js \
-		browser_privatebrowsing_beforeunload.js \
+		browser_privatebrowsing_beforeunload_enter.js \
+		browser_privatebrowsing_beforeunload_exit.js \
 		browser_privatebrowsing_certexceptionsui.js \
 		browser_privatebrowsing_commandline_toggle.js \
 		browser_privatebrowsing_cookieacceptdialog.js \
 		browser_privatebrowsing_crh.js \
 		browser_privatebrowsing_downloadmonitor.js \
 		browser_privatebrowsing_fastswitch.js \
 		browser_privatebrowsing_findbar.js \
 		browser_privatebrowsing_forgetthissite.js \
rename from browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload_enter.js
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload_enter.js
@@ -93,73 +93,21 @@ function test() {
          "Incorrect number of tabs after transition into private browsing");
       gBrowser.selectedBrowser.addEventListener("load", function() {
         gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
         is(gBrowser.currentURI.spec, "about:privatebrowsing",
            "Incorrect page displayed after private browsing transition");
         is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
 
-        gBrowser.selectedBrowser.addEventListener("load", function() {
-          gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-
-          gBrowser.selectedTab = gBrowser.addTab();
-          gBrowser.selectedBrowser.addEventListener("load", function() {
-            gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-
-            confirmCalls = 0;
-            rejectDialog = 1;
-            pb.privateBrowsingEnabled = false;
-
-            ok(pb.privateBrowsingEnabled, "Private browsing mode should not have been deactivated");
-            is(confirmCalls, 1, "Only one confirm box should be shown");
-            is(gBrowser.tabs.length, 2,
-               "No tabs should be closed because private browsing mode transition was canceled");
-            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, TEST_PAGE_1,
-               "The first tab should be the same one we opened");
-            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
-               "The last tab should be the same one we opened");
-            is(rejectDialog, 0, "Only one confirm dialog should have been rejected");
-
-            confirmCalls = 0;
-            acceptDialog = 2;
-            pb.privateBrowsingEnabled = false;
-
-            ok(!pb.privateBrowsingEnabled, "Private browsing mode should have been deactivated");
-            is(confirmCalls, 2, "Only two confirm boxes should be shown");
-            is(gBrowser.tabs.length, 3,
-               "Incorrect number of tabs after transition into private browsing");
-
-            let loads = 0;
-            function waitForLoad(event) {
-              gBrowser.removeEventListener("load", arguments.callee, true);
-
-              if (++loads != 3)
-                return;
-
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
-                 "The first tab should be a blank tab");
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, TEST_PAGE_1,
-                 "The middle tab should be the same one we opened");
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
-                 "The last tab should be the same one we opened");
-              is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
-              is(acceptDialog, 0, "Two prompts should have been raised");
-
-              acceptDialog = 2;
-              gBrowser.removeTab(gBrowser.tabContainer.lastChild);
-              gBrowser.removeTab(gBrowser.tabContainer.lastChild);
-
-              Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
-              finish();
-            }
-            for (let i = 0; i < gBrowser.browsers.length; ++i)
-              gBrowser.browsers[i].addEventListener("load", waitForLoad, true);
-          }, true);
-          gBrowser.selectedBrowser.loadURI(TEST_PAGE_2);
-        }, true);
-        gBrowser.selectedBrowser.loadURI(TEST_PAGE_1);
+        gBrowser.addTab();
+        gBrowser.removeTab(gBrowser.selectedTab);
+        Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);
+        pb.privateBrowsingEnabled = false;
+        Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session");
+        Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
+        finish();
       }, true);
     }, true);
     browser2.loadURI(TEST_PAGE_2);
   }, true);
   browser1.loadURI(TEST_PAGE_1);
 }
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload_exit.js
@@ -0,0 +1,124 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Nochum Sossonko.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Nochum Sossonko <highmind63@gmail.com> (Original Author)
+ *   Ehsan Akhgari <ehsan@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that cancelling the unloading of a page with a beforeunload
+// handler prevents the private browsing mode transition.
+
+function test() {
+  const TEST_PAGE_1 = "data:text/html,<body%20onbeforeunload='return%20false;'>first</body>";
+  const TEST_PAGE_2 = "data:text/html,<body%20onbeforeunload='return%20false;'>second</body>";
+  let pb = Cc["@mozilla.org/privatebrowsing;1"]
+             .getService(Ci.nsIPrivateBrowsingService);
+
+  let rejectDialog = 0;
+  let acceptDialog = 0;
+  let confirmCalls = 0;
+  function promptObserver(aSubject, aTopic, aData) {
+    let dialogWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    confirmCalls++;
+    if (acceptDialog-- > 0)
+      dialogWin.document.documentElement.getButton("accept").click();
+    else if (rejectDialog-- > 0)
+      dialogWin.document.documentElement.getButton("cancel").click();
+  }
+
+  Services.obs.addObserver(promptObserver, "common-dialog-loaded", false);
+  pb.privateBrowsingEnabled = true;
+
+  waitForExplicitFinish();
+  let browser1 = gBrowser.getBrowserForTab(gBrowser.addTab());
+  browser1.addEventListener("load", function() {
+    browser1.removeEventListener("load", arguments.callee, true);
+
+    let browser2 = gBrowser.getBrowserForTab(gBrowser.addTab());
+    browser2.addEventListener("load", function() {
+      browser2.removeEventListener("load", arguments.callee, true);
+
+      confirmCalls = 0;
+      rejectDialog = 1;
+      pb.privateBrowsingEnabled = false;
+
+      ok(pb.privateBrowsingEnabled, "Private browsing mode should not have been deactivated");
+      is(confirmCalls, 1, "Only one confirm box should be shown");
+      is(gBrowser.tabs.length, 3,
+         "No tabs should be closed because private browsing mode transition was canceled");
+      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:privatebrowsing",
+         "The first tab should be the same one we opened");
+      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
+         "The last tab should be the same one we opened");
+      is(rejectDialog, 0, "Only one confirm dialog should have been rejected");
+
+      confirmCalls = 0;
+      acceptDialog = 2;
+      pb.privateBrowsingEnabled = false;
+
+      ok(!pb.privateBrowsingEnabled, "Private browsing mode should have been deactivated");
+      is(confirmCalls, 2, "Only two confirm boxes should be shown");
+      is(gBrowser.tabs.length, 3,
+         "Incorrect number of tabs after transition into private browsing");
+
+      let loads = 0;
+      function waitForLoad(event) {
+        gBrowser.removeEventListener("load", arguments.callee, true);
+
+        if (++loads != 3)
+          return;
+
+        is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
+           "The first tab should be a blank tab");
+        is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, TEST_PAGE_1,
+           "The middle tab should be the same one we opened");
+        is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
+           "The last tab should be the same one we opened");
+        is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
+        is(acceptDialog, 0, "Two prompts should have been raised");
+
+        acceptDialog = 2;
+        gBrowser.removeTab(gBrowser.tabContainer.lastChild);
+        gBrowser.removeTab(gBrowser.tabContainer.lastChild);
+
+        Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
+        finish();
+      }
+      for (let i = 0; i < gBrowser.browsers.length; ++i)
+        gBrowser.browsers[i].addEventListener("load", waitForLoad, true);
+    }, true);
+    browser2.loadURI(TEST_PAGE_2);
+  }, true);
+  browser1.loadURI(TEST_PAGE_1);
+}
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -60,20 +60,16 @@ endif
 
 MOZ_NONLOCALIZED_PKG_LIST = \
 	xpcom \
 	browser \
 	$(NULL)
 
 MOZ_LOCALIZED_PKG_LIST = $(AB_CD)
 
-MOZ_OPTIONAL_PKG_LIST = \
-	adt \
-	$(NULL)
-
 DEFINES += -DAB_CD=$(AB_CD) -DMOZ_APP_NAME=$(MOZ_APP_NAME) -DPREF_DIR=$(PREF_DIR)
 ifdef MOZ_ENABLE_GNOME_COMPONENT
 DEFINES += -DMOZ_ENABLE_GNOME_COMPONENT=1
 endif
 
 ifeq (gtk2, $(MOZ_WIDGET_TOOLKIT))
 DEFINES += -DMOZ_GTK2=1
 endif
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -400,132 +400,17 @@
 
 ; [Browser Chrome Files]
 @BINPATH@/chrome/browser.jar
 @BINPATH@/chrome/browser.manifest
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
 #if MOZ_UPDATE_CHANNEL == beta
-@BINPATH@/extensions/testpilot@labs.mozilla.com/chrome.manifest
-@BINPATH@/extensions/testpilot@labs.mozilla.com/components/TestPilot.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/all-studies-window.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/browser.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/browser.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/debug.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/experiment-page.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/feedback-browser.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.image.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.image.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.selection.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.selection.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.stack.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.stack.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/raw-data-dialog.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/raw-data-dialog.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/screen.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/status-quit.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/status.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/survey-generator.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/take-survey.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/tp-browser.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/welcome-page.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/welcome.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/window-utils.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/defaults/preferences/preferences.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/install.rdf
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/chrome.manifest
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/install.rdf
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/instrument.jsm
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/instrument.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/dbutils.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/experiment_data_store.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/extension-update.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/feedback.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/jar-code-store.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/cuddlefish.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/memory.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/observer-service.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/plain-text-console.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/preferences-service.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/securable-module.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/timer.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/traceback.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/unit-test.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/unload.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/url.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/log4moz.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/metadata.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/Observers.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/remote-experiment-loader.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/setup.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/string_sanitizer.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/tasks.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/badge-default.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/bg.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/css/screen-standalone.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/dino_32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/bg-status.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/callout.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/callout_continue.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/data1.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/data2.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_comments.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_computer.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_continue.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_quit.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_results.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_twitter.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_upcoming.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/logo.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/mozilla-logo.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/status-completed.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/status-ejected.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/status-missed.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/testpilot_16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/testPilot_200x200.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/testpilot_32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-completedstudies-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-currentstudies-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-generic-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-learned-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-results-48x48.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-settings-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-study-48x48.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-submit-48x48.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/close_button.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/feedback-frown-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/feedback-smile-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/feedback.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/close_button.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/feedback-frown-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/feedback-smile-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/feedback.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/notification-tail-down.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/notification-tail-up.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/close_button.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/feedback-frown-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/feedback-smile-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/feedback.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/notification-tail-down.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/notification-tail-up.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
+@BINPATH@/extensions/testpilot@labs.mozilla.com/*
 #endif
 @BINPATH@/chrome/toolkit.jar
 @BINPATH@/chrome/toolkit.manifest
 @BINPATH@/@PREF_DIR@/reporter.js
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @BINPATH@/chrome/icons/default/default16.png
 @BINPATH@/chrome/icons/default/default32.png
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -53,16 +53,17 @@ components/nsBackgroundUpdateService.js
 components/nsBookmarkTransactionManager.js
 components/nsCloseAllWindows.js
 components/nsDictionary.js
 components/nsExtensionManager.js
 components/nsInterfaceInfoToIDL.js
 components/nsScriptableIO.js
 components/nsUrlClassifierTable.js
 components/nsXmlRpcClient.js
+components/pluginGlue.js
 components/sidebar.xpt
 components/xmlextras.xpt
 components/xpcom.xpt
 components/xpti.dat
 components/xptitemp.dat
 defaults/pref/all.js
 defaults/pref/bug259708.js
 defaults/pref/bug307259.js
@@ -702,16 +703,17 @@ xpicleanup@BIN_SUFFIX@
   components/xpinstall.xpt
   components/xulapp.xpt
   components/xuldoc.xpt
   components/xultmpl.xpt
   components/zipwriter.xpt
   extensions/inspector@mozilla.org/chrome/chromelist.txt
   init.d/README
   libwidget.rsrc
+  plugin-container
   plugins/Default Plugin.plugin/Contents/Info.plist
   plugins/Default Plugin.plugin/Contents/MacOS/Default Plugin
   plugins/Default Plugin.plugin/Contents/PkgInfo
   plugins/Default Plugin.plugin/Contents/Resources/Default Plugin.rsrc
   plugins/Default Plugin.plugin/Contents/Resources/English.lproj/InfoPlist.strings
   plugins/DefaultPlugin.plugin/
   plugins/DefaultPlugin.plugin/Contents/Info.plist
   plugins/DefaultPlugin.plugin/Contents/MacOS/
--- a/browser/installer/windows/Makefile.in
+++ b/browser/installer/windows/Makefile.in
@@ -49,35 +49,25 @@ include $(topsrcdir)/toolkit/mozapps/ins
 
 CONFIG_DIR = instgen
 SFX_MODULE = $(topsrcdir)/other-licenses/7zstub/firefox/7zSD.sfx
 APP_VERSION := $(shell cat $(srcdir)/../../config/version.txt)
 DEFINES += -DAPP_VERSION=$(APP_VERSION)
 PRE_RELEASE_SUFFIX := $(shell $(PYTHON) $(topsrcdir)/config/printprereleasesuffix.py $(APP_VERSION))
 DEFINES += -DPRE_RELEASE_SUFFIX="$(PRE_RELEASE_SUFFIX)"
 
-# All script and locale files used by the Unicode version of NSIS need to be
-# converted from UTF-8 to UTF-16LE
-INSTALLER_FILES_CONV = \
+INSTALLER_FILES = \
+	app.tag \
 	nsis/installer.nsi \
 	nsis/uninstaller.nsi \
 	nsis/shared.nsh \
 	$(NULL)
 
-INSTALLER_FILES = \
-	app.tag \
-	$(NULL)
-
-# All script and locale files used by the Unicode version of NSIS need to be
-# converted from UTF-8 to UTF-16LE
-BRANDING_FILES_CONV = \
+BRANDING_FILES = \
 	branding.nsi \
-	$(NULL)
-
-BRANDING_FILES = \
 	wizHeader.bmp \
 	wizHeaderRTL.bmp \
 	wizWatermark.bmp \
 	$(NULL)
 
 DEFINES += \
 	-DAB_CD=$(AB_CD) \
 	-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
@@ -90,52 +80,28 @@ include $(topsrcdir)/config/config.mk
 installer::
 	$(MAKE) -C .. installer-stage
 	$(MAKE) $(CONFIG_DIR)/setup.exe
 
 # For building the uninstaller during the application build so it can be
 # included for mar file generation.
 uninstaller::
 	$(RM) -rf $(CONFIG_DIR) && mkdir $(CONFIG_DIR)
-	for i in $(INSTALLER_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(srcdir)/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/`basename $$i`; \
-	done
 	$(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR)
-	for i in $(BRANDING_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(DIST)/branding/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/$$i; \
-	done
 	$(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) \
-	  $(srcdir)/nsis/defines.nsi.in | iconv -f UTF-8 -t UTF-16LE | \
-	  cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	  $(CONFIG_DIR)/defines.nsi
-	$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl \
-	  $(topsrcdir) $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) \
-	  $(CONFIG_DIR)
+	  $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi
+	$(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \
+	  --preprocess-locale $(topsrcdir) \
+	  $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) $(CONFIG_DIR)
 
 $(CONFIG_DIR)/setup.exe::
 	$(RM) -rf $(CONFIG_DIR) && mkdir $(CONFIG_DIR)
-	for i in $(INSTALLER_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(srcdir)/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/`basename $$i`; \
-	done
 	$(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR)
-	for i in $(BRANDING_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(DIST)/branding/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/$$i; \
-	done
 	$(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) \
-	  $(srcdir)/nsis/defines.nsi.in | iconv -f UTF-8 -t UTF-16LE | \
-	  cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	  $(CONFIG_DIR)/defines.nsi
-	$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl \
-	  $(topsrcdir) $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) \
-	  $(CONFIG_DIR)
+	  $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi
+	$(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \
+	  --preprocess-locale $(topsrcdir) \
+	  $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) $(CONFIG_DIR)
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/makensis.mk
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -170,16 +170,17 @@
 <!ENTITY webConsoleCmd.label          "Web Console">
 <!ENTITY webConsoleCmd.accesskey      "W">
 <!ENTITY webConsoleCmd.commandkey     "k">
 
 <!ENTITY inspectMenu.label            "Inspect">
 <!ENTITY inspectMenu.accesskey        "T">
 <!ENTITY inspectMenu.commandkey       "I">
 
+<!ENTITY inspectPanelTitle.label      "HTML">
 <!ENTITY inspectButton.label          "Inspect">
 <!ENTITY inspectButton.accesskey      "I">
 <!ENTITY inspectNextButton.label      "Next">
 <!ENTITY inspectNextButton.accesskey  "N">
 <!ENTITY inspectPreviousButton.label  "Previous">
 <!ENTITY inspectPreviousButton.accesskey "P">
 <!ENTITY inspectStyleButton.label     "Style">
 <!ENTITY inspectStyleButton.accesskey "S">
@@ -251,16 +252,18 @@
 <!ENTITY showAllHistoryCmd.commandkey "H">
 
 <!ENTITY appMenuPrintCmd.label "Print">
 <!ENTITY appMenuCustomize.label "Customize">
 <!ENTITY appMenuToolbarLayout.label "Toolbar Layout…">
 <!ENTITY appMenuSidebars.label "Sidebars">
 <!ENTITY appMenuHelp.label "Help">
 
+<!ENTITY developerMenu.label "Developer">
+
 <!ENTITY openCmd.commandkey           "l">
 <!ENTITY urlbar.placeholder           "Go to a Web Site">
 <!ENTITY urlbar.accesskey             "d">
 <!ENTITY urlbar.switchToTab.label     "Switch to tab:">
 
 <!-- 
   Comment duplicated from browser-sets.inc:
 
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -39,23 +39,30 @@ xpinstallDisabledButton.accesskey=n
 # #1 first add-on's name, #2 number of add-ons, #3 application name
 addonsInstalled=#1 has been installed successfully.;#2 add-ons have been installed successfully.
 addonsInstalledNeedsRestart=#1 will be installed after you restart #3.;#2 add-ons will be installed after you restart #3.
 addonInstallRestartButton=Restart Now
 addonInstallRestartButton.accesskey=R
 addonInstallManage=Open Add-ons Manager
 addonInstallManage.accesskey=O
 
-# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4, addonErrorIncompatible, addonErrorBlocklisted):
+# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4):
 # #1 is the add-on name, #2 is the host name, #3 is the application name
 # #4 is the application version
 addonError-1=The add-on could not be downloaded because of a connection failure on #2.
 addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
 addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
 addonError-4=#1 could not be installed because #3 cannot modify the needed file.
+
+# LOCALIZATION NOTE (addonLocalError-1, addonLocalError-2, addonLocalError-3, addonLocalError-4, addonErrorIncompatible, addonErrorBlocklisted):
+# #1 is the add-on name, #3 is the application name, #4 is the application version
+addonLocalError-1=This add-on could not be installed because of a filesystem error.
+addonLocalError-2=This add-on could not be installed because it does not match the add-on #3 expected.
+addonLocalError-3=This add-on could not be installed because it appears to be corrupt.
+addonLocalError-4=#1 could not be installed because #3 cannot modify the needed file.
 addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
 addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
 
 # LOCALIZATION NOTE (lwthemeInstallRequest.message): %S will be replaced with
 # the host name of the site.
 lwthemeInstallRequest.message=This site (%S) attempted to install a theme.
 lwthemeInstallRequest.allowButton=Allow
 lwthemeInstallRequest.allowButton.accesskey=a
--- a/browser/locales/en-US/chrome/browser/preferences/tabs.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/tabs.dtd
@@ -7,8 +7,11 @@
 <!ENTITY warnOpenManyTabs.label       "Warn me when opening multiple tabs might slow down &brandShortName;">
 <!ENTITY warnOpenManyTabs.accesskey   "o">
 
 <!ENTITY showTabBar.label             "Always show the tab bar">
 <!ENTITY showTabBar.accesskey         "b">
 
 <!ENTITY switchToNewTabs.label        "When I open a link in a new tab, switch to it immediately">
 <!ENTITY switchToNewTabs.accesskey    "s">
+
+<!ENTITY showTabsInTaskbar.label          "Show tab previews in the Windows taskbar">
+<!ENTITY showTabsInTaskbar.accesskey      "k">
--- a/browser/locales/en-US/feedback/main.properties
+++ b/browser/locales/en-US/feedback/main.properties
@@ -10,16 +10,17 @@ testpilot.turnOff = Turn Off User Studie
 
 # studies window
 testpilot.studiesWindow.noStudies = We are working on a new study now; it will knock on your door soon! Stay Tuned!
 testpilot.studiesWindow.uploading = Uploading…
 testpilot.studiesWindow.unableToReachServer = Unable to reach Mozilla; please try again later.
 testpilot.studiesWindow.thanksForContributing = Thanks for contributing!
 testpilot.studiesWindow.finishedOn = Finished on %S
 testpilot.studiesWindow.canceledStudy = (You canceled this study)
+testpilot.studiesWindow.missedStudy = (You missed this study)
 testpilot.studiesWindow.willStart = Will start on %S
 testpilot.studiesWindow.gatheringData = Currently gathering data.
 testpilot.studiesWindow.willFinish = Will finish on %S
 testpilot.studiesWindow.proposeStudy = Propose your own study
 
 # for pages
 testpilot.page.commentsAndDiscussions = Comments & Discussions »
 testpilot.page.proposeATest = Propose a Test »
--- a/browser/locales/filter.py
+++ b/browser/locales/filter.py
@@ -1,14 +1,15 @@
 def test(mod, path, entity = None):
   import re
   # ignore anyhting but Firefox
   if mod not in ("netwerk", "dom", "toolkit", "security/manager",
                  "browser", "extensions/reporter", "extensions/spellcheck",
-                 "other-licenses/branding/firefox"):
+                 "other-licenses/branding/firefox",
+                 "services/sync"):
     return False
   if mod != "browser" and mod != "extensions/spellcheck":
     # we only have exceptions for browser and extensions/spellcheck
     return True
   if not entity:
     if mod == "extensions/spellcheck":
       return False
     # browser
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -163,17 +163,16 @@ toolbarbutton.chevron:-moz-locale-dir(rt
 
 toolbarbutton.bookmark-item {
   font-weight: bold;
   color: #222;
   border: 0;
   -moz-border-radius: 100%;
   padding: 0 8px;
   margin: 0 0 1px;
-  height: 16px;
 }
 
 .bookmark-item > .toolbarbutton-menu-dropmarker {
   list-style-image: url("chrome://browser/skin/places/folderDropArrow.png");
   -moz-image-region: rect(0, 7px, 5px, 0);
   margin-top: 1px;
   -moz-margin-start: 3px;
   -moz-margin-end: -2px;
@@ -206,28 +205,24 @@ toolbarbutton.bookmark-item[open="true"]
   background-color: rgba(0, 0, 0, .5);
 }
 
 toolbarbutton.bookmark-item > menupopup {
   margin-top: 2px;
   -moz-margin-start: 3px;
 }
 
-.bookmark-item[livemark] > .toolbarbutton-menu-dropmarker {
-  list-style-image: url("chrome://browser/skin/places/livemarkFolder.png");
-  -moz-image-region: rect(0, 9px, 10px, 0);
+.bookmark-item > .toolbarbutton-icon {
+  width: 16px;
+  min-height: 16px;
 }
 
-.bookmark-item[livemark]:hover > .toolbarbutton-menu-dropmarker,
-.bookmark-item[livemark][open="true"] > .toolbarbutton-menu-dropmarker {
-  -moz-image-region: rect(0, 18px, 10px, 9px);
-}
-
-.bookmark-item > .toolbarbutton-icon {
-  display: none !important;
+.bookmark-item > .toolbarbutton-icon[label]:not([label=""]),
+.bookmark-item > .toolbarbutton-icon[type="menu"] {
+  -moz-margin-end: 5px;
 }
 
 .bookmark-item[container] {
   list-style-image: url("chrome://global/skin/tree/folder.png");
 }
 
 .query-item[container] {
   list-style-image: url("chrome://browser/skin/places/history.png");
@@ -562,16 +557,17 @@ toolbar[iconsize="small"][mode="icons"] 
   -moz-image-region: rect(20px, 180px, 40px, 160px);
 }
 
 #bookmarks-button[checked="true"]:active:hover {
   -moz-image-region: rect(40px, 180px, 60px, 160px);
 }
 
 #bookmarks-menu-button.bookmark-item {
+  -moz-image-region: rect(2px, 178px, 18px, 162px);
   list-style-image: url("chrome://browser/skin/Toolbar.png");
 }
 
 #bookmarks-menu-button.toolbarbutton-1 {
   -moz-box-orient: horizontal;
 }
 
 /* print button */
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -68,17 +68,16 @@ browser.jar:
   skin/classic/browser/places/livemarkItem.png              (places/livemarkItem.png)
   skin/classic/browser/places/bookmarksMenu.png             (places/bookmarksMenu.png)
   skin/classic/browser/places/bookmarksToolbar.png          (places/bookmarksToolbar.png)
   skin/classic/browser/places/history.png                   (places/history.png)
   skin/classic/browser/places/star-icons.png                (places/star-icons.png)
   skin/classic/browser/places/toolbar.png                   (places/toolbar.png)
   skin/classic/browser/places/toolbarDropMarker.png         (places/toolbarDropMarker.png)
   skin/classic/browser/places/folderDropArrow.png           (places/folderDropArrow.png)
-  skin/classic/browser/places/livemarkFolder.png            (places/livemarkFolder.png)
   skin/classic/browser/places/editBookmarkOverlay.css       (places/editBookmarkOverlay.css)
   skin/classic/browser/places/minus.png                     (places/minus.png)
   skin/classic/browser/places/minus-active.png              (places/minus-active.png)
   skin/classic/browser/places/plus.png                      (places/plus.png)
   skin/classic/browser/places/plus-active.png               (places/plus-active.png)
   skin/classic/browser/places/starPage.png                  (places/starPage.png)
   skin/classic/browser/places/pageStarred.png               (places/pageStarred.png)
   skin/classic/browser/places/searching_16.png              (places/searching_16.png)
deleted file mode 100644
index 5e73536673c8cc561e0e580e2efe957a5ac94130..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -46,17 +46,17 @@ interface nsIScriptSecurityManager : nsI
 {
     ///////////////// Security Checks //////////////////
     /**
      * Checks whether the running script is allowed to access aProperty.
      */
     [noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
                                         in JSObjectPtr aJSObject,
                                         in string aClassName,
-                                        in jsval aProperty,
+                                        in jsid aProperty,
                                         in PRUint32 aAction);
 
     /**
      * Check that the script currently running in context "cx" can load "uri".
      *
      * Will return error code NS_ERROR_DOM_BAD_URI if the load request 
      * should be denied.
      *
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -170,38 +170,38 @@ union SecurityLevel
 
 #define SECURITY_ACCESS_LEVEL_FLAG(_sl) \
            ((_sl.level == 0) || \
             (_sl.level & SCRIPT_SECURITY_ACCESS_IS_SET_BIT))
 
 
 struct PropertyPolicy : public PLDHashEntryHdr
 {
-    jsval          key;  // property name as jsval
+    JSString       *key;  // interned string
     SecurityLevel  mGet;
     SecurityLevel  mSet;
 };
 
 static PRBool
 InitPropertyPolicyEntry(PLDHashTable *table,
                      PLDHashEntryHdr *entry,
                      const void *key)
 {
     PropertyPolicy* pp = (PropertyPolicy*)entry;
-    pp->key = (jsval)key;
+    pp->key = (JSString *)key;
     pp->mGet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
     pp->mSet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
     return PR_TRUE;
 }
 
 static void
 ClearPropertyPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
 {
     PropertyPolicy* pp = (PropertyPolicy*)entry;
-    pp->key = JSVAL_VOID;
+    pp->key = NULL;
 }
 
 // Class Policy
 #define NO_POLICY_FOR_CLASS (ClassPolicy*)1
 
 struct ClassPolicy : public PLDHashEntryHdr
 {
     char* key;
@@ -421,17 +421,17 @@ public:
 private:
 
     // GetScriptSecurityManager is the only call that can make one
     nsScriptSecurityManager();
     virtual ~nsScriptSecurityManager();
 
     static JSBool
     CheckObjectAccess(JSContext *cx, JSObject *obj,
-                      jsval id, JSAccessMode mode,
+                      jsid id, JSAccessMode mode,
                       jsval *vp);
 
     // Decides, based on CSP, whether or not eval() and stuff can be executed.
     static JSBool
     ContentSecurityPolicyPermitsJSAction(JSContext *cx);
 
     // Returns null if a principal cannot be found; generally callers
     // should error out at that point.
@@ -448,27 +448,27 @@ private:
     doGetSubjectPrincipal(nsresult* rv);
     
     nsresult
     CheckPropertyAccessImpl(PRUint32 aAction,
                             nsAXPCNativeCallContext* aCallContext,
                             JSContext* cx, JSObject* aJSObject,
                             nsISupports* aObj, nsIURI* aTargetURI,
                             nsIClassInfo* aClassInfo,
-                            const char* aClassName, jsval aProperty,
+                            const char* aClassName, jsid aProperty,
                             void** aCachedClassPolicy);
 
     nsresult
     CheckSameOriginDOMProp(nsIPrincipal* aSubject, 
                            nsIPrincipal* aObject,
                            PRUint32 aAction);
 
     nsresult
     LookupPolicy(nsIPrincipal* principal,
-                 ClassInfoData& aClassData, jsval aProperty,
+                 ClassInfoData& aClassData, jsid aProperty,
                  PRUint32 aAction,
                  ClassPolicy** aCachedClassPolicy,
                  SecurityLevel* result);
 
     nsresult
     CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal** result);
 
     // This is just like the API method, but it doesn't check that the subject
@@ -607,17 +607,17 @@ private:
 
         ContextPrincipal *mNext;
         JSContext *mCx;
         JSStackFrame *mFp;
         nsCOMPtr<nsIPrincipal> mPrincipal;
     };
 
     // JS strings we need to clean up on shutdown
-    static jsval sEnabledID;
+    static jsid sEnabledID;
 
     inline void
     ScriptSecurityPrefChanged();
 
     static const char sJSEnabledPrefName[];
     static const char sFileOriginPolicyPrefName[];
 
     nsObjectHashtable* mOriginToPolicyMap;
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -111,19 +111,25 @@ PRBool nsScriptSecurityManager::sStrictF
 static JSEqualityOp sXPCWrappedNativeEqualityOps;
 
 
 ///////////////////////////
 // Convenience Functions //
 ///////////////////////////
 // Result of this function should not be freed.
 static inline const PRUnichar *
-JSValIDToString(JSContext *cx, const jsval idval)
+IDToString(JSContext *cx, jsid id)
 {
+    if (JSID_IS_STRING(id))
+        return reinterpret_cast<PRUnichar*>(JS_GetStringChars(JSID_TO_STRING(id)));
+
     JSAutoRequest ar(cx);
+    jsval idval;
+    if (!JS_IdToValue(cx, id, &idval))
+        return nsnull;
     JSString *str = JS_ValueToString(cx, idval);
     if(!str)
         return nsnull;
     return reinterpret_cast<PRUnichar*>(JS_GetStringChars(str));
 }
 
 class nsAutoInPrincipalDomainOriginSetter {
 public:
@@ -560,17 +566,17 @@ nsScriptSecurityManager::ContentSecurity
     }
 
     return evalOK;
 }
 
 
 JSBool
 nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSObject *obj,
-                                           jsval id, JSAccessMode mode,
+                                           jsid id, JSAccessMode mode,
                                            jsval *vp)
 {
     // Get the security manager
     nsScriptSecurityManager *ssm =
         nsScriptSecurityManager::GetScriptSecurityManager();
 
     NS_ASSERTION(ssm, "Failed to get security manager service");
     if (!ssm)
@@ -599,17 +605,17 @@ nsScriptSecurityManager::CheckObjectAcce
 
     return JS_TRUE;
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::CheckPropertyAccess(JSContext* cx,
                                              JSObject* aJSObject,
                                              const char* aClassName,
-                                             jsval aProperty,
+                                             jsid aProperty,
                                              PRUint32 aAction)
 {
     return CheckPropertyAccessImpl(aAction, nsnull, cx, aJSObject,
                                    nsnull, nsnull, nsnull,
                                    aClassName, aProperty, nsnull);
 }
 
 NS_IMETHODIMP
@@ -679,17 +685,17 @@ nsScriptSecurityManager::CheckSameOrigin
 }
 
 nsresult
 nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
                                                  nsAXPCNativeCallContext* aCallContext,
                                                  JSContext* cx, JSObject* aJSObject,
                                                  nsISupports* aObj, nsIURI* aTargetURI,
                                                  nsIClassInfo* aClassInfo,
-                                                 const char* aClassName, jsval aProperty,
+                                                 const char* aClassName, jsid aProperty,
                                                  void** aCachedClassPolicy)
 {
     nsresult rv;
     nsIPrincipal* subjectPrincipal = GetSubjectPrincipal(cx, &rv);
     if (NS_FAILED(rv))
         return rv;
 
     if (!subjectPrincipal || subjectPrincipal == mSystemPrincipal)
@@ -698,17 +704,17 @@ nsScriptSecurityManager::CheckPropertyAc
 
     nsCOMPtr<nsIPrincipal> objectPrincipal;
 
     // Hold the class info data here so we don't have to go back to virtual
     // methods all the time
     ClassInfoData classInfoData(aClassInfo, aClassName);
 #ifdef DEBUG_CAPS_CheckPropertyAccessImpl
     nsCAutoString propertyName;
-    propertyName.AssignWithConversion((PRUnichar*)JSValIDToString(cx, aProperty));
+    propertyName.AssignWithConversion((PRUnichar*)IDToString(cx, aProperty));
     printf("### CanAccess(%s.%s, %i) ", classInfoData.GetName(), 
            propertyName.get(), aAction);
 #endif
 
     //-- Look up the security policy for this class and subject domain
     SecurityLevel securityLevel;
     rv = LookupPolicy(subjectPrincipal, classInfoData, aProperty, aAction, 
                       (ClassPolicy**)aCachedClassPolicy, &securityLevel);
@@ -820,27 +826,27 @@ nsScriptSecurityManager::CheckPropertyAc
         if (NS_SUCCEEDED(rv) && interfaceInfo)
             rv = interfaceInfo->GetIIDShared(&objIID);
         if (NS_SUCCEEDED(rv) && objIID)
         {
             switch (aAction)
             {
             case nsIXPCSecurityManager::ACCESS_GET_PROPERTY:
                 checkedComponent->CanGetProperty(objIID,
-                                                 JSValIDToString(cx, aProperty),
+                                                 IDToString(cx, aProperty),
                                                  getter_Copies(objectSecurityLevel));
                 break;
             case nsIXPCSecurityManager::ACCESS_SET_PROPERTY:
                 checkedComponent->CanSetProperty(objIID,
-                                                 JSValIDToString(cx, aProperty),
+                                                 IDToString(cx, aProperty),
                                                  getter_Copies(objectSecurityLevel));
                 break;
             case nsIXPCSecurityManager::ACCESS_CALL_METHOD:
                 checkedComponent->CanCallMethod(objIID,
-                                                JSValIDToString(cx, aProperty),
+                                                IDToString(cx, aProperty),
                                                 getter_Copies(objectSecurityLevel));
             }
         }
     }
     rv = CheckXPCPermissions(cx, aObj, aJSObject, subjectPrincipal,
                              objectSecurityLevel);
 #ifdef DEBUG_CAPS_CheckPropertyAccessImpl
     if(NS_SUCCEEDED(rv))
@@ -901,17 +907,17 @@ nsScriptSecurityManager::CheckPropertyAc
         NS_ConvertUTF8toUTF16 objectOriginUnicode(objectOrigin);
         NS_ConvertUTF8toUTF16 objectDomainUnicode(objectDomain);
 
         nsXPIDLString errorMsg;
         const PRUnichar *formatStrings[] =
         {
             subjectOriginUnicode.get(),
             className.get(),
-            JSValIDToString(cx, aProperty),
+            IDToString(cx, aProperty),
             objectOriginUnicode.get(),
             subjectDomainUnicode.get(),
             objectDomainUnicode.get()
         };
 
         PRUint32 length = NS_ARRAY_LENGTH(formatStrings);
 
         // XXXbz Our localization system is stupid and can't handle not showing
@@ -1070,17 +1076,17 @@ nsScriptSecurityManager::CheckSameOrigin
     ** Access tests failed, so now report error.
     */
     return NS_ERROR_DOM_PROP_ACCESS_DENIED;
 }
 
 nsresult
 nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
                                       ClassInfoData& aClassData,
-                                      jsval aProperty,
+                                      jsid aProperty,
                                       PRUint32 aAction,
                                       ClassPolicy** aCachedClassPolicy,
                                       SecurityLevel* result)
 {
     nsresult rv;
     result->level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
 
     DomainPolicy* dpolicy = nsnull;
@@ -1181,39 +1187,48 @@ nsScriptSecurityManager::LookupPolicy(ns
 
         if (PL_DHASH_ENTRY_IS_FREE(cpolicy))
             cpolicy = NO_POLICY_FOR_CLASS;
 
         if ((dpolicy == mDefaultPolicy) && aCachedClassPolicy)
             *aCachedClassPolicy = cpolicy;
     }
 
+    NS_ASSERTION(JSID_IS_INT(aProperty) || JSID_IS_OBJECT(aProperty) ||
+                 JSID_IS_STRING(aProperty), "Property must be a valid id");
+
+    // Only atomized strings are stored in the policies' hash tables.
+    if (!JSID_IS_STRING(aProperty))
+        return NS_OK;
+
+    JSString *propertyKey = JSID_TO_STRING(aProperty);
+
     // We look for a PropertyPolicy in the following places:
     // 1)  The ClassPolicy for our class we got from our DomainPolicy
     // 2)  The mWildcardPolicy of our DomainPolicy
     // 3)  The ClassPolicy for our class we got from mDefaultPolicy
     // 4)  The mWildcardPolicy of our mDefaultPolicy
     PropertyPolicy* ppolicy = nsnull;
     if (cpolicy != NO_POLICY_FOR_CLASS)
     {
         ppolicy = static_cast<PropertyPolicy*>
                              (PL_DHashTableOperate(cpolicy->mPolicy,
-                                                      (void*)aProperty,
+                                                      propertyKey,
                                                       PL_DHASH_LOOKUP));
     }
 
     // If there is no class policy for this property, and we have a wildcard
     // policy, try that.
     if (dpolicy->mWildcardPolicy &&
         (!ppolicy || PL_DHASH_ENTRY_IS_FREE(ppolicy)))
     {
         ppolicy =
             static_cast<PropertyPolicy*>
                        (PL_DHashTableOperate(dpolicy->mWildcardPolicy->mPolicy,
-                                                (void*)aProperty,
+                                                propertyKey,
                                                 PL_DHASH_LOOKUP));
     }
 
     // If dpolicy is not the defauly policy and there's no class or wildcard
     // policy for this property, check the default policy for this class and
     // the default wildcard policy
     if (dpolicy != mDefaultPolicy &&
         (!ppolicy || PL_DHASH_ENTRY_IS_FREE(ppolicy)))
@@ -1223,27 +1238,27 @@ nsScriptSecurityManager::LookupPolicy(ns
                                                       aClassData.GetName(),
                                                       PL_DHASH_LOOKUP));
 
         if (PL_DHASH_ENTRY_IS_BUSY(cpolicy))
         {
             ppolicy =
                 static_cast<PropertyPolicy*>
                            (PL_DHashTableOperate(cpolicy->mPolicy,
-                                                    (void*)aProperty,
+                                                    propertyKey,
                                                     PL_DHASH_LOOKUP));
         }
 
         if ((!ppolicy || PL_DHASH_ENTRY_IS_FREE(ppolicy)) &&
             mDefaultPolicy->mWildcardPolicy)
         {
             ppolicy =
               static_cast<PropertyPolicy*>
                          (PL_DHashTableOperate(mDefaultPolicy->mWildcardPolicy->mPolicy,
-                                                  (void*)aProperty,
+                                                  propertyKey,
                                                   PL_DHASH_LOOKUP));
         }
     }
 
     if (!ppolicy || PL_DHASH_ENTRY_IS_FREE(ppolicy))
         return NS_OK;
 
     // Get the correct security level from the property policy
@@ -2363,17 +2378,17 @@ nsScriptSecurityManager::doGetObjectPrin
 {
     NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
     nsIPrincipal* result = nsnull;
 
 #ifdef DEBUG
     JSObject* origObj = aObj;
 #endif
     
-    const JSClass *jsClass = aObj->getClass();
+    js::Class *jsClass = aObj->getClass();
 
     // A common case seen in this code is that we enter this function
     // with aObj being a Function object, whose parent is a Call
     // object. Neither of those have object principals, so we can skip
     // those objects here before we enter the below loop. That way we
     // avoid wasting time checking properties of their classes etc in
     // the loop.
 
@@ -2397,21 +2412,17 @@ nsScriptSecurityManager::doGetObjectPrin
 
     do {
         // Note: jsClass is set before this loop, and also at the
         // *end* of this loop.
 
         // NOTE: These class and equality hook checks better match
         // what IS_WRAPPER_CLASS() does in xpconnect!
         
-        JSEqualityOp op =
-            (jsClass->flags & JSCLASS_IS_EXTENDED) ?
-            reinterpret_cast<const JSExtendedClass*>(jsClass)->equality :
-            nsnull;
-        if (op == sXPCWrappedNativeEqualityOps) {
+        if (jsClass->ext.equality == js::Valueify(sXPCWrappedNativeEqualityOps)) {
             result = sXPConnect->GetPrincipal(aObj,
 #ifdef DEBUG
                                               aAllowShortCircuit
 #else
                                               PR_TRUE
 #endif
                                               );
             if (result) {
@@ -3036,21 +3047,21 @@ nsScriptSecurityManager::CheckComponentP
 
 #ifdef DEBUG_CAPS_CheckComponentPermissions
     printf("### CheckComponentPermissions(ClassID.%s) ",cid.get());
 #endif
 
     // Look up the policy for this class.
     // while this isn't a property we'll treat it as such, using ACCESS_CALL_METHOD
     JSAutoRequest ar(cx);
-    jsval cidVal = STRING_TO_JSVAL(::JS_InternString(cx, cid.get()));
+    jsid cidId = INTERNED_STRING_TO_JSID(::JS_InternString(cx, cid.get()));
 
     ClassInfoData nameData(nsnull, "ClassID");
     SecurityLevel securityLevel;
-    rv = LookupPolicy(subjectPrincipal, nameData, cidVal,
+    rv = LookupPolicy(subjectPrincipal, nameData, cidId,
                       nsIXPCSecurityManager::ACCESS_CALL_METHOD, 
                       nsnull, &securityLevel);
     if (NS_FAILED(rv))
         return rv;
 
     // If there's no policy stored, use the "security.classID.allowByDefault" pref 
     if (securityLevel.level == SCRIPT_SECURITY_UNDEFINED_ACCESS)
         securityLevel.level = mXPCDefaultGrantAll ? SCRIPT_SECURITY_ALL_ACCESS :
@@ -3143,17 +3154,17 @@ nsScriptSecurityManager::CanGetService(J
 
 NS_IMETHODIMP
 nsScriptSecurityManager::CanAccess(PRUint32 aAction,
                                    nsAXPCNativeCallContext* aCallContext,
                                    JSContext* cx,
                                    JSObject* aJSObject,
                                    nsISupports* aObj,
                                    nsIClassInfo* aClassInfo,
-                                   jsval aPropertyName,
+                                   jsid aPropertyName,
                                    void** aPolicy)
 {
     return CheckPropertyAccessImpl(aAction, aCallContext, cx,
                                    aJSObject, aObj, nsnull, aClassInfo,
                                    nsnull, aPropertyName, aPolicy);
 }
 
 nsresult
@@ -3343,18 +3354,18 @@ nsresult nsScriptSecurityManager::Init()
 
     NS_ADDREF(sXPConnect = xpconnect);
     NS_ADDREF(sJSContextStack = xpconnect);
 
     JSContext* cx = GetSafeJSContext();
     if (!cx) return NS_ERROR_FAILURE;   // this can happen of xpt loading fails
     
     ::JS_BeginRequest(cx);
-    if (sEnabledID == JSVAL_VOID)
-        sEnabledID = STRING_TO_JSVAL(::JS_InternString(cx, "enabled"));
+    if (sEnabledID == JSID_VOID)
+        sEnabledID = INTERNED_STRING_TO_JSID(::JS_InternString(cx, "enabled"));
     ::JS_EndRequest(cx);
 
     InitPrefs();
 
     nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIStringBundleService> bundleService =
@@ -3397,17 +3408,17 @@ nsresult nsScriptSecurityManager::Init()
     NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
 
     sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps);
     return NS_OK;
 }
 
 static nsScriptSecurityManager *gScriptSecMan = nsnull;
 
-jsval nsScriptSecurityManager::sEnabledID   = JSVAL_VOID;
+jsid nsScriptSecurityManager::sEnabledID   = JSID_VOID;
 
 nsScriptSecurityManager::~nsScriptSecurityManager(void)
 {
     NS_ASSERTION(!mContextPrincipals, "Leaking mContextPrincipals");
     delete mOriginToPolicyMap;
     if(mDefaultPolicy)
         mDefaultPolicy->Drop();
     delete mCapabilities;
@@ -3416,17 +3427,17 @@ nsScriptSecurityManager::~nsScriptSecuri
 
 void
 nsScriptSecurityManager::Shutdown()
 {
     if (sRuntime) {
         JS_SetRuntimeSecurityCallbacks(sRuntime, NULL);
         sRuntime = nsnull;
     }
-    sEnabledID = JSVAL_VOID;
+    sEnabledID = JSID_VOID;
 
     NS_IF_RELEASE(sIOService);
     NS_IF_RELEASE(sXPConnect);
     NS_IF_RELEASE(sJSContextStack);
     NS_IF_RELEASE(sStrBundle);
 }
 
 nsScriptSecurityManager *
@@ -3746,21 +3757,19 @@ nsScriptSecurityManager::InitDomainPolic
 
         JSAutoRequest ar(cx);
 
         JSString* propertyKey = ::JS_InternString(cx, start);
         if (!propertyKey)
             return NS_ERROR_OUT_OF_MEMORY;
 
         // Store this property in the class policy
-        const void* ppkey =
-          reinterpret_cast<const void*>(STRING_TO_JSVAL(propertyKey));
         PropertyPolicy* ppolicy = 
           static_cast<PropertyPolicy*>
-                     (PL_DHashTableOperate(cpolicy->mPolicy, ppkey,
+                     (PL_DHashTableOperate(cpolicy->mPolicy, propertyKey,
                                               PL_DHASH_ADD));
         if (!ppolicy)
             break;
 
         if (end) // The pref specifies an access mode
         {
             start = end + 1;
             if (PL_strcasecmp(start, "set") == 0)
@@ -4018,17 +4027,17 @@ static PLDHashOperator
 PrintPropertyPolicy(PLDHashTable *table, PLDHashEntryHdr *entry,
                     PRUint32 number, void *arg)
 {
     PropertyPolicy* pp = (PropertyPolicy*)entry;
     nsCAutoString prop("        ");
     JSContext* cx = (JSContext*)arg;
     prop.AppendInt((PRUint32)pp->key);
     prop += ' ';
-    prop.AppendWithConversion((PRUnichar*)JSValIDToString(cx, pp->key));
+    prop.AppendWithConversion((PRUnichar*)JS_GetStringChars(pp->key));
     prop += ": Get=";
     if (SECURITY_ACCESS_LEVEL_FLAG(pp->mGet))
         prop.AppendInt(pp->mGet.level);
     else
         prop += pp->mGet.capability;
 
     prop += " Set=";
     if (SECURITY_ACCESS_LEVEL_FLAG(pp->mSet))
--- a/config/Expression.py
+++ b/config/Expression.py
@@ -104,20 +104,17 @@ class Expression:
     Production: ( [0-9]+ | \w+)
     Note that the order is important, and the expression is kind-of
     ambiguous as \w includes 0-9. One could make it unambiguous by
     removing 0-9 from the first char of a string literal.
     """
     rv = None
     word_len = re.match('[0-9]*', self.content).end()
     if word_len:
-      if self.content[0] == '0':
-        value = int(self.content[:word_len], 8)
-      else:
-        value = int(self.content[:word_len])
+      value = int(self.content[:word_len])
       rv = Expression.__ASTLeaf('int', value)
     else:
       word_len = re.match('\w*', self.content).end()
       if word_len:
         rv = Expression.__ASTLeaf('string', self.content[:word_len])
       else:
         raise Expression.ParseError, self
     self.__strip(word_len)
--- a/config/Preprocessor.py
+++ b/config/Preprocessor.py
@@ -177,20 +177,17 @@ class Preprocessor:
     def handleD(option, opt, value, parser):
       vals = value.split('=', 1)
       if len(vals) == 1:
         vals.append(1)
       elif unescapeDefines and escapedValue.match(vals[1]):
         # strip escaped string values
         vals[1] = vals[1][1:-1]
       elif numberValue.match(vals[1]):
-        if vals[1][0] == '0':
-          vals[1] = int(vals[1], 8)
-        else:
-          vals[1] = int(vals[1])
+        vals[1] = int(vals[1])
       self.context[vals[0]] = vals[1]
     def handleU(option, opt, value, parser):
       del self.context[value]
     def handleF(option, opt, value, parser):
       self.do_filter(value)
     def handleLE(option, opt, value, parser):
       self.setLineEndings(value)
     def handleMarker(option, opt, value, parser):
@@ -242,20 +239,17 @@ class Preprocessor:
   def do_define(self, args):
     m = re.match('(?P<name>\w+)(?:\s(?P<value>.*))?', args, re.U)
     if not m:
       raise Preprocessor.Error(self, 'SYNTAX_DEF', args)
     val = 1
     if m.group('value'):
       val = m.group('value')
       try:
-        if val[0] == '0':
-          val = int(val, 8)
-        else:
-          val = int(val)
+        val = int(val)
       except:
         pass
     self.context[m.group('name')] = val
   def do_undef(self, args):
     m = re.match('(?P<name>\w+)$', args, re.U)
     if not m:
       raise Preprocessor.Error(self, 'SYNTAX_DEF', args)
     if args in self.context:
--- a/config/tests/unit-Preprocessor.py
+++ b/config/tests/unit-Preprocessor.py
@@ -443,10 +443,52 @@ octal value is equal
 #else
 octal value is not equal
 #endif
 """)
     self.pp.handleCommandLine(["-DFOO=0100"])
     self.pp.do_include(f)
     self.assertEqual(self.pp.out.getvalue(), "octal value is equal\n")
 
+  def test_value_quoted_expansion(self):
+    """
+    Quoted values on the commandline don't currently have quotes stripped.
+    Pike says this is for compat reasons.
+    """
+    f = NamedIO("value_quoted_expansion.in", """#filter substitution
+@FOO@
+""")
+    self.pp.handleCommandLine(['-DFOO="ABCD"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), '"ABCD"\n')
+
+  def test_octal_value_quoted_expansion(self):
+    f = NamedIO("value_quoted_expansion.in", """#filter substitution
+@FOO@
+""")
+    self.pp.handleCommandLine(['-DFOO="0100"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), '"0100"\n')
+
+  def test_number_value_not_equals_quoted_defines(self):
+    f = NamedIO("number_value_not_equals_quoted_defines.in", """#if FOO == 1000
+number value is equal
+#else
+number value is not equal
+#endif
+""")
+    self.pp.handleCommandLine(['-DFOO="1000"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "number value is not equal\n")
+
+  def test_octal_value_not_equals_quoted_defines(self):
+    f = NamedIO("octal_value_not_equals_quoted_defines.in", """#if FOO == 0100
+octal value is equal
+#else
+octal value is not equal
+#endif
+""")
+    self.pp.handleCommandLine(['-DFOO="0100"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "octal value is not equal\n")
+
 if __name__ == '__main__':
   unittest.main()
--- a/configure.in
+++ b/configure.in
@@ -6437,23 +6437,16 @@ if test -n "$MOZ_INSTALLER" -a "$OS_ARCH
     if test "$MAKENSISU_VER" == "" -o \
        ! "$MAKENSISU_MAJOR_VER" == "$REQ_NSIS_MAJOR_VER" -o \
        ! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
         AC_MSG_RESULT([no])
         AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the installer reconfigure using --disable-installer.])
     fi
     AC_MSG_RESULT([yes])
     MAKENSISU="${CYGWIN_WRAPPER} $MAKENSISU"
-
-    # The Windows build for NSIS requires the iconv command line utility to
-    # convert the charset of the locale files.
-    MOZ_PATH_PROGS(HOST_ICONV, $HOST_ICONV "iconv", "")
-    if test -z "$HOST_ICONV"; then
-        AC_MSG_ERROR([To build the installer iconv is required in your path. To build without the installer reconfigure using --disable-installer.])
-    fi
 fi
 
 AC_SUBST(MOZ_INSTALLER)
 
 AC_MSG_CHECKING([for tar archiver])
 AC_CHECK_PROGS(TAR, gnutar gtar tar, "")
 if test -z "$TAR"; then
     AC_MSG_ERROR([no tar archiver found in \$PATH])
@@ -6891,16 +6884,24 @@ if test $MOZ_PLATFORM_MAEMO; then
       PKG_CHECK_MODULES(LIBHILDONFM,hildon-fm-2, _LIB_FOUND=1, _LIB_FOUND=)
       MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBHILDONFM_LIBS"
       MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBHILDONFM_CFLAGS"
       if test -z "$_LIB_FOUND"; then
          AC_MSG_ERROR([Hildon FM-2 is required when building for Maemo])
       fi
 
    fi
+   if test $MOZ_PLATFORM_MAEMO = 6; then
+      PKG_CHECK_MODULES(LIBCONTENTACTION, contentaction-0.1, _LIB_FOUND=1, _LIB_FOUND=)
+      MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBCONTENTACTION_LIBS"
+      MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBCONTENTACTION_CFLAGS"
+      if test -z "$_LIB_FOUND"; then
+         AC_MSG_ERROR([libcontentaction is required when build for Maemo])
+      fi
+   fi
 
    if test "$MOZ_PLATFORM_MAEMO" -gt 5; then
      MOZ_THUMB2=1
    fi
 
    PKG_CHECK_MODULES(LIBLOCATION,liblocation, _LIB_FOUND=1, _LIB_FOUND=)
    MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBLOCATION_LIBS"
    MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBLOCATION_CFLAGS"
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -60,17 +60,16 @@ nsIMutationObserver.h \
 nsINameSpaceManager.h \
 nsINode.h \
 nsINodeInfo.h \
 nsINodeList.h \
 nsIRange.h \
 nsIRangeUtils.h \
 nsIScriptElement.h \
 nsIStyleSheetLinkingElement.h \
-nsIPrivateDOMImplementation.h \
 nsIContentSerializer.h \
 nsIHTMLToTextSink.h \
 nsIXPathEvaluatorInternal.h \
 mozISanitizingSerializer.h \
 nsCaseTreatment.h \
 nsContentCID.h \
 nsCopySupport.h \
 nsContentCreatorFunctions.h \
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -106,17 +106,16 @@ class nsILineBreaker;
 class nsIWordBreaker;
 class nsIJSRuntimeService;
 class nsIEventListenerManager;
 class nsIScriptContext;
 class nsIRunnable;
 class nsIInterfaceRequestor;
 template<class E> class nsCOMArray;
 struct JSRuntime;
-class nsICaseConversion;
 class nsIUGenCategory;
 class nsIWidget;
 class nsIDragSession;
 class nsPIDOMWindow;
 class nsPIDOMEventTarget;
 class nsIPresShell;
 class nsIXPConnectJSObjectHolder;
 class nsPrefOldCallback;
@@ -153,16 +152,17 @@ class Element;
 extern const char kLoadAsData[];
 
 enum EventNameType {
   EventNameType_None = 0x0000,
   EventNameType_HTML = 0x0001,
   EventNameType_XUL = 0x0002,
   EventNameType_SVGGraphic = 0x0004, // svg graphic elements
   EventNameType_SVGSVG = 0x0008, // the svg element
+  EventNameType_SMIL = 0x0016, // smil elements
 
   EventNameType_HTMLXUL = 0x0003,
   EventNameType_All = 0xFFFF
 };
 
 struct EventNameMapping
 {
   nsIAtom* mAtom;
@@ -610,21 +610,16 @@ public:
   {
     return sLineBreaker;
   }
 
   static nsIWordBreaker* WordBreaker()
   {
     return sWordBreaker;
   }
-  
-  static nsICaseConversion* GetCaseConv()
-  {
-    return sCaseConv;
-  }
 
   static nsIUGenCategory* GetGenCat()
   {
     return sGenCat;
   }
 
   /**
    * Regster aObserver as a shutdown observer. A strong reference is held
@@ -1736,17 +1731,16 @@ private:
   static nsIStringBundleService* sStringBundleService;
   static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
 
   static nsIContentPolicy* sContentPolicyService;
   static PRBool sTriedToGetContentPolicy;
 
   static nsILineBreaker* sLineBreaker;
   static nsIWordBreaker* sWordBreaker;
-  static nsICaseConversion* sCaseConv;
   static nsIUGenCategory* sGenCat;
 
   // Holds pointers to nsISupports* that should be released at shutdown
   static nsTArray<nsISupports**>* sPtrsToPtrsToRelease;
 
   static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
   static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
   static PRUint32 sJSGCThingRootCount;
@@ -1825,17 +1819,17 @@ public:
     mPtr(aPtr), mRootType(RootType_Object)
   {
     MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
     mResult = *aResult = AddJSGCRoot(aPtr, RootType_Object, "nsAutoGCRoot");
   }
 
   ~nsAutoGCRoot() {
     if (NS_SUCCEEDED(mResult)) {
-      RemoveJSGCRoot(mPtr, mRootType);
+      RemoveJSGCRoot((jsval *)mPtr, mRootType);
     }
   }
 
   static void Shutdown();
 
 private:
   enum RootType { RootType_JSVal, RootType_Object };
   static nsresult AddJSGCRoot(void *aPtr, RootType aRootType, const char* aName);
--- a/content/base/public/nsReferencedElement.h
+++ b/content/base/public/nsReferencedElement.h
@@ -171,18 +171,18 @@ private:
       return NS_OK;
     }
     virtual void SetTo(Element* aTo) { mTo = aTo; }
     virtual void Clear()
     {
       Notification::Clear(); mFrom = nsnull; mTo = nsnull;
     }
   protected:
-    nsCOMPtr<Element> mFrom;
-    nsCOMPtr<Element> mTo;
+    nsRefPtr<Element> mFrom;
+    nsRefPtr<Element> mTo;
   };
   friend class ChangeNotification;
 
   class DocumentLoadNotification : public Notification,
                                    public nsIObserver
   {
   public:
     DocumentLoadNotification(nsReferencedElement* aTarget,
@@ -201,13 +201,13 @@ private:
     virtual void SetTo(Element* aTo) { }
 
     nsString mRef;
   };
   friend class DocumentLoadNotification;
   
   nsCOMPtr<nsIAtom>      mWatchID;
   nsCOMPtr<nsIDocument>  mWatchDocument;
-  nsCOMPtr<Element> mElement;
+  nsRefPtr<Element> mElement;
   nsRefPtr<Notification> mPendingNotification;
 };
 
 #endif /*NSREFERENCEDELEMENT_H_*/
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -141,17 +141,16 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIDOMUserDataHandler.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsTPtrArray.h"
 #include "nsGUIEvent.h"
 #include "nsMutationEvent.h"
 #include "nsIMEStateManager.h"
 #include "nsContentErrors.h"
 #include "nsUnicharUtilCIID.h"
-#include "nsICaseConversion.h"
 #include "nsCompressedCharMap.h"
 #include "nsINativeKeyBindings.h"
 #include "nsIDOMNSUIEvent.h"
 #include "nsIDOMNSEvent.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsXULPopupManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptObjectPrincipal.h"
@@ -236,17 +235,16 @@ nsDataHashtable<nsISupportsHashKey, Even
 nsDataHashtable<nsStringHashKey, EventNameMapping>* nsContentUtils::sStringEventTable = nsnull;
 nsCOMArray<nsIAtom>* nsContentUtils::sUserDefinedEvents = nsnull;
 nsIStringBundleService *nsContentUtils::sStringBundleService;
 nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
 nsIContentPolicy *nsContentUtils::sContentPolicyService;
 PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE;
 nsILineBreaker *nsContentUtils::sLineBreaker;
 nsIWordBreaker *nsContentUtils::sWordBreaker;
-nsICaseConversion *nsContentUtils::sCaseConv;
 nsIUGenCategory *nsContentUtils::sGenCat;
 nsTArray<nsISupports**> *nsContentUtils::sPtrsToPtrsToRelease;
 nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
 PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
 PRUint32 nsContentUtils::sJSGCThingRootCount;
 #ifdef IBMBIDI
 nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
 #endif
@@ -398,19 +396,16 @@ nsContentUtils::Init()
     sIOService = nsnull;
   }
 
   rv = CallGetService(NS_LBRK_CONTRACTID, &sLineBreaker);
   NS_ENSURE_SUCCESS(rv, rv);
   
   rv = CallGetService(NS_WBRK_CONTRACTID, &sWordBreaker);
   NS_ENSURE_SUCCESS(rv, rv);
-  
-  rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &sCaseConv);
-  NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(NS_UNICHARCATEGORY_CONTRACTID, &sGenCat);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(NS_IHISTORY_CONTRACTID, &sHistory);
   if (NS_FAILED(rv)) {
     NS_RUNTIMEABORT("Cannot get the history service");
     return rv;
@@ -575,16 +570,24 @@ nsContentUtils::InitializeEventTable() {
     { nsGkAtoms::onSVGResize,                   NS_SVG_RESIZE, EventNameType_None, NS_SVG_EVENT },
     { nsGkAtoms::onSVGScroll,                   NS_SVG_SCROLL, EventNameType_None, NS_SVG_EVENT },
 
     { nsGkAtoms::onSVGZoom,                     NS_SVG_ZOOM, EventNameType_None, NS_SVGZOOM_EVENT },
 
     // This is a bit hackish, but SVG's event names are weird.
     { nsGkAtoms::onzoom,                        NS_SVG_ZOOM, EventNameType_SVGSVG, NS_EVENT_NULL },
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    { nsGkAtoms::onbegin,                       NS_SMIL_BEGIN, EventNameType_SMIL, NS_EVENT_NULL },
+    { nsGkAtoms::onbeginEvent,                  NS_SMIL_BEGIN, EventNameType_None, NS_SMIL_TIME_EVENT },
+    { nsGkAtoms::onend,                         NS_SMIL_END, EventNameType_SMIL, NS_EVENT_NULL },
+    { nsGkAtoms::onendEvent,                    NS_SMIL_END, EventNameType_None, NS_SMIL_TIME_EVENT },
+    { nsGkAtoms::onrepeat,                      NS_SMIL_REPEAT, EventNameType_SMIL, NS_EVENT_NULL },
+    { nsGkAtoms::onrepeatEvent,                 NS_SMIL_REPEAT, EventNameType_None, NS_SMIL_TIME_EVENT },
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
     { nsGkAtoms::onloadstart,                   NS_LOADSTART, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onprogress,                    NS_PROGRESS, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onsuspend,                     NS_SUSPEND, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onemptied,                     NS_EMPTIED, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onstalled,                     NS_STALLED, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onplay,                        NS_PLAY, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onpause,                       NS_PAUSE, EventNameType_HTML, NS_EVENT_NULL },
@@ -1078,17 +1081,16 @@ nsContentUtils::Shutdown()
   sXPConnect = nsnull;
   sThreadJSContextStack = nsnull;
   NS_IF_RELEASE(sSecurityManager);
   NS_IF_RELEASE(sNameSpaceManager);
   NS_IF_RELEASE(sParserService);
   NS_IF_RELEASE(sIOService);
   NS_IF_RELEASE(sLineBreaker);
   NS_IF_RELEASE(sWordBreaker);
-  NS_IF_RELEASE(sCaseConv);
   NS_IF_RELEASE(sGenCat);
 #ifdef MOZ_XTF
   NS_IF_RELEASE(sXTFService);
 #endif
   NS_IF_RELEASE(sImgLoader);
   NS_IF_RELEASE(sImgCache);
   NS_IF_RELEASE(sHistory);
   NS_IF_RELEASE(sPrefBranch);
@@ -5617,25 +5619,16 @@ CloneSimpleValues(JSContext* cx,
 {
   *wasCloned = PR_TRUE;
 
   // No cloning necessary for these non-GC'd jsvals.
   if (!JSVAL_IS_GCTHING(val) || JSVAL_IS_NULL(val)) {
     return SetPropertyOnValueOrObject(cx, val, rval, robj, rid);
   }
 
-  // Clone doubles.
-  if (JSVAL_IS_DOUBLE(val)) {
-    jsval newVal;
-    if (!JS_NewDoubleValue(cx, *JSVAL_TO_DOUBLE(val), &newVal)) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    return SetPropertyOnValueOrObject(cx, newVal, rval, robj, rid);
-  }
-
   // We'll use immutable strings to prevent copying if we can.
   if (JSVAL_IS_STRING(val)) {
     if (!JS_MakeStringImmutable(cx, JSVAL_TO_STRING(val))) {
       return NS_ERROR_FAILURE;
     }
     return SetPropertyOnValueOrObject(cx, val, rval, robj, rid);
   }
 
@@ -5707,21 +5700,18 @@ CloneSimpleValues(JSContext* cx,
   // Do we support FileList?
 
   // Function objects don't get cloned.
   if (JS_ObjectIsFunction(cx, obj)) {
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
 
   // Security wrapped objects are not allowed either.
-  JSClass* clasp = JS_GET_CLASS(cx, obj);
-  if ((clasp->flags & JSCLASS_IS_EXTENDED) &&
-      ((JSExtendedClass*)clasp)->wrappedObject) {
+  if (obj->getClass()->ext.wrappedObject)
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-  }
 
   // See if this JSObject is backed by some C++ object. If it is then we assume
   // that it is inappropriate to clone.
   nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
   nsContentUtils::XPConnect()->
     GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrapper));
   if (wrapper) {
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -113,17 +113,16 @@
 #include "nsIRefreshURI.h"
 #include "nsIWebNavigation.h"
 #include "nsIScriptError.h"
 
 #include "nsNetUtil.h"     // for NS_MakeAbsoluteURI
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIPrincipal.h"
-#include "nsIPrivateDOMImplementation.h"
 
 #include "nsIDOMWindowInternal.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMElement.h"
 #include "nsFocusManager.h"
 
 // for radio group stuff
 #include "nsIDOMHTMLInputElement.h"
@@ -1219,35 +1218,30 @@ nsDOMStyleSheetSetList::GetSets(nsTArray
 
   return NS_OK;
 }
 
 // ==================================================================
 // =
 // ==================================================================
 
-class nsDOMImplementation : public nsIDOMDOMImplementation,
-                            public nsIPrivateDOMImplementation
+class nsDOMImplementation : public nsIDOMDOMImplementation
 {
 public:
   nsDOMImplementation(nsIScriptGlobalObject* aScriptObject,
                       nsIURI* aDocumentURI,
                       nsIURI* aBaseURI,
                       nsIPrincipal* aPrincipal);
   virtual ~nsDOMImplementation();
 
   NS_DECL_ISUPPORTS
 
   // nsIDOMDOMImplementation
   NS_DECL_NSIDOMDOMIMPLEMENTATION
 
-  // nsIPrivateDOMImplementation
-  NS_IMETHOD Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
-                  nsIPrincipal* aPrincipal);
-
 protected:
   nsWeakPtr mScriptObject;
   nsCOMPtr<nsIURI> mDocumentURI;
   nsCOMPtr<nsIURI> mBaseURI;
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 
@@ -1279,17 +1273,16 @@ nsDOMImplementation::~nsDOMImplementatio
 {
 }
 
 DOMCI_DATA(DOMImplementation, nsDOMImplementation)
 
 // QueryInterface implementation for nsDOMImplementation
 NS_INTERFACE_MAP_BEGIN(nsDOMImplementation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMImplementation)
-  NS_INTERFACE_MAP_ENTRY(nsIPrivateDOMImplementation)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDOMImplementation)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMImplementation)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_ADDREF(nsDOMImplementation)
 NS_IMPL_RELEASE(nsDOMImplementation)
 
@@ -1366,28 +1359,16 @@ nsDOMImplementation::CreateDocument(cons
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptObject);
 
   return nsContentUtils::CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
                                         mDocumentURI, mBaseURI, mPrincipal,
                                         scriptHandlingObject, aReturn);
 }
 
-NS_IMETHODIMP
-nsDOMImplementation::Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
-                          nsIPrincipal* aPrincipal)
-{
-  // Note: can't require that the args be non-null, since at least one
-  // caller (XMLHttpRequest) doesn't have decent args to pass in.
-  mDocumentURI = aDocumentURI;
-  mBaseURI = aBaseURI;
-  mPrincipal = aPrincipal;
-  return NS_OK;
-}
-
 // ==================================================================
 // =
 // ==================================================================
 
   // NOTE! nsDocument::operator new() zeroes out all members, so don't
   // bother initializing members to 0.
 
 nsDocument::nsDocument(const char* aContentType)
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -217,36 +217,30 @@ nsFrameMessageManager::SendSyncMessage()
       NS_ENSURE_STATE(ncc);
 
       JSContext* ctx = nsnull;
       rv = ncc->GetJSContext(&ctx);
       NS_ENSURE_SUCCESS(rv, rv);
       JSAutoRequest ar(ctx);
 
       PRUint32 len = retval.Length();
-      jsval* dest = nsnull;
-      JSObject* dataArray = js_NewArrayObjectWithCapacity(ctx, len, &dest);
+      JSObject* dataArray = JS_NewArrayObject(ctx, len, NULL);
       NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
-      nsAutoGCRoot arrayGCRoot(&dataArray, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
 
       for (PRUint32 i = 0; i < len; ++i) {
-        dest[i] = JSVAL_NULL;
         if (!retval[i].Length())
           continue;
 
         jsval ret = JSVAL_VOID;
-        nsAutoGCRoot root(&ret, &rv);
-        NS_ENSURE_SUCCESS(rv, rv);
         JSONParser* parser = JS_BeginJSONParse(ctx, &ret);
         JSBool ok = JS_ConsumeJSONText(ctx, parser, (jschar*)retval[i].get(),
                                        (uint32)retval[i].Length());
         ok = JS_FinishJSONParse(ctx, parser, JSVAL_NULL) && ok;
         if (ok) {
-          dest[i] = ret;
+          NS_ENSURE_TRUE(JS_SetElement(ctx, dataArray, i, &ret), NS_ERROR_OUT_OF_MEMORY);
         }
       }
 
       jsval* retvalPtr;
       ncc->GetRetValPtr(&retvalPtr);
       *retvalPtr = OBJECT_TO_JSVAL(dataArray);
       ncc->SetReturnValueWasSet(PR_TRUE);
     }
@@ -345,20 +339,19 @@ nsFrameMessageManager::ReceiveMessage(ns
         NS_ENSURE_SUCCESS(rv, rv);
         nsContentUtils::WrapNative(ctx,
                                    JS_GetGlobalObject(ctx),
                                    aTarget, &targetv);
 
         // To keep compatibility with e10s message manager,
         // define empty objects array.
         if (!aObjectsArray) {
-          jsval* dest = nsnull;
           // Because we want JS messages to have always the same properties,
           // create array even if len == 0.
-          aObjectsArray = js_NewArrayObjectWithCapacity(ctx, 0, &dest);
+          aObjectsArray = JS_NewArrayObject(ctx, 0, NULL);
           if (!aObjectsArray) {
             return false;
           }
         }
         nsAutoGCRoot arrayGCRoot(&aObjectsArray, &rv);
         NS_ENSURE_SUCCESS(rv, rv);
 
         jsval json = JSVAL_NULL;
@@ -421,21 +414,21 @@ nsFrameMessageManager::ReceiveMessage(ns
           thisValue = OBJECT_TO_JSVAL(object);
         }
 
         jsval rval = JSVAL_VOID;
         nsAutoGCRoot resultGCRoot4(&rval, &rv);
         NS_ENSURE_SUCCESS(rv, rv);
 
         js::AutoValueRooter argv(ctx);
-        argv.setObject(param);
+        argv.set(OBJECT_TO_JSVAL(param));
 
         JSObject* thisObject = JSVAL_TO_OBJECT(thisValue);
         JS_CallFunctionValue(ctx, thisObject,
-                             funval, 1, argv.addr(), &rval);
+                             funval, 1, argv.jsval_addr(), &rval);
         if (aJSONRetVal) {
           nsString json;
           if (JS_TryJSON(ctx, &rval) &&
               JS_Stringify(ctx, &rval, nsnull, JSVAL_NULL,
                            JSONCreator, &json)) {
             aJSONRetVal->AppendElement(json);
           }
         }
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1304,16 +1304,22 @@ GK_ATOM(begin, "begin")
 GK_ATOM(by, "by")
 GK_ATOM(calcMode, "calcMode")
 GK_ATOM(css, "CSS")
 GK_ATOM(dur, "dur")
 GK_ATOM(keyPoints, "keyPoints")
 GK_ATOM(keySplines, "keySplines")
 GK_ATOM(keyTimes, "keyTimes")
 GK_ATOM(mozAnimateMotionDummyAttr, "_mozAnimateMotionDummyAttr")
+GK_ATOM(onbegin, "onbegin")
+GK_ATOM(onbeginEvent, "onbeginEvent")
+GK_ATOM(onend, "onend")
+GK_ATOM(onendEvent, "onendEvent")
+GK_ATOM(onrepeat, "onrepeat")
+GK_ATOM(onrepeatEvent, "onrepeatEvent")
 GK_ATOM(repeatCount, "repeatCount")
 GK_ATOM(repeatDur, "repeatDur")
 GK_ATOM(restart, "restart")
 GK_ATOM(to, "to")
 GK_ATOM(XML, "XML")
 #endif
 
 #ifdef MOZ_MATHML
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -17,16 +17,17 @@
  *
  * The Initial Developer of the Original Code is
  * Boris Zbarsky <bzbarsky@mit.edu>.
  * Portions created by the Initial Developer are Copyright (C) 2003
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Christian Biesinger <cbiesinger@web.de>
+ *   Bobby Holley <bobbyholley@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -98,45 +99,36 @@ static void PrintReqURL(imgIRequest* req
 }
 #endif /* DEBUG_chb */
 
 
 nsImageLoadingContent::nsImageLoadingContent()
   : mObserverList(nsnull),
     mImageBlockingStatus(nsIContentPolicy::ACCEPT),
     mLoadingEnabled(PR_TRUE),
-    mStartingLoad(PR_FALSE),
     mIsImageStateForced(PR_FALSE),
     mLoading(PR_FALSE),
     // mBroken starts out true, since an image without a URI is broken....
     mBroken(PR_TRUE),
     mUserDisabled(PR_FALSE),
     mSuppressed(PR_FALSE),
-    mBlockingOnload(PR_FALSE)
+    mBlockingOnload(PR_FALSE),
+    mStateChangerDepth(0)
 {
   if (!nsContentUtils::GetImgLoader()) {
     mLoadingEnabled = PR_FALSE;
   }
 }
 
 void
 nsImageLoadingContent::DestroyImageLoadingContent()
 {
-  // If we're blocking onload for any reason, now's a good time to stop
-  SetBlockingOnload(PR_FALSE);
-
   // Cancel our requests so they won't hold stale refs to us
-  if (mCurrentRequest) {
-    mCurrentRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
-    mCurrentRequest = nsnull;
-  }
-  if (mPendingRequest) {
-    mPendingRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
-    mPendingRequest = nsnull;
-  }
+  ClearCurrentRequest(NS_BINDING_ABORTED);
+  ClearPendingRequest(NS_BINDING_ABORTED);
 }
 
 nsImageLoadingContent::~nsImageLoadingContent()
 {
   NS_ASSERTION(!mCurrentRequest && !mPendingRequest,
                "DestroyImageLoadingContent not called");
   NS_ASSERTION(!mObserverList.mObserver && !mObserverList.mNext,
                "Observers still registered?");
@@ -256,43 +248,45 @@ nsImageLoadingContent::OnStopContainer(i
   // always fired in the decoders at the same time as OnStopDecode.
   if (aRequest == mCurrentRequest)
     SetBlockingOnload(PR_FALSE);
 
   LOOP_OVER_OBSERVERS(OnStopContainer(aRequest, aContainer));
   return NS_OK;
 }
 
+// Warning - This isn't actually fired when decode is complete. Rather, it's
+// fired when load is complete. See bug 505385, and in the mean time use
+// OnStopContainer.
 NS_IMETHODIMP
 nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
                                     nsresult aStatus,
                                     const PRUnichar* aStatusArg)
 {
   // We should definitely have a request here
   NS_ABORT_IF_FALSE(aRequest, "no request?");
 
   NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
                   "Unknown request");
   LOOP_OVER_OBSERVERS(OnStopDecode(aRequest, aStatus, aStatusArg));
 
-  if (aRequest == mPendingRequest) {
-
-    // If we were blocking for the soon-to-be-obsolete request, stop doing so
-    SetBlockingOnload(PR_FALSE);
+  // XXXbholley - When we fix bug 505385,  everything here should go in
+  // OnStopRequest.
 
-    // The new image is decoded - switch to it
-    // XXXbholley - This is technically not true pre bug 505385, but I don't
-    // think it's a big enough issue to worry about handling in the mean time
-    mCurrentRequest->Cancel(NS_ERROR_IMAGE_SRC_CHANGED);
-    mPendingRequest.swap(mCurrentRequest);
+  // Our state may change. Watch it.
+  AutoStateChanger changer(this, PR_TRUE);
+
+  // If the pending request is loaded, switch to it.
+  if (aRequest == mPendingRequest) {
+    PrepareCurrentRequest() = mPendingRequest;
     mPendingRequest = nsnull;
   }
+  NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
+                    "One way or another, we should be current by now");
 
-  // XXXbholley - When we fix bug 505385,  this should go in OnStopRequest.
-  //
   // We just loaded all the data we're going to get. If we haven't done an
   // initial paint, we want to make sure the image starts decoding for 2
   // reasons:
   //
   // 1) This image is sitting idle but might need to be decoded as soon as we
   // start painting, in which case we've wasted time.
   //
   // 2) We want to block onload until all visible images are decoded. We do this
@@ -319,36 +313,26 @@ nsImageLoadingContent::OnStopDecode(imgI
     // to be suppressed for reasons other than the initial paint delay (for
     // example - being in the bfcache), but we probably aren't loading images in
     // those situations.
     if (shell->IsPaintingSuppressed())
       doRequestDecode = PR_TRUE;
 
     // If we're requesting a decode, do it
     if (doRequestDecode)
-      aRequest->RequestDecode();
+      mCurrentRequest->RequestDecode();
   }
 
-  // XXXldb What's the difference between when OnStopDecode and OnStopRequest
-  // fire?  Should we do this work there instead?  Should they just be the
-  // same?
-
+  // Fire the appropriate DOM event.
   if (NS_SUCCEEDED(aStatus)) {
     FireEvent(NS_LITERAL_STRING("load"));
   } else {
     FireEvent(NS_LITERAL_STRING("error"));
   }
 
-  // Have to check for state changes here (for example, the new load could
-  // have resulted in a broken image).  Note that we don't want to do this
-  // async, unlike the event, because while this is waiting to happen our
-  // state could change yet again, and then we'll get confused about our
-  // state.
-  UpdateImageState(PR_TRUE);
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest, PRBool aLastPart)
 {
   LOOP_OVER_OBSERVERS(OnStopRequest(aRequest, aLastPart));
 
@@ -508,49 +492,46 @@ nsImageLoadingContent::GetCurrentURI(nsI
   
   return NS_EnsureSafeToReturn(mCurrentURI, aURI);
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
                                             nsIStreamListener** aListener)
 {
-  NS_PRECONDITION(aListener, "null out param");
-  
-  NS_ENSURE_ARG_POINTER(aChannel);
-
   if (!nsContentUtils::GetImgLoader()) {
     return NS_ERROR_NULL_POINTER;
   }
 
-  // XXX what should we do with content policies here, if anything?
-  // Shouldn't that be done before the start of the load?
-  // XXX what about shouldProcess?
-  
   nsCOMPtr<nsIDocument> doc = GetOurDocument();
   if (!doc) {
     // Don't bother
     return NS_OK;
   }
 
-  // Null out our mCurrentURI, in case we have no image requests right now.
-  mCurrentURI = nsnull;
-  
-  CancelImageRequests(NS_ERROR_IMAGE_SRC_CHANGED, PR_FALSE,
-                      nsIContentPolicy::ACCEPT);
+  // XXX what should we do with content policies here, if anything?
+  // Shouldn't that be done before the start of the load?
+  // XXX what about shouldProcess?
 
-  nsCOMPtr<imgIRequest> & req = mCurrentRequest ? mPendingRequest : mCurrentRequest;
+  // Our state might change. Watch it.
+  AutoStateChanger changer(this, PR_TRUE);
 
+  // Do the load.
   nsresult rv = nsContentUtils::GetImgLoader()->
-    LoadImageWithChannel(aChannel, this, doc, aListener, getter_AddRefs(req));
-
-  // Make sure our state is up to date
-  UpdateImageState(PR_TRUE);
-
-  return rv;
+    LoadImageWithChannel(aChannel, this, doc, aListener,
+                         getter_AddRefs(PrepareNextRequest()));
+  if (NS_FAILED(rv)) {
+    // If we don't have a current URI, we might as well store this URI so people
+    // know what we tried (and failed) to load.
+    if (!mCurrentRequest)
+      aChannel->GetURI(getter_AddRefs(mCurrentURI));
+    FireEvent(NS_LITERAL_STRING("error"));
+    return rv;
+  }
+  return NS_OK;;
 }
 
 NS_IMETHODIMP nsImageLoadingContent::ForceReload()
 {
   nsCOMPtr<nsIURI> currentURI;
   GetCurrentURI(getter_AddRefs(currentURI));
   if (!currentURI) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -623,98 +604,72 @@ nsImageLoadingContent::LoadImage(nsIURI*
   if (!aDocument) {
     aDocument = GetOurDocument();
     if (!aDocument) {
       // No reason to bother, I think...
       return NS_OK;
     }
   }
 
-
-  nsresult rv;   // XXXbz Should failures in this method fire onerror?
-
-  // Skip the URI equality check if our current image was blocked.  If
-  // that happened, we really do want to try loading again.
+  // URI equality check.
+  //
+  // We skip the equality check if our current image was blocked, since in that
+  // case we really do want to try loading again.
   if (!aForce && NS_CP_ACCEPTED(mImageBlockingStatus)) {
     nsCOMPtr<nsIURI> currentURI;
     GetCurrentURI(getter_AddRefs(currentURI));
     PRBool equal;
     if (currentURI &&
         NS_SUCCEEDED(currentURI->Equals(aNewURI, &equal)) &&
         equal) {
       // Nothing to do here.
       return NS_OK;
     }
   }
 
-  // From this point on, our state could change before return, so make
-  // sure to notify if it does.
+  // From this point on, our image state could change. Watch it.
   AutoStateChanger changer(this, aNotify);
 
-  // Use the principal of aDocument to avoid having to QI |this| an extra time.
-  // It should be the same as the principal of this node in any case.
+  // Sanity check.
+  //
+  // We use the principal of aDocument to avoid having to QI |this| an extra
+  // time. It should always be the same as the principal of this node.
 #ifdef DEBUG
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
-  NS_ASSERTION(thisContent &&
-               thisContent->NodePrincipal() == aDocument->NodePrincipal(),
-               "Principal mismatch?");
+  NS_ABORT_IF_FALSE(thisContent &&
+                    thisContent->NodePrincipal() == aDocument->NodePrincipal(),
+                    "Principal mismatch?");
 #endif
-  
-  // If we'll be loading a new image, we want to cancel our existing
-  // requests; the question is what reason to pass in.  If everything
-  // is going smoothly, that reason should be
-  // NS_ERROR_IMAGE_SRC_CHANGED so that our frame (if any) will know
-  // not to show the broken image icon.  If the load is blocked by the
-  // content policy or security manager, we will want to cancel with
-  // the error code from those.
 
-  PRInt16 newImageStatus;
-  PRBool loadImage = nsContentUtils::CanLoadImage(aNewURI, this, aDocument,
-                                                  aDocument->NodePrincipal(),
-                                                  &newImageStatus);
-  NS_ASSERTION(loadImage || !NS_CP_ACCEPTED(newImageStatus),
-               "CanLoadImage lied");
-
-  nsresult cancelResult = loadImage ? NS_ERROR_IMAGE_SRC_CHANGED
-                                    : NS_ERROR_IMAGE_BLOCKED;
-
-  CancelImageRequests(cancelResult, PR_FALSE, newImageStatus);
-
-  // Remember the URL of this request, in case someone asks us for it later.
-  // But this only matters if we are affecting the current request.  Need to do
-  // this after CancelImageRequests, since that affects the value of
-  // mCurrentRequest.
-  if (!mCurrentRequest) {
-    mCurrentURI = aNewURI;
-  }
-  
-  if (!loadImage) {
-    // Don't actually load anything!  This was blocked by CanLoadImage.
+  // Are we blocked?
+  PRInt16 cpDecision = nsIContentPolicy::REJECT_REQUEST;
+  nsContentUtils::CanLoadImage(aNewURI, this, aDocument,
+                               aDocument->NodePrincipal(), &cpDecision);
+  if (!NS_CP_ACCEPTED(cpDecision)) {
     FireEvent(NS_LITERAL_STRING("error"));
+    SetBlockedRequest(aNewURI, cpDecision);
     return NS_OK;
   }
 
-  nsCOMPtr<imgIRequest> & req = mCurrentRequest ? mPendingRequest : mCurrentRequest;
-
+  // Not blocked. Do the load.
+  nsresult rv;
   rv = nsContentUtils::LoadImage(aNewURI, aDocument,
                                  aDocument->NodePrincipal(),
                                  aDocument->GetDocumentURI(),
                                  this, aLoadFlags,
-                                 getter_AddRefs(req));
+                                 getter_AddRefs(PrepareNextRequest()));
   if (NS_FAILED(rv)) {
+    // If we don't have a current URI, we might as well store this URI so people
+    // know what we tried (and failed) to load.
+    if (!mCurrentRequest)
+      mCurrentURI = aNewURI;
     FireEvent(NS_LITERAL_STRING("error"));
     return NS_OK;
   }
 
-  // If we now have a current request, we don't need to store the URI, since
-  // we can get it off the request. Release it.
-  if (mCurrentRequest) {
-    mCurrentURI = nsnull;
-  }
-
   return NS_OK;
 }
 
 nsresult
 nsImageLoadingContent::ForceImageState(PRBool aForce, PRInt32 aState)
 {
   mIsImageStateForced = aForce;
   mForcedImageState = aState;
@@ -729,22 +684,23 @@ nsImageLoadingContent::ImageState() cons
     (mUserDisabled * NS_EVENT_STATE_USERDISABLED) |
     (mSuppressed * NS_EVENT_STATE_SUPPRESSED) |
     (mLoading * NS_EVENT_STATE_LOADING);
 }
 
 void
 nsImageLoadingContent::UpdateImageState(PRBool aNotify)
 {
-  if (mStartingLoad) {
-    // Ignore this call; we'll update our state when the state changer is
-    // destroyed.  Need this to work around the fact that some libpr0n stuff is
-    // actually sync and hence we can get OnStopDecode called while we're still
-    // under LoadImage, and OnStopDecode doesn't know anything about
-    // aNotify
+  if (mStateChangerDepth > 0) {
+    // Ignore this call; we'll update our state when the outermost state
+    // changer is destroyed. Need this to work around the fact that some libpr0n
+    // stuff is actually sync and hence we can get OnStopDecode called while
+    // we're still under LoadImage, and OnStopDecode doesn't know anything about
+    // aNotify.
+    // XXX - This machinery should be removed after bug 521604.
     return;
   }
   
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
   if (!thisContent) {
     return;
   }
 
@@ -783,88 +739,38 @@ nsImageLoadingContent::UpdateImageState(
       }
     }
   }
 }
 
 void
 nsImageLoadingContent::CancelImageRequests(PRBool aNotify)
 {
-  // Make sure to null out mCurrentURI here, so we no longer look like an image
   AutoStateChanger changer(this, aNotify);
-  mCurrentURI = nsnull;
-  CancelImageRequests(NS_BINDING_ABORTED, PR_TRUE, nsIContentPolicy::ACCEPT);
-}
-
-void
-nsImageLoadingContent::CancelImageRequests(nsresult aReason,
-                                           PRBool   aEvenIfSizeAvailable,
-                                           PRInt16  aNewImageStatus)
-{
-  // Cancel the pending request, if any
-  if (mPendingRequest) {
-    mPendingRequest->Cancel(aReason);
-    mPendingRequest = nsnull;
-  }
-
-  // Cancel the current request if it has not progressed enough to
-  // have a size yet
-  if (mCurrentRequest) {
-    PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
-    mCurrentRequest->GetImageStatus(&loadStatus);
-
-    NS_ASSERTION(NS_CP_ACCEPTED(mImageBlockingStatus),
-                 "Have current request but blocked image?");
-    
-    if (aEvenIfSizeAvailable ||
-        !(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
-      // The new image is going to become the current request.  Make sure to
-      // set mImageBlockingStatus _before_ we cancel the request... if we set
-      // it after, things that are watching the mCurrentRequest will get wrong
-      // data.
-
-      // If we were blocking onload for this image, stop doing so
-      SetBlockingOnload(PR_FALSE);
-
-      // Get rid of it
-      mImageBlockingStatus = aNewImageStatus;
-      mCurrentRequest->Cancel(aReason);
-      mCurrentRequest = nsnull;
-    }
-  } else {
-    // No current request so the new image status will become the
-    // status of the current request
-    mImageBlockingStatus = aNewImageStatus;
-  }
-
-  // Note that the only way we could have avoided setting the image blocking
-  // status above is if we have a current request and have kept it as the
-  // current request.  In that case, we want to leave our old status, since the
-  // status corresponds to the current request.  Even if we plan to do a
-  // pending request load, having an mCurrentRequest means that our current
-  // status is not a REJECT_* status, and doing the load shouldn't change that.
-  // XXXbz there is an issue here if different ACCEPT statuses are used, but...
+  ClearPendingRequest(NS_BINDING_ABORTED);
+  ClearCurrentRequest(NS_BINDING_ABORTED);
 }
 
 nsresult
 nsImageLoadingContent::UseAsPrimaryRequest(imgIRequest* aRequest,
                                            PRBool aNotify)
 {
-  // Use an AutoStateChanger so that the clone call won't
-  // automatically notify from inside OnStopDecode.
-  // Also, make sure to use the CancelImageRequests which doesn't
-  // notify, so that the changer is handling the notifications.
-  NS_PRECONDITION(aRequest, "Must have a request here!");
+  // Our state will change. Watch it.
   AutoStateChanger changer(this, aNotify);
-  mCurrentURI = nsnull;
-  CancelImageRequests(NS_BINDING_ABORTED, PR_TRUE, nsIContentPolicy::ACCEPT);
+
+  // Get rid if our existing images
+  ClearPendingRequest(NS_BINDING_ABORTED);
+  ClearCurrentRequest(NS_BINDING_ABORTED);
 
-  NS_ASSERTION(!mCurrentRequest, "We should not have a current request now");
+  // Clone the request we were given.
+  nsCOMPtr<imgIRequest> newRequest;
+  nsresult rv = aRequest->Clone(this, getter_AddRefs(PrepareNextRequest()));
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  return aRequest->Clone(this, getter_AddRefs(mCurrentRequest));
+  return NS_OK;
 }
 
 nsIDocument*
 nsImageLoadingContent::GetOurDocument()
 {
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
   NS_ENSURE_TRUE(thisContent, nsnull);
 
@@ -906,16 +812,122 @@ nsImageLoadingContent::FireEvent(const n
 
   nsRefPtr<nsPLDOMEvent> event =
     new nsLoadBlockingPLDOMEvent(thisNode, aEventType, PR_FALSE, PR_FALSE);
   event->PostDOMEvent();
   
   return NS_OK;
 }
 
+nsCOMPtr<imgIRequest>&
+nsImageLoadingContent::PrepareNextRequest()
+{
+  // If we don't have a usable current request, get rid of any half-baked
+  // request that might be sitting there and make this one current.
+  if (!HaveSize(mCurrentRequest))
+    return PrepareCurrentRequest();
+
+  // Otherwise, make it pending.
+  return PreparePendingRequest();
+}
+
+void
+nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision)
+{
+  // Sanity
+  NS_ABORT_IF_FALSE(!NS_CP_ACCEPTED(aContentDecision), "Blocked but not?");
+
+  // We do some slightly illogical stuff here to maintain consistency with
+  // old behavior that people probably depend on. Even in the case where the
+  // new image is blocked, the old one should really be canceled with the
+  // reason "image source changed". However, apparently there's some abuse
+  // over in nsImageFrame where the displaying of the "broken" icon for the
+  // next image depends on the cancel reason of the previous image. ugh.
+  ClearPendingRequest(NS_ERROR_IMAGE_BLOCKED);
+
+  // For the blocked case, we only want to cancel the existing current request
+  // if size is not available. bz says the web depends on this behavior.
+  if (!HaveSize(mCurrentRequest)) {
+
+    mImageBlockingStatus = aContentDecision;
+    ClearCurrentRequest(NS_ERROR_IMAGE_BLOCKED);
+
+    // We still want to remember what URI we were despite not having an actual
+    // request.
+    mCurrentURI = aURI;
+  }
+}
+
+nsCOMPtr<imgIRequest>&
+nsImageLoadingContent::PrepareCurrentRequest()
+{
+  // Blocked images go through SetBlockedRequest, which is a separate path. For
+  // everything else, we're unblocked.
+  mImageBlockingStatus = nsIContentPolicy::ACCEPT;
+
+  // Get rid of anything that was there previously.
+  ClearCurrentRequest(NS_ERROR_IMAGE_SRC_CHANGED);
+
+  // Return a reference.
+  return mCurrentRequest;
+}
+
+nsCOMPtr<imgIRequest>&
+nsImageLoadingContent::PreparePendingRequest()
+{
+  // Get rid of anything that was there previously.
+  ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED);
+
+  // Return a reference.
+  return mPendingRequest;
+}
+
+void
+nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
+{
+  if (!mCurrentRequest) {
+    // Even if we didn't have a current request, we might have been keeping
+    // a URI as a placeholder for a failed load. Clear that now.
+    mCurrentURI = nsnull;
+    return;
+  }
+  NS_ABORT_IF_FALSE(!mCurrentURI,
+                    "Shouldn't have both mCurrentRequest and mCurrentURI!");
+
+  // Clean up the request.
+  mCurrentRequest->CancelAndForgetObserver(aReason);
+  mCurrentRequest = nsnull;
+
+  // We only block onload during the decoding of "current" images. This one is
+  // going away, so we should unblock unconditionally here.
+  SetBlockingOnload(PR_FALSE);
+}
+
+void
+nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
+{
+  if (!mPendingRequest)
+    return;
+  mPendingRequest->CancelAndForgetObserver(aReason);
+  mPendingRequest = nsnull;
+}
+
+bool
+nsImageLoadingContent::HaveSize(imgIRequest *aImage)
+{
+  // Handle the null case
+  if (!aImage)
+    return false;
+
+  // Query the image
+  PRUint32 status;
+  nsresult rv = aImage->GetImageStatus(&status);
+  return (NS_SUCCEEDED(rv) && (status & imgIRequest::STATUS_SIZE_AVAILABLE));
+}
+
 void
 nsImageLoadingContent::SetBlockingOnload(PRBool aBlocking)
 {
   // If we're already in the desired state, we have nothing to do
   if (mBlockingOnload == aBlocking)
     return;
 
   // Get the document
@@ -935,16 +947,16 @@ nsImageLoadingContent::SetBlockingOnload
 
 void
 nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) const
 {
   aDest->mCurrentRequest = nsContentUtils::GetStaticRequest(mCurrentRequest);
   aDest->mForcedImageState = mForcedImageState;
   aDest->mImageBlockingStatus = mImageBlockingStatus;
   aDest->mLoadingEnabled = mLoadingEnabled;
-  aDest->mStartingLoad = mStartingLoad;
+  aDest->mStateChangerDepth = mStateChangerDepth;
   aDest->mIsImageStateForced = mIsImageStateForced;
   aDest->mLoading = mLoading;
   aDest->mBroken = mBroken;
   aDest->mUserDisabled = mUserDisabled;
   aDest->mSuppressed = mSuppressed;
 }
 
--- a/content/base/src/nsImageLoadingContent.h
+++ b/content/base/src/nsImageLoadingContent.h
@@ -184,23 +184,21 @@ private:
    * Struct to report state changes
    */
   struct AutoStateChanger {
     AutoStateChanger(nsImageLoadingContent* aImageContent,
                      PRBool aNotify) :
       mImageContent(aImageContent),
       mNotify(aNotify)
     {
-      NS_ASSERTION(!mImageContent->mStartingLoad,
-                   "Nested AutoStateChangers somehow?");
-      mImageContent->mStartingLoad = PR_TRUE;
+      mImageContent->mStateChangerDepth++;
     }
     ~AutoStateChanger()
     {
-      mImageContent->mStartingLoad = PR_FALSE;
+      mImageContent->mStateChangerDepth--;
       mImageContent->UpdateImageState(mNotify);
     }
 
     nsImageLoadingContent* mImageContent;
     PRBool mNotify;
   };
 
   friend struct AutoStateChanger;
@@ -243,19 +241,60 @@ private:
    * Method to fire an event once we know what's going on with the image load.
    *
    * @param aEventType "load" or "error" depending on how things went
    */
   nsresult FireEvent(const nsAString& aEventType);
 protected:
   void CreateStaticImageClone(nsImageLoadingContent* aDest) const;
 
+  /**
+   * Prepare and returns a reference to the "next request". If there's already
+   * a _usable_ current request (one with SIZE_AVAILABLE), this request is
+   * "pending" until it becomes usable. Otherwise, this becomes the current
+   * request.
+   */
+   nsCOMPtr<imgIRequest>& PrepareNextRequest();
+
+  /**
+   * Called when we would normally call PrepareNextRequest(), but the request was
+   * blocked.
+   */
+  void SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision);
+
+  /**
+   * Returns a COMPtr reference to the current/pending image requests, cleaning
+   * up and canceling anything that was there before. Note that if you just want
+   * to get rid of one of the requests, you should call
+   * Clear*Request(NS_BINDING_ABORTED) instead, since it passes a more appropriate
+   * aReason than Prepare*Request() does (NS_ERROR_IMAGE_SRC_CHANGED).
+   */
+  nsCOMPtr<imgIRequest>& PrepareCurrentRequest();
+  nsCOMPtr<imgIRequest>& PreparePendingRequest();
+
+  /**
+   * Cancels and nulls-out the "current" and "pending" requests if they exist.
+   */
+  void ClearCurrentRequest(nsresult aReason);
+  void ClearPendingRequest(nsresult aReason);
+
+  /**
+   * Static helper method to tell us if we have the size of a request. The
+   * image may be null.
+   */
+  static bool HaveSize(imgIRequest *aImage);
+
   /* MEMBERS */
   nsCOMPtr<imgIRequest> mCurrentRequest;
   nsCOMPtr<imgIRequest> mPendingRequest;
+
+  // If the image was blocked or if there was an error loading, it's nice to
+  // still keep track of what the URI was despite not having an imgIRequest.
+  // We only maintain this in those situations (in the common case, this is
+  // always null).
   nsCOMPtr<nsIURI>      mCurrentURI;
 
 private:
   /**
    * Typically we will have only one observer (our frame in the screen
    * prescontext), so we want to only make space for one and to
    * heap-allocate anything past that (saves memory and malloc churn
    * in the common case).  The storage is a linked list, we just
@@ -267,17 +306,16 @@ private:
   /**
    * When mIsImageStateForced is true, this holds the ImageState that we'll
    * return in ImageState().
    */
   PRInt32 mForcedImageState;
 
   PRInt16 mImageBlockingStatus;
   PRPackedBool mLoadingEnabled : 1;
-  PRPackedBool mStartingLoad : 1;
 
   /**
    * When true, we return mForcedImageState from ImageState().
    */
   PRPackedBool mIsImageStateForced : 1;
 
   /**
    * The state we had the last time we checked whether we needed to notify the
@@ -287,11 +325,14 @@ private:
   PRPackedBool mBroken : 1;
   PRPackedBool mUserDisabled : 1;
   PRPackedBool mSuppressed : 1;
 
   /**
    * Whether we're currently blocking document load.
    */
   PRPackedBool mBlockingOnload : 1;
+
+  /* The number of nested AutoStateChangers currently tracking our state. */
+  PRUint8 mStateChangerDepth;
 };
 
 #endif // nsImageLoadingContent_h__
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -281,18 +281,19 @@ nsInProcessTabChildGlobal::InitTabChildG
                          nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
 
   nsISupports* scopeSupports =
     NS_ISUPPORTS_CAST(nsPIDOMEventTarget*, this);
   JS_SetContextPrivate(cx, scopeSupports);
 
   nsresult rv =
     xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports,
-                                         NS_GET_IID(nsISupports), flags,
-                                         getter_AddRefs(mGlobal));
+                                         NS_GET_IID(nsISupports),
+                                         GetPrincipal(), EmptyCString(),
+                                         flags, getter_AddRefs(mGlobal));
   NS_ENSURE_SUCCESS(rv, false);
 
   JSObject* global = nsnull;
   rv = mGlobal->GetJSObject(&global);
   NS_ENSURE_SUCCESS(rv, false);
 
   JS_SetGlobalObject(cx, global);
 
--- a/content/base/src/nsSyncLoadService.cpp
+++ b/content/base/src/nsSyncLoadService.cpp
@@ -45,18 +45,16 @@
 #include "nsIChannel.h"
 #include "nsIDOMLoadListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMDOMImplementation.h"
-#include "nsIPrivateDOMImplementation.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 #include "nsAutoPtr.h"
 #include "nsLoadListenerProxy.h"
 #include "nsStreamUtils.h"
 #include "nsCrossSiteListenerProxy.h"
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -39,24 +39,24 @@
 
 #include "nsDOMError.h"
 #include "nsIDOMCanvasRenderingContext2D.h"
 
 typedef nsresult (NS_STDCALL nsIDOMCanvasRenderingContext2D::*CanvasStyleSetterType)(const nsAString &, nsISupports *);
 typedef nsresult (NS_STDCALL nsIDOMCanvasRenderingContext2D::*CanvasStyleGetterType)(nsAString &, nsISupports **, PRInt32 *);
 
 static JSBool
-Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
+Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
                         CanvasStyleSetterType setfunc)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     nsresult rv;
 
     if (JSVAL_IS_STRING(*vp)) {
         xpc_qsDOMString arg0(cx, *vp, vp,
                              xpc_qsDOMString::eDefaultNullBehavior,
                              xpc_qsDOMString::eDefaultUndefinedBehavior);
@@ -64,34 +64,34 @@ Canvas2D_SetStyleHelper(JSContext *cx, J
             return JS_FALSE;
 
         rv = (self->*setfunc)(arg0, nsnull);
     } else {
         nsISupports *arg0;
         xpc_qsSelfRef arg0ref;
         rv = xpc_qsUnwrapArg<nsISupports>(cx, *vp, &arg0, &arg0ref.ptr, vp);
         if (NS_FAILED(rv)) {
-            xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(*tvr.addr()), id);
+            xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
             return JS_FALSE;
         }
 
         nsString voidStr;
         voidStr.SetIsVoid(PR_TRUE);
 
         rv = (self->*setfunc)(voidStr, arg0);
     }
 
     if (NS_FAILED(rv))
-        return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*tvr.addr()), id);
+        return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
 
     return JS_TRUE;
 }
 
 static JSBool
-Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
+Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
                         CanvasStyleGetterType getfunc)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
     XPCLazyCallContext lccx(JS_CALLER, cx, obj);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, vp, &lccx))
         return JS_FALSE;
@@ -129,35 +129,35 @@ Canvas2D_GetStyleHelper(JSContext *cx, J
                                         &interfaces[k_nsIDOMCanvasGradient], vp);
     }
     default:
         return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(*vp), id);
     }
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
 }
 
 static JSBool
 nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, uintN argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
@@ -186,24 +186,24 @@ nsIDOMCanvasRenderingContext2D_CreateIma
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     uint32 len = len0 * 4;
     if (len / 4 != len0)
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     // create the fast typed array; it's initialized to 0 by default
     JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
-    js::AutoValueRooter rd(cx, darray);
+    js::AutoObjectRooter rd(cx, darray);
     if (!darray)
         return JS_FALSE;
 
     // Do JS_NewObject after CreateTypedArray, so that gc will get
     // triggered here if necessary
     JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
-    js::AutoValueRooter rr(cx, result);
+    js::AutoObjectRooter rr(cx, result);
     if (!result)
         return JS_FALSE;
 
     if (!JS_DefineProperty(cx, result, "width", INT_TO_JSVAL(w), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "height", INT_TO_JSVAL(h), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "data", OBJECT_TO_JSVAL(darray), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
         return JS_FALSE;
 
@@ -220,17 +220,17 @@ nsIDOMCanvasRenderingContext2D_GetImageD
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 4)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     int32 x, y;
@@ -253,31 +253,31 @@ nsIDOMCanvasRenderingContext2D_GetImageD
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     uint32 len = len0 * 4;
     if (len / 4 != len0)
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     // create the fast typed array
     JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
-    js::AutoValueRooter rd(cx, darray);
+    js::AutoObjectRooter rd(cx, darray);
     if (!darray)
         return JS_FALSE;
 
     js::TypedArray *tdest = js::TypedArray::fromJSObject(darray);
 
     // make the call
     rv = self->GetImageData_explicit(x, y, w, h, (PRUint8*) tdest->data, tdest->byteLength);
     if (NS_FAILED(rv))
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     // Do JS_NewObject after CreateTypedArray, so that gc will get
     // triggered here if necessary
     JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
-    js::AutoValueRooter rr(cx, result);
+    js::AutoObjectRooter rr(cx, result);
     if (!result)
         return JS_FALSE;
 
     if (!JS_DefineProperty(cx, result, "width", INT_TO_JSVAL(w), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "height", INT_TO_JSVAL(h), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "data", OBJECT_TO_JSVAL(darray), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
         return JS_FALSE;
 
@@ -294,17 +294,17 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     if (JSVAL_IS_PRIMITIVE(argv[0]))
@@ -317,49 +317,49 @@ nsIDOMCanvasRenderingContext2D_PutImageD
         return JS_FALSE;
 
     int32 wi, hi;
     JSObject *darray;
 
     // grab width, height, and the dense array from the dataObject
     js::AutoValueRooter tv(cx);
 
-    if (!JS_GetProperty(cx, dataObject, "width", tv.addr()) ||
-        !JS_ValueToECMAInt32(cx, tv.value(), &wi))
+    if (!JS_GetProperty(cx, dataObject, "width", tv.jsval_addr()) ||
+        !JS_ValueToECMAInt32(cx, tv.jsval_value(), &wi))
         return JS_FALSE;
 
-    if (!JS_GetProperty(cx, dataObject, "height", tv.addr()) ||
-        !JS_ValueToECMAInt32(cx, tv.value(), &hi))
+    if (!JS_GetProperty(cx, dataObject, "height", tv.jsval_addr()) ||
+        !JS_ValueToECMAInt32(cx, tv.jsval_value(), &hi))
         return JS_FALSE;
 
     if (wi <= 0 || hi <= 0)
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     uint32 w = (uint32) wi;
     uint32 h = (uint32) hi;
 
-    if (!JS_GetProperty(cx, dataObject, "data", tv.addr()) ||
-        JSVAL_IS_PRIMITIVE(tv.value()))
+    if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr()) ||
+        JSVAL_IS_PRIMITIVE(tv.jsval_value()))
         return JS_FALSE;
-    darray = JSVAL_TO_OBJECT(tv.value());
+    darray = JSVAL_TO_OBJECT(tv.jsval_value());
 
     js::AutoValueRooter tsrc_tvr(cx);
 
     js::TypedArray *tsrc = NULL;
     if (darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
         darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
     {
         tsrc = js::TypedArray::fromJSObject(darray);
     } else if (JS_IsArrayObject(cx, darray) || js_IsTypedArray(darray)) {
         // ugh, this isn't a uint8 typed array, someone made their own object; convert it to a typed array
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_UINT8, darray);
         if (!nobj)
             return JS_FALSE;
 
-        *tsrc_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *tsrc_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         tsrc = js::TypedArray::fromJSObject(nobj);
     } else {
         // yeah, no.
         return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
     }
 
     // make the call
     rv = self->PutImageData_explicit(x, y, w, h, (PRUint8*) tsrc->data, tsrc->byteLength);
--- a/content/canvas/src/CustomQS_WebGL.h
+++ b/content/canvas/src/CustomQS_WebGL.h
@@ -87,17 +87,17 @@ nsICanvasRenderingContextWebGL_BufferDat
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     int32 target;
@@ -154,17 +154,17 @@ nsICanvasRenderingContextWebGL_BufferSub
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     int32 target;
@@ -222,17 +222,17 @@ nsICanvasRenderingContextWebGL_ReadPixel
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     // XXX we currently allow passing only 6 args to support the API. Eventually drop that.
     if (argc < 6)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -318,17 +318,17 @@ nsICanvasRenderingContextWebGL_TexImage2
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     // XXX we currently allow passing only 3 args to support the API. Eventually drop that.
     // if (argc < 6 || argc == 7 || argc == 8)
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
@@ -451,17 +451,17 @@ nsICanvasRenderingContextWebGL_TexSubIma
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 7 || argc == 8)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     // arguments common to all cases
@@ -559,17 +559,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     nsIWebGLUniformLocation *location;
@@ -595,17 +595,17 @@ helper_nsICanvasRenderingContextWebGL_Un
         wa = js::TypedArray::fromJSObject(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_INT32, arg1);
         if (!nobj) {
             // XXX this will likely return a strange error message if it goes wrong
             return JS_FALSE;
         }
 
-        *obj_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         wa = js::TypedArray::fromJSObject(nobj);
     } else {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     if (nElements == 1) {
         rv = self->Uniform1iv_array(location, wa);
@@ -633,17 +633,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     nsIWebGLUniformLocation *location;
@@ -669,17 +669,17 @@ helper_nsICanvasRenderingContextWebGL_Un
         wa = js::TypedArray::fromJSObject(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
         if (!nobj) {
             // XXX this will likely return a strange error message if it goes wrong
             return JS_FALSE;
         }
 
-        *obj_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         wa = js::TypedArray::fromJSObject(nobj);
     } else {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     if (nElements == 1) {
         rv = self->Uniform1fv_array(location, wa);
@@ -707,17 +707,17 @@ helper_nsICanvasRenderingContextWebGL_Un
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     nsIWebGLUniformLocation *location;
@@ -747,17 +747,17 @@ helper_nsICanvasRenderingContextWebGL_Un
         wa = js::TypedArray::fromJSObject(arg2);
     }  else if (JS_IsArrayObject(cx, arg2)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg2);
         if (!nobj) {
             // XXX this will likely return a strange error message if it goes wrong
             return JS_FALSE;
         }
 
-        *obj_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         wa = js::TypedArray::fromJSObject(nobj);
     } else {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
         return JS_FALSE;
     }
 
     if (nElements == 2) {
         rv = self->UniformMatrix2fv_array(location, transpose ? 1 : 0, wa);
@@ -782,17 +782,17 @@ helper_nsICanvasRenderingContextWebGL_Ve
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     js::AutoValueRooter tvr(cx);
-    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
+    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     uint32 location;
@@ -814,17 +814,17 @@ helper_nsICanvasRenderingContextWebGL_Ve
         wa = js::TypedArray::fromJSObject(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
         if (!nobj) {
             // XXX this will likely return a strange error message if it goes wrong
             return JS_FALSE;
         }
 
-        *obj_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         wa = js::TypedArray::fromJSObject(nobj);
     } else {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     if (nElements == 1) {
         rv = self->VertexAttrib1fv_array(location, wa);
@@ -930,59 +930,59 @@ nsICanvasRenderingContextWebGL_VertexAtt
 static JSBool
 nsICanvasRenderingContextWebGL_VertexAttrib4fv(JSContext *cx, uintN argc, jsval *vp)
 {
     return helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(cx, argc, vp, 4);
 }
 
 #ifdef JS_TRACER
 
-static inline jsval FASTCALL
+static inline void FASTCALL
 helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
                                                       JSObject *arg, int nElements)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     xpc_qsArgValArray<3> vp(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     js::AutoValueRooter obj_tvr(cx);
 
     nsIWebGLUniformLocation *location;
     xpc_qsSelfRef location_selfref;
     nsresult rv_convert_arg0
         = xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
     if (NS_FAILED(rv_convert_arg0)) {
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     js::TypedArray *wa = 0;
 
     if (helper_isInt32Array(arg)) {
         wa = js::TypedArray::fromJSObject(arg);
     }  else if (JS_IsArrayObject(cx, arg)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_INT32, arg);
         if (!nobj) {
             // XXX this will likely return a strange error message if it goes wrong
             js_SetTraceableNativeFailed(cx);
-            return JSVAL_VOID;
+            return;
         }
 
-        *obj_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         wa = js::TypedArray::fromJSObject(nobj);
     } else {
         xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv");
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     nsresult rv;
 
     if (nElements == 1) {
         rv = self->Uniform1iv_array(location, wa);
     } else if (nElements == 2) {
         rv = self->Uniform2iv_array(location, wa);
@@ -991,63 +991,61 @@ helper_nsICanvasRenderingContextWebGL_Un
     } else if (nElements == 4) {
         rv = self->Uniform4iv_array(location, wa);
     }
 
     if (NS_FAILED(rv)) {
         xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNiv");
         js_SetTraceableNativeFailed(cx);
     }
-
-    return JSVAL_VOID;
 }
 
-static inline jsval FASTCALL
+static inline void FASTCALL
 helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
                                                       JSObject *arg, int nElements)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     xpc_qsArgValArray<3> vp(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     js::AutoValueRooter obj_tvr(cx);
 
     nsIWebGLUniformLocation *location;
     xpc_qsSelfRef location_selfref;
     nsresult rv_convert_arg0
         = xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
     if (NS_FAILED(rv_convert_arg0)) {
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     js::TypedArray *wa = 0;
 
     if (helper_isFloat32Array(arg)) {
         wa = js::TypedArray::fromJSObject(arg);
     }  else if (JS_IsArrayObject(cx, arg)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg);
         if (!nobj) {
             // XXX this will likely return a strange error message if it goes wrong
             js_SetTraceableNativeFailed(cx);
-            return JSVAL_VOID;
+            return;
         }
 
-        *obj_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         wa = js::TypedArray::fromJSObject(nobj);
     } else {
         xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv");
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     nsresult rv;
 
     if (nElements == 1) {
         rv = self->Uniform1fv_array(location, wa);
     } else if (nElements == 2) {
         rv = self->Uniform2fv_array(location, wa);
@@ -1057,173 +1055,204 @@ helper_nsICanvasRenderingContextWebGL_Un
         rv = self->Uniform4fv_array(location, wa);
     }
 
     if (NS_FAILED(rv)) {
         xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNfv");
         js_SetTraceableNativeFailed(cx);
     }
 
-    return JSVAL_VOID;
+    return;
 }
 
-static inline jsval FASTCALL
+static inline void FASTCALL
 helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
                                                             JSBool transpose, JSObject *arg, int nElements)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
     nsICanvasRenderingContextWebGL *self;
     xpc_qsSelfRef selfref;
     xpc_qsArgValArray<4> vp(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     js::AutoValueRooter obj_tvr(cx);
 
     nsIWebGLUniformLocation *location;
     xpc_qsSelfRef location_selfref;
     nsresult rv_convert_arg0
         = xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
     if (NS_FAILED(rv_convert_arg0)) {
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     js::TypedArray *wa = 0;
 
     if (helper_isFloat32Array(arg)) {
         wa = js::TypedArray::fromJSObject(arg);
     }  else if (JS_IsArrayObject(cx, arg)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg);
         if (!nobj) {
             // XXX this will likely return a strange error message if it goes wrong
             js_SetTraceableNativeFailed(cx);
-            return JSVAL_VOID;
+            return;
         }
 
-        *obj_tvr.addr() = OBJECT_TO_JSVAL(nobj);
+        *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
         wa = js::TypedArray::fromJSObject(nobj);
     } else {
         xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
         js_SetTraceableNativeFailed(cx);
-        return JSVAL_VOID;
+        return;
     }
 
     nsresult rv;
     if (nElements == 2) {
         rv = self->UniformMatrix2fv_array(location, transpose, wa);
     } else if (nElements == 3) {
         rv = self->UniformMatrix3fv_array(location, transpose, wa);
     } else if (nElements == 4) {
         rv = self->UniformMatrix4fv_array(location, transpose, wa);
     }
 
     if (NS_FAILED(rv)) {
         xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
         js_SetTraceableNativeFailed(cx);
     }
-
-    return JSVAL_VOID;
 }
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform1iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 1);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 1);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1iv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform2iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 2);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 2);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2iv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform3iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 3);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 3);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3iv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform4iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 4);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 4);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4iv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform1fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 1);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 1);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1fv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform2fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 2);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 2);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2fv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform3fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 3);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 3);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3fv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_Uniform4fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 4);
+    helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 4);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4fv,
-    (4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 2);
+    helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 2);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix2fv,
-    (5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 3);
+    helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 3);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix3fv,
-    (5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
-static jsval FASTCALL
+// FIXME This should return void, not uint32
+//       (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
+static uint32 FASTCALL
 nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
 {
-    return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 4);
+    helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 4);
+    return 0;
 }
 
 JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix4fv,
-    (5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
+    (5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
 
 #endif /* JS_TRACER */
--- a/content/canvas/src/NativeJSContext.cpp
+++ b/content/canvas/src/NativeJSContext.cpp
@@ -10,11 +10,10 @@ NativeJSContext::AddGCRoot(JSObject **aP
   PRBool ok;
   return ok = ::JS_AddNamedObjectRoot(ctx, aPtr, aName);
 }
 
 void
 NativeJSContext::ReleaseGCRoot(JSObject **aPtr)
 {
   NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-
   ::JS_RemoveObjectRoot(ctx, aPtr);
 }
--- a/content/canvas/src/NativeJSContext.h
+++ b/content/canvas/src/NativeJSContext.h
@@ -62,108 +62,92 @@ public:
         return PR_FALSE;
     }
 
     PRBool AddGCRoot (JSObject **aPtr, const char *aName);
     void ReleaseGCRoot (JSObject **aPtr);
 
     void SetRetVal (PRInt32 val) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        if (INT_FITS_IN_JSVAL(val))
-            SetRetValAsJSVal(INT_TO_JSVAL(val));
-        else
-            SetRetVal((double) val);
+        SetRetValAsJSVal(INT_TO_JSVAL(val));
     }
 
     void SetRetVal (PRUint32 val) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        if (INT_FITS_IN_JSVAL(val))
-            SetRetValAsJSVal(INT_TO_JSVAL((int) val));
-        else
-            SetRetVal((double) val);
+        SetRetValAsJSVal(UINT_TO_JSVAL(val));
     }
 
     void SetRetVal (double val) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        jsval *vp;
-        ncc->GetRetValPtr(&vp);
-        JS_NewDoubleValue(ctx, val, vp);
+        SetRetValAsJSVal(DOUBLE_TO_JSVAL(val));
     }
 
     void SetBoolRetVal (PRBool val) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        if (val)
-            SetRetValAsJSVal(JSVAL_TRUE);
-        else
-            SetRetValAsJSVal(JSVAL_FALSE);
+        SetRetValAsJSVal(BOOLEAN_TO_JSVAL(val));
     }
 
     void SetRetVal (PRInt32 *vp, PRUint32 len) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
         nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
 
         if (!JS_EnterLocalRootScope(ctx))
             return; // XXX ???
 
-        for (PRUint32 i = 0; i < len; i++) {
-            if (INT_FITS_IN_JSVAL(vp[i])) {
-                jsvector[i] = INT_TO_JSVAL(vp[i]);
-            } else {
-                JS_NewDoubleValue(ctx, vp[i], &jsvector[i]);
-            }
-        }
+        for (PRUint32 i = 0; i < len; i++)
+            jsvector[i] = INT_TO_JSVAL(vp[i]);
 
         JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
         SetRetVal(jsarr);
 
         JS_LeaveLocalRootScope(ctx);
     }
 
     void SetRetVal (PRUint32 *vp, PRUint32 len) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
         nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
 
         if (!JS_EnterLocalRootScope(ctx))
             return; // XXX ???
 
-        for (PRUint32 i = 0; i < len; i++) {
-            JS_NewNumberValue(ctx, vp[i], &jsvector[i]);
-        }
+        for (PRUint32 i = 0; i < len; i++)
+            jsvector[i] = UINT_TO_JSVAL(vp[i]);
 
         JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
         SetRetVal(jsarr);
 
         JS_LeaveLocalRootScope(ctx);
     }
 
     void SetRetVal (double *dp, PRUint32 len) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
         nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
 
         if (!JS_EnterLocalRootScope(ctx))
             return; // XXX ???
 
         for (PRUint32 i = 0; i < len; i++)
-            JS_NewDoubleValue(ctx, (jsdouble) dp[i], &jsvector[i]);
-            
+            jsvector[i] = DOUBLE_TO_JSVAL(dp[i]);
+
         JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
         SetRetVal(jsarr);
 
         JS_LeaveLocalRootScope(ctx);
     }
 
     void SetRetVal (float *fp, PRUint32 len) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
         nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
 
         if (!JS_EnterLocalRootScope(ctx))
             return; // XXX ???
 
         for (PRUint32 i = 0; i < len; i++)
-            JS_NewDoubleValue(ctx, (jsdouble) fp[i], &jsvector[i]);
+            jsvector[i] = DOUBLE_TO_JSVAL(fp[i]);
+
         JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
         SetRetVal(jsarr);
 
         JS_LeaveLocalRootScope(ctx);
     }
 
     void SetRetValAsJSVal (jsval val) {
         NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
@@ -337,35 +321,31 @@ public:
     PRBool DefineProperty(const char *name, PRUint32 val) {
         // XXX handle too big ints
         if (!JS_DefineProperty(mCtx->ctx, mObject, name, INT_TO_JSVAL((int)val), NULL, NULL, JSPROP_ENUMERATE))
             return PR_FALSE;
         return PR_TRUE;
     }
 
     PRBool DefineProperty(const char *name, double val) {
-        jsval dv;
-
-        if (!JS_NewDoubleValue(mCtx->ctx, val, &dv))
-            return PR_FALSE;
-
+        jsval dv = DOUBLE_TO_JSVAL(val);
         if (!JS_DefineProperty(mCtx->ctx, mObject, name, dv, NULL, NULL, JSPROP_ENUMERATE))
             return PR_FALSE;
         return PR_TRUE;
     }
 
     PRBool DefineProperty(const char *name, JSObject *val) {
         if (!JS_DefineProperty(mCtx->ctx, mObject, name, OBJECT_TO_JSVAL(val), NULL, NULL, JSPROP_ENUMERATE))
             return PR_FALSE;
         return PR_TRUE;
     }
 
     // Blah.  We can't name this DefineProperty also because PRBool is the same as PRInt32
     PRBool DefineBoolProperty(const char *name, PRBool val) {
-        if (!JS_DefineProperty(mCtx->ctx, mObject, name, val ? JS_TRUE : JS_FALSE, NULL, NULL, JSPROP_ENUMERATE))
+        if (!JS_DefineProperty(mCtx->ctx, mObject, name, val ? JSVAL_TRUE : JSVAL_FALSE, NULL, NULL, JSPROP_ENUMERATE))
             return PR_FALSE;
         return PR_TRUE;
     }
 
     // We can't use ns*Substring, because we don't have internal linkage
 #if 0
     PRBool DefineProperty(const char *name, const nsCSubstring& val) {
         JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -2906,22 +2906,22 @@ WebGLContext::CompileShader(nsIWebGLShad
         resources.maxVertexUniformVectors = mGLMaxVertexUniformVectors;
         resources.maxVaryingVectors = mGLMaxVaryingVectors;
         resources.maxVertexTextureImageUnits = mGLMaxVertexTextureImageUnits;
         resources.maxCombinedTextureImageUnits = mGLMaxTextureUnits;
         resources.maxTextureImageUnits = mGLMaxTextureImageUnits;
         resources.maxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
         resources.maxDrawBuffers = 1;
 
-        compiler = ShConstructCompiler(lang, debugFlags);
+        compiler = ShConstructCompiler(lang, EShSpecWebGL, &resources);
 
         nsDependentCString src(shader->Source());
         const char *s = src.get();
 
-        if (!ShCompile(compiler, &s, 1, EShOptNone, &resources, debugFlags)) {
+        if (!ShCompile(compiler, &s, 1, EShOptSimple, debugFlags)) {
             shader->SetTranslationFailure(nsDependentCString(ShGetInfoLog(compiler)));
             ShDestruct(compiler);
             return NS_OK;
         }
 
         s = ShGetObjectCode(compiler);
         gl->fShaderSource(shadername, 1, &s, NULL);
         shader->SetTranslationSuccess();
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -3514,21 +3514,26 @@ nsCanvasRenderingContext2D::DrawImage(ns
 
                 ShadowFinalize(blur);
             }
         }
 
         mThebes->SetPattern(pattern);
         DirtyAllStyles();
 
-        mThebes->Clip(clip);
-
+        /* Direct2D isn't very good at clipping so use Fill() when we can */
+        if (CurrentState().globalAlpha == 1.0f && mThebes->CurrentOperator() == gfxContext::OPERATOR_OVER) {
+            mThebes->Rectangle(clip);
+            mThebes->Fill();
+        } else {
+            /* we need to use to clip instead of fill for globalAlpha */
+            mThebes->Clip(clip);
+            mThebes->Paint(CurrentState().globalAlpha);
+        }
         dirty = mThebes->UserToDevice(clip);
-
-        mThebes->Paint(CurrentState().globalAlpha);
     }
 
 #if 1
     // XXX cairo bug workaround; force a clip update on mThebes.
     // Otherwise, a pixman clip gets left around somewhere, and pixman
     // (Render) does source clipping as well -- so we end up
     // compositing with an incorrect clip.  This only seems to affect
     // fallback cases, which happen when we have CSS scaling going on.
@@ -3855,24 +3860,16 @@ nsCanvasRenderingContext2D::AsyncDrawXUL
 
     return DrawWindow(window, aX, aY, aW, aH, aBGColor, flags);
 #endif
 }
 
 //
 // device pixel getting/setting
 //
-extern "C" {
-#include "jstypes.h"
-JS_FRIEND_API(JSBool)
-js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
-                                JSUint8 *dest);
-JS_FRIEND_API(JSObject *)
-js_NewArrayObjectWithCapacity(JSContext *cx, jsuint capacity, jsval **vector);
-}
 
 void
 nsCanvasRenderingContext2D::EnsureUnpremultiplyTable() {
   if (sUnpremultiplyTable)
     return;
 
   // Infallably alloc the unpremultiply table.
   sUnpremultiplyTable = new PRUint8[256][256];
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -98,16 +98,20 @@ NS_NewDOMBeforeUnloadEvent(nsIDOMEvent**
 nsresult
 NS_NewDOMPageTransitionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 #ifdef MOZ_SVG
 nsresult
 NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsGUIEvent* aEvent);
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+nsresult
+NS_NewDOMTimeEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
+#endif // MOZ_SMIL
 nsresult
 NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsInputEvent* aEvent);
 nsresult
 NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsCommandEvent* aEvent);
 nsresult
 NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -76,16 +76,19 @@ static const char* const sEventNames[] =
   "DOMAttrModified", "DOMCharacterDataModified",
   "DOMActivate", "DOMFocusIn", "DOMFocusOut",
   "pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll",
   "offline", "online", "copy", "cut", "paste",
 #ifdef MOZ_SVG
   "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
   "SVGZoom",
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+  "beginEvent", "endEvent", "repeatEvent",
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
   "loadstart", "progress", "suspend", "emptied", "stalled", "play", "pause",
   "loadedmetadata", "loadeddata", "waiting", "playing", "canplay",
   "canplaythrough", "seeking", "seeked", "timeupdate", "ended", "ratechange",
   "durationchange", "volumechange",
 #endif // MOZ_MEDIA
   "MozAfterPaint",
   "MozSwipeGesture",
@@ -768,16 +771,25 @@ NS_METHOD nsDOMEvent::DuplicatePrivateDa
     case NS_SVGZOOM_EVENT:
     {
       newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
       newEvent->eventStructType = NS_SVGZOOM_EVENT;
       break;
     }
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    case NS_SMIL_TIME_EVENT:
+    {
+      newEvent = new nsUIEvent(PR_FALSE, msg, 0);
+      NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
+      newEvent->eventStructType = NS_SMIL_TIME_EVENT;
+      break;
+    }
+#endif // MOZ_SMIL
     case NS_SIMPLE_GESTURE_EVENT:
     {
       nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
       nsSimpleGestureEvent* simpleGestureEvent = 
         new nsSimpleGestureEvent(PR_FALSE, msg, nsnull, 0, 0.0);
       NS_ENSURE_TRUE(simpleGestureEvent, NS_ERROR_OUT_OF_MEMORY);
       isInputEvent = PR_TRUE;
       simpleGestureEvent->direction = oldSimpleGestureEvent->direction;
@@ -1220,16 +1232,24 @@ const char* nsDOMEvent::GetEventName(PRU
     return sEventNames[eDOMEvents_SVGError];
   case NS_SVG_RESIZE:
     return sEventNames[eDOMEvents_SVGResize];
   case NS_SVG_SCROLL:
     return sEventNames[eDOMEvents_SVGScroll];
   case NS_SVG_ZOOM:
     return sEventNames[eDOMEvents_SVGZoom];
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+  case NS_SMIL_BEGIN:
+    return sEventNames[eDOMEvents_beginEvent];
+  case NS_SMIL_END:
+    return sEventNames[eDOMEvents_endEvent];
+  case NS_SMIL_REPEAT:
+    return sEventNames[eDOMEvents_repeatEvent];
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
   case NS_LOADSTART:
     return sEventNames[eDOMEvents_loadstart];
   case NS_PROGRESS:
     return sEventNames[eDOMEvents_progress];
   case NS_SUSPEND:
     return sEventNames[eDOMEvents_suspend];
   case NS_EMPTIED:
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -137,16 +137,21 @@ public:
     eDOMEvents_SVGLoad,
     eDOMEvents_SVGUnload,
     eDOMEvents_SVGAbort,
     eDOMEvents_SVGError,
     eDOMEvents_SVGResize,
     eDOMEvents_SVGScroll,
     eDOMEvents_SVGZoom,
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    eDOMEvents_beginEvent,
+    eDOMEvents_endEvent,
+    eDOMEvents_repeatEvent,
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
     eDOMEvents_loadstart,
     eDOMEvents_progress,
     eDOMEvents_suspend,
     eDOMEvents_emptied,
     eDOMEvents_stalled,
     eDOMEvents_play,
     eDOMEvents_pause,
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -737,16 +737,20 @@ nsEventDispatcher::CreateEvent(nsPresCon
 #ifdef MOZ_SVG
     case NS_SVG_EVENT:
       return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
                                aEvent);
     case NS_SVGZOOM_EVENT:
       return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext,
                                    static_cast<nsGUIEvent*>(aEvent));
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    case NS_SMIL_TIME_EVENT:
+      return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, aEvent);
+#endif // MOZ_SMIL
 
     case NS_COMMAND_EVENT:
       return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
                                    static_cast<nsCommandEvent*>(aEvent));
     case NS_SIMPLE_GESTURE_EVENT:
       return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext,
                                          static_cast<nsSimpleGestureEvent*>(aEvent));
     case NS_TRANSITION_EVENT:
@@ -792,16 +796,21 @@ nsEventDispatcher::CreateEvent(nsPresCon
 #ifdef MOZ_SVG
   if (aEventType.LowerCaseEqualsLiteral("svgevent") ||
       aEventType.LowerCaseEqualsLiteral("svgevents"))
     return NS_NewDOMSVGEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("svgzoomevent") ||
       aEventType.LowerCaseEqualsLiteral("svgzoomevents"))
     return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext, nsnull);
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+  if (aEventType.LowerCaseEqualsLiteral("timeevent") ||
+      aEventType.LowerCaseEqualsLiteral("timeevents"))
+    return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, nsnull);
+#endif // MOZ_SMIL
   if (aEventType.LowerCaseEqualsLiteral("xulcommandevent") ||
       aEventType.LowerCaseEqualsLiteral("xulcommandevents"))
     return NS_NewDOMXULCommandEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("commandevent") ||
       aEventType.LowerCaseEqualsLiteral("commandevents"))
     return NS_NewDOMCommandEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("datacontainerevent") ||
       aEventType.LowerCaseEqualsLiteral("datacontainerevents"))
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -306,17 +306,17 @@ nsEventListenerManager::RemoveAllListene
   mListeners.Clear();
   return NS_OK;
 }
 
 void
 nsEventListenerManager::Shutdown()
 {
   NS_IF_RELEASE(gSystemEventGroup);
-  sAddListenerID = JSVAL_VOID;
+  sAddListenerID = JSID_VOID;
   nsDOMEvent::Shutdown();
 }
 
 nsIDOMEventGroup*
 nsEventListenerManager::GetSystemEventGroup()
 {
   if (!gSystemEventGroup) {
     CallCreateInstance(kDOMEventGroupCID, &gSystemEventGroup);
@@ -836,18 +836,18 @@ nsEventListenerManager::RemoveScriptEven
     mListeners.RemoveElementAt(PRUint32(ls - &mListeners.ElementAt(0)));
     mNoListenerForEvent = NS_EVENT_TYPE_NULL;
     mNoListenerForEventAtom = nsnull;
   }
 
   return NS_OK;
 }
 
-jsval
-nsEventListenerManager::sAddListenerID = JSVAL_VOID;
+jsid
+nsEventListenerManager::sAddListenerID = JSID_VOID;
 
 NS_IMETHODIMP
 nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
                                                     void *aScope,
                                                     nsISupports *aObject, 
                                                     nsIAtom *aName)
 {
   // Check that we have access to set an event listener. Prevents
@@ -861,20 +861,20 @@ nsEventListenerManager::RegisterScriptEv
     do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
   if (NS_FAILED(rv))
     return rv;
   JSContext *cx;
   if (NS_FAILED(rv = stack->Peek(&cx)))
     return rv;
 
   if (cx) {
-    if (sAddListenerID == JSVAL_VOID) {
+    if (sAddListenerID == JSID_VOID) {
       JSAutoRequest ar(cx);
       sAddListenerID =
-        STRING_TO_JSVAL(::JS_InternString(cx, "addEventListener"));
+        INTERNED_STRING_TO_JSID(::JS_InternString(cx, "addEventListener"));
     }
 
     if (aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT) {
         nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
         jsval v;
         rv = nsContentUtils::WrapNative(cx, (JSObject *)aScope, aObject, &v,
                                         getter_AddRefs(holder));
         NS_ENSURE_SUCCESS(rv, rv);
@@ -978,16 +978,24 @@ nsEventListenerManager::CompileEventHand
         attrName = nsGkAtoms::onerror;
       else if (aName == nsGkAtoms::onSVGResize)
         attrName = nsGkAtoms::onresize;
       else if (aName == nsGkAtoms::onSVGScroll)
         attrName = nsGkAtoms::onscroll;
       else if (aName == nsGkAtoms::onSVGZoom)
         attrName = nsGkAtoms::onzoom;
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+      else if (aName == nsGkAtoms::onbeginEvent)
+        attrName = nsGkAtoms::onbegin;
+      else if (aName == nsGkAtoms::onrepeatEvent)
+        attrName = nsGkAtoms::onrepeat;
+      else if (aName == nsGkAtoms::onendEvent)
+        attrName = nsGkAtoms::onend;
+#endif // MOZ_SMIL
 
       content->GetAttr(kNameSpaceID_None, attrName, handlerBody);
 
       PRUint32 lineNo = 0;
       nsCAutoString url (NS_LITERAL_CSTRING("javascript:alert('TODO: FIXME')"));
       nsIDocument* doc = nsnull;
       nsCOMPtr<nsINode> node = do_QueryInterface(aCurrentTarget);
       if (node) {
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -226,15 +226,15 @@ protected:
   PRBool ListenerCanHandle(nsListenerStruct* aLs, nsEvent* aEvent);
   nsPIDOMWindow* GetInnerWindowForTarget();
 
   nsAutoTObserverArray<nsListenerStruct, 2> mListeners;
   nsISupports*                              mTarget;  //WEAK
   nsCOMPtr<nsIAtom>                         mNoListenerForEventAtom;
 
   static PRUint32                           mInstanceCount;
-  static jsval                              sAddListenerID;
+  static jsid                               sAddListenerID;
 
   friend class nsEventTargetChainItem;
   static PRUint32                           sCreatedCount;
 };
 
 #endif // nsEventListenerManager_h__
--- a/content/events/src/nsEventListenerService.cpp
+++ b/content/events/src/nsEventListenerService.cpp
@@ -134,20 +134,23 @@ nsEventListenerInfo::ToSource(nsAString&
 
   if (GetJSVal(&v)) {
     nsCOMPtr<nsIThreadJSContextStack> stack =
       nsContentUtils::ThreadJSContextStack();
     if (stack) {
       JSContext* cx = nsnull;
       stack->GetSafeJSContext(&cx);
       if (cx && NS_SUCCEEDED(stack->Push(cx))) {
-        JSAutoRequest ar(cx);
-        JSString* str = JS_ValueToSource(cx, v);
-        if (str) {
-          aResult.Assign(nsDependentJSString(str));
+        {
+          // Extra block to finish the auto request before calling pop
+          JSAutoRequest ar(cx);
+          JSString* str = JS_ValueToSource(cx, v);
+          if (str) {
+            aResult.Assign(nsDependentJSString(str));
+          }
         }
         stack->Pop(&cx);
       }
     }
   }
 
   return NS_OK;
 }
--- a/content/html/content/public/nsHTMLAudioElement.h
+++ b/content/html/content/public/nsHTMLAudioElement.h
@@ -72,13 +72,14 @@ public:
   // nsIDOMHTMLAudioElement
   NS_DECL_NSIDOMHTMLAUDIOELEMENT
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
                         JSObject* aObj, PRUint32 argc, jsval* argv);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
 
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 #endif
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -37,16 +37,17 @@
  * ***** END LICENSE BLOCK ***** */
 #if !defined(nsHTMLMediaElement_h__)
 #define nsHTMLMediaElement_h__
 
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsMediaDecoder.h"
 #include "nsIChannel.h"
+#include "nsIHttpChannel.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMRange.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsILoadGroup.h"
 #include "nsIObserver.h"
 #include "ImageLayers.h"
 
 // Define to output information on decoding and painting framerate
@@ -301,16 +302,23 @@ public:
 
   /**
    * Returns PR_TRUE if the media has played or completed a seek.
    * Used by video frame to determine whether to paint the poster.
    */
   PRBool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; }
 
   nsresult CopyInnerTo(nsGenericElement* aDest) const;
+
+  /**
+   * Sets the Accept header on the HTTP channel to the required
+   * video or audio MIME types.
+   */
+  virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0;
+
 protected:
   class MediaLoadListener;
   class LoadNextSourceEvent;
   class SelectResourceEvent;
 
   /**
    * Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes
    * we'll force a reflow so that the video frame gets reflowed to reflect
--- a/content/html/content/public/nsHTMLVideoElement.h
+++ b/content/html/content/public/nsHTMLVideoElement.h
@@ -75,12 +75,14 @@ public:
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // Returns the current video frame width and height.
   // If there is no video frame, returns the given default size.
   nsIntSize GetVideoSize(nsIntSize defaultSize);
 
+  virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
+
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 #endif
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-no-quirks-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-right;"><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: center;"><div></div>absmiddle
+</table>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-no-quirks.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td align=left><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=justify><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=right><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=center><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=middle><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=absmiddle><div></div>absmiddle
+</table>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-quirks-ref.html
@@ -0,0 +1,27 @@
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-right;"><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: center;"><div></div>absmiddle
+</table>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-quirks.html
@@ -0,0 +1,27 @@
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td align=left><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=justify><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=right><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=center><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=middle><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=absmiddle><div></div>absmiddle
+</table>
--- a/content/html/content/reftests/reftest.list
+++ b/content/html/content/reftests/reftest.list
@@ -6,10 +6,12 @@
 != 468263-1c.html about:blank
 != 468263-1d.html about:blank
 == 468263-2.html 468263-2-ref.html
 == 468263-2.html 468263-2-alternate-ref.html
 == 484200-1.html 484200-1-ref.html
 == 485377.html 485377-ref.html
 == 557840.html 557840-ref.html
 == 560059-video-dimensions.html 560059-video-dimensions-ref.html
+== 573322-quirks.html 573322-quirks-ref.html
+== 573322-no-quirks.html 573322-no-quirks-ref.html
 == href-attr-change-restyles.html href-attr-change-restyles-ref.html
 == figure.html figure-ref.html
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -233,17 +233,17 @@ class nsGenericHTMLElementTearoff : publ
 
   NS_FORWARD_NSIDOMNSHTMLELEMENT(mElement->)
   NS_FORWARD_NSIDOMELEMENTCSSINLINESTYLE(mElement->)
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGenericHTMLElementTearoff,
                                            nsIDOMNSHTMLElement)
 
 private:
-  nsCOMPtr<nsGenericHTMLElement> mElement;
+  nsRefPtr<nsGenericHTMLElement> mElement;
 };
 
 NS_IMPL_CYCLE_COLLECTION_1(nsGenericHTMLElementTearoff, mElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsGenericHTMLElementTearoff,
                                           nsIDOMNSHTMLElement)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsGenericHTMLElementTearoff,
                                            nsIDOMNSHTMLElement)
@@ -1536,49 +1536,32 @@ PRBool
 nsGenericHTMLElement::ParseTableHAlignValue(const nsAString& aString,
                                             nsAttrValue& aResult)
 {
   return aResult.ParseEnumValue(aString, kTableHAlignTable, PR_FALSE);
 }
 
 //----------------------------------------
 
-// These tables are used for TD,TH,TR, etc (but not TABLE)
+// This table is used for td, th, tr, col, thead, tbody and tfoot.
 static const nsAttrValue::EnumTable kTableCellHAlignTable[] = {
   { "left",   NS_STYLE_TEXT_ALIGN_MOZ_LEFT },
   { "right",  NS_STYLE_TEXT_ALIGN_MOZ_RIGHT },
   { "center", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
   { "char",   NS_STYLE_TEXT_ALIGN_CHAR },
   { "justify",NS_STYLE_TEXT_ALIGN_JUSTIFY },
-  { 0 }
-};
-
-static const nsAttrValue::EnumTable kCompatTableCellHAlignTable[] = {
-  { "left",   NS_STYLE_TEXT_ALIGN_MOZ_LEFT },
-  { "right",  NS_STYLE_TEXT_ALIGN_MOZ_RIGHT },
-  { "center", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
-  { "char",   NS_STYLE_TEXT_ALIGN_CHAR },
-  { "justify",NS_STYLE_TEXT_ALIGN_JUSTIFY },
-
-  // The following are non-standard but necessary for Nav4 compatibility
   { "middle", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
-  // allow center and absmiddle to map to NS_STYLE_TEXT_ALIGN_CENTER and
-  // NS_STYLE_TEXT_ALIGN_CENTER to map to center by using the following order
-  { "center", NS_STYLE_TEXT_ALIGN_CENTER },
   { "absmiddle", NS_STYLE_TEXT_ALIGN_CENTER },
   { 0 }
 };
 
 PRBool
 nsGenericHTMLElement::ParseTableCellHAlignValue(const nsAString& aString,
-                                                nsAttrValue& aResult) const
+                                                nsAttrValue& aResult)
 {
-  if (InNavQuirksMode(GetOwnerDoc())) {
-    return aResult.ParseEnumValue(aString, kCompatTableCellHAlignTable, PR_FALSE);
-  }
   return aResult.ParseEnumValue(aString, kTableCellHAlignTable, PR_FALSE);
 }
 
 //----------------------------------------
 
 PRBool
 nsGenericHTMLElement::ParseTableVAlignValue(const nsAString& aString,
                                             nsAttrValue& aResult)
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -268,18 +268,18 @@ public:
 
   /**
    * Convert a table cell halign string to value
    *
    * @param aString the string to parse
    * @param aResult the resulting HTMLValue
    * @return whether the value was parsed
    */
-  PRBool ParseTableCellHAlignValue(const nsAString& aString,
-                                   nsAttrValue& aResult) const;
+  static PRBool ParseTableCellHAlignValue(const nsAString& aString,
+                                          nsAttrValue& aResult);
 
   /**
    * Convert a table valign string to value (left/right/center/char/justify/
    * abscenter/absmiddle/middle)
    *
    * @param aString the string to parse
    * @param aResult the resulting HTMLValue
    * @return whether the value was parsed
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -45,34 +45,31 @@
 #include "nsGenericHTMLElement.h"
 #include "nsILink.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIEventStateManager.h"
 
-// For GetText().
-#include "nsIContentIterator.h"
-#include "nsIDOMText.h"
-
 #include "nsHTMLDNSPrefetch.h"
 
 #include "Link.h"
 using namespace mozilla::dom;
 
-nsresult NS_NewPreContentIterator(nsIContentIterator** aInstancePtrResult);
-
 class nsHTMLAnchorElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLAnchorElement,
                             public nsIDOMNSHTMLAnchorElement2,
                             public nsILink,
                             public Link
 {
 public:
+  using nsGenericElement::GetText;
+  using nsGenericElement::SetText;
+
   nsHTMLAnchorElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLAnchorElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
@@ -364,46 +361,24 @@ IMPL_URI_PART(Search)
 IMPL_URI_PART(Port)
 IMPL_URI_PART(Hash)
 
 #undef IMPL_URI_PART
 
 NS_IMETHODIMP    
 nsHTMLAnchorElement::GetText(nsAString& aText)
 {
-  aText.Truncate();
-
-  // Since this is a Netscape 4 proprietary attribute, we have to implement
-  // the same behavior. Basically it is returning the last text node of
-  // of the anchor. Returns an empty string if there is no text node.
-  // The nsIContentIterator does exactly what we want, if we start the 
-  // iteration from the end.
-  nsCOMPtr<nsIContentIterator> iter;
-  nsresult rv = NS_NewPreContentIterator(getter_AddRefs(iter));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Initialize the content iterator with the children of the anchor
-  iter->Init(this);
+  nsContentUtils::GetNodeTextContent(this, PR_TRUE, aText);
+  return NS_OK;
+}
 
-  // Last() positions the iterator to the last child of the anchor,
-  // starting at the deepest level of children, just like NS4 does.
-  iter->Last();
-
-  while (!iter->IsDone()) {
-    nsCOMPtr<nsIDOMText> textNode(do_QueryInterface(iter->GetCurrentNode()));
-    if(textNode) {
-      // The current node is a text node. Get its value and break the loop.
-      textNode->GetData(aText);
-      break;
-    }
-
-    iter->Prev();
-  }
-
-  return NS_OK;
+NS_IMETHODIMP    
+nsHTMLAnchorElement::SetText(const nsAString& aText)
+{
+  return nsContentUtils::SetNodeTextContent(this, aText, PR_FALSE);
 }
 
 NS_IMETHODIMP
 nsHTMLAnchorElement::ToString(nsAString& aSource)
 {
   return GetHref(aSource);
 }
 
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -141,8 +141,32 @@ nsHTMLAudioElement::Initialize(nsISuppor
   if (NS_FAILED(rv))
     return rv;
 
   // We have been specified with a src URL. Begin a load.
   QueueSelectResourceTask();
 
   return NS_OK;
 }
+
+  
+nsresult nsHTMLAudioElement::SetAcceptHeader(nsIHttpChannel* aChannel)
+{
+    nsCAutoString value(
+#ifdef MOZ_WEBM
+      "audio/webm,"
+#endif
+#ifdef MOZ_OGG
+      "audio/ogg,"
+#endif
+#ifdef MOZ_WAVE
+      "audio/wav,"
+#endif
+      "audio/*;q=0.9,"
+#ifdef MOZ_OGG
+      "application/ogg;q=0.7,"
+#endif
+      "video/*;q=0.6,*/*;q=0.5");
+
+    return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
+                                      value,
+                                      PR_FALSE);
+}
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -734,16 +734,19 @@ nsresult nsHTMLMediaElement::LoadResourc
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
   if (hc) {
     // Use a byte range request from the start of the resource.
     // This enables us to detect if the stream supports byte range
     // requests, and therefore seeking, early.
     hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
                          NS_LITERAL_CSTRING("bytes=0-"),
                          PR_FALSE);
+
+    // Send Accept header for video and audio types only (Bug 489071)
+    SetAcceptHeader(hc);
   }
 
   rv = mChannel->AsyncOpen(listener, nsnull);
   if (NS_FAILED(rv)) {
     // OnStartRequest is guaranteed to be called if the open succeeds.  If
     // the open failed, the listener's OnStartRequest will never be called,
     // so we need to break the element->channel->listener->element reference
     // cycle here.  The channel holds the only reference to the listener,
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -791,18 +791,18 @@ nsHTMLSelectElement::SetSelectedIndex(PR
   return rv;
 }
 
 NS_IMETHODIMP
 nsHTMLSelectElement::GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
                                     PRInt32 aStartIndex, PRBool aForward,
                                     PRInt32* aIndex)
 {
-  nsCOMPtr<Element> option = do_QueryInterface(aOption);
-  return mOptions->GetOptionIndex(option, aStartIndex, aForward, aIndex);
+  nsCOMPtr<nsINode> option = do_QueryInterface(aOption);
+  return mOptions->GetOptionIndex(option->AsElement(), aStartIndex, aForward, aIndex);
 }
 
 PRBool
 nsHTMLSelectElement::IsOptionSelectedByIndex(PRInt32 aIndex)
 {
   nsIDOMHTMLOptionElement *option = mOptions->ItemAsOption(aIndex);
   PRBool isSelected = PR_FALSE;
   if (option) {
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/nsHTMLVideoElement.cpp
@@ -155,9 +155,29 @@ nsHTMLVideoElement::IsAttributeMapped(co
 }
 
 nsMapRuleToAttributesFunc
 nsHTMLVideoElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
+nsresult nsHTMLVideoElement::SetAcceptHeader(nsIHttpChannel* aChannel)
+{
+    nsCAutoString value(
+#ifdef MOZ_WEBM
+        "video/webm,"
+#endif
+#ifdef MOZ_OGG
+        "video/ogg,"
+#endif
+        "video/*;q=0.9,"
+#ifdef MOZ_OGG
+        "application/ogg;q=0.7,"
+#endif
+        "audio/*;q=0.6,*/*;q=0.5");
+
+    return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
+                                      value,
+                                      PR_FALSE);
+}
+
 NS_IMPL_URI_ATTR(nsHTMLVideoElement, Poster, poster)
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -139,16 +139,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug448166.html \
 		test_bug460568.html \
 		test_bug347174.html \
 		test_bug347174_write.html \
 		test_bug347174_xsl.html \
 		test_bug347174_xslp.html \
 		347174transformable.xml \
 		347174transform.xsl \
+		test_a_text.html \
 		test_anchor_href_cache_invalidation.html \
 		test_bug481335.xhtml \
 		test_bug500885.html \
 		test_bug514856.html \
 		bug514856_iframe.html \
 		test_bug518122.html \
 		test_bug519987.html \
 		test_bug579079.html \
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_a_text.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for a.text</title>
+  <script src="/MochiKit/packed.js"></script>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+  <link rel="help" href="http://www.whatwg.org/html/#dom-a-text"/>
+</head>
+<body>
+<div id="content">
+<a href="a">a b c</a>
+<a href="b">a <!--b--> c</a>
+<a href="c">a <b>b</b> c</a>
+</div>
+<pre id="test">
+<script>
+var d = document.getElementById("content")
+                .appendChild(document.createElement("a"));
+d.href = "d";
+d.appendChild(document.createTextNode("a "));
+d.appendChild(document.createTextNode("b "));
+d.appendChild(document.createTextNode("c "));
+var expected = ["a b c", "a  c", "a b c", "a b c "];
+var list = document.getElementById("content").getElementsByTagName("a");
+for (var i = 0, il = list.length; i < il; ++i) {
+  is(list[i].text, list[i].textContent);
+  is(list[i].text, expected[i]);
+
+  list[i].text = "x";
+  is(list[i].text, "x");
+  is(list[i].textContent, "x");
+  is(list[i].firstChild.data, "x");
+  is(list[i].childNodes.length, 1);
+
+  list[i].textContent = "y";
+  is(list[i].text, "y");
+  is(list[i].textContent, "y");
+  is(list[i].firstChild.data, "y");
+  is(list[i].childNodes.length, 1);
+}
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -3642,20 +3642,20 @@ ConvertToMidasInternalCommand(const nsAS
   nsCAutoString dummyCString;
   nsAutoString dummyString;
   PRBool dummyBool;
   return ConvertToMidasInternalCommandInner(inCommandID, dummyString,
                                             outCommandID, dummyCString,
                                             dummyBool, dummyBool, PR_TRUE);
 }
 
-jsval
-nsHTMLDocument::sCutCopyInternal_id = JSVAL_VOID;
-jsval
-nsHTMLDocument::sPasteInternal_id = JSVAL_VOID;
+jsid
+nsHTMLDocument::sCutCopyInternal_id = JSID_VOID;
+jsid
+nsHTMLDocument::sPasteInternal_id = JSID_VOID;
 
 /* Helper function to check security of clipboard commands. If aPaste is */
 /* true, we check paste, else we check cutcopy */
 nsresult
 nsHTMLDocument::DoClipboardSecurityCheck(PRBool aPaste)
 {
   nsresult rv = NS_ERROR_FAILURE;
 
@@ -3671,27 +3671,27 @@ nsHTMLDocument::DoClipboardSecurityCheck
 
     JSAutoRequest ar(cx);
 
     NS_NAMED_LITERAL_CSTRING(classNameStr, "Clipboard");
 
     nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
 
     if (aPaste) {
-      if (nsHTMLDocument::sPasteInternal_id == JSVAL_VOID) {
+      if (nsHTMLDocument::sPasteInternal_id == JSID_VOID) {
         nsHTMLDocument::sPasteInternal_id =
-          STRING_TO_JSVAL(::JS_InternString(cx, "paste"));
+          INTERNED_STRING_TO_JSID(::JS_InternString(cx, "paste"));
       }
       rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
                                        nsHTMLDocument::sPasteInternal_id,
                                        nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
     } else {
-      if (nsHTMLDocument::sCutCopyInternal_id == JSVAL_VOID) {
+      if (nsHTMLDocument::sCutCopyInternal_id == JSID_VOID) {
         nsHTMLDocument::sCutCopyInternal_id =
-          STRING_TO_JSVAL(::JS_InternString(cx, "cutcopy"));
+          INTERNED_STRING_TO_JSID(::JS_InternString(cx, "cutcopy"));
       }
       rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
                                        nsHTMLDocument::sCutCopyInternal_id,
                                        nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
     }
   }
   return rv;
 }
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -376,18 +376,18 @@ protected:
   nsresult TurnEditingOff();
   nsresult EditingStateChanged();
   void MaybeEditingStateChanged();
 
   PRUint32 mContentEditableCount;
   EditingState mEditingState;
 
   nsresult   DoClipboardSecurityCheck(PRBool aPaste);
-  static jsval       sCutCopyInternal_id;
-  static jsval       sPasteInternal_id;
+  static jsid        sCutCopyInternal_id;
+  static jsid        sPasteInternal_id;
 
   // When false, the .cookies property is completely disabled
   PRBool mDisableCookieAccess;
 
   // Parser used for constructing document fragments.
   nsCOMPtr<nsIParser> mFragmentParser;
 };
 
--- a/content/media/nsMediaStream.cpp
+++ b/content/media/nsMediaStream.cpp
@@ -463,16 +463,24 @@ void nsMediaChannelStream::SetupChannelH
   // This enables us to detect if the stream supports byte range
   // requests, and therefore seeking, early.
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
   if (hc) {
     nsCAutoString rangeString("bytes=");
     rangeString.AppendInt(mOffset);
     rangeString.Append("-");
     hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, PR_FALSE);
+
+    // Send Accept header for video and audio types only (Bug 489071)
+    NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
+    nsHTMLMediaElement* element = mDecoder->GetMediaElement();
+    if (!element) {
+      return;
+    }
+    element->SetAcceptHeader(hc);
   } else {
     NS_ASSERTION(mOffset == 0, "Don't know how to seek on this channel type");
   }
 }
 
 nsresult nsMediaChannelStream::Close()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
--- a/content/media/nsMediaStream.h
+++ b/content/media/nsMediaStream.h
@@ -388,16 +388,17 @@ protected:
                            nsIInputStream* aStream,
                            PRUint32 aCount);
   nsresult OnChannelRedirect(nsIChannel* aOld, nsIChannel* aNew, PRUint32 aFlags);
 
   // Opens the channel, using an HTTP byte range request to start at mOffset
   // if possible. Main thread only.
   nsresult OpenChannel(nsIStreamListener** aStreamListener);
   nsresult RecreateChannel();
+  // Add headers to HTTP request. Main thread only.
   void SetupChannelHeaders();
   // Closes the channel. Main thread only.
   void CloseChannel();
 
   void DoNotifyDataReceived();
 
   static NS_METHOD CopySegmentToCache(nsIInputStream *aInStream,
                                       void *aClosure,
--- a/content/smil/Makefile.in
+++ b/content/smil/Makefile.in
@@ -49,16 +49,17 @@ LIBXUL_LIBRARY	= 1
 
 # nsSMILKeySpline is used by CSS transitions -- need to build it regardless
 # of whether SMIL is enabled.
 CPPSRCS		= nsSMILKeySpline.cpp
 EXPORTS		= nsSMILKeySpline.h
 
 ifdef MOZ_SMIL
 CPPSRCS		+= \
+	nsDOMTimeEvent.cpp \
 	nsSMILAnimationController.cpp \
 	nsSMILAnimationFunction.cpp \
 	nsSMILCompositor.cpp \
 	nsSMILCSSProperty.cpp \
 	nsSMILCSSValueType.cpp \
 	nsSMILFloatType.cpp \
 	nsSMILInstanceTime.cpp \
 	nsSMILInterval.cpp \
@@ -100,14 +101,15 @@ EXPORTS		+= \
 	  nsSMILMilestone.h \
 	  nsSMILTimeContainer.h \
 	  nsSMILTypes.h \
 	  $(NULL)
 
 INCLUDES += 	\
 		-I$(srcdir)/../base/src \
 		-I$(srcdir)/../../layout/style \
+		-I$(srcdir)/../events/src \
 		$(NULL)
 endif # MOZ_SMIL
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES += -D_IMPL_NS_LAYOUT
new file mode 100644
--- /dev/null
+++ b/content/smil/nsDOMTimeEvent.cpp
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SMIL Module.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsDOMTimeEvent.h"
+#include "nsGUIEvent.h"
+#include "nsPresContext.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIDOMAbstractView.h"
+
+nsDOMTimeEvent::nsDOMTimeEvent(nsPresContext* aPresContext, nsEvent* aEvent)
+  : nsDOMEvent(aPresContext, aEvent ? aEvent : new nsUIEvent(PR_FALSE, 0, 0)),
+    mDetail(0)
+{
+  if (aEvent) {
+    mEventIsInternal = PR_FALSE;
+  } else {
+    mEventIsInternal = PR_TRUE;
+    mEvent->eventStructType = NS_SMIL_TIME_EVENT;
+  }
+
+  if (mEvent->eventStructType == NS_SMIL_TIME_EVENT) {
+    nsUIEvent* event = static_cast<nsUIEvent*>(mEvent);
+    mDetail = event->detail;
+  }
+
+  mEvent->flags |= NS_EVENT_FLAG_CANT_BUBBLE |
+                   NS_EVENT_FLAG_CANT_CANCEL;
+
+  if (mPresContext) {
+    nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
+    if (container) {
+      nsCOMPtr<nsIDOMWindowInternal> window = do_GetInterface(container);
+      if (window) {
+        mView = do_QueryInterface(window);
+      }
+    }
+  }
+}
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTimeEvent)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mView)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mView)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_ADDREF_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+NS_IMPL_RELEASE_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+
+DOMCI_DATA(TimeEvent, nsDOMTimeEvent)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMTimeEvent)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMTimeEvent)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TimeEvent)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
+
+NS_IMETHODIMP
+nsDOMTimeEvent::GetView(nsIDOMAbstractView** aView)
+{
+  *aView = mView;
+  NS_IF_ADDREF(*aView);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMTimeEvent::GetDetail(PRInt32* aDetail)
+{
+  *aDetail = mDetail;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMTimeEvent::InitTimeEvent(const nsAString& aTypeArg,
+                              nsIDOMAbstractView* aViewArg,
+                              PRInt32 aDetailArg)
+{
+  nsresult rv = nsDOMEvent::InitEvent(aTypeArg, PR_FALSE /*doesn't bubble*/,
+                                                PR_FALSE /*can't cancel*/);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mDetail = aDetailArg;
+  mView = aViewArg;
+
+  return NS_OK;
+}
+
+nsresult NS_NewDOMTimeEvent(nsIDOMEvent** aInstancePtrResult,
+                            nsPresContext* aPresContext,
+                            nsEvent* aEvent)
+{
+  nsDOMTimeEvent* it = new nsDOMTimeEvent(aPresContext, aEvent);
+  return CallQueryInterface(it, aInstancePtrResult);
+}
new file mode 100644
--- /dev/null
+++ b/content/smil/nsDOMTimeEvent.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SMIL Module.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef NS_DOMTIMEEVENT_H_
+#define NS_DOMTIMEEVENT_H_
+
+#include "nsIDOMTimeEvent.h"
+#include "nsDOMEvent.h"
+
+class nsDOMTimeEvent : public nsDOMEvent,
+                       public nsIDOMTimeEvent
+{
+public:
+  nsDOMTimeEvent(nsPresContext* aPresContext, nsEvent* aEvent);
+                     
+  // nsISupports interface:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+
+  // nsIDOMTimeEvent interface:
+  NS_DECL_NSIDOMTIMEEVENT
+
+  // Forward to base class
+  NS_FORWARD_TO_NSDOMEVENT
+
+private:
+  nsCOMPtr<nsIDOMAbstractView> mView;
+  PRInt32                      mDetail;
+};
+
+#endif // NS_DOMTIMEEVENT_H_
--- a/content/smil/nsSMILTimedElement.cpp
+++ b/content/smil/nsSMILTimedElement.cpp
@@ -38,25 +38,29 @@
 #include "nsSMILTimedElement.h"
 #include "nsSMILAnimationFunction.h"
 #include "nsSMILTimeValue.h"
 #include "nsSMILTimeValueSpec.h"
 #include "nsSMILInstanceTime.h"
 #include "nsSMILParserUtils.h"
 #include "nsSMILTimeContainer.h"
 #include "nsGkAtoms.h"
+#include "nsGUIEvent.h"
+#include "nsEventDispatcher.h"
 #include "nsReadableUtils.h"
 #include "nsMathUtils.h"
+#include "nsThreadUtils.h"
+#include "nsIPresShell.h"
 #include "prdtoa.h"
 #include "plstr.h"
 #include "prtime.h"
 #include "nsString.h"
 
 //----------------------------------------------------------------------
-// Helper classes -- InstanceTimeComparator
+// Helper class: InstanceTimeComparator
 
 // Upon inserting an instance time into one of our instance time lists we assign
 // it a serial number. This allows us to sort the instance times in such a way
 // that where we have several equal instance times, the ones added later will
 // sort later. This means that when we call UpdateCurrentInterval during the
 // waiting state we won't unnecessarily change the begin instance.
 //
 // The serial number also means that every instance time has an unambiguous
@@ -86,16 +90,53 @@ nsSMILTimedElement::InstanceTimeComparat
   NS_ABORT_IF_FALSE(aElem1->Serial() && aElem2->Serial(),
       "Instance times have not been assigned serial numbers");
 
   PRInt8 cmp = aElem1->Time().CompareTo(aElem2->Time());
   return cmp == 0 ? aElem1->Serial() < aElem2->Serial() : cmp < 0;
 }
 
 //----------------------------------------------------------------------
+// Helper class: AsyncTimeEventRunner
+
+namespace
+{
+  class AsyncTimeEventRunner : public nsRunnable
+  {
+  protected:
+    nsRefPtr<nsIContent> mTarget;
+    PRUint32             mMsg;
+    PRInt32              mDetail;
+
+  public:
+    AsyncTimeEventRunner(nsIContent* aTarget, PRUint32 aMsg, PRInt32 aDetail)
+      : mTarget(aTarget), mMsg(aMsg), mDetail(aDetail)
+    {
+    }
+
+    NS_IMETHOD Run()
+    {
+      nsUIEvent event(PR_TRUE, mMsg, mDetail);
+      event.eventStructType = NS_SMIL_TIME_EVENT;
+
+      nsPresContext* context = nsnull;
+      nsIDocument* doc = mTarget->GetCurrentDoc();
+      if (doc) {
+        nsCOMPtr<nsIPresShell> shell = doc->GetShell();
+        if (shell) {
+          context = shell->GetPresContext();
+        }
+      }
+
+      return nsEventDispatcher::Dispatch(mTarget, context, &event);
+    }
+  };
+}
+
+//----------------------------------------------------------------------
 // Templated helper functions
 
 // Selectively remove elements from an array of type
 // nsTArray<nsRefPtr<nsSMILInstanceTime> > with O(n) performance.
 template <class TestFunctor>
 void
 nsSMILTimedElement::RemoveInstanceTimes(InstanceTimeList& aArray,
                                         TestFunctor& aTest)
@@ -145,16 +186,17 @@ nsSMILTimedElement::nsSMILTimedElement()
   mAnimationElement(nsnull),
   mFillMode(FILL_REMOVE),
   mRestartMode(RESTART_ALWAYS),
   mBeginSpecSet(PR_FALSE),
   mEndHasEventConditions(PR_FALSE),
   mInstanceSerialIndex(0),
   mClient(nsnull),
   mCurrentInterval(nsnull),
+  mCurrentRepeatIteration(0),
   mPrevRegisteredMilestone(sMaxMilestone),
   mElementState(STATE_STARTUP),
   mSeekState(SEEK_NOT_SEEKING)
 {
   mSimpleDur.SetIndefinite();
   mMin.SetMillis(0L);
   mMax.SetIndefinite();
   mTimeDependents.Init();
@@ -501,30 +543,31 @@ nsSMILTimedElement::DoSampleAt(nsSMILTim
       }
       break;
 
     case STATE_WAITING:
       {
         if (mCurrentInterval->Begin()->Time() <= sampleTime) {
           mElementState = STATE_ACTIVE;
           mCurrentInterval->FixBegin();
-          if (HasPlayed()) {
-            Reset(); // Apply restart behaviour
-          }
           if (mClient) {
             mClient->Activate(mCurrentInterval->Begin()->Time().GetMillis());
           }
+          if (mSeekState == SEEK_NOT_SEEKING) {
+            FireTimeEventAsync(NS_SMIL_BEGIN, 0);
+          }
           if (HasPlayed()) {
+            Reset(); // Apply restart behaviour
             // The call to Reset() may mean that the end point of our current
             // interval should be changed and so we should update the interval
             // now. However, calling UpdateCurrentInterval could result in the
             // interval getting deleted (perhaps through some web of syncbase
             // dependencies) therefore we make updating the interval the last
-            // thing we do. There is no guarantee that mCurrentInterval.IsSet()
-            // is true after this.
+            // thing we do. There is no guarantee that mCurrentInterval is set
+            // after this.
             UpdateCurrentInterval();
           }
           stateChanged = PR_TRUE;
         }
       }
       break;
 
     case STATE_ACTIVE:
@@ -536,31 +579,48 @@ nsSMILTimedElement::DoSampleAt(nsSMILTim
           mElementState =
             NS_SUCCEEDED(GetNextInterval(mCurrentInterval, nsnull, newInterval))
             ? STATE_WAITING
             : STATE_POSTACTIVE;
           if (mClient) {
             mClient->Inactivate(mFillMode == FILL_FREEZE);
           }
           mCurrentInterval->FixEnd();
+          if (mSeekState == SEEK_NOT_SEEKING) {
+            FireTimeEventAsync(NS_SMIL_END, 0);
+          }
+          mCurrentRepeatIteration = 0;
           mOldIntervals.AppendElement(mCurrentInterval.forget());
           // We must update mOldIntervals before calling SampleFillValue
           SampleFillValue();
           if (mElementState == STATE_WAITING) {
             mCurrentInterval = new nsSMILInterval(newInterval);
             NotifyNewInterval();
           }
           FilterHistory();
           stateChanged = PR_TRUE;
         } else {
           nsSMILTime beginTime = mCurrentInterval->Begin()->Time().GetMillis();
           NS_ASSERTION(aContainerTime >= beginTime,
                        "Sample time should not precede current interval");
           nsSMILTime activeTime = aContainerTime - beginTime;
           SampleSimpleTime(activeTime);
+          // We register our repeat times as milestones (except when we're
+          // seeking) so we should get a sample at exactly the time we repeat.
+          // (And even when we are seeking we want to update
+          // mCurrentRepeatIteration so we do that first before testing the seek
+          // state.)
+          PRUint32 prevRepeatIteration = mCurrentRepeatIteration;
+          if (ActiveTimeToSimpleTime(activeTime, mCurrentRepeatIteration)==0 &&
+              mCurrentRepeatIteration != prevRepeatIteration &&
+              mCurrentRepeatIteration &&
+              mSeekState == SEEK_NOT_SEEKING) {
+            FireTimeEventAsync(NS_SMIL_REPEAT,
+                          static_cast<PRInt32>(mCurrentRepeatIteration));
+          }
         }
       }
       break;
 
     case STATE_POSTACTIVE:
       break;
     }
 
@@ -602,16 +662,17 @@ nsSMILTimedElement::Rewind()
 
   mSeekState = mElementState == STATE_ACTIVE ?
                SEEK_BACKWARD_FROM_ACTIVE :
                SEEK_BACKWARD_FROM_INACTIVE;
 
   // Set the STARTUP state first so that if we get any callbacks we won't waste
   // time recalculating the current interval
   mElementState = STATE_STARTUP;
+  mCurrentRepeatIteration = 0;
 
   // Clear the intervals and instance times except those instance times we can't
   // regenerate (DOM calls etc.)
   RewindTiming();
 
   UnsetBeginSpec();
   UnsetEndSpec();
 
@@ -1233,23 +1294,16 @@ nsSMILTimedElement::Reset()
 
   RemoveReset resetEnd(nsnull);
   RemoveInstanceTimes(mEndInstances, resetEnd);
 }
 
 void
 nsSMILTimedElement::DoPostSeek()
 {
-  // XXX When implementing TimeEvents we'll need to compare mElementState with
-  // mSeekState and dispatch events as follows:
-  //     ACTIVE->INACTIVE: End event
-  //     INACTIVE->ACTIVE: Begin event
-  //     ACTIVE->ACTIVE: Nothing (even if they're different intervals)
-  //     INACTIVE->INACTIVE: Nothing (even if we've skipped intervals)
-
   // Finish backwards seek
   if (mSeekState == SEEK_BACKWARD_FROM_INACTIVE ||
       mSeekState == SEEK_BACKWARD_FROM_ACTIVE) {
     // Previously some dynamic instance times may have been marked to be
     // preserved because they were endpoints of an historic interval (which may
     // or may not have been filtered). Now that we've finished a seek we should
     // clear that flag for those instance times whose intervals are no longer
     // historic.
@@ -1261,16 +1315,44 @@ nsSMILTimedElement::DoPostSeek()
     // SMIL seems to require this. SMIL 3.0, 'Hyperlinks and timing':
     //   Resolved end times associated with events, Repeat-values,
     //   Accesskey-values or added via DOM method calls are cleared when seeking
     //   to time earlier than the resolved end time.
     Reset();
     UpdateCurrentInterval();
   }
 
+  // XXX
+  // Note that SMIL gives the very cryptic description:
+  //   The associated time for the event is the document time before the seek.
+  //   This action does not resolve any times in the instance times list for end
+  //   times.
+  //
+  // The second sentence was added as a clarification in a SMIL 2.0 erratum.
+  // Presumably the intention is that we fire the event as implemented below but
+  // don't act on it. This makes sense at least for dependencies within the same
+  // time container. So we'll probably need to set a flag here to ensure we
+  // don't actually act on it when we implement event-based timing.
+  switch (mSeekState)
+  {
+  case SEEK_FORWARD_FROM_ACTIVE:
+  case SEEK_BACKWARD_FROM_ACTIVE:
+    if (mElementState != STATE_ACTIVE) {
+      FireTimeEventAsync(NS_SMIL_END, 0);
+    }
+    break;
+
+  case SEEK_FORWARD_FROM_INACTIVE:
+  case SEEK_BACKWARD_FROM_INACTIVE:
+    if (mElementState == STATE_ACTIVE) {
+      FireTimeEventAsync(NS_SMIL_BEGIN, 0);
+    }
+    break;
+  }
+
   mSeekState = SEEK_NOT_SEEKING;
 }
 
 void
 nsSMILTimedElement::UnpreserveInstanceTimes(InstanceTimeList& aList)
 {
   const nsSMILInterval* prevInterval = GetPreviousInterval();
   const nsSMILInstanceTime* cutoff = mCurrentInterval ?
@@ -1856,20 +1938,16 @@ nsSMILTimedElement::RegisterMilestone()
   mPrevRegisteredMilestone = nextMilestone;
 }
 
 PRBool
 nsSMILTimedElement::GetNextMilestone(nsSMILMilestone& aNextMilestone) const
 {
   // Return the next key moment in our lifetime.
   //
-  // XXX Once we implement TimeEvents and event based timing we might need to
-  // include repeat times too, particularly if it's important to get them in
-  // order.
-  //
   // XXX It may be possible in future to optimise this so that we only register
   // for milestones if:
   // a) We have time dependents, or
   // b) We are dependent on events or syncbase relationships, or
   // c) There are registered listeners for our events
   //
   // Then for the simple case where everything uses offset values we could
   // ignore milestones altogether.
@@ -1891,32 +1969,37 @@ nsSMILTimedElement::GetNextMilestone(nsS
     NS_ABORT_IF_FALSE(mCurrentInterval,
         "In waiting state but the current interval has not been set");
     aNextMilestone.mIsEnd = PR_FALSE;
     aNextMilestone.mTime = mCurrentInterval->Begin()->Time().GetMillis();
     return PR_TRUE;
 
   case STATE_ACTIVE:
     {
-      // XXX When we implement TimeEvents, we may need to consider what comes
-      // next: the interval end or an interval repeat.
+      // Work out what comes next: the interval end or the next repeat iteration
+      nsSMILTimeValue nextRepeat;
+      if (mSeekState == SEEK_NOT_SEEKING && mSimpleDur.IsResolved()) {
+        nextRepeat.SetMillis(mCurrentInterval->Begin()->Time().GetMillis() +
+            (mCurrentRepeatIteration + 1) * mSimpleDur.GetMillis());
+      }
+      nsSMILTimeValue nextMilestone =
+        NS_MIN(mCurrentInterval->End()->Time(), nextRepeat);
 
-      // Check for an early end
-      nsSMILInstanceTime* earlyEnd =
-        CheckForEarlyEnd(mCurrentInterval->End()->Time());
+      // Check for an early end before that time
+      nsSMILInstanceTime* earlyEnd = CheckForEarlyEnd(nextMilestone);
       if (earlyEnd) {
         aNextMilestone.mIsEnd = PR_TRUE;
         aNextMilestone.mTime = earlyEnd->Time().GetMillis();
         return PR_TRUE;
       }
 
-      // Otherwise it's just the next interval end
-      if (mCurrentInterval->End()->Time().IsResolved()) {
-        aNextMilestone.mIsEnd = PR_TRUE;
-        aNextMilestone.mTime = mCurrentInterval->End()->Time().GetMillis();
+      // Apply the previously calculated milestone
+      if (nextMilestone.IsResolved()) {
+        aNextMilestone.mIsEnd = nextMilestone != nextRepeat;
+        aNextMilestone.mTime = nextMilestone.GetMillis();
         return PR_TRUE;
       }
 
       return PR_FALSE;
     }
 
   case STATE_POSTACTIVE:
     return PR_FALSE;
@@ -1953,16 +2036,27 @@ nsSMILTimedElement::NotifyChangedInterva
   nsSMILTimeContainer* container = GetTimeContainer();
   if (container) {
     container->SyncPauseTime();
   }
 
   mCurrentInterval->NotifyChanged(container);
 }
 
+void
+nsSMILTimedElement::FireTimeEventAsync(PRUint32 aMsg, PRInt32 aDetail)
+{
+  if (!mAnimationElement)
+    return;
+
+  nsCOMPtr<nsIRunnable> event =
+    new AsyncTimeEventRunner(&mAnimationElement->Content(), aMsg, aDetail);
+  NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
+}
+
 const nsSMILInstanceTime*
 nsSMILTimedElement::GetEffectiveBeginInstance() const
 {
   switch (mElementState)
   {
   case STATE_STARTUP:
     return nsnull;
 
--- a/content/smil/nsSMILTimedElement.h
+++ b/content/smil/nsSMILTimedElement.h
@@ -477,16 +477,17 @@ protected:
   void              SampleFillValue();
   void              AddInstanceTimeFromCurrentTime(nsSMILTime aCurrentTime,
                         double aOffsetSeconds, PRBool aIsBegin);
   void              RegisterMilestone();
   PRBool            GetNextMilestone(nsSMILMilestone& aNextMilestone) const;
 
   void              NotifyNewInterval();
   void              NotifyChangedInterval();
+  void              FireTimeEventAsync(PRUint32 aMsg, PRInt32 aDetail);
   const nsSMILInstanceTime* GetEffectiveBeginInstance() const;
   const nsSMILInterval* GetPreviousInterval() const;
   PRBool            HasPlayed() const { return !mOldIntervals.IsEmpty(); }
 
   // Hashtable callback methods
   PR_STATIC_CALLBACK(PLDHashOperator) NotifyNewIntervalCallback(
       TimeValueSpecPtrKey* aKey, void* aData);
 
@@ -534,16 +535,17 @@ protected:
 
   InstanceTimeList                mBeginInstances;
   InstanceTimeList                mEndInstances;
   PRUint32                        mInstanceSerialIndex;
 
   nsSMILAnimationFunction*        mClient;
   nsAutoPtr<nsSMILInterval>       mCurrentInterval;
   IntervalList                    mOldIntervals;
+  PRUint32                        mCurrentRepeatIteration;
   nsSMILMilestone                 mPrevRegisteredMilestone;
   static const nsSMILMilestone    sMaxMilestone;
   static const PRUint8            sMaxNumIntervals;
   static const PRUint8            sMaxNumInstanceTimes;
 
   // Set of dependent time value specs to be notified when establishing a new
   // current interval. Change notifications and delete notifications are handled
   // by the interval.
--- a/content/smil/test/Makefile.in
+++ b/content/smil/test/Makefile.in
@@ -77,16 +77,17 @@ include $(topsrcdir)/config/rules.mk
 	  test_smilGetSimpleDuration.xhtml \
 	  test_smilKeySplines.xhtml \
 	  test_smilKeyTimesPacedMode.xhtml \
 	  test_smilSetCurrentTime.xhtml \
 	  test_smilSync.xhtml \
 	  test_smilSyncbaseTarget.xhtml \
 	  test_smilSyncTransform.xhtml \
 	  test_smilTextZoom.xhtml \
+	  test_smilTimeEvents.xhtml \
 	  test_smilTiming.xhtml \
 	  test_smilTimingZeroIntervals.xhtml \
 	  test_smilUpdatedInterval.xhtml \
 	  test_smilXHR.xhtml \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/smil/test/test_smilTimeEvents.xhtml
@@ -0,0 +1,292 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=572270
+-->
+<head>
+  <title>Test TimeEvents dispatching</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank"
+  href="https://bugzilla.mozilla.org/show_bug.cgi?id=572270">Mozilla Bug
+  572270</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
+  <g font-size="10px">
+    <circle cx="0" cy="0" r="15" fill="blue" id="circle"
+      onbegin="parentHandler(evt)" onrepeat="parentHandler(evt)"
+      onend="parentHandler(evt)">
+      <animate attributeName="cy" from="0" to="100" dur="60s" begin="2s"
+        id="anim" repeatCount="2"
+        onbegin="handleOnBegin(evt)" onrepeat="handleOnRepeat(evt)"
+        onend="handleOnEnd(evt)"/>
+    </circle>
+  </g>
+</svg>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+/** Test SMIL TimeEvents dispatching **/
+
+/* Global Variables */
+const gTimeoutDur = 5000; // Time until we give up waiting for events in ms
+var gSvg    = document.getElementById("svg");
+var gAnim   = document.getElementById('anim');
+var gCircle = document.getElementById('circle');
+var gExpectedEvents = new Array();
+var gTimeoutID;
+var gTestStages =
+  [ testPlaybackBegin,
+    testPlaybackRepeat,
+    testPlaybackEnd,
+    testForwardsSeekToMid,
+    testForwardsSeekToNextInterval,
+    testForwardsSeekPastEnd,
+    testBackwardsSeekToMid,
+    testBackwardsSeekToStart,
+    testCreateEvent,
+    testRegistration
+    ];
+
+SimpleTest.waitForExplicitFinish();
+
+function continueTest()
+{
+  if (gTestStages.length == 0) {
+    SimpleTest.finish();
+    return;
+  }
+  gTestStages.shift()();
+}
+
+function testPlaybackBegin()
+{
+  // Test events are dispatched through normal playback
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(1.99);
+  gExpectedEvents.push("beginEvent", "beginEvent"); // Two registered handlers
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testPlaybackRepeat()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(61.99);
+  gExpectedEvents.push(["repeatEvent", 1], ["repeatEvent", 1]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testPlaybackEnd()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(121.99);
+  gExpectedEvents.push("endEvent", "endEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testForwardsSeekToMid()
+{
+  gSvg.pauseAnimations();
+  // Set animation parameters to something that repeats a lot
+  gSvg.setCurrentTime(0);
+  gAnim.setAttribute('begin', '2s; 102s');
+  gAnim.setAttribute('dur', '15s');
+  gAnim.setAttribute('repeatCount', '6');
+  gSvg.setCurrentTime(46.99);
+  gExpectedEvents.push("beginEvent", "beginEvent",
+                       ["repeatEvent", 3], ["repeatEvent", 3]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testForwardsSeekToNextInterval()
+{
+  // Skip to next interval -- we shouldn't get any additional begin or end
+  // events in between
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(131.99);
+  gExpectedEvents.push(["repeatEvent", 2], ["repeatEvent", 2]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testForwardsSeekPastEnd()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(200);
+  gExpectedEvents.push("endEvent", "endEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testBackwardsSeekToMid()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(31.99);
+  gExpectedEvents.push("beginEvent", "beginEvent",
+                       ["repeatEvent", 2], ["repeatEvent", 2]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testBackwardsSeekToStart()
+{
+  gSvg.pauseAnimations();
+  gExpectedEvents.push("endEvent", "endEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.setCurrentTime(0);
+}
+
+function testCreateEvent()
+{
+  var evt;
+  try {
+    evt = document.createEvent("TimeEvents");
+  } catch (e) {
+    ok(false, "Failed to create TimeEvent via script: " + e);
+    return;
+  }
+  evt.initTimeEvent("repeatEvent", null, 3);
+  is(evt.type, "repeatEvent", "Unexpected type for user-generated event");
+  is(evt.detail, 3, "Unexpected detail for user-generated event");
+  is(evt.target, null, "Unexpected event target");
+  is(evt.currentTarget, null, "Unexpected event current target");
+  is(evt.eventPhase, evt.AT_TARGET);
+  is(evt.bubbles, false, "Event should not bubble");
+  is(evt.cancelable, false, "Event should not be cancelable");
+  is(evt.view, null, "Event view should be null");
+
+  // Prior to dispatch we should be able to change the event type
+  evt.initTimeEvent("beginEvent", document.defaultView, 0);
+  is(evt.type, "beginEvent", "Failed to update event type before dispatch");
+  is(evt.detail, 0, "Failed to update event detail before dispatch");
+  is(evt.view, document.defaultView, "Event view should be set");
+
+  // But not directly as it's readonly
+  try {
+    evt.type = "endEvent";
+  } catch(e) { }
+  is(evt.type, "beginEvent", "Event type should be readonly");
+
+  // Likewise the detail field should be readonly
+  try {
+    evt.detail = "8";
+  } catch(e) { }
+  is(evt.detail, 0, "Event detail should be readonly");
+
+  // Dispatch
+  gExpectedEvents.push("beginEvent", "beginEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gAnim.dispatchEvent(evt);
+}
+
+function testRegistration()
+{
+  gSvg.pauseAnimations();
+  // Reset animation to something simple
+  gSvg.setCurrentTime(0);
+  gAnim.setAttribute('begin', '2s');
+  gAnim.setAttribute('dur', '50s');
+
+  // Remove attribute handler
+  gAnim.removeAttribute('onbegin');
+
+  // Add bogus handlers
+  gAnim.setAttribute('onbeginElement', 'handleOnBegin(evt)');
+  gAnim.addEventListener("begin", handleOnBegin, false);
+  gAnim.addEventListener("onbegin", handleOnBegin, false);
+
+  // We should now have just one legitimate listener: the one registered to
+  // handle 'beginElement'
+  gSvg.setCurrentTime(1.99);
+  gExpectedEvents.push("beginEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function handleOnBegin(evt)
+{
+  is(evt.type, "beginEvent", "Expected begin event but got " + evt.type);
+  checkExpectedEvent(evt);
+}
+
+function handleOnRepeat(evt)
+{
+  is(evt.type, "repeatEvent", "Expected repeat event but got " + evt.type);
+  checkExpectedEvent(evt);
+}
+
+function handleOnEnd(evt)
+{
+  is(evt.type, "endEvent", "Expected end event but got " + evt.type);
+  checkExpectedEvent(evt);
+}
+
+function sanityCheckEvent(evt)
+{
+  is(evt.target, gAnim, "Unexpected event target");
+  is(evt.currentTarget, gAnim, "Unexpected event current target");
+  is(evt.eventPhase, evt.AT_TARGET);
+  is(evt.bubbles, false, "Event should not bubble");
+  is(evt.cancelable, false, "Event should not be cancelable");
+  // Currently we set event timestamps to 0 which DOM 2 allows. This isn't
+  // correct since SMIL uses this field to avoid synchronisation slew but first
+  // we need to fix bug 323039 and bug 77992 which involve storing timestamps as
+  // 64-bit integers and deciding whether those timestamps should be related to
+  // the epoch or system start.
+  is(evt.timeStamp, 0, "Event timeStamp should be 0");
+  ok(evt.view !== null, "Event view not set");
+}
+
+function checkExpectedEvent(evt)
+{
+  sanityCheckEvent(evt);
+  ok(gExpectedEvents.length > 0, "Unexpected event: " + evt.type);
+  if (gExpectedEvents.length == 0) return;
+
+  var expected = gExpectedEvents.shift();
+  if (typeof expected == 'string') {
+    is(evt.type, expected, "Unexpected event type");
+    is(evt.detail, 0, "Unexpected event detail (repeat iteration)");
+  } else {
+    is(evt.type, expected[0], "Unexpected event type");
+    is(evt.detail, expected[1], "Unexpected event detail (repeat iteration)");
+  }
+  if (gExpectedEvents.length == 0) {
+    clearTimeout(gTimeoutID);
+    continueTest();
+  }
+}
+
+function timeoutFail()
+{
+  ok(false, "Timed out waiting for events: " + gExpectedEvents.join(', '));
+  SimpleTest.finish(); // No point continuing
+}
+
+function parentHandler(evt)
+{
+  ok(false, "Handler on parent got called but event shouldn't bubble.");
+}
+
+window.addEventListener("load", continueTest, false);
+
+// Register event handlers *in addition* to the handlers already added via the
+// "onbegin", "onend", "onrepeat" attributes on the <animate> and <circle>
+// elements. This is to test that both types of registration work.
+gAnim.addEventListener("beginEvent", handleOnBegin, false);
+gAnim.addEventListener("repeatEvent", handleOnRepeat, false);
+gAnim.addEventListener("endEvent", handleOnEnd, false);
+gCircle.addEventListener("beginEvent", parentHandler, false);
+]]>
+</script>
+</pre>
+</body>
+</html>
--- a/content/svg/content/src/nsSVGAnimationElement.cpp
+++ b/content/svg/content/src/nsSVGAnimationElement.cpp
@@ -471,16 +471,22 @@ nsSVGAnimationElement::EndElementAt(floa
   if (NS_FAILED(rv))
     return rv;
 
   AnimationNeedsResample();
  
   return NS_OK;
 }
 
+PRBool
+nsSVGAnimationElement::IsEventName(nsIAtom* aName)
+{
+  return nsContentUtils::IsEventAttributeName(aName, EventNameType_SMIL);
+}
+
 void
 nsSVGAnimationElement::UpdateHrefTarget(nsIContent* aNodeForContext,
                                         const nsAString& aHrefStr)
 {
   nsCOMPtr<nsIURI> targetURI;
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
   nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
                                             aHrefStr, GetOwnerDoc(), baseURI);
--- a/content/svg/content/src/nsSVGAnimationElement.h
+++ b/content/svg/content/src/nsSVGAnimationElement.h
@@ -93,16 +93,19 @@ public:
   virtual PRBool HasAnimAttr(nsIAtom* aAttName) const;
   virtual mozilla::dom::Element* GetTargetElementContent();
   virtual nsIAtom* GetTargetAttributeName() const;
   virtual nsSMILTargetAttrType GetTargetAttributeType() const;
   virtual nsSMILTimedElement& TimedElement();
   virtual nsSMILTimeContainer* GetTimeContainer();
 
 protected:
+  // nsSVGElement overrides
+  PRBool IsEventName(nsIAtom* aName);
+
   void UpdateHrefTarget(nsIContent* aNodeForContext,
                         const nsAString& aHrefStr);
 
   class TargetReference : public nsReferencedElement {
   public:
     TargetReference(nsSVGAnimationElement* aAnimationElement) :
       mAnimationElement(aAnimationElement) {}
   protected:
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1359,16 +1359,24 @@ nsIAtom* nsSVGElement::GetEventNameForAt
   if (aAttr == nsGkAtoms::onerror)
     return nsGkAtoms::onSVGError;
   if (aAttr == nsGkAtoms::onresize)
     return nsGkAtoms::onSVGResize;
   if (aAttr == nsGkAtoms::onscroll)
     return nsGkAtoms::onSVGScroll;
   if (aAttr == nsGkAtoms::onzoom)
     return nsGkAtoms::onSVGZoom;
+#ifdef MOZ_SMIL
+  if (aAttr == nsGkAtoms::onbegin)
+    return nsGkAtoms::onbeginEvent;
+  if (aAttr == nsGkAtoms::onrepeat)
+    return nsGkAtoms::onrepeatEvent;
+  if (aAttr == nsGkAtoms::onend)
+    return nsGkAtoms::onendEvent;
+#endif // MOZ_SMIL
 
   return aAttr;
 }
 
 nsSVGSVGElement *
 nsSVGElement::GetCtx()
 {
   nsCOMPtr<nsIDOMSVGSVGElement> svg;
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=79: */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -623,16 +624,19 @@ nsBindingManager::SetWrappedJS(nsIConten
 }
 
 void
 nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent,
                                               nsIDocument* aOldDocument)
 {
   NS_PRECONDITION(aOldDocument != nsnull, "no old document");
 
+  if (mDestroyed)
+    return;
+
   // Hold a ref to the binding so it won't die when we remove it from our
   // table.
   nsRefPtr<nsXBLBinding> binding = GetBinding(aContent);
   if (aContent->HasFlag(NODE_IS_INSERTION_PARENT)) {
     nsRefPtr<nsXBLBinding> parentBinding = GetBinding(aContent->GetBindingParent());
     if (parentBinding) {
       parentBinding->RemoveInsertionParent(aContent);
       // Clear insertion parent only if we don't have a binding which
@@ -1673,16 +1677,18 @@ nsBindingManager::ContentRemoved(nsIDocu
       }
     }
   }
 }
 
 void
 nsBindingManager::DropDocumentReference()
 {
+  mDestroyed = PR_TRUE;
+
   // Make sure to not run any more XBL constructors
   mProcessingAttachedStack = PR_TRUE;
   if (mProcessAttachedQueueEvent) {
     mProcessAttachedQueueEvent->Revoke();
   }
 
   if (mContentListTable.ops)
     PL_DHashTableFinish(&(mContentListTable));
@@ -1691,16 +1697,19 @@ nsBindingManager::DropDocumentReference(
   if (mAnonymousNodesTable.ops)
     PL_DHashTableFinish(&(mAnonymousNodesTable));
   mAnonymousNodesTable.ops = nsnull;
 
   if (mInsertionParentTable.ops)
     PL_DHashTableFinish(&(mInsertionParentTable));
   mInsertionParentTable.ops = nsnull;
 
+  if (mBindingTable.IsInitialized())
+    mBindingTable.Clear();
+
   mDocument = nsnull;
 }
 
 void
 nsBindingManager::Traverse(nsIContent *aContent,
                            nsCycleCollectionTraversalCallback &cb)
 {
   if (!aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -118,30 +118,30 @@ XBLFinalize(JSContext *cx, JSObject *obj
     static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(cx, obj));
   NS_RELEASE(docInfo);
   
   nsXBLJSClass* c = static_cast<nsXBLJSClass*>(::JS_GET_CLASS(cx, obj));
   c->Drop();
 }
 
 static JSBool
-XBLResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+XBLResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
            JSObject **objp)
 {
   // Note: if we get here, that means that the implementation for some binding
   // was installed, which means that AllowScripts() tested true.  Hence no need
   // to do checks like that here.
   
   // Default to not resolving things.
   NS_ASSERTION(*objp, "Must have starting object");
 
   JSObject* origObj = *objp;
   *objp = NULL;
 
-  if (!JSVAL_IS_STRING(id)) {
+  if (!JSID_IS_STRING(id)) {
     return JS_TRUE;
   }
 
   nsDependentJSString fieldName(id);
 
   jsval slotVal;
   ::JS_GetReservedSlot(cx, obj, 0, &slotVal);
   NS_ASSERTION(!JSVAL_IS_VOID(slotVal), "How did that happen?");
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -76,17 +76,17 @@ public:
   virtual nsIScriptContext *GetContext();
   virtual JSObject *GetGlobalJSObject();
   virtual void OnFinalize(PRUint32 aLangID, void *aScriptGlobal);
   virtual void SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts);
 
   // nsIScriptObjectPrincipal methods
   virtual nsIPrincipal* GetPrincipal();
 
-  static JSBool doCheckAccess(JSContext *cx, JSObject *obj, jsval id,
+  static JSBool doCheckAccess(JSContext *cx, JSObject *obj, jsid id,
                               PRUint32 accessType);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXBLDocGlobalObject,
                                            nsIScriptGlobalObject)
 
   void ClearGlobalObjectOwner();
 
 protected:
@@ -99,17 +99,17 @@ protected:
   nsCOMPtr<nsIScriptContext> mScriptContext;
   JSObject *mJSObject;    // XXX JS language rabies bigotry badness
 
   nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // weak reference
   static JSClass gSharedGlobalClass;
 };
 
 JSBool
-nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsval id, PRUint32 accessType)
+nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsid id, PRUint32 accessType)
 {
   nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
   if (!ssm) {
     ::JS_ReportError(cx, "Unable to verify access to a global object property.");
     return JS_FALSE;
   }
 
   // Make sure to actually operate on our object, and not some object further
@@ -124,32 +124,32 @@ nsXBLDocGlobalObject::doCheckAccess(JSCo
 
   nsresult rv = ssm->CheckPropertyAccess(cx, obj, JS_GET_CLASS(cx, obj)->name,
                                          id, accessType);
   return NS_SUCCEEDED(rv);
 }
 
 static JSBool
 nsXBLDocGlobalObject_getProperty(JSContext *cx, JSObject *obj,
-                                 jsval id, jsval *vp)
+                                 jsid id, jsval *vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 }
 
 static JSBool
 nsXBLDocGlobalObject_setProperty(JSContext *cx, JSObject *obj,
-                                 jsval id, jsval *vp)
+                                 jsid id, jsval *vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
 }
 
 static JSBool
-nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSObject *obj, jsval id,
+nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
                                  JSAccessMode mode, jsval *vp)
 {
   PRUint32 translated;
   if (mode & JSACC_WRITE) {
     translated = nsIXPCSecurityManager::ACCESS_SET_PROPERTY;
   } else {
     translated = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
   }
@@ -168,17 +168,17 @@ nsXBLDocGlobalObject_finalize(JSContext 
   if (sgo)
     sgo->OnFinalize(nsIProgrammingLanguage::JAVASCRIPT, obj);
 
   // The addref was part of JSObject construction
   NS_RELEASE(nativeThis);
 }
 
 static JSBool
-nsXBLDocGlobalObject_resolve(JSContext *cx, JSObject *obj, jsval id)
+nsXBLDocGlobalObject_resolve(JSContext *cx, JSObject *obj, jsid id)
 {
   JSBool did_resolve = JS_FALSE;
   return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
 JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
     "nsXBLPrototypeScript compilation scope",
@@ -258,17 +258,17 @@ nsXBLDocGlobalObject::SetContext(nsIScri
   NS_ASSERTION(aScriptContext->GetScriptTypeID() ==
                                         nsIProgrammingLanguage::JAVASCRIPT,
                "xbl is not multi-language");
   aScriptContext->WillInitializeContext();
   // NOTE: We init this context with a NULL global, so we automatically
   // hook up to the existing nsIScriptGlobalObject global setup by
   // nsGlobalWindow.
   nsresult rv;
-  rv = aScriptContext->InitContext(nsnull);
+  rv = aScriptContext->InitContext();
   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Script Language's InitContext failed");
   aScriptContext->SetGCOnDestruction(PR_FALSE);
   aScriptContext->DidInitializeContext();
   // and we set up our global manually
   mScriptContext = aScriptContext;
 }
 
 nsresult
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -2434,17 +2434,17 @@ nsXULDocument::PrepareToWalk()
     }
 
     // Now check the chrome registry for any additional overlays.
     rv = AddChromeOverlays();
     if (NS_FAILED(rv)) return rv;
 
     // Do one-time initialization if we're preparing to walk the
     // master document's prototype.
-    nsCOMPtr<Element> root;
+    nsRefPtr<Element> root;
 
     if (mState == eState_Master) {
         // Add the root element
         rv = CreateElementFromPrototype(proto, getter_AddRefs(root));
         if (NS_FAILED(rv)) return rv;
 
         rv = AppendChildTo(root, PR_FALSE);
         if (NS_FAILED(rv)) return rv;
@@ -2925,17 +2925,17 @@ nsXULDocument::ResumeWalk()
                          "no element on context stack");
 
             switch (childproto->mType) {
             case nsXULPrototypeNode::eType_Element: {
                 // An 'element', which may contain more content.
                 nsXULPrototypeElement* protoele =
                     static_cast<nsXULPrototypeElement*>(childproto);
 
-                nsCOMPtr<Element> child;
+                nsRefPtr<Element> child;
 
                 if (!processingOverlayHookupNodes) {
                     rv = CreateElementFromPrototype(protoele,
                                                     getter_AddRefs(child));
                     if (NS_FAILED(rv)) return rv;
 
                     // ...and append it to the content model.
                     rv = element->AppendChildTo(child, PR_FALSE);
@@ -3675,17 +3675,17 @@ nsXULDocument::CreateElementFromPrototyp
         nsCAutoString tagstrC;
         tagstrC.AssignWithConversion(tagstr);
         PR_LOG(gXULLog, PR_LOG_NOTICE,
                ("xul: creating <%s> from prototype",
                 tagstrC.get()));
     }
 #endif
 
-    nsCOMPtr<Element> result;
+    nsRefPtr<Element> result;
 
     if (aPrototype->mNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
         // If it's a XUL element, it'll be lightweight until somebody
         // monkeys with it.
         rv = nsXULElement::Create(aPrototype, this, PR_TRUE, getter_AddRefs(result));
         if (NS_FAILED(rv)) return rv;
     }
     else {
@@ -3723,17 +3723,17 @@ nsXULDocument::CreateElementFromPrototyp
 }
 
 nsresult
 nsXULDocument::CreateOverlayElement(nsXULPrototypeElement* aPrototype,
                                     Element** aResult)
 {
     nsresult rv;
 
-    nsCOMPtr<Element> element;
+    nsRefPtr<Element> element;
     rv = CreateElementFromPrototype(aPrototype, getter_AddRefs(element));
     if (NS_FAILED(rv)) return rv;
 
     OverlayForwardReference* fwdref =
         new OverlayForwardReference(this, element);
     if (! fwdref)
         return NS_ERROR_OUT_OF_MEMORY;
 
--- a/content/xul/document/src/nsXULDocument.h
+++ b/content/xul/document/src/nsXULDocument.h
@@ -487,17 +487,17 @@ protected:
 
     /**
      * Used to resolve broadcaster references
      */
     class BroadcasterHookup : public nsForwardReference
     {
     protected:
         nsXULDocument* mDocument;              // [WEAK]
-        nsCOMPtr<mozilla::dom::Element> mObservesElement; // [OWNER]
+        nsRefPtr<mozilla::dom::Element> mObservesElement; // [OWNER]
         PRBool mResolved;
 
     public:
         BroadcasterHookup(nsXULDocument* aDocument,
                           mozilla::dom::Element* aObservesElement)
             : mDocument(aDocument),
               mObservesElement(aObservesElement),
               mResolved(PR_FALSE)
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -127,17 +127,17 @@ nsXULPDGlobalObject_finalize(JSContext *
     }
 
     // The addref was part of JSObject construction
     NS_RELEASE(nativeThis);
 }
 
 
 JSBool
-nsXULPDGlobalObject_resolve(JSContext *cx, JSObject *obj, jsval id)
+nsXULPDGlobalObject_resolve(JSContext *cx, JSObject *obj, jsid id)
 {
     JSBool did_resolve = JS_FALSE;
 
     return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
 JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
@@ -679,17 +679,17 @@ nsXULPDGlobalObject::SetScriptContext(PR
 
   if (!aScriptContext)
     NS_WARNING("Possibly early removal of script object, see bug #41608");
   else {
     // should probably assert the context is clean???
     aScriptContext->WillInitializeContext();
     // NOTE: We init this context with a NULL global - this is subtly
     // different than nsGlobalWindow which passes 'this'
-    rv = aScriptContext->InitContext(nsnull);
+    rv = aScriptContext->InitContext();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   NS_ASSERTION(!aScriptContext || !mScriptContexts[lang_ndx],
                "Bad call to SetContext()!");
 
   void *script_glob = nsnull;
 
--- a/content/xul/templates/src/Makefile.in
+++ b/content/xul/templates/src/Makefile.in
@@ -77,12 +77,13 @@ CPPSRCS		= \
 		$(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES	= -I$(srcdir)/../../../base/src \
-		   -I$(srcdir)/../../content/src \
-		   $(NULL)
+		  -I$(srcdir)/../../content/src \
+		  -I$(srcdir)/../../../../layout/xul/base/src/tree/src \
+		  $(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/xul/templates/src/nsXULContentUtils.cpp
+++ b/content/xul/templates/src/nsXULContentUtils.cpp
@@ -85,16 +85,17 @@
 #include "nsIDateTimeFormat.h"
 #include "nsDateTimeFormatCID.h"
 #include "nsIScriptableDateFormat.h"
 #include "nsICollation.h"
 #include "nsCollationCID.h"
 #include "nsILocale.h"
 #include "nsILocaleService.h"
 #include "nsIConsoleService.h"
+#include "nsEscape.h"
 
 static NS_DEFINE_CID(kRDFServiceCID,        NS_RDFSERVICE_CID);
 
 //------------------------------------------------------------------------
 
 nsIRDFService* nsXULContentUtils::gRDF;
 nsIDateTimeFormat* nsXULContentUtils::gFormat;
 nsICollation *nsXULContentUtils::gCollation;
@@ -330,16 +331,30 @@ nsXULContentUtils::MakeElementURI(nsIDoc
     nsIURI *docURL = aDocument->GetDocumentURI();
     NS_ENSURE_TRUE(docURL, NS_ERROR_UNEXPECTED);
 
     nsCOMPtr<nsIURI> docURIClone;
     nsresult rv = docURL->Clone(getter_AddRefs(docURIClone));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIURL> mutableURL(do_QueryInterface(docURIClone));
+    if (!mutableURL) {
+        nsCString uri;
+        rv = docURL->GetSpec(aURI);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        nsCAutoString ref;
+        NS_EscapeURL(NS_ConvertUTF16toUTF8(aElementID), esc_FilePath | esc_AlwaysCopy, ref);
+
+        aURI.Append('#');
+        aURI.Append(ref);
+
+        return NS_OK;
+    }
+
     NS_ENSURE_TRUE(mutableURL, NS_ERROR_NOT_AVAILABLE);
 
     rv = mutableURL->SetRef(NS_ConvertUTF16toUTF8(aElementID));
     NS_ENSURE_SUCCESS(rv, rv);
 
     return mutableURL->GetSpec(aURI);
 }
 
@@ -376,16 +391,29 @@ nsXULContentUtils::MakeElementID(nsIDocu
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIURL> url = do_QueryInterface(uri);
     if (url) {
         nsCAutoString ref;
         url->GetRef(ref);
         CopyUTF8toUTF16(ref, aElementID);
     } else {
+        const char* start = aURI.BeginReading();
+        const char* end = aURI.EndReading();
+        const char* chr = end;
+
+        while (--chr >= start) {
+            if (*chr == '#') {
+                nsDependentCSubstring ref = Substring(chr + 1, end);
+                nsCAutoString unescaped;
+                CopyUTF8toUTF16(NS_UnescapeURL(ref, esc_FilePath, unescaped), aElementID);
+                return NS_OK;
+            }
+        }
+
         aElementID.Truncate();
     }
 
     return NS_OK;
 }
 
 nsresult
 nsXULContentUtils::GetResource(PRInt32 aNameSpaceID, nsIAtom* aAttribute, nsIRDFResource** aResult)
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -59,17 +59,16 @@
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsFixedSizeAllocator.h"
 #include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMXMLDocument.h"
-#include "nsIPrivateDOMImplementation.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocument.h"
 #include "nsBindingManager.h"
 #include "nsIDOMNodeList.h"
 #include "nsINameSpaceManager.h"
 #include "nsIObserverService.h"
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFInferDataSource.h"
--- a/content/xul/templates/src/nsXULTreeBuilder.cpp
+++ b/content/xul/templates/src/nsXULTreeBuilder.cpp
@@ -60,16 +60,17 @@
 #include "nsXULContentUtils.h"
 #include "nsXULTemplateBuilder.h"
 #include "nsIXULSortService.h"
 #include "nsTArray.h"
 #include "nsUnicharUtils.h"
 #include "nsINameSpaceManager.h"
 #include "nsIDOMClassInfo.h"
 #include "nsWhitespaceTokenizer.h"
+#include "nsTreeContentView.h"
 
 // For security check
 #include "nsIDocument.h"
 
 /**
  * A XUL template builder that serves as an tree view, allowing
  * (pretty much) arbitrary RDF to be presented in an tree.
  */
@@ -462,16 +463,19 @@ nsXULTreeBuilder::GetSelection(nsITreeSe
 {
     NS_IF_ADDREF(*aSelection = mSelection.get());
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeBuilder::SetSelection(nsITreeSelection* aSelection)
 {
+    NS_ENSURE_TRUE(!aSelection ||
+                   nsTreeContentView::CanTrustTreeSelection(aSelection),
+                   NS_ERROR_DOM_SECURITY_ERR);
     mSelection = aSelection;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeBuilder::GetRowProperties(PRInt32 aIndex, nsISupportsArray* aProperties)
 {
     NS_ENSURE_ARG_POINTER(aProperties);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -372,16 +372,17 @@
 #ifdef MOZ_SMIL
 #include "nsIDOMSVGAnimateElement.h"
 #include "nsIDOMSVGAnimateTransformElement.h"
 #include "nsIDOMSVGAnimateMotionElement.h"
 #include "nsIDOMSVGMpathElement.h"
 #include "nsIDOMSVGSetElement.h"
 #include "nsIDOMSVGAnimationElement.h"
 #include "nsIDOMElementTimeControl.h"
+#include "nsIDOMTimeEvent.h"
 #endif // MOZ_SMIL
 #include "nsIDOMSVGAnimTransformList.h"
 #include "nsIDOMSVGCircleElement.h"
 #include "nsIDOMSVGClipPathElement.h"
 #include "nsIDOMSVGDefsElement.h"
 #include "nsIDOMSVGDescElement.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIDOMSVGElement.h"
@@ -998,16 +999,18 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(SVGAnimateTransformElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGAnimateMotionElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGMpathElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGSetElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(TimeEvent, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif // MOZ_SMIL
   NS_DEFINE_CLASSINFO_DATA(SVGCircleElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGClipPathElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGDefsElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGDescElement, nsElementSH,
@@ -1492,101 +1495,101 @@ static const nsConstructorFuncMapData kC
 
 nsIXPConnect *nsDOMClassInfo::sXPConnect = nsnull;
 nsIScriptSecurityManager *nsDOMClassInfo::sSecMan = nsnull;
 PRBool nsDOMClassInfo::sIsInitialized = PR_FALSE;
 PRBool nsDOMClassInfo::sDisableDocumentAllSupport = PR_FALSE;
 PRBool nsDOMClassInfo::sDisableGlobalScopePollutionSupport = PR_FALSE;
 
 
-jsval nsDOMClassInfo::sTop_id             = JSVAL_VOID;
-jsval nsDOMClassInfo::sParent_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sScrollbars_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sLocation_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sConstructor_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::s_content_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sContent_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sMenubar_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sToolbar_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sLocationbar_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sPersonalbar_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sStatusbar_id       = JSVAL_VOID;
-jsval nsDOMClassInfo::sDialogArguments_id = JSVAL_VOID;
-jsval nsDOMClassInfo::sControllers_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sLength_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sInnerHeight_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sInnerWidth_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOuterHeight_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sOuterWidth_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sScreenX_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sScreenY_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sStatus_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sName_id            = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnmousedown_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnmouseup_id       = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnclick_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndblclick_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOncontextmenu_id   = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnmouseover_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnmouseout_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnkeydown_id       = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnkeyup_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnkeypress_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnmousemove_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnfocus_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnblur_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnsubmit_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnreset_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnchange_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnselect_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnload_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnpopstate_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnbeforeunload_id  = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnunload_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnhashchange_id    = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnreadystatechange_id = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnpageshow_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnpagehide_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnabort_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnerror_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnpaint_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnresize_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnscroll_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndrag_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndragend_id       = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndragenter_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndragleave_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndragover_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndragstart_id     = JSVAL_VOID;
-jsval nsDOMClassInfo::sOndrop_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sScrollX_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sScrollY_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sScrollMaxX_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sScrollMaxY_id      = JSVAL_VOID;
-jsval nsDOMClassInfo::sOpen_id            = JSVAL_VOID;
-jsval nsDOMClassInfo::sItem_id            = JSVAL_VOID;
-jsval nsDOMClassInfo::sNamedItem_id       = JSVAL_VOID;
-jsval nsDOMClassInfo::sEnumerate_id       = JSVAL_VOID;
-jsval nsDOMClassInfo::sNavigator_id       = JSVAL_VOID;
-jsval nsDOMClassInfo::sDocument_id        = JSVAL_VOID;
-jsval nsDOMClassInfo::sWindow_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sFrames_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sSelf_id            = JSVAL_VOID;
-jsval nsDOMClassInfo::sOpener_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sAll_id             = JSVAL_VOID;
-jsval nsDOMClassInfo::sTags_id            = JSVAL_VOID;
-jsval nsDOMClassInfo::sAddEventListener_id= JSVAL_VOID;
-jsval nsDOMClassInfo::sBaseURIObject_id   = JSVAL_VOID;
-jsval nsDOMClassInfo::sNodePrincipal_id   = JSVAL_VOID;
-jsval nsDOMClassInfo::sDocumentURIObject_id=JSVAL_VOID;
-jsval nsDOMClassInfo::sOncopy_id          = JSVAL_VOID;
-jsval nsDOMClassInfo::sOncut_id           = JSVAL_VOID;
-jsval nsDOMClassInfo::sOnpaste_id         = JSVAL_VOID;
-jsval nsDOMClassInfo::sJava_id            = JSVAL_VOID;
-jsval nsDOMClassInfo::sPackages_id        = JSVAL_VOID;
+jsid nsDOMClassInfo::sTop_id             = JSID_VOID;
+jsid nsDOMClassInfo::sParent_id          = JSID_VOID;
+jsid nsDOMClassInfo::sScrollbars_id      = JSID_VOID;
+jsid nsDOMClassInfo::sLocation_id        = JSID_VOID;
+jsid nsDOMClassInfo::sConstructor_id     = JSID_VOID;
+jsid nsDOMClassInfo::s_content_id        = JSID_VOID;
+jsid nsDOMClassInfo::sContent_id         = JSID_VOID;
+jsid nsDOMClassInfo::sMenubar_id         = JSID_VOID;
+jsid nsDOMClassInfo::sToolbar_id         = JSID_VOID;
+jsid nsDOMClassInfo::sLocationbar_id     = JSID_VOID;
+jsid nsDOMClassInfo::sPersonalbar_id     = JSID_VOID;
+jsid nsDOMClassInfo::sStatusbar_id       = JSID_VOID;
+jsid nsDOMClassInfo::sDialogArguments_id = JSID_VOID;
+jsid nsDOMClassInfo::sControllers_id     = JSID_VOID;
+jsid nsDOMClassInfo::sLength_id          = JSID_VOID;
+jsid nsDOMClassInfo::sInnerHeight_id     = JSID_VOID;
+jsid nsDOMClassInfo::sInnerWidth_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOuterHeight_id     = JSID_VOID;
+jsid nsDOMClassInfo::sOuterWidth_id      = JSID_VOID;
+jsid nsDOMClassInfo::sScreenX_id         = JSID_VOID;
+jsid nsDOMClassInfo::sScreenY_id         = JSID_VOID;
+jsid nsDOMClassInfo::sStatus_id          = JSID_VOID;
+jsid nsDOMClassInfo::sName_id            = JSID_VOID;
+jsid nsDOMClassInfo::sOnmousedown_id     = JSID_VOID;
+jsid nsDOMClassInfo::sOnmouseup_id       = JSID_VOID;
+jsid nsDOMClassInfo::sOnclick_id         = JSID_VOID;
+jsid nsDOMClassInfo::sOndblclick_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOncontextmenu_id   = JSID_VOID;
+jsid nsDOMClassInfo::sOnmouseover_id     = JSID_VOID;
+jsid nsDOMClassInfo::sOnmouseout_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOnkeydown_id       = JSID_VOID;
+jsid nsDOMClassInfo::sOnkeyup_id         = JSID_VOID;
+jsid nsDOMClassInfo::sOnkeypress_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOnmousemove_id     = JSID_VOID;
+jsid nsDOMClassInfo::sOnfocus_id         = JSID_VOID;
+jsid nsDOMClassInfo::sOnblur_id          = JSID_VOID;
+jsid nsDOMClassInfo::sOnsubmit_id        = JSID_VOID;
+jsid nsDOMClassInfo::sOnreset_id         = JSID_VOID;
+jsid nsDOMClassInfo::sOnchange_id        = JSID_VOID;
+jsid nsDOMClassInfo::sOnselect_id        = JSID_VOID;
+jsid nsDOMClassInfo::sOnload_id          = JSID_VOID;
+jsid nsDOMClassInfo::sOnpopstate_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOnbeforeunload_id  = JSID_VOID;
+jsid nsDOMClassInfo::sOnunload_id        = JSID_VOID;
+jsid nsDOMClassInfo::sOnhashchange_id    = JSID_VOID;
+jsid nsDOMClassInfo::sOnreadystatechange_id = JSID_VOID;
+jsid nsDOMClassInfo::sOnpageshow_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOnpagehide_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOnabort_id         = JSID_VOID;
+jsid nsDOMClassInfo::sOnerror_id         = JSID_VOID;
+jsid nsDOMClassInfo::sOnpaint_id         = JSID_VOID;
+jsid nsDOMClassInfo::sOnresize_id        = JSID_VOID;
+jsid nsDOMClassInfo::sOnscroll_id        = JSID_VOID;
+jsid nsDOMClassInfo::sOndrag_id          = JSID_VOID;
+jsid nsDOMClassInfo::sOndragend_id       = JSID_VOID;
+jsid nsDOMClassInfo::sOndragenter_id     = JSID_VOID;
+jsid nsDOMClassInfo::sOndragleave_id     = JSID_VOID;
+jsid nsDOMClassInfo::sOndragover_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOndragstart_id     = JSID_VOID;
+jsid nsDOMClassInfo::sOndrop_id          = JSID_VOID;
+jsid nsDOMClassInfo::sScrollX_id         = JSID_VOID;
+jsid nsDOMClassInfo::sScrollY_id         = JSID_VOID;
+jsid nsDOMClassInfo::sScrollMaxX_id      = JSID_VOID;
+jsid nsDOMClassInfo::sScrollMaxY_id      = JSID_VOID;
+jsid nsDOMClassInfo::sOpen_id            = JSID_VOID;
+jsid nsDOMClassInfo::sItem_id            = JSID_VOID;
+jsid nsDOMClassInfo::sNamedItem_id       = JSID_VOID;
+jsid nsDOMClassInfo::sEnumerate_id       = JSID_VOID;
+jsid nsDOMClassInfo::sNavigator_id       = JSID_VOID;
+jsid nsDOMClassInfo::sDocument_id        = JSID_VOID;
+jsid nsDOMClassInfo::sWindow_id          = JSID_VOID;
+jsid nsDOMClassInfo::sFrames_id          = JSID_VOID;
+jsid nsDOMClassInfo::sSelf_id            = JSID_VOID;
+jsid nsDOMClassInfo::sOpener_id          = JSID_VOID;
+jsid nsDOMClassInfo::sAll_id             = JSID_VOID;
+jsid nsDOMClassInfo::sTags_id            = JSID_VOID;
+jsid nsDOMClassInfo::sAddEventListener_id= JSID_VOID;
+jsid nsDOMClassInfo::sBaseURIObject_id   = JSID_VOID;
+jsid nsDOMClassInfo::sNodePrincipal_id   = JSID_VOID;
+jsid nsDOMClassInfo::sDocumentURIObject_id=JSID_VOID;
+jsid nsDOMClassInfo::sOncopy_id          = JSID_VOID;
+jsid nsDOMClassInfo::sOncut_id           = JSID_VOID;
+jsid nsDOMClassInfo::sOnpaste_id         = JSID_VOID;
+jsid nsDOMClassInfo::sJava_id            = JSID_VOID;
+jsid nsDOMClassInfo::sPackages_id        = JSID_VOID;
 
 static const JSClass *sObjectClass = nsnull;
 JSPropertyOp nsDOMClassInfo::sXPCNativeWrapperGetPropertyOp = nsnull;
 JSPropertyOp nsDOMClassInfo::sXrayWrapperPropertyHolderGetPropertyOp = nsnull;
 
 /**
  * Set our JSClass pointer for the Object class
  */
@@ -1596,17 +1599,17 @@ FindObjectClass(JSObject* aGlobalObject)
   NS_ASSERTION(!sObjectClass,
                "Double set of sObjectClass");
   JSObject *obj, *proto = aGlobalObject;
   do {
     obj = proto;
     proto = obj->getProto();
   } while (proto);
 
-  sObjectClass = obj->getClass();
+  sObjectClass = obj->getJSClass();
 }
 
 static void
 PrintWarningOnConsole(JSContext *cx, const char *stringBundleProperty)
 {
   nsCOMPtr<nsIStringBundleService> stringService =
     mozilla::services::GetStringBundleService();
   if (!stringService) {
@@ -1664,132 +1667,131 @@ PrintWarningOnConsole(JSContext *cx, con
                                   0, // column for error is not available
                                   nsIScriptError::warningFlag,
                                   "DOM:HTML");
   if (NS_SUCCEEDED(rv)){
     consoleService->LogMessage(scriptError);
   }
 }
 
-static jsval
-GetInternedJSVal(JSContext *cx, const char *str)
-{
-  JSString *s = ::JS_InternString(cx, str);
-
-  if (!s) {
-    return JSVAL_VOID;
-  }
-
-  return STRING_TO_JSVAL(s);
+static inline JSString *
+IdToString(JSContext *cx, jsid id)
+{
+  if (JSID_IS_STRING(id))
+    return JSID_TO_STRING(id);
+  jsval idval;
+  if (!::JS_IdToValue(cx, id, &idval))
+    return nsnull;
+  return JS_ValueToString(cx, idval);
 }
 
 // static
 
 nsISupports *
 nsDOMClassInfo::GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj)
 {
   return wrapper ? wrapper->Native() : static_cast<nsISupports*>(obj->getPrivate());
 }
 
 nsresult
 nsDOMClassInfo::DefineStaticJSVals(JSContext *cx)
 {
-#define SET_JSVAL_TO_STRING(_val, _cx, _str)                                  \
-  _val = GetInternedJSVal(_cx, _str);                                         \
-  if (!JSVAL_IS_STRING(_val)) {                                               \
-    return NS_ERROR_OUT_OF_MEMORY;                                            \
-  }
+#define SET_JSID_TO_STRING(_id, _cx, _str)                                    \
+  if (JSString *str = ::JS_InternString(_cx, _str))                           \
+      _id = INTERNED_STRING_TO_JSID(str);                                     \
+  else                                                                        \
+      return NS_ERROR_OUT_OF_MEMORY;
 
   JSAutoRequest ar(cx);
 
-  SET_JSVAL_TO_STRING(sTop_id,             cx, "top");
-  SET_JSVAL_TO_STRING(sParent_id,          cx, "parent");
-  SET_JSVAL_TO_STRING(sScrollbars_id,      cx, "scrollbars");
-  SET_JSVAL_TO_STRING(sLocation_id,        cx, "location");
-  SET_JSVAL_TO_STRING(sConstructor_id,     cx, "constructor");
-  SET_JSVAL_TO_STRING(s_content_id,        cx, "_content");
-  SET_JSVAL_TO_STRING(sContent_id,         cx, "content");
-  SET_JSVAL_TO_STRING(sMenubar_id,         cx, "menubar");
-  SET_JSVAL_TO_STRING(sToolbar_id,         cx, "toolbar");
-  SET_JSVAL_TO_STRING(sLocationbar_id,     cx, "locationbar");
-  SET_JSVAL_TO_STRING(sPersonalbar_id,     cx, "personalbar");
-  SET_JSVAL_TO_STRING(sStatusbar_id,       cx, "statusbar");
-  SET_JSVAL_TO_STRING(sDialogArguments_id, cx, "dialogArguments");
-  SET_JSVAL_TO_STRING(sControllers_id,     cx, "controllers");
-  SET_JSVAL_TO_STRING(sLength_id,          cx, "length");
-  SET_JSVAL_TO_STRING(sInnerHeight_id,     cx, "innerHeight");
-  SET_JSVAL_TO_STRING(sInnerWidth_id,      cx, "innerWidth");
-  SET_JSVAL_TO_STRING(sOuterHeight_id,     cx, "outerHeight");
-  SET_JSVAL_TO_STRING(sOuterWidth_id,      cx, "outerWidth");
-  SET_JSVAL_TO_STRING(sScreenX_id,         cx, "screenX");
-  SET_JSVAL_TO_STRING(sScreenY_id,         cx, "screenY");
-  SET_JSVAL_TO_STRING(sStatus_id,          cx, "status");
-  SET_JSVAL_TO_STRING(sName_id,            cx, "name");
-  SET_JSVAL_TO_STRING(sOnmousedown_id,     cx, "onmousedown");
-  SET_JSVAL_TO_STRING(sOnmouseup_id,       cx, "onmouseup");
-  SET_JSVAL_TO_STRING(sOnclick_id,         cx, "onclick");
-  SET_JSVAL_TO_STRING(sOndblclick_id,      cx, "ondblclick");
-  SET_JSVAL_TO_STRING(sOncontextmenu_id,   cx, "oncontextmenu");
-  SET_JSVAL_TO_STRING(sOnmouseover_id,     cx, "onmouseover");
-  SET_JSVAL_TO_STRING(sOnmouseout_id,      cx, "onmouseout");
-  SET_JSVAL_TO_STRING(sOnkeydown_id,       cx, "onkeydown");
-  SET_JSVAL_TO_STRING(sOnkeyup_id,         cx, "onkeyup");
-  SET_JSVAL_TO_STRING(sOnkeypress_id,      cx, "onkeypress");
-  SET_JSVAL_TO_STRING(sOnmousemove_id,     cx, "onmousemove");
-  SET_JSVAL_TO_STRING(sOnfocus_id,         cx, "onfocus");
-  SET_JSVAL_TO_STRING(sOnblur_id,          cx, "onblur");
-  SET_JSVAL_TO_STRING(sOnsubmit_id,        cx, "onsubmit");
-  SET_JSVAL_TO_STRING(sOnreset_id,         cx, "onreset");
-  SET_JSVAL_TO_STRING(sOnchange_id,        cx, "onchange");
-  SET_JSVAL_TO_STRING(sOnselect_id,        cx, "onselect");
-  SET_JSVAL_TO_STRING(sOnload_id,          cx, "onload");
-  SET_JSVAL_TO_STRING(sOnpopstate_id,      cx, "onpopstate");
-  SET_JSVAL_TO_STRING(sOnbeforeunload_id,  cx, "onbeforeunload");
-  SET_JSVAL_TO_STRING(sOnunload_id,        cx, "onunload");
-  SET_JSVAL_TO_STRING(sOnhashchange_id,    cx, "onhashchange");
-  SET_JSVAL_TO_STRING(sOnreadystatechange_id, cx, "onreadystatechange");
-  SET_JSVAL_TO_STRING(sOnpageshow_id,      cx, "onpageshow");
-  SET_JSVAL_TO_STRING(sOnpagehide_id,      cx, "onpagehide");
-  SET_JSVAL_TO_STRING(sOnabort_id,         cx, "onabort");
-  SET_JSVAL_TO_STRING(sOnerror_id,         cx, "onerror");
-  SET_JSVAL_TO_STRING(sOnpaint_id,         cx, "onpaint");
-  SET_JSVAL_TO_STRING(sOnresize_id,        cx, "onresize");
-  SET_JSVAL_TO_STRING(sOnscroll_id,        cx, "onscroll");
-  SET_JSVAL_TO_STRING(sOndrag_id,          cx, "ondrag");
-  SET_JSVAL_TO_STRING(sOndragend_id,       cx, "ondragend");
-  SET_JSVAL_TO_STRING(sOndragenter_id,     cx, "ondragenter");
-  SET_JSVAL_TO_STRING(sOndragleave_id,     cx, "ondragleave");
-  SET_JSVAL_TO_STRING(sOndragover_id,      cx, "ondragover");
-  SET_JSVAL_TO_STRING(sOndragstart_id,     cx, "ondragstart");
-  SET_JSVAL_TO_STRING(sOndrop_id,          cx, "ondrop");
-  SET_JSVAL_TO_STRING(sScrollX_id,         cx, "scrollX");
-  SET_JSVAL_TO_STRING(sScrollY_id,         cx, "scrollY");
-  SET_JSVAL_TO_STRING(sScrollMaxX_id,      cx, "scrollMaxX");
-  SET_JSVAL_TO_STRING(sScrollMaxY_id,      cx, "scrollMaxY");
-  SET_JSVAL_TO_STRING(sOpen_id,            cx, "open");
-  SET_JSVAL_TO_STRING(sItem_id,            cx, "item");
-  SET_JSVAL_TO_STRING(sNamedItem_id,       cx, "namedItem");
-  SET_JSVAL_TO_STRING(sEnumerate_id,       cx, "enumerateProperties");
-  SET_JSVAL_TO_STRING(sNavigator_id,       cx, "navigator");
-  SET_JSVAL_TO_STRING(sDocument_id,        cx, "document");
-  SET_JSVAL_TO_STRING(sWindow_id,          cx, "window");
-  SET_JSVAL_TO_STRING(sFrames_id,          cx, "frames");
-  SET_JSVAL_TO_STRING(sSelf_id,            cx, "self");
-  SET_JSVAL_TO_STRING(sOpener_id,          cx, "opener");
-  SET_JSVAL_TO_STRING(sAll_id,             cx, "all");
-  SET_JSVAL_TO_STRING(sTags_id,            cx, "tags");
-  SET_JSVAL_TO_STRING(sAddEventListener_id,cx, "addEventListener");
-  SET_JSVAL_TO_STRING(sBaseURIObject_id,   cx, "baseURIObject");
-  SET_JSVAL_TO_STRING(sNodePrincipal_id,   cx, "nodePrincipal");
-  SET_JSVAL_TO_STRING(sDocumentURIObject_id,cx,"documentURIObject");
-  SET_JSVAL_TO_STRING(sOncopy_id,          cx, "oncopy");
-  SET_JSVAL_TO_STRING(sOncut_id,           cx, "oncut");
-  SET_JSVAL_TO_STRING(sOnpaste_id,         cx, "onpaste");
-  SET_JSVAL_TO_STRING(sJava_id,            cx, "java");
-  SET_JSVAL_TO_STRING(sPackages_id,        cx, "Packages");
+  SET_JSID_TO_STRING(sTop_id,             cx, "top");
+  SET_JSID_TO_STRING(sParent_id,          cx, "parent");
+  SET_JSID_TO_STRING(sScrollbars_id,      cx, "scrollbars");
+  SET_JSID_TO_STRING(sLocation_id,        cx, "location");
+  SET_JSID_TO_STRING(sConstructor_id,     cx, "constructor");
+  SET_JSID_TO_STRING(s_content_id,        cx, "_content");
+  SET_JSID_TO_STRING(sContent_id,         cx, "content");
+  SET_JSID_TO_STRING(sMenubar_id,         cx, "menubar");
+  SET_JSID_TO_STRING(sToolbar_id,         cx, "toolbar");
+  SET_JSID_TO_STRING(sLocationbar_id,     cx, "locationbar");
+  SET_JSID_TO_STRING(sPersonalbar_id,     cx, "personalbar");
+  SET_JSID_TO_STRING(sStatusbar_id,       cx, "statusbar");
+  SET_JSID_TO_STRING(sDialogArguments_id, cx, "dialogArguments");
+  SET_JSID_TO_STRING(sControllers_id,     cx, "controllers");
+  SET_JSID_TO_STRING(sLength_id,          cx, "length");
+  SET_JSID_TO_STRING(sInnerHeight_id,     cx, "innerHeight");
+  SET_JSID_TO_STRING(sInnerWidth_id,      cx, "innerWidth");
+  SET_JSID_TO_STRING(sOuterHeight_id,     cx, "outerHeight");
+  SET_JSID_TO_STRING(sOuterWidth_id,      cx, "outerWidth");
+  SET_JSID_TO_STRING(sScreenX_id,         cx, "screenX");
+  SET_JSID_TO_STRING(sScreenY_id,         cx, "screenY");
+  SET_JSID_TO_STRING(sStatus_id,          cx, "status");
+  SET_JSID_TO_STRING(sName_id,            cx, "name");
+  SET_JSID_TO_STRING(sOnmousedown_id,     cx, "onmousedown");
+  SET_JSID_TO_STRING(sOnmouseup_id,       cx, "onmouseup");
+  SET_JSID_TO_STRING(sOnclick_id,         cx, "onclick");
+  SET_JSID_TO_STRING(sOndblclick_id,      cx, "ondblclick");
+  SET_JSID_TO_STRING(sOncontextmenu_id,   cx, "oncontextmenu");
+  SET_JSID_TO_STRING(sOnmouseover_id,     cx, "onmouseover");
+  SET_JSID_TO_STRING(sOnmouseout_id,      cx, "onmouseout");
+  SET_JSID_TO_STRING(sOnkeydown_id,       cx, "onkeydown");
+  SET_JSID_TO_STRING(sOnkeyup_id,         cx, "onkeyup");
+  SET_JSID_TO_STRING(sOnkeypress_id,      cx, "onkeypress");
+  SET_JSID_TO_STRING(sOnmousemove_id,     cx, "onmousemove");
+  SET_JSID_TO_STRING(sOnfocus_id,         cx, "onfocus");
+  SET_JSID_TO_STRING(sOnblur_id,          cx, "onblur");
+  SET_JSID_TO_STRING(sOnsubmit_id,        cx, "onsubmit");
+  SET_JSID_TO_STRING(sOnreset_id,         cx, "onreset");
+  SET_JSID_TO_STRING(sOnchange_id,        cx, "onchange");
+  SET_JSID_TO_STRING(sOnselect_id,        cx, "onselect");
+  SET_JSID_TO_STRING(sOnload_id,          cx, "onload");
+  SET_JSID_TO_STRING(sOnpopstate_id,      cx, "onpopstate");
+  SET_JSID_TO_STRING(sOnbeforeunload_id,  cx, "onbeforeunload");
+  SET_JSID_TO_STRING(sOnunload_id,        cx, "onunload");
+  SET_JSID_TO_STRING(sOnhashchange_id,    cx, "onhashchange");
+  SET_JSID_TO_STRING(sOnreadystatechange_id, cx, "onreadystatechange");
+  SET_JSID_TO_STRING(sOnpageshow_id,      cx, "onpageshow");
+  SET_JSID_TO_STRING(sOnpagehide_id,      cx, "onpagehide");
+  SET_JSID_TO_STRING(sOnabort_id,         cx, "onabort");
+  SET_JSID_TO_STRING(sOnerror_id,         cx, "onerror");
+  SET_JSID_TO_STRING(sOnpaint_id,         cx, "onpaint");
+  SET_JSID_TO_STRING(sOnresize_id,        cx, "onresize");
+  SET_JSID_TO_STRING(sOnscroll_id,        cx, "onscroll");
+  SET_JSID_TO_STRING(sOndrag_id,          cx, "ondrag");
+  SET_JSID_TO_STRING(sOndragend_id,       cx, "ondragend");
+  SET_JSID_TO_STRING(sOndragenter_id,     cx, "ondragenter");
+  SET_JSID_TO_STRING(sOndragleave_id,     cx, "ondragleave");
+  SET_JSID_TO_STRING(sOndragover_id,      cx, "ondragover");
+  SET_JSID_TO_STRING(sOndragstart_id,     cx, "ondragstart");
+  SET_JSID_TO_STRING(sOndrop_id,          cx, "ondrop");
+  SET_JSID_TO_STRING(sScrollX_id,         cx, "scrollX");
+  SET_JSID_TO_STRING(sScrollY_id,         cx, "scrollY");
+  SET_JSID_TO_STRING(sScrollMaxX_id,      cx, "scrollMaxX");
+  SET_JSID_TO_STRING(sScrollMaxY_id,      cx, "scrollMaxY");
+  SET_JSID_TO_STRING(sOpen_id,            cx, "open");
+  SET_JSID_TO_STRING(sItem_id,            cx, "item");
+  SET_JSID_TO_STRING(sNamedItem_id,       cx, "namedItem");
+  SET_JSID_TO_STRING(sEnumerate_id,       cx, "enumerateProperties");
+  SET_JSID_TO_STRING(sNavigator_id,       cx, "navigator");
+  SET_JSID_TO_STRING(sDocument_id,        cx, "document");
+  SET_JSID_TO_STRING(sWindow_id,          cx, "window");
+  SET_JSID_TO_STRING(sFrames_id,          cx, "frames");
+  SET_JSID_TO_STRING(sSelf_id,            cx, "self");
+  SET_JSID_TO_STRING(sOpener_id,          cx, "opener");
+  SET_JSID_TO_STRING(sAll_id,             cx, "all");
+  SET_JSID_TO_STRING(sTags_id,            cx, "tags");
+  SET_JSID_TO_STRING(sAddEventListener_id,cx, "addEventListener");
+  SET_JSID_TO_STRING(sBaseURIObject_id,   cx, "baseURIObject");
+  SET_JSID_TO_STRING(sNodePrincipal_id,   cx, "nodePrincipal");
+  SET_JSID_TO_STRING(sDocumentURIObject_id,cx,"documentURIObject");
+  SET_JSID_TO_STRING(sOncopy_id,          cx, "oncopy");
+  SET_JSID_TO_STRING(sOncut_id,           cx, "oncut");
+  SET_JSID_TO_STRING(sOnpaste_id,         cx, "onpaste");
+  SET_JSID_TO_STRING(sJava_id,            cx, "java");
+  SET_JSID_TO_STRING(sPackages_id,        cx, "Packages");
 
   return NS_OK;
 }
 
 static nsresult
 CreateExceptionFromResult(JSContext *cx, nsresult aResult)
 {
   nsCOMPtr<nsIExceptionService> xs =
@@ -1854,17 +1856,17 @@ nsDOMClassInfo::ObjectIsNativeWrapper(JS
     nsIScriptContext *scx = GetScriptContextFromJSContext(cx);
 
     NS_PRECONDITION(!scx || !scx->IsContextInitialized() ||
                     sXPCNativeWrapperGetPropertyOp,
                     "Must know what the XPCNativeWrapper class GetProperty op is!");
   }
 #endif
 
-  JSPropertyOp op = obj->getClass()->getProperty;
+  JSPropertyOp op = obj->getJSClass()->getProperty;
   return !!op && (op == sXPCNativeWrapperGetPropertyOp ||
                   op == sXrayWrapperPropertyHolderGetPropertyOp);
 }
 
 nsDOMClassInfo::nsDOMClassInfo(nsDOMClassInfoData* aData) : mData(aData)
 {
 }
 
@@ -3036,16 +3038,20 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMpathElement, nsIDOMSVGMpathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(TimeEvent, nsIDOMTimeEvent)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMTimeEvent)
+    DOM_CLASSINFO_EVENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
 #endif // MOZ_SMIL
 
   DOM_CLASSINFO_MAP_BEGIN(SVGCircleElement, nsIDOMSVGCircleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGCircleElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGClipPathElement, nsIDOMSVGClipPathElement)
@@ -4087,34 +4093,35 @@ nsDOMClassInfo::Init()
 
   sIsInitialized = PR_TRUE;
 
   return NS_OK;
 }
 
 // static
 PRInt32
-nsDOMClassInfo::GetArrayIndexFromId(JSContext *cx, jsval id, PRBool *aIsNumber)
-{
-  jsdouble array_index;
-
+nsDOMClassInfo::GetArrayIndexFromId(JSContext *cx, jsid id, PRBool *aIsNumber)
+{
   if (aIsNumber) {
     *aIsNumber = PR_FALSE;
   }
 
-  JSAutoRequest ar(cx);
-
-  if (!::JS_ValueToNumber(cx, id, &array_index)) {
-    return -1;
-  }
-
-  jsint i = -1;
-
-  if (!::JS_DoubleIsInt32(array_index, &i)) {
-    return -1;
+  jsint i;
+  if (JSID_IS_INT(id)) {
+      i = JSID_TO_INT(id);
+  } else {
+      JSAutoRequest ar(cx);
+
+      jsval idval;
+      jsdouble array_index;
+      if (!::JS_IdToValue(cx, id, &idval) ||
+          !::JS_ValueToNumber(cx, idval, &array_index) ||
+          !::JS_DoubleIsInt32(array_index, &i)) {
+        return -1;
+      }
   }
 
   if (aIsNumber) {
     *aIsNumber = PR_TRUE;
   }
 
   return i;
 }
@@ -4266,47 +4273,47 @@ nsDOMClassInfo::PostCreate(nsIXPConnectW
 {
   NS_WARNING("nsDOMClassInfo::PostCreate Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, jsval id, jsval *vp,
+                            JSObject *obj, jsid id, jsval *vp,
                             PRBool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::AddProperty Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, jsval id, jsval *vp,
+                            JSObject *obj, jsid id, jsval *vp,
                             PRBool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::DelProperty Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, jsval id, jsval *vp,
+                            JSObject *obj, jsid id, jsval *vp,
                             PRBool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::GetProperty Don't call me!");
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, jsval id, jsval *vp,
+                            JSObject *obj, jsid id, jsval *vp,
                             PRBool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::SetProperty Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
@@ -4354,32 +4361,30 @@ nsDOMClassInfo::ResolveConstructor(JSCon
   }
 
   if (!JSVAL_IS_PRIMITIVE(val)) {
     // If val is not an (non-null) object there either is no
     // constructor for this class, or someone messed with
     // window.classname, just fall through and let the JS engine
     // return the Object constructor.
 
-    JSString *str = JSVAL_TO_STRING(sConstructor_id);
-    if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                               ::JS_GetStringLength(str), val, nsnull, nsnull,
-                               JSPROP_ENUMERATE)) {
+    if (!::JS_DefinePropertyById(cx, obj, sConstructor_id, val, nsnull, nsnull,
+                                 JSPROP_ENUMERATE)) {
       return NS_ERROR_UNEXPECTED;
     }
 
     *objp = obj;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                           JSObject *obj, jsval id, PRUint32 flags,
+                           JSObject *obj, jsid id, PRUint32 flags,
                            JSObject **objp, PRBool *_retval)
 {
   if (id == sConstructor_id && !(flags & JSRESOLVE_ASSIGNING)) {
     return ResolveConstructor(cx, obj, objp);
   }
 
   return NS_OK;
 }
@@ -4400,17 +4405,17 @@ nsDOMClassInfo::Finalize(nsIXPConnectWra
 {
   NS_WARNING("nsDOMClassInfo::Finalize Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, jsval id, PRUint32 mode,
+                            JSObject *obj, jsid id, PRUint32 mode,
                             jsval *vp, PRBool *_retval)
 {
   PRUint32 mode_type = mode & JSACC_TYPEMASK;
 
   if ((mode_type == JSACC_WATCH ||
        mode_type == JSACC_PROTO ||
        mode_type == JSACC_PARENT) &&
       sSecMan) {
@@ -4455,17 +4460,17 @@ nsDOMClassInfo::Construct(nsIXPConnectWr
 {
   NS_WARNING("nsDOMClassInfo::Construct Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, jsval val, PRBool *bp,
+                            JSObject *obj, const jsval &val, PRBool *bp,
                             PRBool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::HasInstance Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
@@ -4474,17 +4479,17 @@ nsDOMClassInfo::Trace(nsIXPConnectWrappe
 {
   NS_WARNING("nsDOMClassInfo::Trace Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
-                         JSObject * obj, jsval val, PRBool *bp)
+                         JSObject * obj, const jsval &val, PRBool *bp)
 {
   NS_WARNING("nsDOMClassInfo::Equality Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
@@ -4718,99 +4723,99 @@ nsDOMClassInfo::ShutDown()
   if (sClassInfoData[0].u.mConstructorFptr) {
     PRUint32 i;
 
     for (i = 0; i < eDOMClassInfoIDCount; i++) {
       NS_IF_RELEASE(sClassInfoData[i].mCachedClassInfo);
     }
   }
 
-  sTop_id             = JSVAL_VOID;
-  sParent_id          = JSVAL_VOID;
-  sScrollbars_id      = JSVAL_VOID;
-  sLocation_id        = JSVAL_VOID;
-  sConstructor_id     = JSVAL_VOID;
-  s_content_id        = JSVAL_VOID;
-  sContent_id         = JSVAL_VOID;
-  sMenubar_id         = JSVAL_VOID;
-  sToolbar_id         = JSVAL_VOID;
-  sLocationbar_id     = JSVAL_VOID;
-  sPersonalbar_id     = JSVAL_VOID;
-  sStatusbar_id       = JSVAL_VOID;
-  sDialogArguments_id = JSVAL_VOID;
-  sControllers_id     = JSVAL_VOID;
-  sLength_id          = JSVAL_VOID;
-  sInnerHeight_id     = JSVAL_VOID;
-  sInnerWidth_id      = JSVAL_VOID;
-  sOuterHeight_id     = JSVAL_VOID;
-  sOuterWidth_id      = JSVAL_VOID;
-  sScreenX_id         = JSVAL_VOID;
-  sScreenY_id         = JSVAL_VOID;
-  sStatus_id          = JSVAL_VOID;
-  sName_id            = JSVAL_VOID;
-  sOnmousedown_id     = JSVAL_VOID;
-  sOnmouseup_id       = JSVAL_VOID;
-  sOnclick_id         = JSVAL_VOID;
-  sOndblclick_id      = JSVAL_VOID;
-  sOncontextmenu_id   = JSVAL_VOID;
-  sOnmouseover_id     = JSVAL_VOID;
-  sOnmouseout_id      = JSVAL_VOID;
-  sOnkeydown_id       = JSVAL_VOID;
-  sOnkeyup_id         = JSVAL_VOID;
-  sOnkeypress_id      = JSVAL_VOID;
-  sOnmousemove_id     = JSVAL_VOID;
-  sOnfocus_id         = JSVAL_VOID;
-  sOnblur_id          = JSVAL_VOID;
-  sOnsubmit_id        = JSVAL_VOID;
-  sOnreset_id         = JSVAL_VOID;
-  sOnchange_id        = JSVAL_VOID;
-  sOnselect_id        = JSVAL_VOID;
-  sOnload_id          = JSVAL_VOID;
-  sOnbeforeunload_id  = JSVAL_VOID;
-  sOnunload_id        = JSVAL_VOID;
-  sOnhashchange_id    = JSVAL_VOID;
-  sOnreadystatechange_id = JSVAL_VOID;
-  sOnpageshow_id      = JSVAL_VOID;
-  sOnpagehide_id      = JSVAL_VOID;
-  sOnabort_id         = JSVAL_VOID;
-  sOnerror_id         = JSVAL_VOID;
-  sOnpaint_id         = JSVAL_VOID;
-  sOnresize_id        = JSVAL_VOID;
-  sOnscroll_id        = JSVAL_VOID;
-  sOndrag_id          = JSVAL_VOID;
-  sOndragend_id       = JSVAL_VOID;
-  sOndragenter_id     = JSVAL_VOID;
-  sOndragleave_id     = JSVAL_VOID;
-  sOndragover_id      = JSVAL_VOID;
-  sOndragstart_id     = JSVAL_VOID;
-  sOndrop_id          = JSVAL_VOID;
-  sScrollX_id         = JSVAL_VOID;
-  sScrollY_id         = JSVAL_VOID;
-  sScrollMaxX_id      = JSVAL_VOID;
-  sScrollMaxY_id      = JSVAL_VOID;
-  sOpen_id            = JSVAL_VOID;
-  sItem_id            = JSVAL_VOID;
-  sEnumerate_id       = JSVAL_VOID;
-  sNavigator_id       = JSVAL_VOID;
-  sDocument_id        = JSVAL_VOID;
-  sWindow_id          = JSVAL_VOID;
-  sFrames_id          = JSVAL_VOID;
-  sSelf_id            = JSVAL_VOID;
-  sOpener_id          = JSVAL_VOID;
-  sAll_id             = JSVAL_VOID;
-  sTags_id            = JSVAL_VOID;
-  sAddEventListener_id= JSVAL_VOID;
-  sBaseURIObject_id   = JSVAL_VOID;
-  sNodePrincipal_id   = JSVAL_VOID;
-  sDocumentURIObject_id=JSVAL_VOID;
-  sOncopy_id          = JSVAL_VOID;
-  sOncut_id           = JSVAL_VOID;
-  sOnpaste_id         = JSVAL_VOID;
-  sJava_id            = JSVAL_VOID;
-  sPackages_id        = JSVAL_VOID;
+  sTop_id             = JSID_VOID;
+  sParent_id          = JSID_VOID;
+  sScrollbars_id      = JSID_VOID;
+  sLocation_id        = JSID_VOID;
+  sConstructor_id     = JSID_VOID;
+  s_content_id        = JSID_VOID;
+  sContent_id         = JSID_VOID;
+  sMenubar_id         = JSID_VOID;
+  sToolbar_id         = JSID_VOID;
+  sLocationbar_id     = JSID_VOID;
+  sPersonalbar_id     = JSID_VOID;
+  sStatusbar_id       = JSID_VOID;
+  sDialogArguments_id = JSID_VOID;
+  sControllers_id     = JSID_VOID;
+  sLength_id          = JSID_VOID;
+  sInnerHeight_id     = JSID_VOID;
+  sInnerWidth_id      = JSID_VOID;
+  sOuterHeight_id     = JSID_VOID;
+  sOuterWidth_id      = JSID_VOID;
+  sScreenX_id         = JSID_VOID;
+  sScreenY_id         = JSID_VOID;
+  sStatus_id          = JSID_VOID;
+  sName_id            = JSID_VOID;
+  sOnmousedown_id     = JSID_VOID;
+  sOnmouseup_id       = JSID_VOID;
+  sOnclick_id         = JSID_VOID;
+  sOndblclick_id      = JSID_VOID;
+  sOncontextmenu_id   = JSID_VOID;
+  sOnmouseover_id     = JSID_VOID;
+  sOnmouseout_id      = JSID_VOID;
+  sOnkeydown_id       = JSID_VOID;
+  sOnkeyup_id         = JSID_VOID;
+  sOnkeypress_id      = JSID_VOID;
+  sOnmousemove_id     = JSID_VOID;
+  sOnfocus_id         = JSID_VOID;
+  sOnblur_id          = JSID_VOID;
+  sOnsubmit_id        = JSID_VOID;
+  sOnreset_id         = JSID_VOID;
+  sOnchange_id        = JSID_VOID;
+  sOnselect_id        = JSID_VOID;
+  sOnload_id          = JSID_VOID;
+  sOnbeforeunload_id  = JSID_VOID;
+  sOnunload_id        = JSID_VOID;
+  sOnhashchange_id    = JSID_VOID;
+  sOnreadystatechange_id = JSID_VOID;
+  sOnpageshow_id      = JSID_VOID;
+  sOnpagehide_id      = JSID_VOID;
+  sOnabort_id         = JSID_VOID;
+  sOnerror_id         = JSID_VOID;
+  sOnpaint_id         = JSID_VOID;
+  sOnresize_id        = JSID_VOID;
+  sOnscroll_id        = JSID_VOID;
+  sOndrag_id          = JSID_VOID;
+  sOndragend_id       = JSID_VOID;
+  sOndragenter_id     = JSID_VOID;
+  sOndragleave_id     = JSID_VOID;
+  sOndragover_id      = JSID_VOID;
+  sOndragstart_id     = JSID_VOID;
+  sOndrop_id          = JSID_VOID;
+  sScrollX_id         = JSID_VOID;
+  sScrollY_id         = JSID_VOID;
+  sScrollMaxX_id      = JSID_VOID;
+  sScrollMaxY_id      = JSID_VOID;
+  sOpen_id            = JSID_VOID;
+  sItem_id            = JSID_VOID;
+  sEnumerate_id       = JSID_VOID;
+  sNavigator_id       = JSID_VOID;
+  sDocument_id        = JSID_VOID;
+  sWindow_id          = JSID_VOID;
+  sFrames_id          = JSID_VOID;
+  sSelf_id            = JSID_VOID;
+  sOpener_id          = JSID_VOID;
+  sAll_id             = JSID_VOID;
+  sTags_id            = JSID_VOID;
+  sAddEventListener_id= JSID_VOID;
+  sBaseURIObject_id   = JSID_VOID;
+  sNodePrincipal_id   = JSID_VOID;
+  sDocumentURIObject_id=JSID_VOID;
+  sOncopy_id          = JSID_VOID;
+  sOncut_id           = JSID_VOID;
+  sOnpaste_id         = JSID_VOID;
+  sJava_id            = JSID_VOID;
+  sPackages_id        = JSID_VOID;
 
   NS_IF_RELEASE(sXPConnect);
   NS_IF_RELEASE(sSecMan);
   sIsInitialized = PR_FALSE;
 }
 
 // Window helper
 
@@ -4864,17 +4869,17 @@ static JSClass sGlobalScopePolluterClass
   (JSResolveOp)nsWindowSH::GlobalScopePolluterNewResolve, JS_ConvertStub,
   nsHTMLDocumentSH::ReleaseDocument
 };
 
 
 // static
 JSBool
 nsWindowSH::GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
-                                           jsval id, jsval *vp)
+                                           jsid id, jsval *vp)
 {
   // Someone is accessing a element by referencing its name/id in the
   // global scope, do a security check to make sure that's ok.
 
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
                                  nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
@@ -4890,17 +4895,17 @@ nsWindowSH::GlobalScopePolluterGetProper
   // catch and fix these mistakes.
   PrintWarningOnConsole(cx, "GlobalScopeElementReference");
 
   return JS_TRUE;
 }
 
 // static
 JSBool
-nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsval id,
+nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id,
                                    jsval *vp)
 {
   // Someone is accessing a element by referencing its name/id in the
   // global scope, do a security check to make sure that's ok.
 
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
@@ -4916,22 +4921,22 @@ GetDocument(JSContext *cx, JSObject *obj
 {
   return static_cast<nsHTMLDocument*>(
     static_cast<nsIHTMLDocument*>(::JS_GetPrivate(cx, obj)));
 }
 
 // static
 JSBool
 nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
-                                          jsval id, uintN flags,
+                                          jsid id, uintN flags,
                                           JSObject **objp)
 {
   if (flags & (JSRESOLVE_ASSIGNING | JSRESOLVE_DECLARING |
                JSRESOLVE_CLASSNAME | JSRESOLVE_QUALIFIED) ||
-      !JSVAL_IS_STRING(id)) {
+      !JSID_IS_STRING(id)) {
     // Nothing to do here if we're either assigning or declaring,
     // resolving a class name, doing a qualified resolve, or
     // resolving a number.
 
     return JS_TRUE;
   }
 
   nsHTMLDocument *document = GetDocument(cx, obj);
@@ -4940,21 +4945,20 @@ nsWindowSH::GlobalScopePolluterNewResolv
       document->GetCompatibilityMode() != eCompatibility_NavQuirks) {
     // If we don't have a document, or if the document is not in
     // quirks mode, return early.
 
     return JS_TRUE;
   }
 
   JSObject *proto = ::JS_GetPrototype(cx, obj);
-  JSString *jsstr = JSVAL_TO_STRING(id);
+  JSString *jsstr = JSID_TO_STRING(id);
   JSBool hasProp;
 
-  if (!proto || !::JS_HasUCProperty(cx, proto, ::JS_GetStringChars(jsstr),
-                                    ::JS_GetStringLength(jsstr), &hasProp) ||
+  if (!proto || !::JS_HasPropertyById(cx, proto, id, &hasProp) ||
       hasProp) {
     // No prototype, or the property exists on the prototype. Do
     // nothing.
 
     return JS_TRUE;
   }
 
   nsDependentJSString str(jsstr);
@@ -4972,19 +4976,17 @@ nsWindowSH::GlobalScopePolluterNewResolv
 
   if (result) {
     jsval v;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     nsresult rv = WrapNative(cx, obj, result, cache, PR_TRUE, &v,
                              getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, JS_FALSE);
 
-    if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(jsstr),
-                               ::JS_GetStringLength(jsstr), v, nsnull, nsnull,
-                               0)) {
+    if (!::JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull, 0)) {
       nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED);
 
       return JS_FALSE;
     }
 
     *objp = obj;
   }
 
@@ -5068,33 +5070,33 @@ nsWindowSH::InstallGlobalScopePolluter(J
   // invalidation).
   NS_ADDREF(doc);
 
   return NS_OK;
 }
 
 static
 already_AddRefed<nsIDOMWindow>
-GetChildFrame(nsGlobalWindow *win, jsval id)
+GetChildFrame(nsGlobalWindow *win, jsid id)
 {
   nsCOMPtr<nsIDOMWindowCollection> frames;
   win->GetFrames(getter_AddRefs(frames));
 
   nsIDOMWindow *frame = nsnull;
 
   if (frames) {
-    frames->Item(JSVAL_TO_INT(id), &frame);
+    frames->Item(JSID_TO_INT(id), &frame);
   }
 
   return frame;
 }
 
 NS_IMETHODIMP
 nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                        JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
+                        JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
 {
   nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
 
   JSAutoRequest ar(cx);
 
 #ifdef DEBUG_SH_FORWARDING
   {
     JSString *jsstr = ::JS_ValueToString(cx, id);
@@ -5124,38 +5126,35 @@ nsWindowSH::GetProperty(nsIXPConnectWrap
 
     JSObject *innerObj;
     if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
 #ifdef DEBUG_SH_FORWARDING
       printf(" --- Forwarding get to inner window %p\n", (void *)innerWin);
 #endif
 
       // Forward the get to the inner object
-      if (JSVAL_IS_STRING(id)) {
-        JSString *str = JSVAL_TO_STRING(id);
-
-        *_retval = ::JS_GetUCProperty(cx, innerObj, ::JS_GetStringChars(str),
-                                      ::JS_GetStringLength(str), vp);
-      } else if (JSVAL_IS_INT(id)) {
-        *_retval = ::JS_GetElement(cx, innerObj, JSVAL_TO_INT(id), vp);
+      if (JSID_IS_STRING(id)) {
+        *_retval = ::JS_GetPropertyById(cx, innerObj, id, vp);
+      } else if (JSID_IS_INT(id)) {
+        *_retval = ::JS_GetElement(cx, innerObj, JSID_TO_INT(id), vp);
       } else {
         NS_ERROR("Write me!");
 
         return NS_ERROR_NOT_IMPLEMENTED;
       }
 
       return NS_OK;
     }
   }
 
   // The order in which things are done in this method are a bit
   // whacky, that's because this method is *extremely* performace
   // critical. Don't touch this unless you know what you're doing.
 
-  if (JSVAL_IS_INT(id)) {
+  if (JSID_IS_INT(id)) {
     // If we're accessing a numeric property we'll treat that as if
     // window.frames[n] is accessed (since window.frames === window),
     // if window.frames[n] is a child frame, wrap the frame and return
     // it without doing a security check.
 
     nsCOMPtr<nsIDOMWindow> frame = GetChildFrame(win, id);
     nsresult rv = NS_OK;
 
@@ -5181,17 +5180,17 @@ nsWindowSH::GetProperty(nsIXPConnectWrap
         rv = sXPConnect->GetXOWForObject(cx, scopeobj, JSVAL_TO_OBJECT(*vp),
                                          vp);
       }
     }
 
     return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
   }
 
-  if (JSVAL_IS_STRING(id) && !JSVAL_IS_PRIMITIVE(*vp) &&
+  if (JSID_IS_STRING(id) && !JSVAL_IS_PRIMITIVE(*vp) &&
       ::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION) {
     // A named property accessed which could have been resolved to a
     // child frame in nsWindowSH::NewResolve() (*vp will tell us if
     // that's the case). If *vp is a window object (i.e. a child
     // frame), return without doing a security check.
     //
     // Calling GetWrappedNativeOfJSObject() is not all that cheap, so
     // only do that if the JSClass name is one that is likely to be a
@@ -5223,17 +5222,17 @@ nsWindowSH::GetProperty(nsIXPConnectWrap
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                        JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
+                        JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
 {
   nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
 
 #ifdef DEBUG_SH_FORWARDING
   {
     nsDependentJSString str(::JS_ValueToString(cx, id));
 
     if (win->IsInnerWindow()) {
@@ -5258,23 +5257,20 @@ nsWindowSH::SetProperty(nsIXPConnectWrap
 
     JSObject *innerObj;
     if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
 #ifdef DEBUG_SH_FORWARDING
       printf(" --- Forwarding set to inner window %p\n", (void *)innerWin);
 #endif
 
       // Forward the set to the inner object
-      if (JSVAL_IS_STRING(id)) {
-        JSString *str = JSVAL_TO_STRING(id);
-
-        *_retval = ::JS_SetUCProperty(cx, innerObj, ::JS_GetStringChars(str),
-                                      ::JS_GetStringLength(str), vp);
-      } else if (JSVAL_IS_INT(id)) {
-        *_retval = ::JS_SetElement(cx, innerObj, JSVAL_TO_INT(id), vp);
+      if (JSID_IS_STRING(id)) {
+        *_retval = ::JS_SetPropertyById(cx, innerObj, id, vp);
+      } else if (JSID_IS_INT(id)) {
+        *_retval = ::JS_SetElement(cx, innerObj, JSID_TO_INT(id), vp);
       } else {
         NS_ERROR("Write me!");
 
         return NS_ERROR_NOT_IMPLEMENTED;
       }
 
       return NS_OK;
     }
@@ -5303,17 +5299,17 @@ nsWindowSH::SetProperty(nsIXPConnectWrap
     return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
   }
 
   return nsEventReceiverSH::SetProperty(wrapper, cx, obj, id, vp, _retval);
 }
 
 NS_IMETHODIMP
 nsWindowSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                        JSObject *obj, jsval id, jsval *vp,
+                        JSObject *obj, jsid id, jsval *vp,
                         PRBool *_retval)
 {
   nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
 
 #ifdef DEBUG_SH_FORWARDING
   {
     nsDependentJSString str(::JS_ValueToString(cx, id));
 
@@ -5342,43 +5338,37 @@ nsWindowSH::AddProperty(nsIXPConnectWrap
       if (sResolving) {
         return NS_OK;
       }
 
 #ifdef DEBUG_SH_FORWARDING
       printf(" --- Forwarding add to inner window %p\n", (void *)innerWin);
 #endif
 
-      jsid interned_id;
-      if (!JS_ValueToId(cx, id, &interned_id)) {
-        *_retval = JS_FALSE;
-        return NS_OK;
-      }
-
       JSPropertyDescriptor desc;
-      if (!JS_GetPropertyDescriptorById(cx, obj, interned_id,
+      if (!JS_GetPropertyDescriptorById(cx, obj, id,
                                         JSRESOLVE_QUALIFIED, &desc)) {
         *_retval = JS_FALSE;
         return NS_OK;
       }
 
       // Forward the add to the inner object
-      *_retval = JS_DefinePropertyById(cx, innerObj, interned_id, *vp,
+      *_retval = JS_DefinePropertyById(cx, innerObj, id, *vp,
                                        desc.getter, desc.setter,
                                        desc.attrs | JSPROP_ENUMERATE);
       return NS_OK;
     }
   }
 
   return nsEventReceiverSH::AddProperty(wrapper, cx, obj, id, vp, _retval);
 }
 
 NS_IMETHODIMP
 nsWindowSH::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                        JSObject *obj, jsval id, jsval *vp,
+                        JSObject *obj, jsid id, jsval *vp,
                         PRBool *_retval)
 {
   nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
 
 #ifdef DEBUG_SH_FORWARDING
   {
     nsDependentJSString str(::JS_ValueToString(cx, id));
 
@@ -5402,19 +5392,17 @@ nsWindowSH::DelProperty(nsIXPConnectWrap
 
     JSObject *innerObj;
     if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
 #ifdef DEBUG_SH_FORWARDING
       printf(" --- Forwarding del to inner window %p\n", (void *)innerWin);
 #endif
 
       // Forward the del to the inner object
-      jsid interned_id;
-      *_retval = (JS_ValueToId(cx, id, &interned_id) &&
-                  JS_DeletePropertyById(cx, innerObj, interned_id));
+      *_retval = JS_DeletePropertyById(cx, innerObj, id);
 
       return NS_OK;
     }
   }
 
   // Notify any XOWs on our outer window.
 
   nsGlobalWindow *outerWin = win->GetOuterWindowInternal();
@@ -5614,71 +5602,60 @@ DefineInterfaceConstants(JSContext *cx, 
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLBodyElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext
-                                *cx, JSObject *obj, jsval id, PRUint32 flags,
+                                *cx, JSObject *obj, jsid id, PRUint32 flags,
                                 JSObject **objp, PRBool *_retval)
 {
   if (id == sOnhashchange_id) {
     // Special handling so |"onhashchange" in document.body| returns true.
-    jsid interned_id;
-
-    if (!JS_ValueToId(cx, id, &interned_id) ||
-        !JS_DefinePropertyById(cx, obj, interned_id, JSVAL_VOID,
+    if (!JS_DefinePropertyById(cx, obj, id, JSVAL_VOID,
                                nsnull, nsnull, JSPROP_ENUMERATE)) {
       *_retval = PR_FALSE;
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;
     return NS_OK;
   }
 
   return nsElementSH::NewResolve(wrapper, cx, obj, id, flags, objp, _retval);
 }
 
 NS_IMETHODIMP
 nsHTMLBodyElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
-                                 JSContext *cx, JSObject *obj, jsval id,
+                                 JSContext *cx, JSObject *obj, jsid id,
                                  jsval *vp, PRBool *_retval)
 {
   if (id == sOnhashchange_id) {
     // Forward the request to the Window.
-    jsid interned_id;
-
-    if (!JS_ValueToId(cx, id, &interned_id) ||
-        !JS_GetPropertyById(cx, JS_GetGlobalForObject(cx, obj),
-                            interned_id, vp)) {
+    if (!JS_GetPropertyById(cx, JS_GetGlobalForObject(cx, obj), id, vp)) {
       *_retval = PR_FALSE;
       return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
   }
 
   return nsElementSH::GetProperty(wrapper, cx, obj, id, vp, _retval);
 }
 
 NS_IMETHODIMP
 nsHTMLBodyElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
                                  JSContext *cx, JSObject *obj,
-                                 jsval id, jsval *vp, PRBool *_retval)
+                                 jsid id, jsval *vp, PRBool *_retval)
 {
   if (id == sOnhashchange_id) {
     // Forward the request to the Window.
-    jsid interned_id;
-
-    if (!JS_ValueToId(cx, id, &interned_id) ||
-        !JS_SetPropertyById(cx, JS_GetGlobalForObject(cx, obj),
-                            interned_id, vp)) {
+    if (!JS_SetPropertyById(cx, JS_GetGlobalForObject(cx, obj), id, vp)) {
       *_retval = PR_FALSE;
       return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
   }
 
   return nsElementSH::SetProperty(wrapper, cx, obj, id, vp, _retval);
@@ -5707,17 +5684,17 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMDOMCONSTRUCTOR
 
   nsresult Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                      JSObject *obj, PRUint32 argc, jsval *argv,
                      jsval *vp, PRBool *_retval);
 
   nsresult HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                       JSObject *obj, jsval val, PRBool *bp,
+                       JSObject *obj, const jsval &val, PRBool *bp,
                        PRBool *_retval);
 
   nsresult Install(JSContext *cx, JSObject *target, jsval thisAsVal)
   {
     JSBool ok =
       ::JS_DefineUCProperty(cx, target,
                             reinterpret_cast<const jschar *>(mClassName),
                             nsCRT::strlen(mClassName), thisAsVal, nsnull,
@@ -5867,17 +5844,17 @@ nsDOMConstructor::Construct(nsIXPConnect
   }
 
   return BaseStubConstructor(mWeakOwner, name_struct, cx, obj, argc, argv, vp);
 }
 
 nsresult
 nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
                               JSContext * cx, JSObject * obj,
-                              jsval v, PRBool *bp, PRBool *_retval)
+                              const jsval &v, PRBool *bp, PRBool *_retval)
 
 {
   // No need to look these up in the hash.
   if (JSVAL_IS_PRIMITIVE(v)) {
     return NS_OK;
   }
 
   JSObject *dom_obj = JSVAL_TO_OBJECT(v);
@@ -6469,17 +6446,17 @@ ContentWindowGetter(JSContext *cx, JSObj
   return ::JS_GetProperty(cx, obj, "content", rval);
 }
 
 PRBool
 nsWindowSH::sResolving = PR_FALSE;
 
 NS_IMETHODIMP
 nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                       JSObject *obj, jsval id, PRUint32 flags,
+                       JSObject *obj, jsid id, PRUint32 flags,
                        JSObject **objp, PRBool *_retval)
 {
   nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
 
 #ifdef DEBUG_SH_FORWARDING
   {
     nsDependentJSString str(::JS_ValueToString(cx, id));
 
@@ -6535,22 +6512,19 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     JSObject *realObj;
     wrapper->GetJSObject(&realObj);
     if (realObj == obj &&
         innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
 #ifdef DEBUG_SH_FORWARDING
       printf(" --- Forwarding resolve to inner window %p\n", (void *)innerWin);
 #endif
 
-      jsid interned_id;
       JSPropertyDescriptor desc;
 
-      *_retval = (JS_ValueToId(cx, id, &interned_id) &&
-                  JS_GetPropertyDescriptorById(cx, innerObj, interned_id,
-                                               flags, &desc));
+      *_retval = JS_GetPropertyDescriptorById(cx, innerObj, id, flags, &desc);
 
       if (*_retval && desc.obj) {
 #ifdef DEBUG_SH_FORWARDING
         printf(" --- Resolve on inner window found property.\n");
 #endif
 
         // The JS engine assumes that the object that we return in objp is on
         // our prototype chain. As a result, for an assignment, it wants to
@@ -6563,47 +6537,47 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
         // we only care about fast expandos on the innerObj itself, things
         // found further up the prototype chain need to fend for themselves.
         if ((flags & JSRESOLVE_ASSIGNING) &&
             !(desc.attrs & (JSPROP_GETTER | JSPROP_SETTER)) &&
             desc.obj == innerObj) {
           PRBool oldResolving = sResolving;
           sResolving = PR_TRUE;
 
-          *_retval = JS_DefinePropertyById(cx, obj, interned_id, JSVAL_VOID,
+          *_retval = JS_DefinePropertyById(cx, obj, id, JSVAL_VOID,
                                            nsnull, nsnull,
                                            desc.attrs & JSPROP_ENUMERATE);
 
           sResolving = oldResolving;
           if (!*_retval) {
             return NS_OK;
           }
         }
 
         *objp = desc.obj;
       }
 
       return NS_OK;
     }
   }
 
-  if (!JSVAL_IS_STRING(id)) {
-    if (JSVAL_IS_INT(id) && !(flags & JSRESOLVE_ASSIGNING)) {
+  if (!JSID_IS_STRING(id)) {
+    if (JSID_IS_INT(id) && !(flags & JSRESOLVE_ASSIGNING)) {
       // If we're resolving a numeric property, treat that as if
       // window.frames[n] is resolved (since window.frames ===
       // window), if window.frames[n] is a child frame, define a
       // property for this index.
 
       nsCOMPtr<nsIDOMWindow> frame = GetChildFrame(win, id);
 
       if (frame) {
         // A numeric property accessed and the numeric property is a
         // child frame. Define a property for this index.
 
-        *_retval = ::JS_DefineElement(cx, obj, JSVAL_TO_INT(id), JSVAL_VOID,
+        *_retval = ::JS_DefineElement(cx, obj, JSID_TO_INT(id), JSVAL_VOID,
                                       nsnull, nsnull, JSPROP_SHARED);
 
         if (*_retval) {
           *objp = obj;
         }
       }
     }
 
@@ -6628,17 +6602,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     my_cx = cx;
   } else {
     my_cx = (JSContext *)my_context->GetNativeContext();
   }
 
   JSBool ok;
   jsval exn;
   {
-    JSAutoTransferRequest transfer(cx, my_cx);
+    JSAutoRequest transfer(my_cx);
 
     JSObject *realObj;
     wrapper->GetJSObject(&realObj);
     
     // Don't resolve standard classes on XPCNativeWrapper etc, only
     // resolve them if we're resolving on the real global object.
     ok = obj == realObj ?
          ::JS_ResolveStandardClass(my_cx, obj, id, &did_resolve) :
@@ -6689,17 +6663,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     return NS_OK;
   }
 
 
   // Hmm, we do an awful lot of QIs here; maybe we should add a
   // method on an interface that would let us just call into the
   // window code directly...
 
-  JSString *str = JSVAL_TO_STRING(id);
+  JSString *str = JSID_TO_STRING(id);
 
   // Don't resolve named frames on native wrappers
   if (!ObjectIsNativeWrapper(cx, obj)) {
     nsCOMPtr<nsIDocShellTreeNode> dsn(do_QueryInterface(win->GetDocShell()));
 
     PRInt32 count = 0;
 
     if (dsn) {
@@ -6738,20 +6712,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
                        !strcmp(JSVAL_TO_OBJECT(v)->getClass()->name,
                                "XPCCrossOriginWrapper"),
                        "Didn't wrap a window!");
         }
 #endif
 
         JSAutoRequest ar(cx);
 
-        PRBool ok = ::JS_DefineUCProperty(cx, obj, chars,
-                                          ::JS_GetStringLength(str),
-                                          v, nsnull, nsnull, 0);
-
+        PRBool ok = ::JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull, 0);
         if (!ok) {
           return NS_ERROR_FAILURE;
         }
 
         *objp = obj;
 
         return NS_OK;
       }
@@ -6795,22 +6766,21 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     JSObject *funObj = ::JS_GetFunctionObject(fun);
 
     nsAutoGCRoot root(&funObj, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if (!::JS_DefineUCProperty(cx, windowObj, ::JS_GetStringChars(str),
-                               ::JS_GetStringLength(str), JSVAL_VOID,
-                               JS_DATA_TO_FUNC_PTR(JSPropertyOp, funObj),
-                               nsnull,
-                               JSPROP_ENUMERATE | JSPROP_GETTER |
-                               JSPROP_SHARED)) {
+    if (!::JS_DefinePropertyById(cx, windowObj, id, JSVAL_VOID,
+                                 JS_DATA_TO_FUNC_PTR(JSPropertyOp, funObj),
+                                 nsnull,
+                                 JSPROP_ENUMERATE | JSPROP_GETTER |
+                                 JSPROP_SHARED)) {
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;
 
     return NS_OK;
   }
 
@@ -6859,37 +6829,31 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
                        !strcmp(JSVAL_TO_OBJECT(v)->getClass()->name,
                                "XPCCrossOriginWrapper"),
                        "Didn't wrap a location object!");
     }
 #endif
 
     JSAutoRequest ar(cx);
 
-    JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                                      ::JS_GetStringLength(str), v, nsnull,
-                                      nsnull,
-                                      JSPROP_PERMANENT |
-                                      JSPROP_ENUMERATE);
+    JSBool ok = ::JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull,
+                                        JSPROP_PERMANENT | JSPROP_ENUMERATE);
 
     if (!ok) {
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;
 
     return NS_OK;
   }
 
   if (id == sOnhashchange_id) {
     // Special handling so |"onhashchange" in window| returns true
-    jsid interned_id;
-
-    if (!JS_ValueToId(cx, id, &interned_id) ||
-        !JS_DefinePropertyById(cx, obj, interned_id, JSVAL_VOID,
+    if (!JS_DefinePropertyById(cx, obj, id, JSVAL_VOID,
                                 nsnull, nsnull, JSPROP_ENUMERATE)) {
       *_retval = PR_FALSE;
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;
     return NS_OK;
   }
@@ -6899,20 +6863,18 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
         (!(flags & JSRESOLVE_QUALIFIED) && IsWritableReplaceable(id))) {
       // A readonly "replaceable" property is being set, or a
       // readwrite "replaceable" property is being set w/o being
       // fully qualified. Define the property on obj with the value
       // undefined to override the predefined property. This is done
       // for compatibility with other browsers.
       JSAutoRequest ar(cx);
 
-      if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                                 ::JS_GetStringLength(str),
-                                 JSVAL_VOID, JS_PropertyStub, JS_PropertyStub,
-                                 JSPROP_ENUMERATE)) {
+      if (!::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, JS_PropertyStub,
+                                   JS_PropertyStub, JSPROP_ENUMERATE)) {
         return NS_ERROR_FAILURE;
       }
       *objp = obj;
 
       return NS_OK;
     }
   } else {
     if (id == sNavigator_id) {
@@ -6923,20 +6885,19 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       jsval v;
       nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
       rv = WrapNative(cx, obj, navigator, &NS_GET_IID(nsIDOMNavigator), PR_TRUE,
                       &v, getter_AddRefs(holder));
       NS_ENSURE_SUCCESS(rv, rv);
 
       JSAutoRequest ar(cx);
 
-      if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                                 ::JS_GetStringLength(str), v, nsnull, nsnull,
-                                 JSPROP_READONLY | JSPROP_PERMANENT |
-                                 JSPROP_ENUMERATE)) {
+      if (!::JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull,
+                                   JSPROP_READONLY | JSPROP_PERMANENT |
+                                   JSPROP_ENUMERATE)) {
         return NS_ERROR_FAILURE;
       }
       *objp = obj;
 
       return NS_OK;
     }
 
     if (id == sDocument_id) {
@@ -6991,20 +6952,18 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
           scope = oldWin->GetGlobalJSObject();
         }
 
         rv = sXPConnect->GetXOWForObject(cx, scope, JSVAL_TO_OBJECT(winVal),
                                          &winVal);
         NS_ENSURE_SUCCESS(rv, rv);
       }
       PRBool ok =
-        ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                              ::JS_GetStringLength(str),
-                              winVal, JS_PropertyStub, JS_PropertyStub,
-                              JSPROP_READONLY | JSPROP_ENUMERATE);
+        ::JS_DefinePropertyById(cx, obj, id, winVal, JS_PropertyStub, JS_PropertyStub,
+                                JSPROP_READONLY | JSPROP_ENUMERATE);
 
       if (!ok) {
         return NS_ERROR_FAILURE;
       }
       *objp = obj;
 
       return NS_OK;
     }
@@ -7075,22 +7034,20 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
   if ((flags & JSRESOLVE_ASSIGNING) && !(flags & JSRESOLVE_WITH) &&
       win->IsInnerWindow()) {
     JSObject *realObj;
     wrapper->GetJSObject(&realObj);
 
     if (obj == realObj) {
       JSObject *proto = obj->getProto();
       if (proto) {
-        jsid interned_id;
         JSObject *pobj = NULL;
         jsval val;
 
-        if (!::JS_ValueToId(cx, id, &interned_id) ||
-            !::JS_LookupPropertyWithFlagsById(cx, proto, interned_id, flags,
+        if (!::JS_LookupPropertyWithFlagsById(cx, proto, id, flags,
                                               &pobj, &val)) {
           *_retval = JS_FALSE;
 
           return NS_OK;
         }
 
         if (pobj) {
           // A property was found on the prototype chain.
@@ -7105,23 +7062,21 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       //
       // We don't need to worry about property attributes here as we
       // know here we're dealing with an undefined property set, so
       // we're not declaring readonly or permanent properties.
       //
       // Since we always create the undeclared property here without given a
       // chance for the interpreter to report applicable strict mode warnings,
       // we must take care to check those warnings here.
-      JSString *str = JSVAL_TO_STRING(id);
+      JSString *str = JSID_TO_STRING(id);
       if ((!(flags & JSRESOLVE_QUALIFIED) &&
-           !js_CheckUndeclaredVarAssignment(cx, id)) ||
-          !::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                                 ::JS_GetStringLength(str), JSVAL_VOID,
-                                 JS_PropertyStub, JS_PropertyStub,
-                                 JSPROP_ENUMERATE)) {
+           !js_CheckUndeclaredVarAssignment(cx, str)) ||
+          !::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, JS_PropertyStub,
+                                   JS_PropertyStub, JSPROP_ENUMERATE)) {
         *_retval = JS_FALSE;
 
         return NS_OK;
       }
 
       *objp = obj;
     }
   }
@@ -7162,28 +7117,28 @@ nsWindowSH::NewEnumerate(nsIXPConnectWra
       if (!iterator) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
 
       *statep = OBJECT_TO_JSVAL(iterator);
       if (idp) {
         // Note: With these property iterators, we can't tell ahead of time how
         // many properties we're going to be iterating over.
-        *idp = JSVAL_ZERO;
+        *idp = INT_TO_JSID(0);
       }
       break;
     }
     case JSENUMERATE_NEXT:
     {
       JSObject *iterator = (JSObject*)JSVAL_TO_OBJECT(*statep);
       if (!JS_NextProperty(cx, iterator, idp)) {
         return NS_ERROR_UNEXPECTED;
       }
 
-      if (*idp != JSVAL_VOID) {
+      if (*idp != JSID_VOID) {
         break;
       }
 
       // Fall through.
     }
     case JSENUMERATE_DESTROY:
       // Let GC at our iterator object.
       *statep = JSVAL_NULL;
@@ -7202,17 +7157,17 @@ nsWindowSH::Finalize(nsIXPConnectWrapped
 
   sgo->OnFinalize(nsIProgrammingLanguage::JAVASCRIPT, obj);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindowSH::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
-                     JSObject * obj, jsval val, PRBool *bp)
+                     JSObject * obj, const jsval &val, PRBool *bp)
 {
   *bp = PR_FALSE;
 
   if (JSVAL_IS_PRIMITIVE(val)) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIXPConnectWrappedNative> other_wrapper;
@@ -7299,17 +7254,17 @@ nsWindowSH::InnerObject(nsIXPConnectWrap
 
   return NS_OK;
 }
 
 // DOM Location helper
 
 NS_IMETHODIMP
 nsLocationSH::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                          JSObject *obj, jsval id, PRUint32 mode,
+                          JSObject *obj, jsid id, PRUint32 mode,
                           jsval *vp, PRBool *_retval)
 {
   if ((mode & JSACC_TYPEMASK) == JSACC_PROTO && (mode & JSACC_WRITE)) {
     // No setting location.__proto__, ever!
 
     // Let XPConnect know that the access was not granted.
     *_retval = PR_FALSE;
 
@@ -7404,29 +7359,26 @@ nsNodeSH::IsCapabilityEnabled(const char
 {
   PRBool enabled;
   return sSecMan &&
     NS_SUCCEEDED(sSecMan->IsCapabilityEnabled(aCapability, &enabled)) &&
     enabled;
 }
 
 nsresult
-nsNodeSH::DefineVoidProp(JSContext* cx, JSObject* obj, jsval id,
+nsNodeSH::DefineVoidProp(JSContext* cx, JSObject* obj, jsid id,
                          JSObject** objp)
 {
-  NS_ASSERTION(JSVAL_IS_STRING(id), "id must be a string");
-
-  JSString* str = JSVAL_TO_STRING(id);
+  NS_ASSERTION(JSID_IS_STRING(id), "id must be a string");
 
   // We want this to be as invisible to content script as possible.  So
   // don't enumerate this, and set is as JSPROP_SHARED so it won't get
   // cached on the object.
-  JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                                    ::JS_GetStringLength(str), JSVAL_VOID,
-                                    nsnull, nsnull, JSPROP_SHARED);
+  JSBool ok = ::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID,
+                                      nsnull, nsnull, JSPROP_SHARED);
 
   if (!ok) {
     return NS_ERROR_FAILURE;
   }
 
   *objp = obj;
   return NS_OK;
 }
@@ -7562,25 +7514,25 @@ nsNodeSH::PreCreate(nsISupports *nativeO
   NS_ENSURE_SUCCESS(rv, rv);
 
   return node->IsInNativeAnonymousSubtree() ?
     NS_SUCCESS_CHROME_ACCESS_ONLY : NS_SUCCESS_ALLOW_SLIM_WRAPPERS;
 }
 
 NS_IMETHODIMP
 nsNodeSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                      JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
+                      JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
 {
   nsNodeSH::PreserveWrapper(GetNative(wrapper, obj));
   return nsEventReceiverSH::AddProperty(wrapper, cx, obj, id, vp, _retval);
 }
 
 NS_IMETHODIMP
 nsNodeSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                     JSObject *obj, jsval id, PRUint32 flags,
+                     JSObject *obj, jsid id, PRUint32 flags,
                      JSObject **objp, PRBool *_retval)
 {
   if ((id == sBaseURIObject_id || id == sNodePrincipal_id) &&
       IsPrivilegedScript()) {
     return DefineVoidProp(cx, obj, id, objp);
   }
 
   if (id == sOnload_id || id == sOnerror_id) {
@@ -7590,17 +7542,17 @@ nsNodeSH::NewResolve(nsIXPConnectWrapped
   }
 
   return nsEventReceiverSH::NewResolve(wrapper, cx, obj, id, flags, objp,
                                        _retval);
 }
 
 NS_IMETHODIMP
 nsNodeSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                      JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
+                      JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
 {
   if (id == sBaseURIObject_id && IsPrivilegedScript()) {
     // I wish GetBaseURI lived on nsINode
     nsCOMPtr<nsIURI> uri;
     nsCOMPtr<nsIContent> content = do_QueryWrappedNative(wrapper, obj);
     if (content) {
       uri = content->GetBaseURI();
       NS_ENSURE_TRUE(uri, NS_ERROR_OUT_OF_MEMORY);
@@ -7630,17 +7582,17 @@ nsNodeSH::GetProperty(nsIXPConnectWrappe
   }    
 
   // Note: none of our ancestors want GetProperty
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNodeSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                      JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
+                      JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
 {
   if ((id == sBaseURIObject_id || id == sNodePrincipal_id) &&
       IsPrivilegedScript()) {
     // We don't want privileged script that can read this property to set it,
     // but _do_ want to allow everyone else to set a value they can then read.
     //
     // XXXbz Is there a better error we could use here?
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
@@ -7663,17 +7615,17 @@ nsNodeSH::PreserveWrapper(nsISupports *a
   nsINode *node = static_cast<nsINode*>(aNative);
   nsContentUtils::PreserveWrapper(aNative, node);
 }
 
 // EventReceiver helper
 
 // static
 PRBool
-nsEventReceiverSH::ReallyIsEventName(jsval id, jschar aFirstChar)
+nsEventReceiverSH::ReallyIsEventName(jsid id, jschar aFirstChar)
 {
   // I wonder if this is faster than using a hash...
 
   switch (aFirstChar) {
   case 'a' :
     return id == sOnabort_id;
   case 'b' :
     return (id == sOnbeforeunload_id ||
@@ -7730,17 +7682,17 @@ nsEventReceiverSH::ReallyIsEventName(jsv
   }
 
   return PR_FALSE;
 }
 
 nsresult
 nsEventReceiverSH::RegisterCompileHandler(nsIXPConnectWrappedNative *wrapper,
                                           JSContext *cx, JSObject *obj,
-                                          jsval id, PRBool compile,
+                                          jsid id, PRBool compile,
                                           PRBool remove,
                                           PRBool *did_define)
 {
   NS_PRECONDITION(!compile || !remove,
                   "Can't both compile and remove at the same time");
   *did_define = PR_FALSE;
 
   if (!IsEventName(id)) {
@@ -7782,48 +7734,43 @@ nsEventReceiverSH::RegisterCompileHandle
                                               atom);
   }
 
   return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
 }
 
 NS_IMETHODIMP
 nsEventReceiverSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
-                              JSContext *cx, JSObject *obj, jsval id,
+                              JSContext *cx, JSObject *obj, jsid id,
                               PRUint32 flags, JSObject **objp, PRBool *_retval)
 {
-  if (!JSVAL_IS_STRING(id)) {
+  if (!JSID_IS_STRING(id)) {
     return NS_OK;
   }
 
   if (flags & JSRESOLVE_ASSIGNING) {
     if (!IsEventName(id)) {
       // Bail out.  We don't care about this assignment.
       return NS_OK;
     }
 
     // If we're assigning to an on* property, just resolve to null for
     // now; the assignment will then set the right value. Only do this
     // in the case where the property isn't already defined on the
     // object's prototype chain though.
-    JSString* str = JSVAL_TO_STRING(id);
     JSAutoRequest ar(cx);
 
     JSObject *proto = ::JS_GetPrototype(cx, obj);
     PRBool ok = PR_TRUE, hasProp = PR_FALSE;
-    if (!proto || ((ok = ::JS_HasUCProperty(cx, proto, ::JS_GetStringChars(str),
-                                            ::JS_GetStringLength(str),
-                                            &hasProp)) &&
+    if (!proto || ((ok = ::JS_HasPropertyById(cx, proto, id, &hasProp)) &&
                    !hasProp)) {
       // Make sure the flags here match those in
       // nsJSContext::BindCompiledEventHandler
-      if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-                                 ::JS_GetStringLength(str), JSVAL_NULL,
-                                 nsnull, nsnull,
-                                 JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
+      if (!::JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, nsnull, nsnull,
+                                   JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
         return NS_ERROR_FAILURE;
       }
 
       *objp = obj;
       return NS_OK;
     }
 
     return ok ? NS_OK : NS_ERROR_FAILURE;
@@ -7843,35 +7790,35 @@ nsEventReceiverSH::NewResolve(nsIXPConne
   }
 
   return nsDOMGenericSH::NewResolve(wrapper, cx, obj, id, flags, objp,
                                     _retval);
 }
 
 NS_IMETHODIMP
 nsEventReceiverSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
-                               JSContext *cx, JSObject *obj, jsval id,
+                               JSContext *cx, JSObject *obj, jsid id,
                                jsval *vp, PRBool *_retval)
 {
   JSAutoRequest ar(cx);
 
   if ((::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION && !JSVAL_IS_NULL(*vp)) ||
-      !JSVAL_IS_STRING(id) || id == sAddEventListener_id) {
+      !JSID_IS_STRING(id) || id == sAddEventListener_id) {
     return NS_OK;
   }
 
   PRBool did_compile; // Ignored here.
 
   return RegisterCompileHandler(wrapper, cx, obj, id, PR_FALSE,
                                 JSVAL_IS_NULL(*vp), &did_compile);
 }
 
 NS_IMETHODIMP
 nsEventReceiverSH::AddProperty(nsIXPConnectWrappedNative *wrapper,
-                               JSContext *cx, JSObject *obj, jsval id,
+                               JSContext *cx, JSObject *obj, jsid id,
                                jsval *vp, PRBool *_retval)
 {
   return nsEventReceiverSH::SetProperty(wrapper, cx, obj, id, vp, _retval);
 }
 
 // EventTarget helper
 
 NS_IMETHODIMP
@@ -7886,17 +7833,17 @@ nsEventTargetSH::PreCreate(nsISupports *
 
   *parentObj = native_parent ? native_parent->GetGlobalJSObject() : globalObj;
 
   return NS_OK;
 }