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 id17440
push userdb48x@yahoo.com
push dateWed, 08 Dec 2010 04:15:54 +0000
treeherdermozilla-central@a89f24bf1798 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
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,