Merge m-c to inbound.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 29 Jan 2013 13:48:40 -0500
changeset 120253 6f3581295ea798d0f73c303678a06acda218b02f
parent 120252 b211a11259a7e4b622f57ca599a041cfed99149c (diff)
parent 120197 6cca454559c8b9f0c785354f2e69441ae34650f1 (current diff)
child 120254 f370ad0944a23bb3c3b2ae731fb21e111c816c2d
push id24243
push userryanvm@gmail.com
push dateWed, 30 Jan 2013 00:49:21 +0000
treeherdermozilla-central@5c248ef0fe62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone21.0a1
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
Merge m-c to inbound.
--- a/accessible/src/base/AccEvent.h
+++ b/accessible/src/base/AccEvent.h
@@ -118,17 +118,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
 
 protected:
   bool mIsFromUserInput;
   uint32_t mEventType;
   EEventRule mEventRule;
   nsRefPtr<Accessible> mAccessible;
 
-  friend class NotificationController;
+  friend class EventQueue;
   friend class AccReorderEvent;
 };
 
 
 /**
  * Accessible state change event.
  */
 class AccStateChangeEvent: public AccEvent
@@ -158,17 +158,17 @@ public:
   // AccStateChangeEvent
   uint64_t GetState() const { return mState; }
   bool IsStateEnabled() const { return mIsEnabled; }
 
 private:
   uint64_t mState;
   bool mIsEnabled;
 
-  friend class NotificationController;
+  friend class EventQueue;
 };
 
 
 /**
  * Accessible text change event.
  */
 class AccTextChangeEvent: public AccEvent
 {
@@ -193,17 +193,17 @@ public:
   void GetModifiedText(nsAString& aModifiedText)
     { aModifiedText = mModifiedText; }
 
 private:
   int32_t mStart;
   bool mIsInserted;
   nsString mModifiedText;
 
-  friend class NotificationController;
+  friend class EventQueue;
   friend class AccReorderEvent;
 };
 
 
 /**
  * Base class for show and hide accessible events.
  */
 class AccMutationEvent: public AccEvent
@@ -230,17 +230,17 @@ public:
   bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
   bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
 
 protected:
   nsCOMPtr<nsINode> mNode;
   nsRefPtr<Accessible> mParent;
   nsRefPtr<AccTextChangeEvent> mTextChangeEvent;
 
-  friend class NotificationController;
+  friend class EventQueue;
 };
 
 
 /**
  * Accessible hide event.
  */
 class AccHideEvent: public AccMutationEvent
 {
@@ -260,17 +260,17 @@ public:
   Accessible* TargetParent() const { return mParent; }
   Accessible* TargetNextSibling() const { return mNextSibling; }
   Accessible* TargetPrevSibling() const { return mPrevSibling; }
 
 protected:
   nsRefPtr<Accessible> mNextSibling;
   nsRefPtr<Accessible> mPrevSibling;
 
-  friend class NotificationController;
+  friend class EventQueue;
 };
 
 
 /**
  * Accessible show event.
  */
 class AccShowEvent: public AccMutationEvent
 {
@@ -328,17 +328,17 @@ public:
   uint32_t IsShowHideEventTarget(const Accessible* aTarget) const;
 
 protected:
   /**
    * Show and hide events causing this reorder event.
    */
   nsTArray<AccMutationEvent*> mDependentEvents;
 
-  friend class NotificationController;
+  friend class EventQueue;
 };
 
 
 /**
  * Accessible caret move event.
  */
 class AccCaretMoveEvent: public AccEvent
 {
@@ -358,17 +358,17 @@ public:
   }
 
   // AccCaretMoveEvent
   int32_t GetCaretOffset() const { return mCaretOffset; }
 
 private:
   int32_t mCaretOffset;
 
-  friend class NotificationController;
+  friend class EventQueue;
 };
 
 
 /**
  * Accessible widget selection change event.
  */
 class AccSelChangeEvent : public AccEvent
 {
@@ -395,17 +395,17 @@ public:
 
 private:
   nsRefPtr<Accessible> mWidget;
   nsRefPtr<Accessible> mItem;
   SelChangeType mSelChangeType;
   uint32_t mPreceedingCount;
   AccSelChangeEvent* mPackedEvent;
 
-  friend class NotificationController;
+  friend class EventQueue;
 };
 
 
 /**
  * Accessible table change event.
  */
 class AccTableChangeEvent : public AccEvent
 {
copy from accessible/src/base/NotificationController.cpp
copy to accessible/src/base/EventQueue.cpp
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/EventQueue.cpp
@@ -1,328 +1,57 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "NotificationController.h"
+#include "EventQueue.h"
 
 #include "Accessible-inl.h"
-#include "nsAccessibilityService.h"
-#include "nsAccUtils.h"
-#include "nsCoreUtils.h"
 #include "DocAccessible-inl.h"
 #include "nsEventShell.h"
-#include "FocusManager.h"
-#include "Role.h"
-#include "TextLeafAccessible.h"
-#include "TextUpdater.h"
-
-#ifdef A11Y_LOG
-#include "Logging.h"
-#endif
-
-#include "mozilla/dom/Element.h"
-#include "mozilla/Telemetry.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 // Defines the number of selection add/remove events in the queue when they
 // aren't packed into single selection within event.
 const unsigned int kSelChangeCountToPack = 5;
 
 ////////////////////////////////////////////////////////////////////////////////
-// NotificationCollector
+// EventQueue
 ////////////////////////////////////////////////////////////////////////////////
 
-NotificationController::NotificationController(DocAccessible* aDocument,
-                                               nsIPresShell* aPresShell) :
-  mObservingState(eNotObservingRefresh), mDocument(aDocument),
-  mPresShell(aPresShell)
-{
-  mTextHash.Init();
-
-  // Schedule initial accessible tree construction.
-  ScheduleProcessing();
-}
-
-NotificationController::~NotificationController()
-{
-  NS_ASSERTION(!mDocument, "Controller wasn't shutdown properly!");
-  if (mDocument)
-    Shutdown();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationCollector: AddRef/Release and cycle collection
-
-NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(NotificationController)
-NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(NotificationController)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(NotificationController)
-  if (tmp->mDocument)
-    tmp->Shutdown();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHangingChildDocuments)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentInsertions)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvents)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController, Release)
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationCollector: public
-
-void
-NotificationController::Shutdown()
-{
-  if (mObservingState != eNotObservingRefresh &&
-      mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
-    mObservingState = eNotObservingRefresh;
-  }
-
-  // Shutdown handling child documents.
-  int32_t childDocCount = mHangingChildDocuments.Length();
-  for (int32_t idx = childDocCount - 1; idx >= 0; idx--) {
-    if (!mHangingChildDocuments[idx]->IsDefunct())
-      mHangingChildDocuments[idx]->Shutdown();
-  }
-
-  mHangingChildDocuments.Clear();
-
-  mDocument = nullptr;
-  mPresShell = nullptr;
-
-  mTextHash.Clear();
-  mContentInsertions.Clear();
-  mNotifications.Clear();
-  mEvents.Clear();
-}
-
-void
-NotificationController::QueueEvent(AccEvent* aEvent)
+bool
+EventQueue::PushEvent(AccEvent* aEvent)
 {
   NS_ASSERTION((aEvent->mAccessible && aEvent->mAccessible->IsApplication()) ||
                aEvent->GetDocAccessible() == mDocument,
                "Queued event belongs to another document!");
 
   if (!mEvents.AppendElement(aEvent))
-    return;
+    return false;
 
   // Filter events.
   CoalesceEvents();
 
   // Associate text change with hide event if it wasn't stolen from hiding
   // siblings during coalescence.
   AccMutationEvent* showOrHideEvent = downcast_accEvent(aEvent);
   if (showOrHideEvent && !showOrHideEvent->mTextChangeEvent)
     CreateTextChangeEventFor(showOrHideEvent);
 
-  ScheduleProcessing();
-}
-
-void
-NotificationController::ScheduleChildDocBinding(DocAccessible* aDocument)
-{
-  // Schedule child document binding to the tree.
-  mHangingChildDocuments.AppendElement(aDocument);
-  ScheduleProcessing();
-}
-
-void
-NotificationController::ScheduleContentInsertion(Accessible* aContainer,
-                                                 nsIContent* aStartChildNode,
-                                                 nsIContent* aEndChildNode)
-{
-  nsRefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
-                                                              aContainer);
-  if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
-      mContentInsertions.AppendElement(insertion)) {
-    ScheduleProcessing();
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationCollector: protected
-
-void
-NotificationController::ScheduleProcessing()
-{
-  // If notification flush isn't planed yet start notification flush
-  // asynchronously (after style and layout).
-  if (mObservingState == eNotObservingRefresh) {
-    if (mPresShell->AddRefreshObserver(this, Flush_Display))
-      mObservingState = eRefreshObserving;
-  }
-}
-
-bool
-NotificationController::IsUpdatePending()
-{
-  return mPresShell->IsLayoutFlushObserver() ||
-    mObservingState == eRefreshProcessingForUpdate ||
-    mContentInsertions.Length() != 0 || mNotifications.Length() != 0 ||
-    mTextHash.Count() != 0 ||
-    !mDocument->HasLoadState(DocAccessible::eTreeConstructed);
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// NotificationCollector: private
+// EventQueue: private
 
 void
-NotificationController::WillRefresh(mozilla::TimeStamp aTime)
-{
-  Telemetry::AutoTimer<Telemetry::A11Y_UPDATE_TIME> updateTimer;
-
-  // If the document accessible that notification collector was created for is
-  // now shut down, don't process notifications anymore.
-  NS_ASSERTION(mDocument,
-               "The document was shut down while refresh observer is attached!");
-  if (!mDocument)
-    return;
-
-  // Any generic notifications should be queued if we're processing content
-  // insertions or generic notifications.
-  mObservingState = eRefreshProcessingForUpdate;
-
-  // Initial accessible tree construction.
-  if (!mDocument->HasLoadState(DocAccessible::eTreeConstructed)) {
-    // If document is not bound to parent at this point then the document is not
-    // ready yet (process notifications later).
-    if (!mDocument->IsBoundToParent()) {
-      mObservingState = eRefreshObserving;
-      return;
-    }
-
-#ifdef A11Y_LOG
-    if (logging::IsEnabled(logging::eTree)) {
-      logging::MsgBegin("TREE", "initial tree created");
-      logging::Address("document", mDocument);
-      logging::MsgEnd();
-    }
-#endif
-
-    mDocument->DoInitialUpdate();
-
-    NS_ASSERTION(mContentInsertions.Length() == 0,
-                 "Pending content insertions while initial accessible tree isn't created!");
-  }
-
-  // Initialize scroll support if needed.
-  if (!(mDocument->mDocFlags & DocAccessible::eScrollInitialized))
-    mDocument->AddScrollListener();
-
-  // Process content inserted notifications to update the tree. Process other
-  // notifications like DOM events and then flush event queue. If any new
-  // notifications are queued during this processing then they will be processed
-  // on next refresh. If notification processing queues up new events then they
-  // are processed in this refresh. If events processing queues up new events
-  // then new events are processed on next refresh.
-  // Note: notification processing or event handling may shut down the owning
-  // document accessible.
-
-  // Process only currently queued content inserted notifications.
-  nsTArray<nsRefPtr<ContentInsertion> > contentInsertions;
-  contentInsertions.SwapElements(mContentInsertions);
-
-  uint32_t insertionCount = contentInsertions.Length();
-  for (uint32_t idx = 0; idx < insertionCount; idx++) {
-    contentInsertions[idx]->Process();
-    if (!mDocument)
-      return;
-  }
-
-  // Process rendered text change notifications.
-  mTextHash.EnumerateEntries(TextEnumerator, mDocument);
-  mTextHash.Clear();
-
-  // Bind hanging child documents.
-  uint32_t hangingDocCnt = mHangingChildDocuments.Length();
-  for (uint32_t idx = 0; idx < hangingDocCnt; idx++) {
-    DocAccessible* childDoc = mHangingChildDocuments[idx];
-    if (childDoc->IsDefunct())
-      continue;
-
-    nsIContent* ownerContent = mDocument->DocumentNode()->
-      FindContentForSubDocument(childDoc->DocumentNode());
-    if (ownerContent) {
-      Accessible* outerDocAcc = mDocument->GetAccessible(ownerContent);
-      if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
-        if (mDocument->AppendChildDocument(childDoc))
-          continue;
-
-        outerDocAcc->RemoveChild(childDoc);
-      }
-
-      // Failed to bind the child document, destroy it.
-      childDoc->Shutdown();
-    }
-  }
-  mHangingChildDocuments.Clear();
-
-  // If the document is ready and all its subdocuments are completely loaded
-  // then process the document load.
-  if (mDocument->HasLoadState(DocAccessible::eReady) &&
-      !mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
-      hangingDocCnt == 0) {
-    uint32_t childDocCnt = mDocument->ChildDocumentCount(), childDocIdx = 0;
-    for (; childDocIdx < childDocCnt; childDocIdx++) {
-      DocAccessible* childDoc = mDocument->GetChildDocumentAt(childDocIdx);
-      if (!childDoc->HasLoadState(DocAccessible::eCompletelyLoaded))
-        break;
-    }
-
-    if (childDocIdx == childDocCnt) {
-      mDocument->ProcessLoad();
-      if (!mDocument)
-        return;
-    }
-  }
-
-  // Process only currently queued generic notifications.
-  nsTArray < nsRefPtr<Notification> > notifications;
-  notifications.SwapElements(mNotifications);
-
-  uint32_t notificationCount = notifications.Length();
-  for (uint32_t idx = 0; idx < notificationCount; idx++) {
-    notifications[idx]->Process();
-    if (!mDocument)
-      return;
-  }
-
-  // Process invalidation list of the document after all accessible tree
-  // modification are done.
-  mDocument->ProcessInvalidationList();
-
-  // If a generic notification occurs after this point then we may be allowed to
-  // process it synchronously.
-  mObservingState = eRefreshObserving;
-
-  ProcessEventQueue();
-  if (!mDocument)
-    return;
-
-  // Stop further processing if there are no new notifications of any kind or
-  // events and document load is processed.
-  if (mContentInsertions.Length() == 0 && mNotifications.Length() == 0 &&
-      mEvents.Length() == 0 && mTextHash.Count() == 0 &&
-      mHangingChildDocuments.Length() == 0 &&
-      mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
-      mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
-    mObservingState = eNotObservingRefresh;
-  }
-}
-
-void
-NotificationController::CoalesceEvents()
+EventQueue::CoalesceEvents()
 {
   NS_ASSERTION(mEvents.Length(), "There should be at least one pending event!");
   uint32_t tail = mEvents.Length() - 1;
   AccEvent* tailEvent = mEvents[tail];
 
   switch(tailEvent->mEventRule) {
     case AccEvent::eCoalesceReorder:
       CoalesceReorderEvents(tailEvent);
@@ -435,17 +164,17 @@ NotificationController::CoalesceEvents()
     } break; // case eRemoveDupes
 
     default:
       break; // case eAllowDupes, eDoNotEmit
   } // switch
 }
 
 void
-NotificationController::CoalesceReorderEvents(AccEvent* aTailEvent)
+EventQueue::CoalesceReorderEvents(AccEvent* aTailEvent)
 {
   uint32_t count = mEvents.Length();
   for (uint32_t index = count - 2; index < count; index--) {
     AccEvent* thisEvent = mEvents[index];
 
     // Skip events of different types and targeted to application accessible.
     if (thisEvent->mEventType != aTailEvent->mEventType ||
         thisEvent->mAccessible->IsApplication())
@@ -524,19 +253,19 @@ NotificationController::CoalesceReorderE
 
       tailParent = tailParent->Parent();
     }
 
   } // for (index)
 }
 
 void
-NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
-                                                AccSelChangeEvent* aThisEvent,
-                                                uint32_t aThisIndex)
+EventQueue::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
+                                    AccSelChangeEvent* aThisEvent,
+                                    uint32_t aThisIndex)
 {
   aTailEvent->mPreceedingCount = aThisEvent->mPreceedingCount + 1;
 
   // Pack all preceding events into single selection within event
   // when we receive too much selection add/remove events.
   if (aTailEvent->mPreceedingCount >= kSelChangeCountToPack) {
     aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION_WITHIN;
     aTailEvent->mAccessible = aTailEvent->mWidget;
@@ -604,18 +333,18 @@ NotificationController::CoalesceSelChang
 
   // Convert into selection add since control has single selection but other
   // selection events for this control are queued.
   if (aTailEvent->mEventType == nsIAccessibleEvent::EVENT_SELECTION)
     aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
 }
 
 void
-NotificationController::CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
-                                                    AccHideEvent* aThisEvent)
+EventQueue::CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
+                                        AccHideEvent* aThisEvent)
 {
   // XXX: we need a way to ignore SplitNode and JoinNode() when they do not
   // affect the text within the hypertext.
 
   AccTextChangeEvent* textEvent = aThisEvent->mTextChangeEvent;
   if (!textEvent)
     return;
 
@@ -627,18 +356,18 @@ NotificationController::CoalesceTextChan
     aTailEvent->mAccessible->AppendTextTo(textEvent->mModifiedText);
     textEvent->mStart -= textEvent->GetLength() - oldLen;
   }
 
   aTailEvent->mTextChangeEvent.swap(aThisEvent->mTextChangeEvent);
 }
 
 void
-NotificationController::CoalesceTextChangeEventsFor(AccShowEvent* aTailEvent,
-                                                    AccShowEvent* aThisEvent)
+EventQueue::CoalesceTextChangeEventsFor(AccShowEvent* aTailEvent,
+                                        AccShowEvent* aThisEvent)
 {
   AccTextChangeEvent* textEvent = aThisEvent->mTextChangeEvent;
   if (!textEvent)
     return;
 
   if (aTailEvent->mAccessible->IndexInParent() ==
       aThisEvent->mAccessible->IndexInParent() + 1) {
     // If tail target was inserted after this target, i.e. tail target is next
@@ -654,17 +383,17 @@ NotificationController::CoalesceTextChan
     textEvent->mModifiedText = startText + textEvent->mModifiedText;
     textEvent->mStart -= startText.Length();
   }
 
   aTailEvent->mTextChangeEvent.swap(aThisEvent->mTextChangeEvent);
 }
 
 void
-NotificationController::CreateTextChangeEventFor(AccMutationEvent* aEvent)
+EventQueue::CreateTextChangeEventFor(AccMutationEvent* aEvent)
 {
   Accessible* container = aEvent->mAccessible->Parent();
   if (!container)
     return;
 
   HyperTextAccessible* textAccessible = container->AsHyperText();
   if (!textAccessible)
     return;
@@ -688,20 +417,20 @@ NotificationController::CreateTextChange
     return;
 
   aEvent->mTextChangeEvent =
     new AccTextChangeEvent(textAccessible, offset, text, aEvent->IsShow(),
                            aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// NotificationController: event queue
+// EventQueue: event queue
 
 void
-NotificationController::ProcessEventQueue()
+EventQueue::ProcessEventQueue()
 {
   // Process only currently queued events.
   nsTArray<nsRefPtr<AccEvent> > events;
   events.SwapElements(mEvents);
 
   uint32_t eventCount = events.Length();
 #ifdef A11Y_LOG
   if (eventCount > 0 && logging::IsEnabled(logging::eEvents)) {
@@ -755,151 +484,8 @@ NotificationController::ProcessEventQueu
 
     if (event->mEventType == nsIAccessibleEvent::EVENT_HIDE)
       mDocument->ShutdownChildrenInSubtree(event->mAccessible);
 
     if (!mDocument)
       return;
   }
 }
-
-////////////////////////////////////////////////////////////////////////////////
-// Notification controller: text leaf accessible text update
-
-PLDHashOperator
-NotificationController::TextEnumerator(nsCOMPtrHashKey<nsIContent>* aEntry,
-                                       void* aUserArg)
-{
-  DocAccessible* document = static_cast<DocAccessible*>(aUserArg);
-  nsIContent* textNode = aEntry->GetKey();
-  Accessible* textAcc = document->GetAccessible(textNode);
-
-  // If the text node is not in tree or doesn't have frame then this case should
-  // have been handled already by content removal notifications.
-  nsINode* containerNode = textNode->GetParentNode();
-  if (!containerNode) {
-    NS_ASSERTION(!textAcc,
-                 "Text node was removed but accessible is kept alive!");
-    return PL_DHASH_NEXT;
-  }
-
-  nsIFrame* textFrame = textNode->GetPrimaryFrame();
-  if (!textFrame) {
-    NS_ASSERTION(!textAcc,
-                 "Text node isn't rendered but accessible is kept alive!");
-    return PL_DHASH_NEXT;
-  }
-
-  nsIContent* containerElm = containerNode->IsElement() ?
-    containerNode->AsElement() : nullptr;
-
-  nsAutoString text;
-  textFrame->GetRenderedText(&text);
-
-  // Remove text accessible if rendered text is empty.
-  if (textAcc) {
-    if (text.IsEmpty()) {
-#ifdef A11Y_LOG
-      if (logging::IsEnabled(logging::eTree | logging::eText)) {
-        logging::MsgBegin("TREE", "text node lost its content");
-        logging::Node("container", containerElm);
-        logging::Node("content", textNode);
-        logging::MsgEnd();
-      }
-#endif
-
-      document->ContentRemoved(containerElm, textNode);
-      return PL_DHASH_NEXT;
-    }
-
-    // Update text of the accessible and fire text change events.
-#ifdef A11Y_LOG
-    if (logging::IsEnabled(logging::eText)) {
-      logging::MsgBegin("TEXT", "text may be changed");
-      logging::Node("container", containerElm);
-      logging::Node("content", textNode);
-      logging::MsgEntry("old text '%s'",
-                        NS_ConvertUTF16toUTF8(textAcc->AsTextLeaf()->Text()).get());
-      logging::MsgEntry("new text: '%s'",
-                        NS_ConvertUTF16toUTF8(text).get());
-      logging::MsgEnd();
-    }
-#endif
-
-    TextUpdater::Run(document, textAcc->AsTextLeaf(), text);
-    return PL_DHASH_NEXT;
-  }
-
-  // Append an accessible if rendered text is not empty.
-  if (!text.IsEmpty()) {
-#ifdef A11Y_LOG
-    if (logging::IsEnabled(logging::eTree | logging::eText)) {
-      logging::MsgBegin("TREE", "text node gains new content");
-      logging::Node("container", containerElm);
-      logging::Node("content", textNode);
-      logging::MsgEnd();
-    }
-#endif
-
-    // Make sure the text node is in accessible document still.
-    Accessible* container = document->GetAccessibleOrContainer(containerNode);
-    NS_ASSERTION(container,
-                 "Text node having rendered text hasn't accessible document!");
-    if (container) {
-      nsTArray<nsCOMPtr<nsIContent> > insertedContents;
-      insertedContents.AppendElement(textNode);
-      document->ProcessContentInserted(container, &insertedContents);
-    }
-  }
-
-  return PL_DHASH_NEXT;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationController: content inserted notification
-
-NotificationController::ContentInsertion::
-  ContentInsertion(DocAccessible* aDocument, Accessible* aContainer) :
-  mDocument(aDocument), mContainer(aContainer)
-{
-}
-
-bool
-NotificationController::ContentInsertion::
-  InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode)
-{
-  bool haveToUpdate = false;
-
-  nsIContent* node = aStartChildNode;
-  while (node != aEndChildNode) {
-    // Notification triggers for content insertion even if no content was
-    // actually inserted, check if the given content has a frame to discard
-    // this case early.
-    if (node->GetPrimaryFrame()) {
-      if (mInsertedContent.AppendElement(node))
-        haveToUpdate = true;
-    }
-
-    node = node->GetNextSibling();
-  }
-
-  return haveToUpdate;
-}
-
-NS_IMPL_CYCLE_COLLECTION_1(NotificationController::ContentInsertion,
-                           mContainer)
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController::ContentInsertion,
-                                     AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController::ContentInsertion,
-                                       Release)
-
-void
-NotificationController::ContentInsertion::Process()
-{
-  mDocument->ProcessContentInserted(mContainer, &mInsertedContent);
-
-  mDocument = nullptr;
-  mContainer = nullptr;
-  mInsertedContent.Clear();
-}
-
copy from accessible/src/base/NotificationController.h
copy to accessible/src/base/EventQueue.h
--- a/accessible/src/base/NotificationController.h
+++ b/accessible/src/base/EventQueue.h
@@ -1,207 +1,46 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef NotificationController_h_
-#define NotificationController_h_
+#ifndef mozilla_a11y_EventQueue_h_
+#define mozilla_a11y_EventQueue_h_
 
 #include "AccEvent.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsRefreshDriver.h"
-
-#ifdef A11Y_LOG
-#include "Logging.h"
-#endif
 
 class nsIContent;
 
 namespace mozilla {
 namespace a11y {
 
-class Accessible;
 class DocAccessible;
 
 /**
- * Notification interface.
+ * Used to organize and coalesce pending events.
  */
-class Notification
-{
-public:
-  virtual ~Notification() { }
-
-  NS_INLINE_DECL_REFCOUNTING(Notification)
-
-  /**
-   * Process notification.
-   */
-  virtual void Process() = 0;
-
-protected:
-  Notification() { }
-
-private:
-  Notification(const Notification&);
-  Notification& operator = (const Notification&);
-};
-
-
-/**
- * Template class for generic notification.
- *
- * @note  Instance is kept as a weak ref, the caller must guarantee it exists
- *        longer than the document accessible owning the notification controller
- *        that this notification is processed by.
- */
-template<class Class, class Arg>
-class TNotification : public Notification
+class EventQueue
 {
-public:
-  typedef void (Class::*Callback)(Arg*);
-
-  TNotification(Class* aInstance, Callback aCallback, Arg* aArg) :
-    mInstance(aInstance), mCallback(aCallback), mArg(aArg) { }
-  virtual ~TNotification() { mInstance = nullptr; }
-
-  virtual void Process()
-  {
-    (mInstance->*mCallback)(mArg);
-
-    mInstance = nullptr;
-    mCallback = nullptr;
-    mArg = nullptr;
-  }
-
-private:
-  TNotification(const TNotification&);
-  TNotification& operator = (const TNotification&);
-
-  Class* mInstance;
-  Callback mCallback;
-  nsRefPtr<Arg> mArg;
-};
-
-/**
- * Used to process notifications from core for the document accessible.
- */
-class NotificationController : public nsARefreshObserver
-{
-public:
-  NotificationController(DocAccessible* aDocument, nsIPresShell* aPresShell);
-  virtual ~NotificationController();
-
-  NS_IMETHOD_(nsrefcnt) AddRef(void);
-  NS_IMETHOD_(nsrefcnt) Release(void);
-
-  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)
-
-  /**
-   * Shutdown the notification controller.
-   */
-  void Shutdown();
+protected:
+  EventQueue(DocAccessible* aDocument) : mDocument(aDocument) { }
 
   /**
    * Put an accessible event into the queue to process it later.
    */
-  void QueueEvent(AccEvent* aEvent);
-
-  /**
-   * Schedule binding the child document to the tree of this document.
-   */
-  void ScheduleChildDocBinding(DocAccessible* aDocument);
-
-  /**
-   * Schedule the accessible tree update because of rendered text changes.
-   */
-  inline void ScheduleTextUpdate(nsIContent* aTextNode)
-  {
-    if (mTextHash.PutEntry(aTextNode))
-      ScheduleProcessing();
-  }
-
-  /**
-   * Pend accessible tree update for content insertion.
-   */
-  void ScheduleContentInsertion(Accessible* aContainer,
-                                nsIContent* aStartChildNode,
-                                nsIContent* aEndChildNode);
+  bool PushEvent(AccEvent* aEvent);
 
   /**
-   * Process the generic notification synchronously if there are no pending
-   * layout changes and no notifications are pending or being processed right
-   * now. Otherwise, queue it up to process asynchronously.
-   *
-   * @note  The caller must guarantee that the given instance still exists when
-   *        the notification is processed.
+   * Process events from the queue and fires events.
    */
-  template<class Class, class Arg>
-  inline void HandleNotification(Class* aInstance,
-                                 typename TNotification<Class, Arg>::Callback aMethod,
-                                 Arg* aArg)
-  {
-    if (!IsUpdatePending()) {
-#ifdef A11Y_LOG
-      if (mozilla::a11y::logging::IsEnabled(mozilla::a11y::logging::eNotifications))
-        mozilla::a11y::logging::Text("sync notification processing");
-#endif
-      (aInstance->*aMethod)(aArg);
-      return;
-    }
-
-    nsRefPtr<Notification> notification =
-      new TNotification<Class, Arg>(aInstance, aMethod, aArg);
-    if (notification && mNotifications.AppendElement(notification))
-      ScheduleProcessing();
-  }
-
-  /**
-   * Schedule the generic notification to process asynchronously.
-   *
-   * @note  The caller must guarantee that the given instance still exists when
-   *        the notification is processed.
-   */
-  template<class Class, class Arg>
-  inline void ScheduleNotification(Class* aInstance,
-                                   typename TNotification<Class, Arg>::Callback aMethod,
-                                   Arg* aArg)
-  {
-    nsRefPtr<Notification> notification =
-      new TNotification<Class, Arg>(aInstance, aMethod, aArg);
-    if (notification && mNotifications.AppendElement(notification))
-      ScheduleProcessing();
-  }
-
-#ifdef DEBUG
-  bool IsUpdating() const
-    { return mObservingState == eRefreshProcessingForUpdate; }
-#endif
-
-protected:
-  nsCycleCollectingAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-
-  /**
-   * Start to observe refresh to make notifications and events processing after
-   * layout.
-   */
-  void ScheduleProcessing();
-
-  /**
-   * Return true if the accessible tree state update is pending.
-   */
-  bool IsUpdatePending();
+  void ProcessEventQueue();
 
 private:
-  NotificationController(const NotificationController&);
-  NotificationController& operator = (const NotificationController&);
-
-  // nsARefreshObserver
-  virtual void WillRefresh(mozilla::TimeStamp aTime);
+  EventQueue(const EventQueue&) MOZ_DELETE;
+  EventQueue& operator = (const EventQueue&) MOZ_DELETE;
 
   // Event queue processing
   /**
    * Coalesce redundant events from the queue.
    */
   void CoalesceEvents();
 
   /**
@@ -226,132 +65,26 @@ private:
 
   /**
     * Create text change event caused by hide or show event. When a node is
     * hidden/removed or shown/appended, the text in an ancestor hyper text will
     * lose or get new characters.
     */
    void CreateTextChangeEventFor(AccMutationEvent* aEvent);
 
-  // Event queue processing
-
-  /**
-   * Process events from the queue and fires events.
-   */
-  void ProcessEventQueue();
-
-private:
-  /**
-   * Indicates whether we're waiting on an event queue processing from our
-   * notification controller to flush events.
-   */
-  enum eObservingState {
-    eNotObservingRefresh,
-    eRefreshObserving,
-    eRefreshProcessingForUpdate
-  };
-  eObservingState mObservingState;
+protected:
 
   /**
    * The document accessible reference owning this queue.
    */
   nsRefPtr<DocAccessible> mDocument;
 
   /**
-   * The presshell of the document accessible.
-   */
-  nsIPresShell* mPresShell;
-
-  /**
-   * Child documents that needs to be bound to the tree.
-   */
-  nsTArray<nsRefPtr<DocAccessible> > mHangingChildDocuments;
-
-  /**
-   * Storage for content inserted notification information.
-   */
-  class ContentInsertion
-  {
-  public:
-    ContentInsertion(DocAccessible* aDocument, Accessible* aContainer);
-    virtual ~ContentInsertion() { mDocument = nullptr; }
-
-    NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ContentInsertion)
-    NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ContentInsertion)
-
-    bool InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode);
-    void Process();
-
-  private:
-    ContentInsertion();
-    ContentInsertion(const ContentInsertion&);
-    ContentInsertion& operator = (const ContentInsertion&);
-
-    // The document used to process content insertion, matched to document of
-    // the notification controller that this notification belongs to, therefore
-    // it's ok to keep it as weak ref.
-    DocAccessible* mDocument;
-
-    // The container accessible that content insertion occurs within.
-    nsRefPtr<Accessible> mContainer;
-
-    // Array of inserted contents.
-    nsTArray<nsCOMPtr<nsIContent> > mInsertedContent;
-  };
-
-  /**
-   * A pending accessible tree update notifications for content insertions.
-   * Don't make this an nsAutoTArray; we use SwapElements() on it.
-   */
-  nsTArray<nsRefPtr<ContentInsertion> > mContentInsertions;
-
-  template<class T>
-  class nsCOMPtrHashKey : public PLDHashEntryHdr
-  {
-  public:
-    typedef T* KeyType;
-    typedef const T* KeyTypePointer;
-
-    nsCOMPtrHashKey(const T* aKey) : mKey(const_cast<T*>(aKey)) {}
-    nsCOMPtrHashKey(const nsPtrHashKey<T> &aToCopy) : mKey(aToCopy.mKey) {}
-    ~nsCOMPtrHashKey() { }
-
-    KeyType GetKey() const { return mKey; }
-    bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
-
-    static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
-    static PLDHashNumber HashKey(KeyTypePointer aKey)
-      { return NS_PTR_TO_INT32(aKey) >> 2; }
-
-    enum { ALLOW_MEMMOVE = true };
-
-   protected:
-     nsCOMPtr<T> mKey;
-  };
-
-  /**
-   * A pending accessible tree update notifications for rendered text changes.
-   */
-  nsTHashtable<nsCOMPtrHashKey<nsIContent> > mTextHash;
-
-  /**
-   * Update the accessible tree for pending rendered text change notifications.
-   */
-  static PLDHashOperator TextEnumerator(nsCOMPtrHashKey<nsIContent>* aEntry,
-                                        void* aUserArg);
-
-  /**
-   * Other notifications like DOM events. Don't make this an nsAutoTArray; we
-   * use SwapElements() on it.
-   */
-  nsTArray<nsRefPtr<Notification> > mNotifications;
-
-  /**
    * Pending events array. Don't make this an nsAutoTArray; we use
    * SwapElements() on it.
    */
   nsTArray<nsRefPtr<AccEvent> > mEvents;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
-#endif
+#endif // mozilla_a11y_EventQueue_h_
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -17,16 +17,17 @@ LIBXUL_LIBRARY = 1
 CPPSRCS = \
   AccCollector.cpp \
   AccEvent.cpp \
   AccGroupInfo.cpp \
   AccIterator.cpp \
   Filters.cpp \
   ARIAStateMap.cpp \
   DocManager.cpp \
+  EventQueue.cpp \
   FocusManager.cpp \
   NotificationController.cpp \
   nsAccessNode.cpp \
   nsARIAMap.cpp \
   nsCoreUtils.cpp \
   nsAccUtils.cpp \
   nsAccessibilityService.cpp \
   nsAccessiblePivot.cpp \
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -1,47 +1,37 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "NotificationController.h"
 
 #include "Accessible-inl.h"
-#include "nsAccessibilityService.h"
-#include "nsAccUtils.h"
-#include "nsCoreUtils.h"
 #include "DocAccessible-inl.h"
-#include "nsEventShell.h"
-#include "FocusManager.h"
-#include "Role.h"
 #include "TextLeafAccessible.h"
 #include "TextUpdater.h"
 
-#ifdef A11Y_LOG
-#include "Logging.h"
-#endif
-
 #include "mozilla/dom/Element.h"
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 // Defines the number of selection add/remove events in the queue when they
 // aren't packed into single selection within event.
 const unsigned int kSelChangeCountToPack = 5;
 
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector
 ////////////////////////////////////////////////////////////////////////////////
 
 NotificationController::NotificationController(DocAccessible* aDocument,
                                                nsIPresShell* aPresShell) :
-  mObservingState(eNotObservingRefresh), mDocument(aDocument),
+  EventQueue(aDocument), mObservingState(eNotObservingRefresh),
   mPresShell(aPresShell)
 {
   mTextHash.Init();
 
   // Schedule initial accessible tree construction.
   ScheduleProcessing();
 }
 
@@ -98,38 +88,16 @@ NotificationController::Shutdown()
 
   mTextHash.Clear();
   mContentInsertions.Clear();
   mNotifications.Clear();
   mEvents.Clear();
 }
 
 void
-NotificationController::QueueEvent(AccEvent* aEvent)
-{
-  NS_ASSERTION((aEvent->mAccessible && aEvent->mAccessible->IsApplication()) ||
-               aEvent->GetDocAccessible() == mDocument,
-               "Queued event belongs to another document!");
-
-  if (!mEvents.AppendElement(aEvent))
-    return;
-
-  // Filter events.
-  CoalesceEvents();
-
-  // Associate text change with hide event if it wasn't stolen from hiding
-  // siblings during coalescence.
-  AccMutationEvent* showOrHideEvent = downcast_accEvent(aEvent);
-  if (showOrHideEvent && !showOrHideEvent->mTextChangeEvent)
-    CreateTextChangeEventFor(showOrHideEvent);
-
-  ScheduleProcessing();
-}
-
-void
 NotificationController::ScheduleChildDocBinding(DocAccessible* aDocument)
 {
   // Schedule child document binding to the tree.
   mHangingChildDocuments.AppendElement(aDocument);
   ScheduleProcessing();
 }
 
 void
@@ -311,461 +279,16 @@ NotificationController::WillRefresh(mozi
       mEvents.Length() == 0 && mTextHash.Count() == 0 &&
       mHangingChildDocuments.Length() == 0 &&
       mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
       mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
     mObservingState = eNotObservingRefresh;
   }
 }
 
-void
-NotificationController::CoalesceEvents()
-{
-  NS_ASSERTION(mEvents.Length(), "There should be at least one pending event!");
-  uint32_t tail = mEvents.Length() - 1;
-  AccEvent* tailEvent = mEvents[tail];
-
-  switch(tailEvent->mEventRule) {
-    case AccEvent::eCoalesceReorder:
-      CoalesceReorderEvents(tailEvent);
-      break; // case eCoalesceReorder
-
-    case AccEvent::eCoalesceMutationTextChange:
-    {
-      for (uint32_t index = tail - 1; index < tail; index--) {
-        AccEvent* thisEvent = mEvents[index];
-        if (thisEvent->mEventRule != tailEvent->mEventRule)
-          continue;
-
-        // We don't currently coalesce text change events from show/hide events.
-        if (thisEvent->mEventType != tailEvent->mEventType)
-          continue;
-
-        // Show events may be duped because of reinsertion (removal is ignored
-        // because initial insertion is not processed). Ignore initial
-        // insertion.
-        if (thisEvent->mAccessible == tailEvent->mAccessible)
-          thisEvent->mEventRule = AccEvent::eDoNotEmit;
-
-        AccMutationEvent* tailMutationEvent = downcast_accEvent(tailEvent);
-        AccMutationEvent* thisMutationEvent = downcast_accEvent(thisEvent);
-        if (tailMutationEvent->mParent != thisMutationEvent->mParent)
-          continue;
-
-        // Coalesce text change events for hide and show events.
-        if (thisMutationEvent->IsHide()) {
-          AccHideEvent* tailHideEvent = downcast_accEvent(tailEvent);
-          AccHideEvent* thisHideEvent = downcast_accEvent(thisEvent);
-          CoalesceTextChangeEventsFor(tailHideEvent, thisHideEvent);
-          break;
-        }
-
-        AccShowEvent* tailShowEvent = downcast_accEvent(tailEvent);
-        AccShowEvent* thisShowEvent = downcast_accEvent(thisEvent);
-        CoalesceTextChangeEventsFor(tailShowEvent, thisShowEvent);
-        break;
-      }
-    } break; // case eCoalesceMutationTextChange
-
-    case AccEvent::eCoalesceOfSameType:
-    {
-      // Coalesce old events by newer event.
-      for (uint32_t index = tail - 1; index < tail; index--) {
-        AccEvent* accEvent = mEvents[index];
-        if (accEvent->mEventType == tailEvent->mEventType &&
-          accEvent->mEventRule == tailEvent->mEventRule) {
-          accEvent->mEventRule = AccEvent::eDoNotEmit;
-          return;
-        }
-      }
-    } break; // case eCoalesceOfSameType
-
-    case AccEvent::eCoalesceSelectionChange:
-    {
-      AccSelChangeEvent* tailSelChangeEvent = downcast_accEvent(tailEvent);
-      for (uint32_t index = tail - 1; index < tail; index--) {
-        AccEvent* thisEvent = mEvents[index];
-        if (thisEvent->mEventRule == tailEvent->mEventRule) {
-          AccSelChangeEvent* thisSelChangeEvent =
-            downcast_accEvent(thisEvent);
-
-          // Coalesce selection change events within same control.
-          if (tailSelChangeEvent->mWidget == thisSelChangeEvent->mWidget) {
-            CoalesceSelChangeEvents(tailSelChangeEvent, thisSelChangeEvent, index);
-            return;
-          }
-        }
-      }
-
-    } break; // eCoalesceSelectionChange
-
-    case AccEvent::eCoalesceStateChange:
-    {
-      // If state change event is duped then ignore previous event. If state
-      // change event is opposite to previous event then no event is emitted
-      // (accessible state wasn't changed).
-      for (uint32_t index = tail - 1; index < tail; index--) {
-        AccEvent* thisEvent = mEvents[index];
-        if (thisEvent->mEventRule != AccEvent::eDoNotEmit &&
-            thisEvent->mEventType == tailEvent->mEventType &&
-            thisEvent->mAccessible == tailEvent->mAccessible) {
-          AccStateChangeEvent* thisSCEvent = downcast_accEvent(thisEvent);
-          AccStateChangeEvent* tailSCEvent = downcast_accEvent(tailEvent);
-          if (thisSCEvent->mState == tailSCEvent->mState) {
-            thisEvent->mEventRule = AccEvent::eDoNotEmit;
-            if (thisSCEvent->mIsEnabled != tailSCEvent->mIsEnabled)
-              tailEvent->mEventRule = AccEvent::eDoNotEmit;
-          }
-        }
-      }
-      break; // eCoalesceStateChange
-    }
-
-    case AccEvent::eRemoveDupes:
-    {
-      // Check for repeat events, coalesce newly appended event by more older
-      // event.
-      for (uint32_t index = tail - 1; index < tail; index--) {
-        AccEvent* accEvent = mEvents[index];
-        if (accEvent->mEventType == tailEvent->mEventType &&
-          accEvent->mEventRule == tailEvent->mEventRule &&
-          accEvent->mAccessible == tailEvent->mAccessible) {
-          tailEvent->mEventRule = AccEvent::eDoNotEmit;
-          return;
-        }
-      }
-    } break; // case eRemoveDupes
-
-    default:
-      break; // case eAllowDupes, eDoNotEmit
-  } // switch
-}
-
-void
-NotificationController::CoalesceReorderEvents(AccEvent* aTailEvent)
-{
-  uint32_t count = mEvents.Length();
-  for (uint32_t index = count - 2; index < count; index--) {
-    AccEvent* thisEvent = mEvents[index];
-
-    // Skip events of different types and targeted to application accessible.
-    if (thisEvent->mEventType != aTailEvent->mEventType ||
-        thisEvent->mAccessible->IsApplication())
-      continue;
-
-    // If thisEvent target is not in document longer, i.e. if it was
-    // removed from the tree then do not emit the event.
-    if (!thisEvent->mAccessible->IsDoc() &&
-        !thisEvent->mAccessible->IsInDocument()) {
-      thisEvent->mEventRule = AccEvent::eDoNotEmit;
-      continue;
-    }
-
-    // Coalesce earlier event of the same target.
-    if (thisEvent->mAccessible == aTailEvent->mAccessible) {
-      if (thisEvent->mEventRule == AccEvent::eDoNotEmit) {
-        AccReorderEvent* tailReorder = downcast_accEvent(aTailEvent);
-        tailReorder->DoNotEmitAll();
-      } else {
-        thisEvent->mEventRule = AccEvent::eDoNotEmit;
-      }
-
-      return;
-    }
-
-    // If tailEvent contains thisEvent
-    // then
-    //   if show of tailEvent contains a grand parent of thisEvent
-    //   then assert
-    //   else if hide of tailEvent contains a grand parent of thisEvent
-    //   then ignore thisEvent and its show and hide events
-    //   otherwise ignore thisEvent but not its show and hide events
-    Accessible* thisParent = thisEvent->mAccessible;
-    while (thisParent && thisParent != mDocument) {
-      if (thisParent->Parent() == aTailEvent->mAccessible) {
-        AccReorderEvent* tailReorder = downcast_accEvent(aTailEvent);
-        uint32_t eventType = tailReorder->IsShowHideEventTarget(thisParent);
-
-        if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
-           NS_ERROR("Accessible tree was created after it was modified! Huh?");
-        } else if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
-          AccReorderEvent* thisReorder = downcast_accEvent(thisEvent);
-          thisReorder->DoNotEmitAll();
-        } else {
-          thisEvent->mEventRule = AccEvent::eDoNotEmit;
-        }
-
-        return;
-      }
-
-      thisParent = thisParent->Parent();
-    }
-
-    // If tailEvent is contained by thisEvent
-    // then
-    //   if show of thisEvent contains the tailEvent
-    //   then ignore tailEvent
-    //   if hide of thisEvent contains the tailEvent
-    //   then assert
-    //   otherwise ignore tailEvent but not its show and hide events
-    Accessible* tailParent = aTailEvent->mAccessible;
-    while (tailParent && tailParent != mDocument) {
-      if (tailParent->Parent() == thisEvent->mAccessible) {
-        AccReorderEvent* thisReorder = downcast_accEvent(thisEvent);
-        AccReorderEvent* tailReorder = downcast_accEvent(aTailEvent);
-        uint32_t eventType = thisReorder->IsShowHideEventTarget(tailParent);
-        if (eventType == nsIAccessibleEvent::EVENT_SHOW)
-          tailReorder->DoNotEmitAll();
-        else if (eventType == nsIAccessibleEvent::EVENT_HIDE)
-          NS_ERROR("Accessible tree was modified after it was removed! Huh?");
-        else
-          aTailEvent->mEventRule = AccEvent::eDoNotEmit;
-
-        return;
-      }
-
-      tailParent = tailParent->Parent();
-    }
-
-  } // for (index)
-}
-
-void
-NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
-                                                AccSelChangeEvent* aThisEvent,
-                                                uint32_t aThisIndex)
-{
-  aTailEvent->mPreceedingCount = aThisEvent->mPreceedingCount + 1;
-
-  // Pack all preceding events into single selection within event
-  // when we receive too much selection add/remove events.
-  if (aTailEvent->mPreceedingCount >= kSelChangeCountToPack) {
-    aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION_WITHIN;
-    aTailEvent->mAccessible = aTailEvent->mWidget;
-    aThisEvent->mEventRule = AccEvent::eDoNotEmit;
-
-    // Do not emit any preceding selection events for same widget if they
-    // weren't coalesced yet.
-    if (aThisEvent->mEventType != nsIAccessibleEvent::EVENT_SELECTION_WITHIN) {
-      for (uint32_t jdx = aThisIndex - 1; jdx < aThisIndex; jdx--) {
-        AccEvent* prevEvent = mEvents[jdx];
-        if (prevEvent->mEventRule == aTailEvent->mEventRule) {
-          AccSelChangeEvent* prevSelChangeEvent =
-            downcast_accEvent(prevEvent);
-          if (prevSelChangeEvent->mWidget == aTailEvent->mWidget)
-            prevSelChangeEvent->mEventRule = AccEvent::eDoNotEmit;
-        }
-      }
-    }
-    return;
-  }
-
-  // Pack sequential selection remove and selection add events into
-  // single selection change event.
-  if (aTailEvent->mPreceedingCount == 1 &&
-      aTailEvent->mItem != aThisEvent->mItem) {
-    if (aTailEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd &&
-        aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionRemove) {
-      aThisEvent->mEventRule = AccEvent::eDoNotEmit;
-      aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION;
-      aTailEvent->mPackedEvent = aThisEvent;
-      return;
-    }
-
-    if (aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd &&
-        aTailEvent->mSelChangeType == AccSelChangeEvent::eSelectionRemove) {
-      aTailEvent->mEventRule = AccEvent::eDoNotEmit;
-      aThisEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION;
-      aThisEvent->mPackedEvent = aThisEvent;
-      return;
-    }
-  }
-
-  // Unpack the packed selection change event because we've got one
-  // more selection add/remove.
-  if (aThisEvent->mEventType == nsIAccessibleEvent::EVENT_SELECTION) {
-    if (aThisEvent->mPackedEvent) {
-      aThisEvent->mPackedEvent->mEventType =
-        aThisEvent->mPackedEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
-          nsIAccessibleEvent::EVENT_SELECTION_ADD :
-          nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
-
-      aThisEvent->mPackedEvent->mEventRule =
-        AccEvent::eCoalesceSelectionChange;
-
-      aThisEvent->mPackedEvent = nullptr;
-    }
-
-    aThisEvent->mEventType =
-      aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
-        nsIAccessibleEvent::EVENT_SELECTION_ADD :
-        nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
-
-    return;
-  }
-
-  // Convert into selection add since control has single selection but other
-  // selection events for this control are queued.
-  if (aTailEvent->mEventType == nsIAccessibleEvent::EVENT_SELECTION)
-    aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
-}
-
-void
-NotificationController::CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
-                                                    AccHideEvent* aThisEvent)
-{
-  // XXX: we need a way to ignore SplitNode and JoinNode() when they do not
-  // affect the text within the hypertext.
-
-  AccTextChangeEvent* textEvent = aThisEvent->mTextChangeEvent;
-  if (!textEvent)
-    return;
-
-  if (aThisEvent->mNextSibling == aTailEvent->mAccessible) {
-    aTailEvent->mAccessible->AppendTextTo(textEvent->mModifiedText);
-
-  } else if (aThisEvent->mPrevSibling == aTailEvent->mAccessible) {
-    uint32_t oldLen = textEvent->GetLength();
-    aTailEvent->mAccessible->AppendTextTo(textEvent->mModifiedText);
-    textEvent->mStart -= textEvent->GetLength() - oldLen;
-  }
-
-  aTailEvent->mTextChangeEvent.swap(aThisEvent->mTextChangeEvent);
-}
-
-void
-NotificationController::CoalesceTextChangeEventsFor(AccShowEvent* aTailEvent,
-                                                    AccShowEvent* aThisEvent)
-{
-  AccTextChangeEvent* textEvent = aThisEvent->mTextChangeEvent;
-  if (!textEvent)
-    return;
-
-  if (aTailEvent->mAccessible->IndexInParent() ==
-      aThisEvent->mAccessible->IndexInParent() + 1) {
-    // If tail target was inserted after this target, i.e. tail target is next
-    // sibling of this target.
-    aTailEvent->mAccessible->AppendTextTo(textEvent->mModifiedText);
-
-  } else if (aTailEvent->mAccessible->IndexInParent() ==
-             aThisEvent->mAccessible->IndexInParent() -1) {
-    // If tail target was inserted before this target, i.e. tail target is
-    // previous sibling of this target.
-    nsAutoString startText;
-    aTailEvent->mAccessible->AppendTextTo(startText);
-    textEvent->mModifiedText = startText + textEvent->mModifiedText;
-    textEvent->mStart -= startText.Length();
-  }
-
-  aTailEvent->mTextChangeEvent.swap(aThisEvent->mTextChangeEvent);
-}
-
-void
-NotificationController::CreateTextChangeEventFor(AccMutationEvent* aEvent)
-{
-  Accessible* container = aEvent->mAccessible->Parent();
-  if (!container)
-    return;
-
-  HyperTextAccessible* textAccessible = container->AsHyperText();
-  if (!textAccessible)
-    return;
-
-  // Don't fire event for the first html:br in an editor.
-  if (aEvent->mAccessible->Role() == roles::WHITESPACE) {
-    nsCOMPtr<nsIEditor> editor = textAccessible->GetEditor();
-    if (editor) {
-      bool isEmpty = false;
-      editor->GetDocumentIsEmpty(&isEmpty);
-      if (isEmpty)
-        return;
-    }
-  }
-
-  int32_t offset = textAccessible->GetChildOffset(aEvent->mAccessible);
-
-  nsAutoString text;
-  aEvent->mAccessible->AppendTextTo(text);
-  if (text.IsEmpty())
-    return;
-
-  aEvent->mTextChangeEvent =
-    new AccTextChangeEvent(textAccessible, offset, text, aEvent->IsShow(),
-                           aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationController: event queue
-
-void
-NotificationController::ProcessEventQueue()
-{
-  // Process only currently queued events.
-  nsTArray<nsRefPtr<AccEvent> > events;
-  events.SwapElements(mEvents);
-
-  uint32_t eventCount = events.Length();
-#ifdef A11Y_LOG
-  if (eventCount > 0 && logging::IsEnabled(logging::eEvents)) {
-    logging::MsgBegin("EVENTS", "events processing");
-    logging::Address("document", mDocument);
-    logging::MsgEnd();
-  }
-#endif
-
-  for (uint32_t idx = 0; idx < eventCount; idx++) {
-    AccEvent* event = events[idx];
-    if (event->mEventRule != AccEvent::eDoNotEmit) {
-      Accessible* target = event->GetAccessible();
-      if (!target || target->IsDefunct())
-        continue;
-
-      // Dispatch the focus event if target is still focused.
-      if (event->mEventType == nsIAccessibleEvent::EVENT_FOCUS) {
-        FocusMgr()->ProcessFocusEvent(event);
-        continue;
-      }
-
-      // Dispatch caret moved and text selection change events.
-      if (event->mEventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
-        AccCaretMoveEvent* caretMoveEvent = downcast_accEvent(event);
-        HyperTextAccessible* hyperText = target->AsHyperText();
-        if (hyperText &&
-            NS_SUCCEEDED(hyperText->GetCaretOffset(&caretMoveEvent->mCaretOffset))) {
-
-          nsEventShell::FireEvent(caretMoveEvent);
-
-          // There's a selection so fire selection change as well.
-          int32_t selectionCount;
-          hyperText->GetSelectionCount(&selectionCount);
-          if (selectionCount)
-            nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED,
-                                    hyperText);
-        }
-        continue;
-      }
-
-      nsEventShell::FireEvent(event);
-
-      // Fire text change events.
-      AccMutationEvent* mutationEvent = downcast_accEvent(event);
-      if (mutationEvent) {
-        if (mutationEvent->mTextChangeEvent)
-          nsEventShell::FireEvent(mutationEvent->mTextChangeEvent);
-      }
-    }
-
-    if (event->mEventType == nsIAccessibleEvent::EVENT_HIDE)
-      mDocument->ShutdownChildrenInSubtree(event->mAccessible);
-
-    if (!mDocument)
-      return;
-  }
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Notification controller: text leaf accessible text update
 
 PLDHashOperator
 NotificationController::TextEnumerator(nsCOMPtrHashKey<nsIContent>* aEntry,
                                        void* aUserArg)
 {
   DocAccessible* document = static_cast<DocAccessible*>(aUserArg);
--- a/accessible/src/base/NotificationController.h
+++ b/accessible/src/base/NotificationController.h
@@ -1,17 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef NotificationController_h_
-#define NotificationController_h_
+#ifndef mozilla_a11y_NotificationController_h_
+#define mozilla_a11y_NotificationController_h_
 
-#include "AccEvent.h"
+#include "EventQueue.h"
+
 #include "nsCycleCollectionParticipant.h"
 #include "nsRefreshDriver.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 class nsIContent;
@@ -79,17 +80,18 @@ private:
   Class* mInstance;
   Callback mCallback;
   nsRefPtr<Arg> mArg;
 };
 
 /**
  * Used to process notifications from core for the document accessible.
  */
-class NotificationController : public nsARefreshObserver
+class NotificationController : public EventQueue,
+                               public nsARefreshObserver
 {
 public:
   NotificationController(DocAccessible* aDocument, nsIPresShell* aPresShell);
   virtual ~NotificationController();
 
   NS_IMETHOD_(nsrefcnt) AddRef(void);
   NS_IMETHOD_(nsrefcnt) Release(void);
 
@@ -98,17 +100,21 @@ public:
   /**
    * Shutdown the notification controller.
    */
   void Shutdown();
 
   /**
    * Put an accessible event into the queue to process it later.
    */
-  void QueueEvent(AccEvent* aEvent);
+  void QueueEvent(AccEvent* aEvent)
+  {
+    if (PushEvent(aEvent))
+      ScheduleProcessing();
+  }
 
   /**
    * Schedule binding the child document to the tree of this document.
    */
   void ScheduleChildDocBinding(DocAccessible* aDocument);
 
   /**
    * Schedule the accessible tree update because of rendered text changes.
@@ -193,74 +199,29 @@ protected:
 
 private:
   NotificationController(const NotificationController&);
   NotificationController& operator = (const NotificationController&);
 
   // nsARefreshObserver
   virtual void WillRefresh(mozilla::TimeStamp aTime);
 
-  // Event queue processing
-  /**
-   * Coalesce redundant events from the queue.
-   */
-  void CoalesceEvents();
-
-  /**
-   * Coalesce events from the same subtree.
-   */
-  void CoalesceReorderEvents(AccEvent* aTailEvent);
-
-  /**
-   * Coalesce two selection change events within the same select control.
-   */
-  void CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
-                               AccSelChangeEvent* aThisEvent,
-                               uint32_t aThisIndex);
-
-  /**
-   * Coalesce text change events caused by sibling hide events.
-   */
-  void CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
-                                   AccHideEvent* aThisEvent);
-  void CoalesceTextChangeEventsFor(AccShowEvent* aTailEvent,
-                                   AccShowEvent* aThisEvent);
-
-  /**
-    * Create text change event caused by hide or show event. When a node is
-    * hidden/removed or shown/appended, the text in an ancestor hyper text will
-    * lose or get new characters.
-    */
-   void CreateTextChangeEventFor(AccMutationEvent* aEvent);
-
-  // Event queue processing
-
-  /**
-   * Process events from the queue and fires events.
-   */
-  void ProcessEventQueue();
-
 private:
   /**
    * Indicates whether we're waiting on an event queue processing from our
    * notification controller to flush events.
    */
   enum eObservingState {
     eNotObservingRefresh,
     eRefreshObserving,
     eRefreshProcessingForUpdate
   };
   eObservingState mObservingState;
 
   /**
-   * The document accessible reference owning this queue.
-   */
-  nsRefPtr<DocAccessible> mDocument;
-
-  /**
    * The presshell of the document accessible.
    */
   nsIPresShell* mPresShell;
 
   /**
    * Child documents that needs to be bound to the tree.
    */
   nsTArray<nsRefPtr<DocAccessible> > mHangingChildDocuments;
@@ -338,20 +299,14 @@ private:
   static PLDHashOperator TextEnumerator(nsCOMPtrHashKey<nsIContent>* aEntry,
                                         void* aUserArg);
 
   /**
    * Other notifications like DOM events. Don't make this an nsAutoTArray; we
    * use SwapElements() on it.
    */
   nsTArray<nsRefPtr<Notification> > mNotifications;
-
-  /**
-   * Pending events array. Don't make this an nsAutoTArray; we use
-   * SwapElements() on it.
-   */
-  nsTArray<nsRefPtr<AccEvent> > mEvents;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
-#endif
+#endif // mozilla_a11y_NotificationController_h_
--- a/accessible/src/generic/DocAccessible.h
+++ b/accessible/src/generic/DocAccessible.h
@@ -576,16 +576,17 @@ protected:
    * @see ProcessInvalidationList
    */
   nsTArray<nsIContent*> mInvalidationList;
 
   /**
    * Used to process notification from core and accessible events.
    */
   nsRefPtr<NotificationController> mNotificationController;
+  friend class EventQueue;
   friend class NotificationController;
 
 private:
 
   nsIPresShell* mPresShell;
 };
 
 inline DocAccessible*
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -1179,16 +1179,19 @@ HyperTextAccessible::NativeAttributes()
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("contentinfo"));
   else if (mContent->Tag() == nsGkAtoms::aside) 
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("complementary"));
   else if (mContent->Tag() == nsGkAtoms::article)
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("article"));
+  else if (mContent->Tag() == nsGkAtoms::main)
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
+                           NS_LITERAL_STRING("main"));
 
   return attributes.forget();
 }
 
 /*
  * Given an offset, the x, y, width, and height values are filled appropriately.
  */
 NS_IMETHODIMP
--- a/accessible/tests/mochitest/attributes/test_xml-roles.html
+++ b/accessible/tests/mochitest/attributes/test_xml-roles.html
@@ -22,16 +22,17 @@
       // Some AT may look for this
       testAttrs("nav", {"xml-roles" : "navigation"}, true);
       testAttrs("footer", {"xml-roles" : "contentinfo"}, true);
       testAttrs("aside", {"xml-roles" : "complementary"}, true);
       testAttrs("section", {"xml-roles" : "region"}, true);
       testAttrs("main", {"xml-roles" : "main"}, true); // // ARIA override
       testAttrs("form", {"xml-roles" : "form"}, true);
       testAttrs("article", {"xml-roles" : "article"}, true);
+      testAttrs("main_element", {"xml-roles" : "main"}, true);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
@@ -74,11 +75,12 @@
 
   <nav id="nav">a nav</nav>
   <footer id="footer">a footer</footer>
   <aside id="aside">by the way I am an aside</aside>
   <section id="section">a section</section>
   <article id="main" role="main">a main area</article>
   <article id="form" role="form">a form area</article>
   <article id="article">article</article>
+  <main id="main_element">another main area</main>
 
 </body>
 </html>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1260,17 +1260,17 @@ var gBrowserInit = {
     IndexedDBPromptHelper.init();
     gFormSubmitObserver.init();
     SocialUI.init();
     AddonManager.addAddonListener(AddonsMgrListener);
     WebrtcIndicator.init();
 
     gBrowser.addEventListener("pageshow", function(event) {
       // Filter out events that are not about the document load we are interested in
-      if (event.target == content.document)
+      if (content && event.target == content.document)
         setTimeout(pageShowEventHandlers, 0, event);
     }, true);
 
     // Ensure login manager is up and running.
     Services.logins;
 
     if (mustLoadSidebar) {
       let sidebar = document.getElementById("sidebar");
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_595934_message_categories.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_595934_message_categories.js
@@ -127,17 +127,18 @@ let TestObserver = {
       info("unexpected message was: " + aSubject.sourceName + ':' + aSubject.lineNumber + '; ' +
                 aSubject.errorMessage);
     }
   }
 };
 
 function consoleOpened(hud) {
   output = hud.outputNode;
-  output.addEventListener("DOMNodeInserted", onDOMNodeInserted, false);
+
+  nodeInsertedListener.observe(output, {childList: true});
   jsterm = hud.jsterm;
 
   Services.console.registerListener(TestObserver);
 
   registerCleanupFunction(testEnd);
 
   executeSoon(testNext);
 }
@@ -145,16 +146,17 @@ function consoleOpened(hud) {
 function testNext() {
   jsterm.clearOutput();
   foundCategory = false;
   foundText = false;
   pageLoaded = false;
   pageError = false;
 
   pos++;
+  info("testNext: #" + pos);
   if (pos < TESTS.length) {
     waitForSuccess({
       timeout: 10000,
       name: "test #" + pos + " successful finish",
       validatorFn: function()
       {
         return foundCategory && foundText && pageLoaded && pageError;
       },
@@ -194,27 +196,36 @@ function testNext() {
   else {
     testEnded = true;
     executeSoon(finishTest);
   }
 }
 
 function testEnd() {
   Services.console.unregisterListener(TestObserver);
-  output.removeEventListener("DOMNodeInserted", onDOMNodeInserted, false);
+  nodeInsertedListener.disconnect();
   TestObserver = output = jsterm = null;
 }
 
-function onDOMNodeInserted(aEvent) {
-  let textContent = output.textContent;
-  foundText = textContent.indexOf(TESTS[pos].matchString) > -1;
-  if (foundText) {
-    ok(foundText, "test #" + pos + ": message found '" + TESTS[pos].matchString + "'");
+var nodeInsertedListener = new MutationObserver(function(mutations) {
+  if (testEnded) {
+    return;
   }
-}
+
+  for (var mutation of mutations) {
+    if (mutation.addedNodes) {
+      let textContent = output.textContent;
+      foundText = textContent.indexOf(TESTS[pos].matchString) > -1;
+      if (foundText) {
+        ok(foundText, "test #" + pos + ": message found '" + TESTS[pos].matchString + "'");
+      }
+      return;
+    }
+  }
+});
 
 function test() {
   requestLongerTimeout(2);
 
   addTab("data:text/html;charset=utf-8,Web Console test for bug 595934 - message categories coverage.");
   browser.addEventListener("load", function onLoad() {
     browser.removeEventListener("load", onLoad, true);
     openConsole(null, consoleOpened);
--- a/configure.in
+++ b/configure.in
@@ -8506,16 +8506,22 @@ AC_SUBST(USE_DEPENDENT_LIBS)
 
 AC_SUBST(MOZ_BUILD_ROOT)
 AC_SUBST(MOZ_OS2_TOOLS)
 
 AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
 AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
 AC_SUBST(MOZ_LINKER_EXTRACT)
 
+AC_SUBST(MOZ_JSDOWNLOADS)
+
+if test -n "$MOZ_JSDOWNLOADS" ; then
+    AC_DEFINE(MOZ_JSDOWNLOADS)
+fi
+
 dnl ========================================================
 dnl = Mac bundle name prefix
 dnl ========================================================
 MOZ_ARG_WITH_STRING(macbundlename-prefix,
 [  --with-macbundlename-prefix=prefix
                           Prefix for MOZ_MACBUNDLE_NAME],
 [ MOZ_MACBUNDLE_NAME_PREFIX="$withval"])
 
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -40,16 +40,18 @@
 #include "nsContentUtils.h"
 #include "nsINodeList.h"
 #include "mozilla/ErrorResult.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMAttr.h"
 #include "nsISMILAttr.h"
 #include "nsClientRect.h"
 #include "nsEvent.h"
+#include "nsAttrValue.h"
+#include "mozilla/dom/BindingDeclarations.h"
 
 class nsIDOMEventListener;
 class nsIFrame;
 class nsIDOMNamedNodeMap;
 class nsIDOMCSSStyleDeclaration;
 class nsIURI;
 class nsINodeInfo;
 class nsIControllers;
@@ -456,17 +458,17 @@ public:
     return false;
   }
 
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
                            const nsAString& aValue, bool aNotify);
   nsresult SetParsedAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
                          nsAttrValue& aParsedValue, bool aNotify);
   virtual bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                         nsAString& aResult) const;
+                       nsAString& aResult) const;
   virtual bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
   // aCaseSensitive == eIgnoreCaase means ASCII case-insensitive matching.
   virtual bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
                              const nsAString& aValue,
                              nsCaseTreatment aCaseSensitive) const;
   virtual bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
                              nsIAtom* aValue,
                              nsCaseTreatment aCaseSensitive) const;
@@ -512,56 +514,84 @@ public:
   }
 
 private:
   static bool
   FindAttributeDependence(const nsIAtom* aAttribute,
                           const MappedAttributeEntry* const aMaps[],
                           uint32_t aMapCount);
 
+protected:
+  inline bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
+                      mozilla::dom::DOMString& aResult) const
+  {
+    NS_ASSERTION(nullptr != aName, "must have attribute name");
+    NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
+                 "must have a real namespace ID!");
+    MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0,
+               "Should have empty string coming in");
+    const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
+    if (val) {
+      val->ToString(aResult);
+    }
+    // else DOMString comes pre-emptied.
+    return val != nullptr;
+  }
+
 public:
   void GetTagName(nsAString& aTagName) const
   {
     aTagName = NodeName();
   }
   void GetId(nsAString& aId) const
   {
     GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
   }
+  void GetId(mozilla::dom::DOMString& aId) const
+  {
+    GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
+  }
   void SetId(const nsAString& aId)
   {
     SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
   }
 
   nsDOMTokenList* GetClassList();
   nsDOMAttributeMap* GetAttributes()
   {
     nsDOMSlots *slots = DOMSlots();
     if (!slots->mAttributeMap) {
       slots->mAttributeMap = new nsDOMAttributeMap(this);
     }
 
     return slots->mAttributeMap;
   }
-  virtual void GetAttribute(const nsAString& aName, nsString& aReturn);
+  void GetAttribute(const nsAString& aName, nsString& aReturn)
+  {
+    mozilla::dom::DOMString str;
+    GetAttribute(aName, str);
+    str.ToString(aReturn);
+  }
+
+  void GetAttribute(const nsAString& aName, mozilla::dom::DOMString& aReturn);
   void GetAttributeNS(const nsAString& aNamespaceURI,
                       const nsAString& aLocalName,
                       nsAString& aReturn);
   void SetAttribute(const nsAString& aName, const nsAString& aValue,
                     ErrorResult& aError);
   void SetAttributeNS(const nsAString& aNamespaceURI,
                       const nsAString& aLocalName,
                       const nsAString& aValue,
                       ErrorResult& aError);
-  virtual void RemoveAttribute(const nsAString& aName,
-                               ErrorResult& aError);
+  void RemoveAttribute(const nsAString& aName,
+                       ErrorResult& aError);
   void RemoveAttributeNS(const nsAString& aNamespaceURI,
                          const nsAString& aLocalName,
                          ErrorResult& aError);
-  virtual bool HasAttribute(const nsAString& aName) const
+  bool HasAttribute(const nsAString& aName) const
   {
     return InternalGetExistingAttrNameFromQName(aName) != nullptr;
   }
   bool HasAttributeNS(const nsAString& aNamespaceURI,
                       const nsAString& aLocalName) const;
   already_AddRefed<nsIHTMLCollection>
     GetElementsByTagName(const nsAString& aQualifiedName);
   already_AddRefed<nsIHTMLCollection>
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -383,16 +383,17 @@ protected:
   /**
    * WrapNode is called from WrapObject to actually wrap this node, WrapObject
    * does some additional checks and fix-up that's common to all nodes. WrapNode
    * should just call the DOM binding's Wrap function.
    */
   virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
                              bool *aTriedToWrap)
   {
+    MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapNode");
     *aTriedToWrap = false;
     return nullptr;
   }
 
 public:
   nsIDocument* GetParentObject() const
   {
     // Make sure that we get the owner document of the content node, in case
--- a/content/base/src/DocumentFragment.cpp
+++ b/content/base/src/DocumentFragment.cpp
@@ -145,16 +145,17 @@ DocumentFragment::DumpContent(FILE* out,
 NS_INTERFACE_MAP_BEGIN(DocumentFragment)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(DocumentFragment)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentFragment)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNodeSelector,
                                  new nsNodeSelectorTearoff(this))
   // nsNodeSH::PreCreate() depends on the identity pointer being the
   // same as nsINode (which nsIContent inherits), so if you change the
   // below line, make sure nsNodeSH::PreCreate() still does the right
   // thing!
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -693,31 +693,31 @@ Element::GetClientRects(ErrorResult& aEr
   return rectList.forget();
 }
 
 
 //----------------------------------------------------------------------
 
 
 void
-Element::GetAttribute(const nsAString& aName, nsString& aReturn)
+Element::GetAttribute(const nsAString& aName, DOMString& aReturn)
 {
   const nsAttrValue* val =
     mAttrsAndChildren.GetAttr(aName,
                               IsHTML() && IsInHTMLDocument() ?
                                 eIgnoreCase : eCaseMatters);
   if (val) {
     val->ToString(aReturn);
   } else {
     if (IsXUL()) {
       // XXX should be SetDOMStringToNull(aReturn);
       // See bug 232598
-      aReturn.Truncate();
+      // aReturn is already empty
     } else {
-      SetDOMStringToNull(aReturn);
+      aReturn.SetNull();
     }
   }
 }
 
 void
 Element::SetAttribute(const nsAString& aName,
                       const nsAString& aValue,
                       ErrorResult& aError)
@@ -1956,33 +1956,20 @@ Element::GetAttrInfo(int32_t aNamespaceI
   return nsAttrInfo(nullptr, nullptr);
 }
   
 
 bool
 Element::GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                  nsAString& aResult) const
 {
-  NS_ASSERTION(nullptr != aName, "must have attribute name");
-  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
-               "must have a real namespace ID!");
-
-  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
-  if (!val) {
-    // Since we are returning a success code we'd better do
-    // something about the out parameters (someone may have
-    // given us a non-empty string).
-    aResult.Truncate();
-    
-    return false;
-  }
-
-  val->ToString(aResult);
-
-  return true;
+  DOMString str;
+  bool haveAttr = GetAttr(aNameSpaceID, aName, str);
+  str.ToString(aResult);
+  return haveAttr;
 }
 
 bool
 Element::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
 {
   NS_ASSERTION(nullptr != aName, "must have attribute name");
   NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
                "must have a real namespace ID!");
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -1659,16 +1659,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN(FragmentOrElement)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(FragmentOrElement)
   NS_INTERFACE_MAP_ENTRY(Element)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNodeSelector,
                                  new nsNodeSelectorTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsITouchEventReceiver,
                                  new nsTouchEventReceiverTearoff(this))
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -15,19 +15,20 @@
 #include "nsStringGlue.h"
 #include "nsStringBuffer.h"
 #include "nsColor.h"
 #include "nsCaseTreatment.h"
 #include "nsMargin.h"
 #include "nsCOMPtr.h"
 #include "SVGAttrValueWrapper.h"
 #include "nsTArrayForwardDeclare.h"
+#include "nsIAtom.h"
+#include "mozilla/dom/BindingDeclarations.h"
 
 class nsAString;
-class nsIAtom;
 class nsIDocument;
 class nsStyledElementNotElementCSSInlineStyle;
 struct MiscContainer;
 
 namespace mozilla {
 namespace css {
 class StyleRule;
 struct URLValue;
@@ -154,16 +155,18 @@ public:
    * type of aValue is eAtom, in which case this object will also have type
    * eAtom.
    */
   void SetToSerialized(const nsAttrValue& aValue);
 
   void SwapValueWith(nsAttrValue& aOther);
 
   void ToString(nsAString& aResult) const;
+  inline void ToString(mozilla::dom::DOMString& aResult) const;
+
   /**
    * Returns the value of this object as an atom. If necessary, the value will
    * first be serialised using ToString before converting to an atom.
    */
   already_AddRefed<nsIAtom> GetAsAtom() const;
 
   // Methods to get value. These methods do not convert so only use them
   // to retrieve the datatype that this nsAttrValue has.
@@ -459,9 +462,35 @@ nsAttrValue::GetPtr() const
 }
 
 inline bool
 nsAttrValue::IsEmptyString() const
 {
   return !mBits;
 }
 
+inline void
+nsAttrValue::ToString(mozilla::dom::DOMString& aResult) const
+{
+  switch (Type()) {
+    case eString:
+    {
+      nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
+      if (str) {
+        aResult.SetStringBuffer(str, str->StorageSize()/sizeof(PRUnichar) - 1);
+      }
+      // else aResult is already empty
+      return;
+    }
+    case eAtom:
+    {
+      nsIAtom *atom = static_cast<nsIAtom*>(GetPtr());
+      aResult.SetStringBuffer(atom->GetStringBuffer(), atom->GetLength());
+      break;
+    }
+    default:
+    {
+      ToString(aResult.AsAString());
+    }
+  }
+}
+
 #endif
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1471,16 +1471,17 @@ nsDocument::~nsDocument()
 
 NS_INTERFACE_TABLE_HEAD(nsDocument)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_DOCUMENT_INTERFACE_TABLE_BEGIN(nsDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocumentXBL)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIScriptObjectPrincipal)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMEventTarget)
+    NS_INTERFACE_TABLE_ENTRY(nsDocument, mozilla::dom::EventTarget)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsISupportsWeakReference)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIMutationObserver)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIApplicationCacheContainer)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocumentTouch)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsITouchEventReceiver)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIInlineEventHandlers)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIObserver)
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -95,16 +95,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataNode)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericDOMDataNode)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   // nsNodeSH::PreCreate() depends on the identity pointer being the
   // same as nsINode (which nsIContent inherits), so if you change the
   // below line, make sure nsNodeSH::PreCreate() still does the right
   // thing!
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -520,16 +520,17 @@ GK_ATOM(longdesc, "longdesc")
 GK_ATOM(loop, "loop")
 GK_ATOM(low, "low")
 GK_ATOM(lowerFirst, "lower-first")
 GK_ATOM(lowest, "lowest")
 GK_ATOM(lowsrc, "lowsrc")
 GK_ATOM(ltr, "ltr")
 GK_ATOM(lwtheme, "lwtheme")
 GK_ATOM(lwthemetextcolor, "lwthemetextcolor")
+GK_ATOM(main, "main")
 GK_ATOM(map, "map")
 GK_ATOM(manifest, "manifest")
 GK_ATOM(marginheight, "marginheight")
 GK_ATOM(marginwidth, "marginwidth")
 GK_ATOM(mark, "mark")
 GK_ATOM(marquee, "marquee")
 GK_ATOM(match, "match")
 GK_ATOM(max, "max")
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -859,19 +859,18 @@ nsScriptLoader::EvaluateScript(nsScriptL
   JSVersion version = JSVersion(aRequest->mJSVersion);
   if (version != JSVERSION_UNKNOWN) {
     JS::CompileOptions options(context->GetNativeContext());
     options.setFileAndLine(url.get(), aRequest->mLineNo)
            .setVersion(JSVersion(aRequest->mJSVersion));
     if (aRequest->mOriginPrincipal) {
       options.setOriginPrincipals(nsJSPrincipals::get(aRequest->mOriginPrincipal));
     }
-    JS::Value ignored;
     rv = context->EvaluateString(aScript, *globalObject->GetGlobalJSObject(),
-                                 options, /* aCoerceToString = */ false, &ignored);
+                                 options, /* aCoerceToString = */ false, nullptr);
   }
 
   // Put the old script back in case it wants to do anything else.
   mCurrentScript = oldCurrent;
 
   JSContext *cx = nullptr; // Initialize this to keep GCC happy.
   cx = context->GetNativeContext();
   JSAutoRequest ar(cx);
--- a/content/base/test/chrome/test_bug429785.xul
+++ b/content/base/test/chrome/test_bug429785.xul
@@ -30,38 +30,32 @@ https://bugzilla.mozilla.org/show_bug.cg
 	return this;
       },
       observe : function (msg) { errorLogged = true; }
     };
 
     function step2() {
       is(errorLogged, false, "Should be no errors");
 
-      serv.registerListener(listener);    
-      try {
-        serv.logStringMessage("This is a test");
-      } finally {
-        serv.unregisterListener(listener);
-      }
+      serv.logStringMessage("This is a test");
 
       setTimeout(step3, 0);
 
     }
 
     function step3() {
       is(errorLogged, true, "Should see errors when they happen");
+      serv.unregisterListener(listener);
       SimpleTest.finish();
     }
         
     serv.registerListener(listener);    
-    try {
-      var p = new DOMParser();
-      p.parseFromString("<root/>", "application/xml");
+
+    var p = new DOMParser();
+    p.parseFromString("<root/>", "application/xml");
 
-      // nsConsoleService notifies its listeners via async proxies, so we need
-      // to wait to see whether there was an error reported.
-      setTimeout(step2, 0);
-    } finally {
-      serv.unregisterListener(listener);
-    }
+    // nsConsoleService notifies its listeners via async proxies, so we need
+    // to wait to see whether there was an error reported.
+    setTimeout(step2, 0);
+
 
   ]]></script>
 </window>
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/basictypes.h"
 #include "CanvasRenderingContext2D.h"
 
-#include "nsIDOMXULElement.h"
+#include "nsXULElement.h"
 
 #include "prenv.h"
 
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
 
 #include "nsContentUtils.h"
 
@@ -3229,17 +3229,17 @@ CanvasRenderingContext2D::DrawWindow(nsI
 
   // note that x and y are coordinates in the document that
   // we're drawing; x and y are drawn to 0,0 in current user
   // space.
   RedrawUser(gfxRect(0, 0, w, h));
 }
 
 void
-CanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* elem,
+CanvasRenderingContext2D::AsyncDrawXULElement(nsXULElement& elem,
                                               double x, double y,
                                               double w, double h,
                                               const nsAString& bgColor,
                                               uint32_t flags,
                                               ErrorResult& error)
 {
   // We can't allow web apps to call this until we fix at least the
   // following potential security issues:
@@ -3250,17 +3250,17 @@ CanvasRenderingContext2D::AsyncDrawXULEl
   if (!nsContentUtils::IsCallerChrome()) {
     // not permitted to use DrawWindow
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
     error.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
 #if 0
-  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(elem);
+  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(&elem);
   if (!loaderOwner) {
     error.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
   if (!frameloader) {
     error.Throw(NS_ERROR_FAILURE);
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -19,17 +19,17 @@
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
     {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
 #define NS_CANVASPATTERNAZURE_PRIVATE_IID \
     {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
 
-class nsIDOMXULElement;
+class nsXULElement;
 
 namespace mozilla {
 namespace gfx {
 struct Rect;
 class SourceSurface;
 }
 
 namespace dom {
@@ -433,17 +433,17 @@ public:
     if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
       CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
     }
   }
 
   void DrawWindow(nsIDOMWindow* window, double x, double y, double w, double h,
                   const nsAString& bgColor, uint32_t flags,
                   mozilla::ErrorResult& error);
-  void AsyncDrawXULElement(nsIDOMXULElement* elem, double x, double y, double w,
+  void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
                            double h, const nsAString& bgColor, uint32_t flags,
                            mozilla::ErrorResult& error);
 
   nsresult Redraw();
 
   // nsICanvasRenderingContextInternal
   NS_IMETHOD SetDimensions(int32_t width, int32_t height);
   NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height);
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -63,16 +63,17 @@ CPPSRCS += \
 	WebGLShaderPrecisionFormat.cpp \
 	WebGLTexelConversions.cpp \
 	WebGLTexture.cpp \
 	WebGLUniformLocation.cpp \
 	$(NULL)
 
 LOCAL_INCLUDES += \
 	-I$(topsrcdir)/js/xpconnect/wrappers \
+	-I$(topsrcdir)/content/xul/content/src \
 	$(NULL)
 
 else
 
 CPPSRCS += WebGLContextNotSupported.cpp
 
 endif
 
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -61,16 +61,17 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMEventTargetHelper)
   return tmp->IsBlack();
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventTargetHelper)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMEventTargetHelper)
 
 NS_IMPL_DOMTARGET_DEFAULTS(nsDOMEventTargetHelper)
 
 nsDOMEventTargetHelper::~nsDOMEventTargetHelper()
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -95,16 +95,17 @@ MOCHITEST_FILES = \
 		test_moz_mouse_pixel_scroll_event.html \
 		test_wheel_default_action.html \
 		window_wheel_default_action.html \
 		test_bug603008.html \
 		test_bug716822.html \
 		test_bug742376.html \
 		test_dragstart.html \
 		test_bug812744.html \
+		test_addEventListenerExtraArg.html \
 		$(NULL)
 
 MOCHITEST_CHROME_FILES = \
 		test_bug336682_2.xul \
 		test_bug336682.js \
 		test_bug586961.xul \
 		test_bug415498.xul \
 		bug415498-doc1.html \
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_addEventListenerExtraArg.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=828554
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 828554</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 828554 **/
+  SimpleTest.waitForExplicitFinish();
+  window.addEventListener("message", function() {
+    ok(true, "We got called");
+    SimpleTest.finish();
+  }, false, undefined);
+  window.postMessage("Hey there", "*");
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=828554">Mozilla Bug 828554</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -166,16 +166,17 @@ HTML_TAG("input", "Input", [], [ "imgINo
 HTML_TAG("ins", "Mod");
 HTML_TAG("kbd", "");
 HTML_TAG("keygen", "Span");
 HTML_TAG("label", "Label");
 HTML_TAG("legend", "Legend");
 HTML_TAG("li", "LI");
 HTML_TAG("link", "Link", [ "nsIDOMLinkStyle" ]);
 HTML_TAG("listing", "");
+HTML_TAG("main", "");
 HTML_TAG("map", "Map");
 HTML_TAG("mark", "");
 HTML_TAG("marquee", "Div");
 HTML_TAG("menu", "Menu");
 HTML_TAG("meta", "Meta");
 HTML_TAG("meter", "Meter");
 HTML_TAG("multicol", "Span");
 HTML_TAG("nav", "")
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -99,18 +99,19 @@
 #include "nsNodeInfoManager.h"
 #include "nsXBLBinding.h"
 #include "nsEventDispatcher.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsICSSDeclaration.h"
 
-namespace css = mozilla::css;
-namespace dom = mozilla::dom;
+#include "mozilla/dom/XULElementBinding.h"
+
+using namespace mozilla;
 
 //----------------------------------------------------------------------
 
 static NS_DEFINE_CID(kXULPopupListenerCID,        NS_XULPOPUPLISTENER_CID);
 
 //----------------------------------------------------------------------
 
 #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
@@ -161,16 +162,18 @@ NS_INTERFACE_MAP_END_AGGREGATED(mElement
 //
 
 nsXULElement::nsXULElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsStyledElement(aNodeInfo),
       mBindingParent(nullptr)
 {
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumElements);
 
+    SetIsDOMBinding();
+
     // We may be READWRITE by default; check.
     if (IsReadWriteTextElement()) {
         AddStatesSilently(NS_EVENT_STATE_MOZ_READWRITE);
         RemoveStatesSilently(NS_EVENT_STATE_MOZ_READONLY);
     }
 }
 
 nsXULElement::nsXULSlots::nsXULSlots()
@@ -395,66 +398,78 @@ nsXULElement::Clone(nsINodeInfo *aNodeIn
 
 //----------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
                                      const nsAString& aValue,
                                      nsIDOMNodeList** aReturn)
 {
+    *aReturn = GetElementsByAttribute(aAttribute, aValue).get();
+    return NS_OK;
+}
+
+already_AddRefed<nsINodeList>
+nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
+                                     const nsAString& aValue)
+{
     nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
-    NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
     void* attrValue = new nsString(aValue);
-    NS_ENSURE_TRUE(attrValue, NS_ERROR_OUT_OF_MEMORY);
-    nsContentList *list = 
+    nsRefPtr<nsContentList> list =
         new nsContentList(this,
                           nsXULDocument::MatchAttribute,
                           nsContentUtils::DestroyMatchString,
                           attrValue,
                           true,
                           attrAtom,
                           kNameSpaceID_Unknown);
-    NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
-
-    NS_ADDREF(*aReturn = list);
-    return NS_OK;
+    return list.forget();
 }
 
 NS_IMETHODIMP
 nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
                                        const nsAString& aAttribute,
                                        const nsAString& aValue,
                                        nsIDOMNodeList** aReturn)
 {
+    ErrorResult rv;
+    *aReturn =
+        GetElementsByAttributeNS(aNamespaceURI, aAttribute, aValue, rv).get();
+    return rv.ErrorCode();
+}
+
+already_AddRefed<nsINodeList>
+nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
+                                       const nsAString& aAttribute,
+                                       const nsAString& aValue,
+                                       ErrorResult& rv)
+{
     nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
-    NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
 
     int32_t nameSpaceId = kNameSpaceID_Wildcard;
     if (!aNamespaceURI.EqualsLiteral("*")) {
-      nsresult rv =
+      rv =
         nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                               nameSpaceId);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (rv.Failed()) {
+          return nullptr;
+      }
     }
 
     void* attrValue = new nsString(aValue);
-    NS_ENSURE_TRUE(attrValue, NS_ERROR_OUT_OF_MEMORY);
-    
-    nsContentList *list = 
+    nsRefPtr<nsContentList> list =
         new nsContentList(this,
                           nsXULDocument::MatchAttribute,
                           nsContentUtils::DestroyMatchString,
                           attrValue,
                           true,
                           attrAtom,
                           nameSpaceId);
-    NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
 
-    NS_ADDREF(*aReturn = list);
-    return NS_OK;
+    return list.forget();
 }
 
 nsEventListenerManager*
 nsXULElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer)
 {
     // XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc()
     // here, override BindToTree for those classes and munge event
     // listeners there?
@@ -1171,60 +1186,81 @@ nsXULElement::PreHandleEvent(nsEventChai
 
     return nsStyledElement::PreHandleEvent(aVisitor);
 }
 
 // XXX This _should_ be an implementation method, _not_ publicly exposed :-(
 NS_IMETHODIMP
 nsXULElement::GetResource(nsIRDFResource** aResource)
 {
+    ErrorResult rv;
+    *aResource = GetResource(rv).get();
+    return rv.ErrorCode();
+}
+
+already_AddRefed<nsIRDFResource>
+nsXULElement::GetResource(ErrorResult& rv)
+{
     nsAutoString id;
     GetAttr(kNameSpaceID_None, nsGkAtoms::ref, id);
     if (id.IsEmpty()) {
         GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
     }
 
-    if (!id.IsEmpty()) {
-        return nsXULContentUtils::RDFService()->
-            GetUnicodeResource(id, aResource);
+    if (id.IsEmpty()) {
+        return nullptr;
     }
-    *aResource = nullptr;
 
-    return NS_OK;
+    nsCOMPtr<nsIRDFResource> resource;
+    rv = nsXULContentUtils::RDFService()->
+        GetUnicodeResource(id, getter_AddRefs(resource));
+    return resource.forget();
 }
 
-
 NS_IMETHODIMP
 nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
 {
-    nsCOMPtr<nsIXULTemplateBuilder> builder;
-    GetBuilder(getter_AddRefs(builder));
+    *aDatabase = GetDatabase().get();
+    return NS_OK;
+}
 
-    if (builder)
-        builder->GetDatabase(aDatabase);
-    else
-        *aDatabase = nullptr;
+already_AddRefed<nsIRDFCompositeDataSource>
+nsXULElement::GetDatabase()
+{
+    nsCOMPtr<nsIXULTemplateBuilder> builder = GetBuilder();
+    if (!builder) {
+        return nullptr;
+    }
 
-    return NS_OK;
+    nsCOMPtr<nsIRDFCompositeDataSource> database;
+    builder->GetDatabase(getter_AddRefs(database));
+    return database.forget();
 }
 
 
 NS_IMETHODIMP
 nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
 {
-    *aBuilder = nullptr;
-
-    // XXX sXBL/XBL2 issue! Owner or current document?
-    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(GetCurrentDoc());
-    if (xuldoc)
-        xuldoc->GetTemplateBuilderFor(this, aBuilder);
-
+    *aBuilder = GetBuilder().get();
     return NS_OK;
 }
 
+already_AddRefed<nsIXULTemplateBuilder>
+nsXULElement::GetBuilder()
+{
+    // XXX sXBL/XBL2 issue! Owner or current document?
+    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(GetCurrentDoc());
+    if (!xuldoc) {
+        return nullptr;
+    }
+
+    nsCOMPtr<nsIXULTemplateBuilder> builder;
+    xuldoc->GetTemplateBuilderFor(this, getter_AddRefs(builder));
+    return builder.forget();
+}
 
 //----------------------------------------------------------------------
 // Implementation methods
 
 NS_IMETHODIMP
 nsXULElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
 {
     return NS_OK;
@@ -1264,39 +1300,55 @@ nsXULElement::IsAttributeMapped(const ns
 {
     return false;
 }
 
 // Controllers Methods
 NS_IMETHODIMP
 nsXULElement::GetControllers(nsIControllers** aResult)
 {
+    ErrorResult rv;
+    NS_IF_ADDREF(*aResult = GetControllers(rv));
+    return rv.ErrorCode();
+}
+
+nsIControllers*
+nsXULElement::GetControllers(ErrorResult& rv)
+{
     if (! Controllers()) {
         nsDOMSlots* slots = DOMSlots();
 
-        nsresult rv;
         rv = NS_NewXULControllers(nullptr, NS_GET_IID(nsIControllers),
                                   reinterpret_cast<void**>(&slots->mControllers));
 
-        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a controllers");
-        if (NS_FAILED(rv)) return rv;
+        NS_ASSERTION(NS_SUCCEEDED(rv.ErrorCode()),
+                     "unable to create a controllers");
+        if (rv.Failed()) {
+            return nullptr;
+        }
     }
 
-    *aResult = Controllers();
-    NS_IF_ADDREF(*aResult);
-    return NS_OK;
+    return Controllers();
 }
 
 NS_IMETHODIMP
 nsXULElement::GetBoxObject(nsIBoxObject** aResult)
 {
-  *aResult = nullptr;
+    ErrorResult rv;
+    *aResult = GetBoxObject(rv).get();
+    return rv.ErrorCode();
+}
 
-  // XXX sXBL/XBL2 issue! Owner or current document?
-  return OwnerDoc()->GetBoxObjectFor(this, aResult);
+already_AddRefed<nsIBoxObject>
+nsXULElement::GetBoxObject(ErrorResult& rv)
+{
+    nsCOMPtr<nsIBoxObject> boxObject;
+    // XXX sXBL/XBL2 issue! Owner or current document?
+    rv = OwnerDoc()->GetBoxObjectFor(this, getter_AddRefs(boxObject));
+    return boxObject.forget();
 }
 
 // Methods for setting/getting attributes from nsIDOMXULElement
 #define NS_IMPL_XUL_STRING_ATTR(_method, _atom)                     \
   NS_IMETHODIMP                                                     \
   nsXULElement::Get##_method(nsAString& aReturn)                    \
   {                                                                 \
     GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aReturn);         \
@@ -1306,36 +1358,29 @@ nsXULElement::GetBoxObject(nsIBoxObject*
   nsXULElement::Set##_method(const nsAString& aValue)               \
   {                                                                 \
     return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue,    \
                    true);                                        \
   }
 
 #define NS_IMPL_XUL_BOOL_ATTR(_method, _atom)                       \
   NS_IMETHODIMP                                                     \
-  nsXULElement::Get##_method(bool* aResult)                       \
+  nsXULElement::Get##_method(bool* aResult)                         \
   {                                                                 \
-    *aResult = BoolAttrIsTrue(nsGkAtoms::_atom);                   \
-                                                                    \
+    *aResult = _method();                                           \
     return NS_OK;                                                   \
   }                                                                 \
   NS_IMETHODIMP                                                     \
-  nsXULElement::Set##_method(bool aValue)                         \
+  nsXULElement::Set##_method(bool aValue)                           \
   {                                                                 \
-    if (aValue)                                                     \
-      SetAttr(kNameSpaceID_None, nsGkAtoms::_atom,                 \
-              NS_LITERAL_STRING("true"), true);                  \
-    else                                                            \
-      UnsetAttr(kNameSpaceID_None, nsGkAtoms::_atom, true);     \
-                                                                    \
-    return NS_OK;                                                   \
+      SetXULBoolAttr(nsGkAtoms::_atom, aValue);                     \
+      return NS_OK;                                                 \
   }
 
 
-NS_IMPL_XUL_STRING_ATTR(Id, id)
 NS_IMPL_XUL_STRING_ATTR(ClassName, _class)
 NS_IMPL_XUL_STRING_ATTR(Align, align)
 NS_IMPL_XUL_STRING_ATTR(Dir, dir)
 NS_IMPL_XUL_STRING_ATTR(Flex, flex)
 NS_IMPL_XUL_STRING_ATTR(FlexGroup, flexgroup)
 NS_IMPL_XUL_STRING_ATTR(Ordinal, ordinal)
 NS_IMPL_XUL_STRING_ATTR(Orient, orient)
 NS_IMPL_XUL_STRING_ATTR(Pack, pack)
@@ -1413,34 +1458,42 @@ nsresult
 nsXULElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
 {
     nsCOMPtr<nsIContent> otherContent(do_QueryInterface(aOtherOwner));
     NS_ENSURE_TRUE(otherContent, NS_ERROR_NOT_IMPLEMENTED);
 
     nsXULElement* otherEl = FromContent(otherContent);
     NS_ENSURE_TRUE(otherEl, NS_ERROR_NOT_IMPLEMENTED);
 
-    if (otherEl == this) {
+    ErrorResult rv;
+    SwapFrameLoaders(*otherEl, rv);
+    return rv.ErrorCode();
+}
+
+void
+nsXULElement::SwapFrameLoaders(nsXULElement& aOtherElement, ErrorResult& rv)
+{
+    if (&aOtherElement == this) {
         // nothing to do
-        return NS_OK;
+        return;
     }
 
     nsXULSlots *ourSlots = static_cast<nsXULSlots*>(GetExistingDOMSlots());
     nsXULSlots *otherSlots =
-        static_cast<nsXULSlots*>(otherEl->GetExistingDOMSlots());
+        static_cast<nsXULSlots*>(aOtherElement.GetExistingDOMSlots());
     if (!ourSlots || !ourSlots->mFrameLoader ||
         !otherSlots || !otherSlots->mFrameLoader) {
         // Can't handle swapping when there is nothing to swap... yet.
-        return NS_ERROR_NOT_IMPLEMENTED;
+        rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+        return;
     }
 
-    return
-        ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
-                                                    ourSlots->mFrameLoader,
-                                                    otherSlots->mFrameLoader);
+    rv = ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
+                                                     ourSlots->mFrameLoader,
+                                                     otherSlots->mFrameLoader);
 }
 
 NS_IMETHODIMP
 nsXULElement::GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement)
 {
     for (nsIContent* current = GetParent(); current;
          current = current->GetParent()) {
         if (current->NodeInfo()->Equals(nsGkAtoms::listbox,
@@ -1454,44 +1507,68 @@ nsXULElement::GetParentTree(nsIDOMXULMul
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::Focus()
 {
+    ErrorResult rv;
+    Focus(rv);
+    return rv.ErrorCode();
+}
+
+void
+nsXULElement::Focus(ErrorResult& rv)
+{
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     nsCOMPtr<nsIDOMElement> elem = do_QueryObject(this);
-    return fm ? fm->SetFocus(this, 0) : NS_OK;
+    if (fm) {
+        rv = fm->SetFocus(this, 0);
+    }
 }
 
 NS_IMETHODIMP
 nsXULElement::Blur()
 {
+    ErrorResult rv;
+    Blur(rv);
+    return rv.ErrorCode();
+}
+
+void
+nsXULElement::Blur(ErrorResult& rv)
+{
     if (!ShouldBlur(this))
-      return NS_OK;
+      return;
 
     nsIDocument* doc = GetCurrentDoc();
     if (!doc)
-      return NS_OK;
+      return;
 
     nsIDOMWindow* win = doc->GetWindow();
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-    if (win && fm)
-      return fm->ClearFocus(win);
-    return NS_OK;
+    if (win && fm) {
+      rv = fm->ClearFocus(win);
+    }
 }
 
 NS_IMETHODIMP
 nsXULElement::Click()
 {
   return ClickWithInputSource(nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN);
 }
 
+void
+nsXULElement::Click(ErrorResult& rv)
+{
+  rv = Click();
+}
+
 nsresult
 nsXULElement::ClickWithInputSource(uint16_t aInputSource)
 {
     if (BoolAttrIsTrue(nsGkAtoms::disabled))
         return NS_OK;
 
     nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // Strong just in case
     if (doc) {
@@ -1787,17 +1864,17 @@ nsXULElement::ResetChromeMargins()
     nsIWidget* mainWidget = GetWindowWidget();
     if (!mainWidget)
         return;
     // See nsIWidget
     nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget));
 }
 
 bool
-nsXULElement::BoolAttrIsTrue(nsIAtom* aName)
+nsXULElement::BoolAttrIsTrue(nsIAtom* aName) const
 {
     const nsAttrValue* attr =
         GetAttrInfo(kNameSpaceID_None, aName).mValue;
 
     return attr && attr->Type() == nsAttrValue::eAtom &&
            attr->GetAtomValue() == nsGkAtoms::_true;
 }
 
@@ -1825,16 +1902,22 @@ nsXULElement::RecompileScriptEventListen
 }
 
 bool
 nsXULElement::IsEventAttributeName(nsIAtom *aName)
 {
   return nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL);
 }
 
+JSObject*
+nsXULElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+    return dom::XULElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULPrototypeNode)
     if (tmp->mType == nsXULPrototypeNode::eType_Element) {
         static_cast<nsXULPrototypeElement*>(tmp)->Unlink();
     }
     else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
         static_cast<nsXULPrototypeScript*>(tmp)->UnlinkJSObjects();
     }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -32,16 +32,18 @@
 #include "nsLayoutCID.h"
 #include "nsAttrAndChildArray.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsStyledElement.h"
 #include "nsDOMScriptObjectHolder.h"
 #include "nsIFrameLoader.h"
 #include "jspubtd.h"
+#include "nsGenericHTMLElement.h"
+#include "nsFrameLoader.h"
 
 class nsIDocument;
 class nsString;
 class nsIDocShell;
 
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class nsIScriptGlobalObjectOwner;
@@ -388,28 +390,30 @@ public:
      * template-generated element has already had its children generated.
      */
     void SetTemplateGenerated() { SetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     void ClearTemplateGenerated() { UnsetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     bool GetTemplateGenerated() { return HasFlag(XUL_ELEMENT_TEMPLATE_GENERATED); }
 
     // nsIDOMNode
     NS_FORWARD_NSIDOMNODE_TO_NSINODE
+    // And since that shadowed GetParentElement with the XPCOM
+    // signature, pull in the one we care about.
+    using nsStyledElement::GetParentElement;
 
     // nsIDOMElement
     NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
     // nsIDOMXULElement
     NS_DECL_NSIDOMXULELEMENT
 
     virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
     virtual nsEventStates IntrinsicState() const;
 
     nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
-    already_AddRefed<nsFrameLoader> GetFrameLoader();
     nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
 
     virtual void RecompileScriptEventListeners();
 
     // This function should ONLY be used by BindToTree implementations.
     // The function exists solely because XUL elements store the binding
     // parent as a member instead of in the slots, as Element does.
     void SetXULBindingParent(nsIContent* aBindingParent)
@@ -418,16 +422,179 @@ public:
     }
 
     virtual nsXPCClassInfo* GetClassInfo();
 
     virtual nsIDOMNode* AsDOMNode() { return this; }
 
     virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
+    void SetXULAttr(nsIAtom* aName, const nsAString& aValue,
+                    mozilla::ErrorResult& aError)
+    {
+        aError = SetAttr(kNameSpaceID_None, aName, aValue, true);
+    }
+    void SetXULBoolAttr(nsIAtom* aName, bool aValue)
+    {
+        if (aValue) {
+            SetAttr(kNameSpaceID_None, aName, NS_LITERAL_STRING("true"), true);
+        } else {
+            UnsetAttr(kNameSpaceID_None, aName, true);
+        }
+    }
+
+    // WebIDL API
+    // The XPCOM getter is fine for our string attributes.
+    // The XPCOM setter is fine for our bool attributes.
+    void SetClassName(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::_class, aValue, rv);
+    }
+    void SetAlign(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::align, aValue, rv);
+    }
+    void SetDir(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::dir, aValue, rv);
+    }
+    void SetFlex(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::flex, aValue, rv);
+    }
+    void SetFlexGroup(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::flexgroup, aValue, rv);
+    }
+    void SetOrdinal(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::ordinal, aValue, rv);
+    }
+    void SetOrient(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::orient, aValue, rv);
+    }
+    void SetPack(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::pack, aValue, rv);
+    }
+    bool Hidden() const
+    {
+        return BoolAttrIsTrue(nsGkAtoms::hidden);
+    }
+    bool Collapsed() const
+    {
+        return BoolAttrIsTrue(nsGkAtoms::collapsed);
+    }
+    void SetObserves(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::observes, aValue, rv);
+    }
+    void SetMenu(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::menu, aValue, rv);
+    }
+    void SetContextMenu(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::contextmenu, aValue, rv);
+    }
+    void SetTooltip(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::tooltip, aValue, rv);
+    }
+    void SetWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::width, aValue, rv);
+    }
+    void SetHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::height, aValue, rv);
+    }
+    void SetMinWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::minwidth, aValue, rv);
+    }
+    void SetMinHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::minheight, aValue, rv);
+    }
+    void SetMaxWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::maxwidth, aValue, rv);
+    }
+    void SetMaxHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::maxheight, aValue, rv);
+    }
+    void SetPersist(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::persist, aValue, rv);
+    }
+    void SetLeft(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::left, aValue, rv);
+    }
+    void SetTop(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::top, aValue, rv);
+    }
+    void SetDatasources(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::datasources, aValue, rv);
+    }
+    void SetRef(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::ref, aValue, rv);
+    }
+    void SetTooltipText(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::tooltiptext, aValue, rv);
+    }
+    void SetStatusText(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::statustext, aValue, rv);
+    }
+    bool AllowEvents() const
+    {
+        return BoolAttrIsTrue(nsGkAtoms::allowevents);
+    }
+    already_AddRefed<nsIRDFCompositeDataSource> GetDatabase();
+    already_AddRefed<nsIXULTemplateBuilder> GetBuilder();
+    already_AddRefed<nsIRDFResource> GetResource(mozilla::ErrorResult& rv);
+    nsIControllers* GetControllers(mozilla::ErrorResult& rv);
+    already_AddRefed<nsIBoxObject> GetBoxObject(mozilla::ErrorResult& rv);
+    void Focus(mozilla::ErrorResult& rv);
+    void Blur(mozilla::ErrorResult& rv);
+    void Click(mozilla::ErrorResult& rv);
+    // The XPCOM DoCommand never fails, so it's OK for us.
+    already_AddRefed<nsINodeList>
+      GetElementsByAttribute(const nsAString& aAttribute,
+                             const nsAString& aValue);
+    already_AddRefed<nsINodeList>
+      GetElementsByAttributeNS(const nsAString& aNamespaceURI,
+                               const nsAString& aAttribute,
+                               const nsAString& aValue,
+                               mozilla::ErrorResult& rv);
+    // Style() inherited from nsStyledElement
+    already_AddRefed<nsFrameLoader> GetFrameLoader();
+    void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& rv);
+
+    // For XUL, the parent is the parent element, if any
+    nsINode* GetParentObject() const
+    {
+        Element* parent = GetParentElement();
+        if (parent) {
+            return parent;
+        }
+        return nsStyledElement::GetParentObject();
+    }
+    static bool PrefEnabled()
+    {
+        return nsGenericHTMLElement::PrefEnabled();
+    }
 protected:
 
     // This can be removed if EnsureContentsGenerated dies.
     friend class nsNSElementTearoff;
 
     // Implementation methods
     nsresult EnsureContentsGenerated(void) const;
 
@@ -506,17 +673,17 @@ protected:
     // Internal accessor. This shadows the 'Slots', and returns
     // appropriate value.
     nsIControllers *Controllers() {
       nsDOMSlots* slots = GetExistingDOMSlots();
       return slots ? slots->mControllers : nullptr; 
     }
 
     void UnregisterAccessKey(const nsAString& aOldValue);
-    bool BoolAttrIsTrue(nsIAtom* aName);
+    bool BoolAttrIsTrue(nsIAtom* aName) const;
 
     friend nsresult
     NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
     friend void
     NS_TrustedNewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
 
     static already_AddRefed<nsXULElement>
     Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
@@ -525,11 +692,14 @@ protected:
     bool IsReadWriteTextElement() const
     {
         const nsIAtom* tag = Tag();
         return
             GetNameSpaceID() == kNameSpaceID_XUL &&
             (tag == nsGkAtoms::textbox || tag == nsGkAtoms::textarea) &&
             !HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
     }
+
+    virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                               bool *aTriedToWrap) MOZ_OVERRIDE;
 };
 
 #endif // nsXULElement_h__
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -2942,16 +2942,17 @@ nsDOMClassInfo::Init()
 
 #ifdef MOZ_XUL
   DOM_CLASSINFO_MAP_BEGIN(XULTemplateBuilder, nsIXULTemplateBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(XULTreeBuilder, nsIXULTreeBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTreeBuilder)
+    DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsITreeView)
   DOM_CLASSINFO_MAP_END
 #endif
 
   DOM_CLASSINFO_MAP_BEGIN(DOMStringList, nsIDOMDOMStringList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMStringList)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1430,17 +1430,17 @@ nsGlobalWindow::FreeInnerObjects()
     foundInterface = 0;                                                       \
   } else
 
 DOMCI_DATA(Window, nsGlobalWindow)
 
 // QueryInterface implementation for nsGlobalWindow
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
   // Make sure this matches the cast in nsGlobalWindow::FromWrapper()
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
 #ifdef MOZ_B2G
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindowB2G)
 #endif // MOZ_B2G
   NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow)
   if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) {
     foundInterface = static_cast<nsIDOMWindowInternal*>(this);
     if (!sWarnedAboutWindowInternal) {
@@ -1449,16 +1449,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
                                       "Extensions", mDoc,
                                       nsContentUtils::eDOM_PROPERTIES,
                                       "nsIDOMWindowInternalWarning");
     }
   } else
   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   NS_INTERFACE_MAP_ENTRY(nsPIDOMWindow)
   NS_INTERFACE_MAP_ENTRY(nsIDOMStorageIndexedDB)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindowPerformance)
   NS_INTERFACE_MAP_ENTRY(nsITouchEventReceiver)
   NS_INTERFACE_MAP_ENTRY(nsIInlineEventHandlers)
   NS_INTERFACE_MAP_ENTRY(nsIWindowCrypto)
@@ -1915,18 +1916,17 @@ nsGlobalWindow::CreateOuterObject(nsGlob
   }
 
   JSObject* outer = NewOuterWindowProxy(cx, aNewInner->FastGetGlobalJSObject(),
                                         isChrome);
   if (!outer) {
     return NS_ERROR_FAILURE;
   }
 
-  js::SetProxyExtra(outer, 0,
-    js::PrivateValue(static_cast<nsIScriptGlobalObject*>(this)));
+  js::SetProxyExtra(outer, 0, js::PrivateValue(ToSupports(this)));
 
   return SetOuterObject(cx, outer);
 }
 
 nsresult
 nsGlobalWindow::SetOuterObject(JSContext* aCx, JSObject* aOuterObject)
 {
   // Force our context's global object to be the outer.
@@ -1963,17 +1963,17 @@ CreateNativeGlobalForInner(JSContext* aC
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(aNativeGlobal);
   MOZ_ASSERT(aHolder);
 
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
 
   nsRefPtr<nsIXPConnectJSObjectHolder> jsholder;
   nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
-    aCx, static_cast<nsIScriptGlobalObject*>(aNewInner),
+    aCx, ToSupports(aNewInner),
     aPrincipal, 0, getter_AddRefs(jsholder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   MOZ_ASSERT(jsholder);
   jsholder->GetJSObject(aNativeGlobal);
   jsholder.forget(aHolder);
 
   // Set the location information for the new global, so that tools like
@@ -2234,18 +2234,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
       js::SetProxyExtra(mJSObject, 0, js::PrivateValue(NULL));
 
       outerObject = xpc::TransplantObject(cx, mJSObject, outerObject);
       if (!outerObject) {
         NS_ERROR("unable to transplant wrappers, probably OOM");
         return NS_ERROR_FAILURE;
       }
 
-      nsIScriptGlobalObject *global = static_cast<nsIScriptGlobalObject*>(this);
-      js::SetProxyExtra(outerObject, 0, js::PrivateValue(global));
+      js::SetProxyExtra(outerObject, 0, js::PrivateValue(ToSupports(this)));
 
       mJSObject = outerObject;
       SetWrapper(mJSObject);
 
       {
         JSAutoCompartment ac(cx, mJSObject);
 
         JS_SetParent(cx, mJSObject, newInnerWindow->mJSObject);
@@ -7194,17 +7193,17 @@ nsGlobalWindow::IsInModalState()
 
 // static
 void
 nsGlobalWindow::NotifyDOMWindowDestroyed(nsGlobalWindow* aWindow) {
   nsCOMPtr<nsIObserverService> observerService =
     services::GetObserverService();
   if (observerService) {
     observerService->
-      NotifyObservers(static_cast<nsIScriptGlobalObject*>(aWindow),
+      NotifyObservers(ToSupports(aWindow),
                       DOM_WINDOW_DESTROYED_TOPIC, nullptr);
   }
 }
 
 class WindowDestroyedEvent : public nsRunnable
 {
 public:
   WindowDestroyedEvent(nsPIDOMWindow* aWindow, uint64_t aID,
@@ -7281,31 +7280,31 @@ nsGlobalWindow::NotifyWindowIDDestroyed(
 // static
 void
 nsGlobalWindow::NotifyDOMWindowFrozen(nsGlobalWindow* aWindow) {
   if (aWindow && aWindow->IsInnerWindow()) {
     nsCOMPtr<nsIObserverService> observerService =
       services::GetObserverService();
     if (observerService) {
       observerService->
-        NotifyObservers(static_cast<nsIScriptGlobalObject*>(aWindow),
+        NotifyObservers(ToSupports(aWindow),
                         DOM_WINDOW_FROZEN_TOPIC, nullptr);
     }
   }
 }
 
 // static
 void
 nsGlobalWindow::NotifyDOMWindowThawed(nsGlobalWindow* aWindow) {
   if (aWindow && aWindow->IsInnerWindow()) {
     nsCOMPtr<nsIObserverService> observerService =
       services::GetObserverService();
     if (observerService) {
       observerService->
-        NotifyObservers(static_cast<nsIScriptGlobalObject*>(aWindow),
+        NotifyObservers(ToSupports(aWindow),
                         DOM_WINDOW_THAWED_TOPIC, nullptr);
     }
   }
 }
 
 JSObject*
 nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
 {
@@ -9998,19 +9997,18 @@ nsGlobalWindow::RunTimeoutHandler(nsTime
 
     const char* filename = nullptr;
     uint32_t lineNo = 0;
     handler->GetLocation(&filename, &lineNo);
 
     JS::CompileOptions options(aScx->GetNativeContext());
     options.setFileAndLine(filename, lineNo)
            .setVersion(JSVERSION_DEFAULT);
-    JS::Value ignored;
     aScx->EvaluateString(nsDependentString(script), *FastGetGlobalJSObject(),
-                         options, /*aCoerceToString = */ false, &ignored);
+                         options, /*aCoerceToString = */ false, nullptr);
   } else {
     nsCOMPtr<nsIVariant> dummy;
     nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
     aScx->CallEventHandler(me, FastGetGlobalJSObject(),
                            scriptObject, handler->GetArgv(),
                            // XXXmarkh - consider allowing CallEventHandler to
                            // accept nullptr?
                            getter_AddRefs(dummy));
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -62,16 +62,18 @@
 #include "mozilla/LinkedList.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIDOMTouchEvent.h"
 #include "nsIInlineEventHandlers.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsIIdleObserver.h"
 #include "nsIDOMWakeLock.h"
 
+#include "mozilla/dom/EventTarget.h"
+
 // JS includes
 #include "jsapi.h"
 
 #ifdef MOZ_B2G
 #include "nsIDOMWindowB2G.h"
 #endif // MOZ_B2G
 
 #define DEFAULT_HOME_PAGE "www.mozilla.org"
@@ -248,25 +250,24 @@ struct IdleObserverHolder
 // needed to ensure that mOuterWindow doesn't end up dangling. The
 // nature of PRCList means that the window itself is always in the
 // list, and an outer window's list will also contain all inner window
 // objects that are still in memory (and in reality all inner window
 // object's lists also contain its outer and all other inner windows
 // belonging to the same outer window, but that's an unimportant
 // side effect of inheriting PRCList).
 
-class nsGlobalWindow : public nsPIDOMWindow,
+class nsGlobalWindow : public mozilla::dom::EventTarget,
+                       public nsPIDOMWindow,
                        public nsIScriptGlobalObject,
                        public nsIDOMJSWindow,
                        public nsIScriptObjectPrincipal,
-                       public nsIDOMEventTarget,
                        public nsIDOMStorageIndexedDB,
                        public nsSupportsWeakReference,
                        public nsIInterfaceRequestor,
-                       public nsWrapperCache,
                        public PRCListStr,
                        public nsIDOMWindowPerformance,
                        public nsITouchEventReceiver,
                        public nsIInlineEventHandlers,
                        public nsIWindowCrypto
 #ifdef MOZ_B2G
                      , public nsIDOMWindowB2G
 #endif // MOZ_B2G
@@ -400,22 +401,22 @@ public:
   already_AddRefed<nsIDOMWindow> IndexedGetter(uint32_t aIndex, bool& aFound);
 
   // Object Management
   nsGlobalWindow(nsGlobalWindow *aOuterWindow);
 
   static nsGlobalWindow *FromSupports(nsISupports *supports)
   {
     // Make sure this matches the casts we do in QueryInterface().
-    return (nsGlobalWindow *)(nsIScriptGlobalObject *)supports;
+    return (nsGlobalWindow *)(nsIDOMEventTarget *)supports;
   }
   static nsISupports *ToSupports(nsGlobalWindow *win)
   {
     // Make sure this matches the casts we do in QueryInterface().
-    return (nsISupports *)(nsIScriptGlobalObject *)win;
+    return (nsISupports *)(nsIDOMEventTarget *)win;
   }
   static nsGlobalWindow *FromWrapper(nsIXPConnectWrappedNative *wrapper)
   {
     return FromSupports(wrapper->Native());
   }
 
   /**
    * Wrap nsIDOMWindow::GetTop so we can overload the inline GetTop()
@@ -524,17 +525,17 @@ public:
   static void CloseBlockScriptTerminationFunc(nsISupports *aRef);
 
   static void RunPendingTimeoutsRecursive(nsGlobalWindow *aTopWindow,
                                           nsGlobalWindow *aWindow);
 
   friend class WindowStateHolder;
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
-                                                                   nsIScriptGlobalObject)
+                                                                   nsIDOMEventTarget)
 
   virtual NS_HIDDEN_(JSObject*)
     GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
 
   virtual NS_HIDDEN_(void)
     CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
                              nsScriptObjectHolder<JSObject>& aHandler);
 
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -67,18 +67,20 @@ public:
    *
    * @param aScript a string representing the script to be executed
    * @param aScopeObject a script object for the scope to execute in.
    * @param aOptions an options object. You probably want to at least set
    *                 filename and line number. The principal is computed
    *                 internally, though 'originPrincipals' may be passed.
    * @param aCoerceToString if the return value is not JSVAL_VOID, convert it
    *                        to a string before returning.
-   * @param aRetValue the result of executing the script.
-   **/
+   * @param aRetValue the result of executing the script.  Pass null if you
+   *                  don't care about the result.  Note that asking for a
+   *                  result will deoptimize your script somewhat in many cases.
+   */
   virtual nsresult EvaluateString(const nsAString& aScript,
                                   JSObject& aScopeObject,
                                   JS::CompileOptions& aOptions,
                                   bool aCoerceToString,
                                   JS::Value* aRetValue) = 0;
 
   /**
    * Compile a script.
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1242,18 +1242,25 @@ nsresult
 nsJSContext::EvaluateString(const nsAString& aScript,
                             JSObject& aScopeObject,
                             JS::CompileOptions& aOptions,
                             bool aCoerceToString,
                             JS::Value* aRetValue)
 {
   SAMPLE_LABEL("JS", "EvaluateString");
   MOZ_ASSERT_IF(aOptions.versionSet, aOptions.version != JSVERSION_UNKNOWN);
+  MOZ_ASSERT_IF(aCoerceToString, aRetValue);
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
-  *aRetValue = JSVAL_VOID;
+  // Unfortunately, the JS engine actually compiles scripts with a return value
+  // in a different, less efficient way.  Furthermore, it can't JIT them in many
+  // cases.  So we need to be explicitly told whether the caller cares about the
+  // return value.  Callers use null to indicate they don't care.
+  if (aRetValue) {
+    *aRetValue = JSVAL_VOID;
+  }
 
   if (!mScriptsEnabled) {
     return NS_OK;
   }
 
   nsCxPusher pusher;
   if (!pusher.Push(mContext))
     return NS_ERROR_FAILURE;
@@ -1278,38 +1285,40 @@ nsJSContext::EvaluateString(const nsAStr
     JSAutoCompartment ac(mContext, &aScopeObject);
 
     ++mExecuteDepth;
 
     js::RootedObject rootedScope(mContext, &aScopeObject);
     ok = JS::Evaluate(mContext, rootedScope, aOptions,
                       PromiseFlatString(aScript).get(),
                       aScript.Length(), aRetValue);
-    if (ok && !aRetValue->isUndefined() && aCoerceToString) {
+    if (ok && aCoerceToString && !aRetValue->isUndefined()) {
       JSString* str = JS_ValueToString(mContext, *aRetValue);
       ok = !!str;
       *aRetValue = ok ? JS::StringValue(str) : JS::UndefinedValue();
     }
     --mExecuteDepth;
   }
 
   if (!ok) {
-    *aRetValue = JS::UndefinedValue();
+    if (aRetValue) {
+      *aRetValue = JS::UndefinedValue();
+    }
     // Tell XPConnect about any pending exceptions. This is needed
     // to avoid dropping JS exceptions in case we got here through
     // nested calls through XPConnect.
     ReportPendingException();
   }
 
   // ScriptEvaluated needs to come after we pop the stack
   pusher.Pop();
   ScriptEvaluated(true);
 
   // Wrap the return value into whatever compartment mContext was in.
-  if (!JS_WrapValue(mContext, aRetValue))
+  if (aRetValue && !JS_WrapValue(mContext, aRetValue))
     return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 nsIScriptObjectPrincipal*
 nsJSContext::GetObjectPrincipal()
 {
   nsCOMPtr<nsIScriptObjectPrincipal> prin = do_QueryInterface(GetGlobalObject());
--- a/dom/base/nsPIWindowRoot.h
+++ b/dom/base/nsPIWindowRoot.h
@@ -3,29 +3,29 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsPIWindowRoot_h__
 #define nsPIWindowRoot_h__
 
 #include "nsISupports.h"
-#include "nsIDOMEventTarget.h"
+#include "mozilla/dom/EventTarget.h"
 
 class nsPIDOMWindow;
 class nsIControllers;
 class nsIController;
 struct JSContext;
 
 // 426C1B56-E38A-435E-B291-BE1557F2A0A2
 #define NS_IWINDOWROOT_IID \
 { 0xc89780f2, 0x8905, 0x417f, \
   { 0xa6, 0x62, 0xf6, 0xc, 0xa6, 0xd7, 0xc, 0x91 } }
 
-class nsPIWindowRoot : public nsIDOMEventTarget
+class nsPIWindowRoot : public mozilla::dom::EventTarget
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWINDOWROOT_IID)
 
   virtual nsPIDOMWindow* GetWindow()=0;
 
   // get and set the node that is the context of a popup menu
   virtual nsIDOMNode* GetPopupNode() = 0;
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -34,25 +34,27 @@ nsWindowRoot::nsWindowRoot(nsPIDOMWindow
 
 nsWindowRoot::~nsWindowRoot()
 {
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
 }
 
-NS_IMPL_CYCLE_COLLECTION_3(nsWindowRoot,
-                           mListenerManager,
-                           mPopupNode,
-                           mParent)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(nsWindowRoot,
+                                        mListenerManager,
+                                        mPopupNode,
+                                        mParent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot)
 
 NS_IMPL_DOMTARGET_DEFAULTS(nsWindowRoot)
 
 NS_IMETHODIMP
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -40,17 +40,18 @@ public:
   virtual void SetPopupNode(nsIDOMNode* aNode);
 
   virtual void SetParentTarget(nsIDOMEventTarget* aTarget)
   {
     mParent = aTarget;
   }
   virtual nsIDOMEventTarget* GetParentTarget() { return mParent; }
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsWindowRoot, nsIDOMEventTarget)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot,
+                                                         nsIDOMEventTarget)
 
 protected:
   // Members
   nsPIDOMWindow* mWindow; // [Weak]. The window will hold on to us and let go when it dies.
   nsRefPtr<nsEventListenerManager> mListenerManager; // [Strong]. We own the manager, which owns event listeners attached
                                                       // to us.
 
   nsCOMPtr<nsIDOMNode> mPopupNode; // [OWNER]
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsWrapperCache_h___
 #define nsWrapperCache_h___
 
 #include "nsCycleCollectionParticipant.h"
+#include "mozilla/Assertions.h"
 
 class JSObject;
 struct JSContext;
 class XPCWrappedNativeScope;
 
 namespace mozilla {
 namespace dom {
 namespace workers {
@@ -156,16 +157,17 @@ public:
    * value set in triedToWrap is meaningless. If null is returned then
    * triedToWrap indicates whether an error occurred, if it's false then the
    * object doesn't actually support creating a wrapper through its WrapObject
    * hook.
    */
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
+    MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapObject");
     *triedToWrap = false;
     return nullptr;
   }
 
   /**
    * Returns true if the object has a non-gray wrapper.
    */
   bool IsBlack();
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -12,16 +12,18 @@
  */
 #ifndef mozilla_dom_BindingDeclarations_h__
 #define mozilla_dom_BindingDeclarations_h__
 
 #include "nsStringGlue.h"
 #include "jsapi.h"
 #include "mozilla/Util.h"
 #include "nsCOMPtr.h"
+#include "nsDOMString.h"
+#include "nsStringBuffer.h"
 
 namespace mozilla {
 namespace dom {
 
 struct MainThreadDictionaryBase
 {
 protected:
   JSContext* ParseJSON(const nsAString& aJSON,
@@ -78,12 +80,139 @@ public:
     return !Get();
   }
 
 private:
   js::RootedObject mGlobalJSObject;
   JSContext* mCx;
 };
 
+/**
+ * A class for representing string return values.  This can be either passed to
+ * callees that have an nsString or nsAString out param or passed to a callee
+ * that actually knows about this class and can work with it.  Such a callee may
+ * call SetStringBuffer on this object, but only if it plans to keep holding a
+ * strong ref to the stringbuffer!
+ *
+ * The proper way to store a value in this class is to either to do nothing
+ * (which leaves this as an empty string), to call SetStringBuffer with a
+ * non-null stringbuffer, to call SetNull(), or to call AsAString() and set the
+ * value in the resulting nsString.  These options are mutually exclusive!
+ * Don't do more than one of them.
+ *
+ * The proper way to extract a value is to check IsNull().  If not null, then
+ * check HasStringBuffer().  If that's true, check for a zero length, and if the
+ * length is nonzero call StringBuffer().  If the length is zero this is the
+ * empty string.  If HasStringBuffer() returns false, call AsAString() and get
+ * the value from that.
+ */
+class NS_STACK_CLASS DOMString {
+public:
+  DOMString()
+    : mStringBuffer(nullptr)
+    , mLength(0)
+    , mIsNull(false)
+  {}
+  ~DOMString()
+  {
+    MOZ_ASSERT(mString.empty() || !mStringBuffer,
+               "Shouldn't have both present!");
+  }
+
+  operator nsString&()
+  {
+    return AsAString();
+  }
+
+  nsString& AsAString()
+  {
+    MOZ_ASSERT(!mStringBuffer, "We already have a stringbuffer?");
+    MOZ_ASSERT(!mIsNull, "We're already set as null");
+    if (mString.empty()) {
+      mString.construct();
+    }
+    return mString.ref();
+  }
+
+  bool HasStringBuffer() const
+  {
+    MOZ_ASSERT(mString.empty() || !mStringBuffer,
+               "Shouldn't have both present!");
+    MOZ_ASSERT(!mIsNull, "Caller should have checked IsNull() first");
+    return mString.empty();
+  }
+
+  // Get the stringbuffer.  This can only be called if HasStringBuffer()
+  // returned true and StringBufferLength() is nonzero.  If that's true, it will
+  // never return null.
+  nsStringBuffer* StringBuffer() const
+  {
+    MOZ_ASSERT(!mIsNull, "Caller should have checked IsNull() first");
+    MOZ_ASSERT(HasStringBuffer(),
+               "Don't ask for the stringbuffer if we don't have it");
+    MOZ_ASSERT(StringBufferLength() != 0, "Why are you asking for this?");
+    MOZ_ASSERT(mStringBuffer,
+               "If our length is nonzero, we better have a stringbuffer.");
+    return mStringBuffer;
+  }
+
+  // Get the length of the stringbuffer.  Can only be called if
+  // HasStringBuffer().
+  uint32_t StringBufferLength() const
+  {
+    MOZ_ASSERT(HasStringBuffer(), "Don't call this if there is no stringbuffer");
+    return mLength;
+  }
+
+  void SetStringBuffer(nsStringBuffer* aStringBuffer, uint32_t aLength)
+  {
+    MOZ_ASSERT(mString.empty(), "We already have a string?");
+    MOZ_ASSERT(!mIsNull, "We're already set as null");
+    MOZ_ASSERT(!mStringBuffer, "Setting stringbuffer twice?");
+    MOZ_ASSERT(aStringBuffer, "Why are we getting null?");
+    mStringBuffer = aStringBuffer;
+    mLength = aLength;
+  }
+
+  void SetNull()
+  {
+    MOZ_ASSERT(!mStringBuffer, "Should have no stringbuffer if null");
+    MOZ_ASSERT(mString.empty(), "Should have no string if null");
+    mIsNull = true;
+  }
+
+  bool IsNull() const
+  {
+    MOZ_ASSERT(!mStringBuffer || mString.empty(),
+               "How could we have a stringbuffer and a nonempty string?");
+    return mIsNull || (!mString.empty() && mString.ref().IsVoid());
+  }
+
+  void ToString(nsAString& aString)
+  {
+    if (IsNull()) {
+      SetDOMStringToNull(aString);
+    } else if (HasStringBuffer()) {
+      if (StringBufferLength() == 0) {
+        aString.Truncate();
+      } else {
+        StringBuffer()->ToString(StringBufferLength(), aString);
+      }
+    } else {
+      aString = AsAString();
+    }
+  }
+
+private:
+  // We need to be able to act like a string as needed
+  Maybe<nsString> mString;
+
+  // For callees that know we exist, we can be a stringbuffer/length/null-flag
+  // triple.
+  nsStringBuffer* mStringBuffer;
+  uint32_t mLength;
+  bool mIsNull;
+};
+
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_BindingDeclarations_h__
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -570,19 +570,19 @@ QueryInterface(JSContext* cx, unsigned a
     return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
   }
 
   JS::Value* argv = JS_ARGV(cx, vp);
   if (!argv[0].isObject()) {
     return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
   }
 
-  nsIJSIID* iid;
+  nsIJSID* iid;
   xpc_qsSelfRef iidRef;
-  if (NS_FAILED(xpc_qsUnwrapArg<nsIJSIID>(cx, argv[0], &iid, &iidRef.ptr,
+  if (NS_FAILED(xpc_qsUnwrapArg<nsIJSID>(cx, argv[0], &iid, &iidRef.ptr,
                                           &argv[0]))) {
     return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
   }
   MOZ_ASSERT(iid);
 
   if (iid->GetID()->Equals(NS_GET_IID(nsIClassInfo))) {
     nsresult rv;
     nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(native, &rv);
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -243,16 +243,27 @@ DOMInterfaces = {
 
 'DOMTokenList': {
     'nativeType': 'nsDOMTokenList',
     'binaryNames': {
         '__stringifier': 'Stringify'
     }
 },
 
+'DummyInterface': {
+    'skipGen': True,
+    'register': False,
+},
+
+'DummyInterfaceWorkers': {
+    'skipGen': True,
+    'register': False,
+    'workers': True
+},
+
 'DynamicsCompressorNode': {
     'resultNotAddRefed': [ 'threshold', 'knee', 'ratio',
                            'reduction', 'attack', 'release' ],
     'binaryNames': {
         'release': 'getRelease'
     },
     'wrapperCache': False
 },
@@ -546,17 +557,16 @@ DOMInterfaces = {
 
 'NodeList': {
     'nativeType': 'nsINodeList',
     'resultNotAddRefed': [ 'item' ]
 },
 
 'PaintRequest': {
     'nativeType': 'nsPaintRequest',
-    'prefable': True
 },
 
 'PaintRequestList': {
     'nativeType': 'nsPaintRequestList',
     'headerFile': 'nsPaintRequest.h',
     'resultNotAddRefed': [ 'item' ]
 },
 
@@ -597,17 +607,16 @@ DOMInterfaces = {
 
 'RGBColor': {
     "nativeType": "nsDOMCSSRGBColor",
     'resultNotAddRefed': [ "alpha", "blue", "green", "red" ]
 },
 
 'Screen': {
     'nativeType': 'nsScreen',
-    'prefable': True,
 },
 
 'SVGAElement': {
   'hasInstanceInterface': 'nsIDOMSVGAElement',
 },
 
 'SVGAnimatedLengthList': {
     'nativeType': 'mozilla::DOMSVGAnimatedLengthList',
@@ -997,16 +1006,22 @@ DOMInterfaces = {
 },
 
 'XPathEvaluator': {
     'nativeType': 'nsXPathEvaluator',
     'headerFile': 'nsXPathEvaluator.h',
     'wrapperCache': False
 },
 
+'XULElement': {
+    'nativeType': 'nsXULElement',
+    'resultNotAddRefed': [ 'controllers', 'style' ],
+    'hasInstanceInterface': 'nsIDOMXULElement',
+},
+
 ####################################
 # Test Interfaces of various sorts #
 ####################################
 
 'TestInterface' : {
         # Keep this in sync with TestExampleInterface
         'headerFile': 'TestBindingHeader.h',
         'register': False,
@@ -1200,16 +1215,23 @@ addExternalIface('DOMStringList')
 addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('HTMLHeadElement', nativeType='mozilla::dom::Element')
 addExternalIface('HTMLCanvasElement', nativeType='mozilla::dom::HTMLCanvasElement')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LockedFile')
 addExternalIface('MediaStream')
+addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
+addExternalIface('MozControllers', nativeType='nsIControllers')
+addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
+addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
+                 notflattened=True)
+addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
+addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
 addExternalIface('NamedNodeMap')
 addExternalIface('NodeIterator')
 addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
 addExternalIface('nsISupports', nativeType='nsISupports')
 addExternalIface('OutputStream', nativeType='nsIOutputStream',
                  notflattened=True)
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
@@ -1228,9 +1250,8 @@ addExternalIface('TouchList', headerFile
 addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
                  notflattened=True)
 addExternalIface('UserDataHandler')
 addExternalIface('Window')
 addExternalIface('WindowProxy', nativeType='nsIDOMWindow')
 addExternalIface('XPathResult', nativeType='nsISupports')
 addExternalIface('XPathExpression')
 addExternalIface('XPathNSResolver')
-addExternalIface('XULElement')
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -5,17 +5,17 @@
 # Common codegen classes.
 
 import operator
 import os
 import re
 import string
 
 from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType
-from Configuration import NoSuchDescriptorError
+from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback
 
 AUTOGENERATED_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
 ADDPROPERTY_HOOK_NAME = '_addProperty'
 FINALIZE_HOOK_NAME = '_finalize'
 TRACE_HOOK_NAME = '_trace'
 CONSTRUCT_HOOK_NAME = '_constructor'
 HASINSTANCE_HOOK_NAME = '_hasInstance'
@@ -384,55 +384,16 @@ class CGIncludeGuard(CGWrapper):
     """
     def __init__(self, prefix, child):
         """|prefix| is the filename without the extension."""
         define = 'mozilla_dom_%s_h__' % prefix
         CGWrapper.__init__(self, child,
                            declarePre='#ifndef %s\n#define %s\n\n' % (define, define),
                            declarePost='\n#endif // %s\n' % define)
 
-def getTypesFromDescriptor(descriptor):
-    """
-    Get all argument and return types for all members of the descriptor
-    """
-    members = [m for m in descriptor.interface.members]
-    if descriptor.interface.ctor():
-        members.append(descriptor.interface.ctor())
-    signatures = [s for m in members if m.isMethod() for s in m.signatures()]
-    types = []
-    for s in signatures:
-        assert len(s) == 2
-        (returnType, arguments) = s
-        types.append(returnType)
-        types.extend(a.type for a in arguments)
-
-    types.extend(a.type for a in members if a.isAttr())
-    return types
-
-def getTypesFromDictionary(dictionary):
-    """
-    Get all member types for this dictionary
-    """
-    types = []
-    curDict = dictionary
-    while curDict:
-        types.extend([m.type for m in curDict.members])
-        curDict = curDict.parent
-    return types
-
-def getTypesFromCallback(callback):
-    """
-    Get the types this callback depends on: its return type and the
-    types of its arguments.
-    """
-    sig = callback.signatures()[0]
-    types = [sig[0]] # Return type
-    types.extend(arg.type for arg in sig[1]) # Arguments
-    return types
-
 def getRelevantProviders(descriptor, dictionary, config):
     assert not descriptor or not dictionary
     if descriptor is not None:
         return [descriptor]
     if dictionary is not None:
         # Do both the non-worker and worker versions
         return [
             config.getDescriptorProvider(False),
@@ -1957,20 +1918,28 @@ class CallbackObjectUnwrapper:
         return checkObjectType + string.Template(
             """nsresult rv;
 XPCCallContext ccx(JS_CALLER, cx);
 if (!ccx.IsValid()) {
   rv = NS_ERROR_XPC_BAD_CONVERT_JS;
 ${codeOnFailure}
 }
 
+nsISupports* supp = nullptr;
+if (XPCConvert::GetISupportsFromJSObject(${source}, &supp)) {
+  nsCOMPtr<nsIXPConnectWrappedNative> xpcwn = do_QueryInterface(supp);
+  if (xpcwn) {
+    supp = xpcwn->Native();
+  }
+}
+
 const nsIID& iid = NS_GET_IID(${nativeType});
 nsRefPtr<nsXPCWrappedJS> wrappedJS;
 rv = nsXPCWrappedJS::GetNewOrUsed(ccx, ${source}, iid,
-                                  NULL, getter_AddRefs(wrappedJS));
+                                  supp, getter_AddRefs(wrappedJS));
 if (NS_FAILED(rv) || !wrappedJS) {
 ${codeOnFailure}
 }
 
 // Use a temp nsCOMPtr for the null-check, because ${target} might be
 // OwningNonNull, not an nsCOMPtr.
 nsCOMPtr<${nativeType}> tmp = do_QueryObject(wrappedJS.get());
 if (!tmp) {
@@ -3568,27 +3537,30 @@ def typeNeedsCx(type, descriptorProvider
 
 # Returns a tuple consisting of a CGThing containing the type of the return
 # value, or None if there is no need for a return value, and a boolean signaling
 # whether the return value is passed in an out parameter.
 #
 # Whenever this is modified, please update CGNativeMember.getRetvalInfo as
 # needed
 def getRetvalDeclarationForType(returnType, descriptorProvider,
-                                resultAlreadyAddRefed):
+                                resultAlreadyAddRefed,
+                                isMember=False):
     if returnType is None or returnType.isVoid():
         # Nothing to declare
         return None, False
     if returnType.isPrimitive() and returnType.tag() in builtinNames:
         result = CGGeneric(builtinNames[returnType.tag()])
         if returnType.nullable():
             result = CGWrapper(result, pre="Nullable<", post=">")
         return result, False
     if returnType.isString():
-        return CGGeneric("nsString"), True
+        if isMember:
+            return CGGeneric("nsString"), True
+        return CGGeneric("DOMString"), True
     if returnType.isEnum():
         if returnType.nullable():
             raise TypeError("We don't support nullable enum return values")
         return CGGeneric(returnType.inner.identifier.name), False
     if returnType.isGeckoInterface():
         result = CGGeneric(descriptorProvider.getDescriptor(
             returnType.unroll().inner.identifier.name).nativeType)
         if resultAlreadyAddRefed:
@@ -3608,17 +3580,18 @@ def getRetvalDeclarationForType(returnTy
     if returnType.isSequence():
         nullable = returnType.nullable()
         if nullable:
             returnType = returnType.inner
         # If our result is already addrefed, use the right type in the
         # sequence argument here.
         (result, _) = getRetvalDeclarationForType(returnType.inner,
                                                   descriptorProvider,
-                                                  resultAlreadyAddRefed)
+                                                  resultAlreadyAddRefed,
+                                                  isMember=True)
         result = CGWrapper(result, pre="nsTArray< ", post=" >")
         if nullable:
             result = CGWrapper(result, pre="Nullable< ", post=" >")
         return result, True
     if returnType.isDictionary():
         nullable = returnType.nullable()
         result = CGGeneric(
             CGDictionary.makeDictionaryName(returnType.unroll().inner,
@@ -6518,44 +6491,26 @@ class CGNamespacedEnum(CGThing):
         assert False # Only for headers.
 
 class CGDictionary(CGThing):
     def __init__(self, dictionary, descriptorProvider):
         self.dictionary = dictionary
         self.descriptorProvider = descriptorProvider
         self.workers = descriptorProvider.workers
         self.needToInitIds = not self.workers and len(dictionary.members) > 0
-        if all(CGDictionary(d, descriptorProvider).generatable for
-               d in CGDictionary.getDictionaryDependencies(dictionary)):
-            self.generatable = True
-        else:
-            self.generatable = False
-            # Nothing else to do here
-            return
-        # Getting a conversion template for interface types can fail
-        # if we don't have a relevant descriptor when self.workers is True.
-        # If that happens, just mark ourselves as not being
-        # generatable and move on.
-        try:
-            self.memberInfo = [
-                (member,
-                 getJSToNativeConversionTemplate(member.type,
-                                                 descriptorProvider,
-                                                 isMember="Dictionary",
-                                                 isOptional=(not member.defaultValue),
-                                                 defaultValue=member.defaultValue))
-                for member in dictionary.members ]
-        except NoSuchDescriptorError, err:
-            if not self.workers:
-                raise err
-            self.generatable = False
+        self.memberInfo = [
+            (member,
+             getJSToNativeConversionTemplate(member.type,
+                                             descriptorProvider,
+                                             isMember="Dictionary",
+                                             isOptional=(not member.defaultValue),
+                                             defaultValue=member.defaultValue))
+            for member in dictionary.members ]
 
     def declare(self):
-        if not self.generatable:
-            return ""
         d = self.dictionary
         if d.parent:
             inheritance = ": public %s " % self.makeClassName(d.parent)
         elif not self.workers:
             inheritance = ": public MainThreadDictionaryBase "
         else:
             inheritance = ""
         memberDecls = ["  %s %s;" %
@@ -6594,18 +6549,16 @@ class CGDictionary(CGThing):
                 "  ${selfName}Initializer() {\n"
                 "    // Safe to pass a null context if we pass a null value\n"
                 "    Init(nullptr, nullptr, JS::NullValue());\n"
                 "  }\n"
                 "};").substitute( { "selfName": self.makeClassName(d),
                                     "inheritance": inheritance }))
 
     def define(self):
-        if not self.generatable:
-            return ""
         d = self.dictionary
         if d.parent:
             initParent = ("// Per spec, we init the parent's members first\n"
                           "if (!%s::Init(cx, scopeObj, val)) {\n"
                           "  return false;\n"
                           "}\n" % self.makeClassName(d.parent))
             toObjectParent = ("// Per spec, we define the parent's members first\n"
                               "if (!%s::ToObject(cx, parentObject, vp)) {\n"
@@ -6879,40 +6832,49 @@ class CGBindingRoot(CGThing):
     """
     Root codegen class for binding generation. Instantiate the class, and call
     declare or define to generate header or cpp code (respectively).
     """
     def __init__(self, config, prefix, webIDLFile):
         descriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                             hasInterfaceOrInterfacePrototypeObject=True,
                                             skipGen=False)
-        dictionaries = config.getDictionaries(webIDLFile)
-        callbacks = config.getCallbacks(webIDLFile)
+        mainDictionaries = config.getDictionaries(webIDLFile=webIDLFile,
+                                                  workers=False)
+        workerDictionaries = config.getDictionaries(webIDLFile=webIDLFile,
+                                                    workers=True)
+        mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile,
+                                            workers=False)
+        workerCallbacks = config.getCallbacks(webIDLFile=webIDLFile,
+                                              workers=True)
         callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                                     isCallback=True)
 
         forwardDeclares = [CGClassForwardDeclare('XPCWrappedNativeScope')]
 
         descriptorsForForwardDeclaration = list(descriptors)
         ifaces = []
         workerIfaces = []
-        for dictionary in dictionaries:
-            dictionaryIfaces = [ type.unroll().inner
-                                 for type in getTypesFromDictionary(dictionary)
-                                 if type.unroll().isGeckoInterface() ]
-            ifaces.extend(dictionaryIfaces)
-            workerIfaces.extend(dictionaryIfaces)
-
-        for callback in callbacks:
-            callbackIfaces = [ t.unroll().inner
-                               for t in getTypesFromCallback(callback)
-                               if t.unroll().isGeckoInterface() ]
-            workerIfaces.extend(callbackIfaces)
-            if not callback.isWorkerOnly():
-                ifaces.extend(callbackIfaces)
+        def getInterfacesFromDictionary(d):
+            return [ type.unroll().inner
+                     for type in getTypesFromDictionary(d)
+                     if type.unroll().isGeckoInterface() ]
+        for dictionary in mainDictionaries:
+            ifaces.extend(getInterfacesFromDictionary(dictionary))
+        for dictionary in workerDictionaries:
+            workerIfaces.extend(getInterfacesFromDictionary(dictionary))
+
+        def getInterfacesFromCallback(c):
+            return [ t.unroll().inner
+                     for t in getTypesFromCallback(c)
+                     if t.unroll().isGeckoInterface() ]
+        for callback in mainCallbacks:
+            ifaces.extend(getInterfacesFromCallback(callback))
+        for callback in workerCallbacks:
+            workerIfaces.extend(getInterfacesFromCallback(callback))
 
         for callbackDescriptor in callbackDescriptors:
             callbackDescriptorIfaces = [
                 t.unroll().inner
                 for t in getTypesFromDescriptor(callbackDescriptor)
                 if t.unroll().isGeckoInterface() ]
             workerIfaces.extend(callbackDescriptorIfaces)
             ifaces.extend(callbackDescriptorIfaces)
@@ -6943,30 +6905,30 @@ class CGBindingRoot(CGThing):
                                             declareOnly=True)
             return CGWrapper(declare, declarePost='\n')
 
         for x in descriptorsForForwardDeclaration:
             forwardDeclares.append(declareNativeType(x.nativeType))
 
         # Now add the forward declarations we need for our union types
         # and callback functions.
-        for callback in callbacks:
+        for callback in mainCallbacks + workerCallbacks:
             forwardDeclares.extend(
                 declareNativeType("mozilla::dom::" + str(t.unroll()))
                 for t in getTypesFromCallback(callback)
                 if t.unroll().isUnion() or t.unroll().isCallback())
 
         for callbackDescriptor in callbackDescriptors:
             forwardDeclares.extend(
                 declareNativeType("mozilla::dom::" + str(t.unroll()))
                 for t in getTypesFromDescriptor(callbackDescriptor)
                 if t.unroll().isUnion() or t.unroll().isCallback())
 
         # Forward declarations for callback functions used in dictionaries.
-        for dictionary in dictionaries:
+        for dictionary in mainDictionaries + workerDictionaries:
             forwardDeclares.extend(
                 declareNativeType("mozilla::dom::" + str(t.unroll()))
                 for t in getTypesFromDictionary(dictionary)
                 if t.unroll().isCallback())
 
         forwardDeclares = CGList(forwardDeclares)
 
         descriptorsWithPrototype = filter(lambda d: d.interface.hasInterfacePrototypeObject(),
@@ -7002,40 +6964,41 @@ class CGBindingRoot(CGThing):
         # here, because we have to generate these in order from least derived
         # to most derived so that class inheritance works out.  We also have to
         # generate members before the dictionary that contains them.
         #
         # XXXbz this will fail if we have two webidl files A and B such that A
         # declares a dictionary which inherits from a dictionary in B and B
         # declares a dictionary (possibly a different one!) that inherits from a
         # dictionary in A.  The good news is that I expect this to never happen.
-        reSortedDictionaries = []
-        dictionaries = set(dictionaries)
-        while len(dictionaries) != 0:
-            # Find the dictionaries that don't depend on anything else anymore
-            # and move them over.
-            toMove = [d for d in dictionaries if
-                      len(CGDictionary.getDictionaryDependencies(d) &
-                          dictionaries) == 0]
-            if len(toMove) == 0:
-                raise TypeError("Loop in dictionary dependency graph")
-            dictionaries = dictionaries - set(toMove)
-            reSortedDictionaries.extend(toMove)
-
-        dictionaries = reSortedDictionaries
+        def sortDictionaries(dictionaries):
+            reSortedDictionaries = []
+            dictionaries = set(dictionaries)
+            while len(dictionaries) != 0:
+                # Find the dictionaries that don't depend on anything else
+                # anymore and move them over.
+                toMove = [d for d in dictionaries if
+                          len(CGDictionary.getDictionaryDependencies(d) &
+                              dictionaries) == 0]
+                if len(toMove) == 0:
+                    raise TypeError("Loop in dictionary dependency graph")
+                dictionaries = dictionaries - set(toMove)
+                reSortedDictionaries.extend(toMove)
+            return reSortedDictionaries
+
         cgthings.extend([CGDictionary(d, config.getDescriptorProvider(True))
-                         for d in dictionaries])
+                         for d in sortDictionaries(workerDictionaries)])
         cgthings.extend([CGDictionary(d, config.getDescriptorProvider(False))
-                         for d in dictionaries])
+                         for d in sortDictionaries(mainDictionaries)])
 
         # Do codegen for all the callbacks.  Only do non-worker codegen for now,
         # since we don't have a sane setup yet for invoking callbacks in workers
         # and managing their lifetimes.
         cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False))
-                        for c in callbacks)
+                        for c in mainCallbacks)
 
         # Do codegen for all the descriptors
         cgthings.extend([CGDescriptor(x) for x in descriptors])
 
         # Do codegen for all the callback interfaces
         cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors])
 
         # And make sure we have the right number of newlines at the end
@@ -7048,18 +7011,18 @@ class CGBindingRoot(CGThing):
         curr = CGList([forwardDeclares,
                        CGWrapper(CGGeneric("using namespace mozilla::dom;"),
                                  defineOnly=True),
                        traitsClasses, curr],
                       "\n")
 
         # Add header includes.
         curr = CGHeaders(descriptors,
-                         dictionaries,
-                         callbacks,
+                         mainDictionaries + workerDictionaries,
+                         mainCallbacks + workerCallbacks,
                          callbackDescriptors,
                          ['mozilla/dom/BindingDeclarations.h',
                           'mozilla/ErrorResult.h',
                           'mozilla/dom/DOMJSClass.h',
                           'mozilla/dom/DOMJSProxyHandler.h'],
                          ['mozilla/dom/BindingUtils.h',
                           'mozilla/dom/NonRefcountedDOMObject.h',
                           'mozilla/dom/Nullable.h',
@@ -7664,48 +7627,32 @@ class CGExampleRoot(CGThing):
 
 class CGCallback(CGClass):
     def __init__(self, idlObject, descriptorProvider, baseName, methods,
                  getters=[], setters=[]):
         self.baseName = baseName
         name = idlObject.identifier.name
         if descriptorProvider.workers:
             name += "Workers"
-        try:
-            # For our public methods that needThisHandling we want most of the
-            # same args and the same return type as what CallbackMember
-            # generates.  So we want to take advantage of all its
-            # CGNativeMember infrastructure, but that infrastructure can't deal
-            # with templates and most especially template arguments.  So just
-            # cheat and have CallbackMember compute all those things for us.
-            realMethods = []
-            for method in methods:
-                if not method.needThisHandling:
-                    realMethods.append(method)
-                else:
-                    realMethods.extend(self.getMethodImpls(method))
-            CGClass.__init__(self, name,
-                             bases=[ClassBase(baseName)],
-                             constructors=self.getConstructors(),
-                             methods=realMethods+getters+setters)
-            self.generatable = True
-        except NoSuchDescriptorError, err:
-            if not descriptorProvider.workers:
-                raise err
-            self.generatable = False
-
-    def define(self):
-        if not self.generatable:
-            return ""
-        return CGClass.define(self)
-
-    def declare(self):
-        if not self.generatable:
-            return ""
-        return CGClass.declare(self)
+        # For our public methods that needThisHandling we want most of the
+        # same args and the same return type as what CallbackMember
+        # generates.  So we want to take advantage of all its
+        # CGNativeMember infrastructure, but that infrastructure can't deal
+        # with templates and most especially template arguments.  So just
+        # cheat and have CallbackMember compute all those things for us.
+        realMethods = []
+        for method in methods:
+            if not method.needThisHandling:
+                realMethods.append(method)
+            else:
+                realMethods.extend(self.getMethodImpls(method))
+        CGClass.__init__(self, name,
+                         bases=[ClassBase(baseName)],
+                         constructors=self.getConstructors(),
+                         methods=realMethods+getters+setters)
 
     def getConstructors(self):
         return [ClassConstructor(
             [Argument("JSContext*", "cx"),
              Argument("JSObject*", "aOwner"),
              Argument("JSObject*", "aCallback"),
              Argument("bool*", "aInited")],
             bodyInHeader=True,
@@ -7763,19 +7710,16 @@ class CGCallback(CGClass):
                             body=bodyWithThis),
                 ClassMethod(method.name, method.returnType, argsWithoutThis,
                             bodyInHeader=True,
                             body=bodyWithoutThis),
                 method]
 
 class CGCallbackFunction(CGCallback):
     def __init__(self, callback, descriptorProvider):
-        if callback.isWorkerOnly() and not descriptorProvider.workers:
-            self.generatable = False
-            return
         CGCallback.__init__(self, callback, descriptorProvider,
                             "CallbackFunction",
                             methods=[CallCallback(callback, descriptorProvider)])
 
     def getConstructors(self):
         return CGCallback.getConstructors(self) + [
             ClassConstructor(
             [Argument("CallbackFunction*", "aOther")],
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -57,20 +57,43 @@ class Configuration:
         # an interface.
         for descriptor in self.descriptors:
             intefaceName = descriptor.interface.identifier.name
             otherDescriptors = [d for d in self.descriptors
                                 if d.interface.identifier.name == intefaceName]
             descriptor.uniqueImplementation = len(otherDescriptors) == 1
 
         self.enums = [e for e in parseData if e.isEnum()]
+
+        # Figure out what our main-thread and worker dictionaries and callbacks
+        # are.
+        mainTypes = set()
+        for descriptor in self.getDescriptors(workers=False, isExternal=False):
+            mainTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
+        (mainCallbacks, mainDictionaries) = findCallbacksAndDictionaries(mainTypes)
+
+        workerTypes = set();
+        for descriptor in self.getDescriptors(workers=True, isExternal=False):
+            workerTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
+        (workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
+
         self.dictionaries = [d for d in parseData if d.isDictionary()]
         self.callbacks = [c for c in parseData if
                           c.isCallback() and not c.isInterface()]
 
+        def flagWorkerOrMainThread(items, main, worker):
+            for item in items:
+                if item in main:
+                    item.setUserData("mainThread", True)
+                if item in worker:
+                    item.setUserData("workers", True)
+        flagWorkerOrMainThread(self.dictionaries, mainDictionaries,
+                               workerDictionaries);
+        flagWorkerOrMainThread(self.callbacks, mainCallbacks, workerCallbacks)
+
         # Keep the descriptor list sorted for determinism.
         self.descriptors.sort(lambda x,y: cmp(x.name, y.name))
 
     def getInterface(self, ifname):
         return self.interfaces[ifname]
     def getDescriptors(self, **filters):
         """Gets the descriptors that match the given filters."""
         curr = self.descriptors
@@ -90,24 +113,36 @@ class Configuration:
             elif key == 'isExternal':
                 getter = lambda x: x.interface.isExternal()
             else:
                 getter = lambda x: getattr(x, key)
             curr = filter(lambda x: getter(x) == val, curr)
         return curr
     def getEnums(self, webIDLFile):
         return filter(lambda e: e.filename() == webIDLFile, self.enums)
-    def getDictionaries(self, webIDLFile=None):
-        if not webIDLFile:
-            return self.dictionaries
-        return filter(lambda d: d.filename() == webIDLFile, self.dictionaries)
-    def getCallbacks(self, webIDLFile=None):
-        if not webIDLFile:
-            return self.callbacks
-        return filter(lambda d: d.filename() == webIDLFile, self.callbacks)
+
+    @staticmethod
+    def _filterForFileAndWorkers(items, filters):
+        """Gets the items that match the given filters."""
+        for key, val in filters.iteritems():
+            if key == 'webIDLFile':
+                items = filter(lambda x: x.filename() == val, items)
+            elif key == 'workers':
+                if val:
+                    items = filter(lambda x: x.getUserData("workers", False), items)
+                else:
+                    items = filter(lambda x: x.getUserData("mainThread", False), items)
+            else:
+                assert(0) # Unknown key
+        return items
+    def getDictionaries(self, **filters):
+        return self._filterForFileAndWorkers(self.dictionaries, filters)
+    def getCallbacks(self, **filters):
+        return self._filterForFileAndWorkers(self.callbacks, filters)
+
     def getDescriptor(self, interfaceName, workers):
         """
         Gets the appropriate descriptor for the given interface name
         and the given workers boolean.
         """
         iface = self.getInterface(interfaceName)
         descriptors = self.getDescriptors(interface=iface)
 
@@ -402,8 +437,87 @@ class Descriptor(DescriptorProvider):
         return self.operations['IndexedGetter'] is not None
 
     def supportsNamedProperties(self):
         return self.operations['NamedGetter'] is not None
 
     def needsConstructHookHolder(self):
         assert self.interface.hasInterfaceObject()
         return not self.hasInstanceInterface and not self.interface.isCallback()
+
+# Some utility methods
+def getTypesFromDescriptor(descriptor):
+    """
+    Get all argument and return types for all members of the descriptor
+    """
+    members = [m for m in descriptor.interface.members]
+    if descriptor.interface.ctor():
+        members.append(descriptor.interface.ctor())
+    signatures = [s for m in members if m.isMethod() for s in m.signatures()]
+    types = []
+    for s in signatures:
+        assert len(s) == 2
+        (returnType, arguments) = s
+        types.append(returnType)
+        types.extend(a.type for a in arguments)
+
+    types.extend(a.type for a in members if a.isAttr())
+    return types
+
+def getFlatTypes(types):
+    retval = set()
+    for type in types:
+        type = type.unroll()
+        if type.isUnion():
+            retval |= set(type.flatMemberTypes)
+        else:
+            retval.add(type)
+    return retval
+
+def getTypesFromDictionary(dictionary):
+    """
+    Get all member types for this dictionary
+    """
+    types = []
+    curDict = dictionary
+    while curDict:
+        types.extend([m.type for m in curDict.members])
+        curDict = curDict.parent
+    return types
+
+def getTypesFromCallback(callback):
+    """
+    Get the types this callback depends on: its return type and the
+    types of its arguments.
+    """
+    sig = callback.signatures()[0]
+    types = [sig[0]] # Return type
+    types.extend(arg.type for arg in sig[1]) # Arguments
+    return types
+
+def findCallbacksAndDictionaries(inputTypes):
+    """
+    Ensure that all callbacks and dictionaries reachable from types end up in
+    the returned callbacks and dictionaries sets.
+
+    Note that we assume that our initial invocation already includes all types
+    reachable via descriptors in "types", so we only have to deal with things
+    that are themeselves reachable via callbacks and dictionaries.
+    """
+    def doFindCallbacksAndDictionaries(types, callbacks, dictionaries):
+        unhandledTypes = set()
+        for type in types:
+            if type.isCallback() and type not in callbacks:
+                unhandledTypes |= getFlatTypes(getTypesFromCallback(type))
+                callbacks.add(type)
+            elif type.isDictionary() and type.inner not in dictionaries:
+                d = type.inner
+                unhandledTypes |= getFlatTypes(getTypesFromDictionary(d))
+                while d:
+                    dictionaries.add(d)
+                    d = d.parent
+        if len(unhandledTypes) != 0:
+            doFindCallbacksAndDictionaries(unhandledTypes, callbacks, dictionaries)
+
+    retCallbacks = set()
+    retDictionaries = set()
+    doFindCallbacksAndDictionaries(inputTypes, retCallbacks, retDictionaries)
+    return (retCallbacks, retDictionaries)
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -81,16 +81,17 @@ LOCAL_INCLUDES += -I$(topsrcdir)/js/xpco
   -I$(topsrcdir)/js/xpconnect/wrappers \
   -I$(topsrcdir)/content/canvas/src \
   -I$(topsrcdir)/content/html/content/src \
   -I$(topsrcdir)/media/webrtc/signaling/src/peerconnection \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/content/xslt/src/base \
   -I$(topsrcdir)/content/xslt/src/xpath \
   -I$(topsrcdir)/content/xml/content/src \
+  -I$(topsrcdir)/content/xul/content/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
   BindingGen.py \
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -2341,17 +2341,16 @@ class IDLCallbackType(IDLType, IDLObject
 
         IDLObjectWithScope.__init__(self, location, parentScope, identifier)
 
         for (returnType, arguments) in self.signatures():
             for argument in arguments:
                 argument.resolve(self)
 
         self._treatNonCallableAsNull = False
-        self._workerOnly = False
 
     def isCallback(self):
         return True
 
     def signatures(self):
         return [(self._returnType, self._arguments)]
 
     def tag(self):
@@ -2382,26 +2381,21 @@ class IDLCallbackType(IDLType, IDLObject
 
     def isDistinguishableFrom(self, other):
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isNonCallbackInterface() or other.isDate())
 
-    def isWorkerOnly(self):
-        return self._workerOnly
-
     def addExtendedAttributes(self, attrs):
         unhandledAttrs = []
         for attr in attrs:
             if attr.identifier() == "TreatNonCallableAsNull":
                 self._treatNonCallableAsNull = True
-            elif attr.identifier() == "WorkerOnly":
-                self._workerOnly = True
             else:
                 unhandledAttrs.append(attr)
         if len(unhandledAttrs) != 0:
             IDLType.addExtendedAttributes(self, unhandledAttrs)
 
 class IDLMethodOverload:
     """
     A class that represents a single overload of a WebIDL method.  This is not
--- a/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
+++ b/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
@@ -67,19 +67,16 @@
   "MutationCallback interface: existence and properties of interface object": true,
   "MutationCallback interface: existence and properties of interface prototype object": true,
   "MutationCallback interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "MutationCallback interface: operation handleEvent(MutationRecord,MutationObserver)": true,
   "XMLDocument interface: existence and properties of interface object": true,
   "XMLDocument interface: existence and properties of interface prototype object": true,
   "XMLDocument interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "Stringification of xmlDoc": "debug",
-  "EventTarget interface: calling addEventListener(DOMString,EventListener,boolean) on xmlDoc with too few arguments must throw TypeError": true,
-  "EventTarget interface: calling removeEventListener(DOMString,EventListener,boolean) on xmlDoc with too few arguments must throw TypeError": true,
-  "EventTarget interface: calling dispatchEvent(Event) on xmlDoc with too few arguments must throw TypeError": true,
   "DocumentType interface: operation remove()": true,
   "DocumentType interface: document.doctype must inherit property \"remove\" with the proper type (3)": true,
   "Element interface: attribute namespaceURI": true,
   "Element interface: attribute prefix": true,
   "Element interface: attribute localName": true,
   "Element interface: attribute attributes": true,
   "Element interface: attribute className": true,
   "Element interface: operation remove()": true,
--- a/dom/interfaces/xul/nsIDOMXULElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULElement.idl
@@ -7,20 +7,19 @@
 
 interface nsIRDFCompositeDataSource;
 interface nsIXULTemplateBuilder;
 interface nsIRDFResource;
 interface nsIControllers;
 interface nsIBoxObject;
 
 
-[scriptable, uuid(3a07dead-39e5-4dad-bc68-6ef369994126)]
+[scriptable, uuid(bece5b0b-6e59-4de5-98d0-088adfd1cadc)]
 interface nsIDOMXULElement : nsIDOMElement
 {
-  attribute DOMString                 id;
   attribute DOMString                 className;
 
   // Layout properties
   attribute DOMString align;
   attribute DOMString dir;
   attribute DOMString flex;
   attribute DOMString flexGroup;
   attribute DOMString ordinal;
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1160,17 +1160,17 @@ ContentChild::RecvFileSystemUpdate(const
                                    const int32_t& aState,
                                    const int32_t& aMountGeneration)
 {
 #ifdef MOZ_WIDGET_GONK
     nsRefPtr<nsVolume> volume = new nsVolume(aFsName, aName, aState,
                                              aMountGeneration);
 
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-    nsString stateStr(NS_ConvertUTF8toUTF16(volume->StateStr()));
+    NS_ConvertUTF8toUTF16 stateStr(volume->StateStr());
     obs->NotifyObservers(volume, NS_VOLUME_STATE_CHANGED, stateStr.get());
 #else
     // Remove warnings about unused arguments
     unused << aFsName;
     unused << aName;
     unused << aState;
     unused << aMountGeneration;
 #endif
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -48,17 +48,16 @@ using namespace mozilla;
 #include "AndroidBridge.h"
 #include "mozilla/dom/ScreenOrientation.h"
 #include "mozilla/Hal.h"
 #include "GLContextProvider.h"
 #include "TexturePoolOGL.h"
 
 using namespace mozilla::gl;
 
-typedef nsNPAPIPluginInstance::TextureInfo TextureInfo;
 typedef nsNPAPIPluginInstance::VideoInfo VideoInfo;
 
 class PluginEventRunnable : public nsRunnable
 {
 public:
   PluginEventRunnable(nsNPAPIPluginInstance* instance, ANPEvent* event)
     : mInstance(instance), mEvent(*event), mCanceled(false) {}
 
@@ -96,32 +95,32 @@ public:
   SharedPluginTexture() : mLock("SharedPluginTexture.mLock")
   {
   }
 
   ~SharedPluginTexture()
   {
   }
 
-  TextureInfo Lock()
+  nsNPAPIPluginInstance::TextureInfo Lock()
   {
     if (!EnsureGLContext()) {
       mTextureInfo.mTexture = 0;
       return mTextureInfo;
     }
 
     if (!mTextureInfo.mTexture && sPluginContext->MakeCurrent()) {
       sPluginContext->fGenTextures(1, &mTextureInfo.mTexture);
     }
 
     mLock.Lock();
     return mTextureInfo;
   }
 
-  void Release(TextureInfo& aTextureInfo)
+  void Release(nsNPAPIPluginInstance::TextureInfo& aTextureInfo)
   { 
     mTextureInfo = aTextureInfo;
     mLock.Unlock();
   } 
 
   SharedTextureHandle CreateSharedHandle()
   {
     MutexAutoLock lock(mLock);
@@ -141,17 +140,17 @@ public:
     // ensures that we create a new one in Lock()
     sPluginContext->fDeleteTextures(1, &mTextureInfo.mTexture);
     mTextureInfo.mTexture = 0;
     
     return handle;
   }
 
 private:
-  TextureInfo mTextureInfo;
+  nsNPAPIPluginInstance::TextureInfo mTextureInfo;
  
   Mutex mLock;
 };
 
 static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap;
 
 #endif
 
@@ -947,23 +946,23 @@ void nsNPAPIPluginInstance::EnsureShared
 GLContext* nsNPAPIPluginInstance::GLContext()
 {
   if (!EnsureGLContext())
     return nullptr;
 
   return sPluginContext;
 }
 
-TextureInfo nsNPAPIPluginInstance::LockContentTexture()
+nsNPAPIPluginInstance::TextureInfo nsNPAPIPluginInstance::LockContentTexture()
 {
   EnsureSharedTexture();
   return mContentTexture->Lock();
 }
 
-void nsNPAPIPluginInstance::ReleaseContentTexture(TextureInfo& aTextureInfo)
+void nsNPAPIPluginInstance::ReleaseContentTexture(nsNPAPIPluginInstance::TextureInfo& aTextureInfo)
 {
   EnsureSharedTexture();
   mContentTexture->Release(aTextureInfo);
 }
 
 nsSurfaceTexture* nsNPAPIPluginInstance::CreateSurfaceTexture()
 {
   if (!EnsureGLContext())
--- a/dom/system/gonk/nsVolumeService.cpp
+++ b/dom/system/gonk/nsVolumeService.cpp
@@ -125,17 +125,17 @@ NS_IMETHODIMP nsVolumeService::Broadcast
         NS_LossyConvertUTF16toASCII(aVolName).get());
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsCOMPtr<nsIObserverService> obs = GetObserverService();
   NS_ENSURE_TRUE(obs, NS_NOINTERFACE);
 
   DBG("nsVolumeService::BroadcastVolume for '%s'", vol->NameStr().get());
-  nsString stateStr(NS_ConvertUTF8toUTF16(vol->StateStr()));
+  NS_ConvertUTF8toUTF16 stateStr(vol->StateStr());
   obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
   return NS_OK;
 }
 
 NS_IMETHODIMP nsVolumeService::GetVolumeByName(const nsAString& aVolName, nsIVolume **aResult)
 {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   nsRefPtr<nsVolume> vol = FindVolumeByName(aVolName);
@@ -264,17 +264,17 @@ void nsVolumeService::UpdateVolume(const
     // Nothing has really changed. Don't bother telling anybody.
     return;
   }
   vol->Set(aVolume);
   nsCOMPtr<nsIObserverService> obs = GetObserverService();
   if (!obs) {
     return;
   }
-  nsString stateStr(NS_ConvertUTF8toUTF16(vol->StateStr()));
+  NS_ConvertUTF8toUTF16 stateStr(vol->StateStr());
   obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
 }
 
 /***************************************************************************
 * The UpdateVolumeRunnable creates an nsVolume and updates the main thread
 * data structure while running on the main thread.
 */
 class UpdateVolumeRunnable : public nsRunnable
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -13,17 +13,16 @@
 
 interface CanvasGradient;
 interface CanvasPattern;
 interface HitRegionOptions;
 interface HTMLCanvasElement;
 interface HTMLVideoElement;
 interface TextMetrics;
 interface Window;
-interface XULElement;
 
 enum CanvasWindingRule { "nonzero", "evenodd" };
 
 interface CanvasRenderingContext2D {
 
   // back-reference to the canvas.  Might be null if we're not
   // associated with a canvas.
   readonly attribute HTMLCanvasElement? canvas;
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -137,134 +137,22 @@ partial interface Document {
   //(HTML only)boolean execCommand(DOMString commandId, boolean showUI, DOMString value);
   //(HTML only)boolean queryCommandEnabled(DOMString commandId);
   //(HTML only)boolean queryCommandIndeterm(DOMString commandId);
   //(HTML only)boolean queryCommandState(DOMString commandId);
   //(HTML only)boolean queryCommandSupported(DOMString commandId);
   //(HTML only)DOMString queryCommandValue(DOMString commandId);
   //(Not implemented)readonly attribute HTMLCollection commands;
 
-  // event handler IDL attributes
-           [SetterThrows]
-           attribute EventHandler onabort;
-           [SetterThrows]
-           attribute EventHandler onblur;
-  //(Not implemented)         attribute EventHandler oncancel;
-           [SetterThrows]
-           attribute EventHandler oncanplay;
-           [SetterThrows]
-           attribute EventHandler oncanplaythrough;
-           [SetterThrows]
-           attribute EventHandler onchange;
-           [SetterThrows]
-           attribute EventHandler onclick;
-  //(Not implemented)         attribute EventHandler onclose;
-           [SetterThrows]
-           attribute EventHandler oncontextmenu;
-  //(Not implemented)         attribute EventHandler oncuechange;
-           [SetterThrows]
-           attribute EventHandler ondblclick;
-           [SetterThrows]
-           attribute EventHandler ondrag;
-           [SetterThrows]
-           attribute EventHandler ondragend;
-           [SetterThrows]
-           attribute EventHandler ondragenter;
-           [SetterThrows]
-           attribute EventHandler ondragleave;
-           [SetterThrows]
-           attribute EventHandler ondragover;
-           [SetterThrows]
-           attribute EventHandler ondragstart;
-           [SetterThrows]
-           attribute EventHandler ondrop;
-           [SetterThrows]
-           attribute EventHandler ondurationchange;
-           [SetterThrows]
-           attribute EventHandler onemptied;
-           [SetterThrows]
-           attribute EventHandler onended;
-           [SetterThrows]
-           attribute EventHandler onerror;
-           [SetterThrows]
-           attribute EventHandler onfocus;
-           [SetterThrows]
-           attribute EventHandler oninput;
-           [SetterThrows]
-           attribute EventHandler oninvalid;
-           [SetterThrows]
-           attribute EventHandler onkeydown;
-           [SetterThrows]
-           attribute EventHandler onkeypress;
-           [SetterThrows]
-           attribute EventHandler onkeyup;
-           [SetterThrows]
-           attribute EventHandler onload;
-           [SetterThrows]
-           attribute EventHandler onloadeddata;
-           [SetterThrows]
-           attribute EventHandler onloadedmetadata;
-           [SetterThrows]
-           attribute EventHandler onloadstart;
-           [SetterThrows]
-           attribute EventHandler onmousedown;
-           [SetterThrows]
-           attribute EventHandler onmousemove;
-           [SetterThrows]
-           attribute EventHandler onmouseout;
-           [SetterThrows]
-           attribute EventHandler onmouseover;
-           [SetterThrows]
-           attribute EventHandler onmouseup;
-  //(Not implemented)         attribute EventHandler onmousewheel;
-           [SetterThrows]
-           attribute EventHandler onpause;
-           [SetterThrows]
-           attribute EventHandler onplay;
-           [SetterThrows]
-           attribute EventHandler onplaying;
-           [SetterThrows]
-           attribute EventHandler onprogress;
-           [SetterThrows]
-           attribute EventHandler onratechange;
-           [SetterThrows]
-           attribute EventHandler onreset;
-           [SetterThrows]
-           attribute EventHandler onscroll;
-           [SetterThrows]
-           attribute EventHandler onseeked;
-           [SetterThrows]
-           attribute EventHandler onseeking;
-           [SetterThrows]
-           attribute EventHandler onselect;
-           [SetterThrows]
-           attribute EventHandler onshow;
-           [SetterThrows]
-           attribute EventHandler onstalled;
-           [SetterThrows]
-           attribute EventHandler onsubmit;
-           [SetterThrows]
-           attribute EventHandler onsuspend;
-           [SetterThrows]
-           attribute EventHandler ontimeupdate;
-           [SetterThrows]
-           attribute EventHandler onvolumechange;
-           [SetterThrows]
-           attribute EventHandler onwaiting;
-
   // special event handler IDL attributes that only apply to Document objects
   [LenientThis, SetterThrows] attribute EventHandler onreadystatechange;
 
   // Gecko extensions?
   [LenientThis, SetterThrows] attribute EventHandler onmouseenter;
   [LenientThis, SetterThrows] attribute EventHandler onmouseleave;
-  [SetterThrows] attribute EventHandler onmozfullscreenchange;
-  [SetterThrows] attribute EventHandler onmozfullscreenerror;
-  [SetterThrows] attribute EventHandler onmozpointerlockchange;
-  [SetterThrows] attribute EventHandler onmozpointerlockerror;
   [SetterThrows] attribute EventHandler onwheel;
   [SetterThrows] attribute EventHandler oncopy;
   [SetterThrows] attribute EventHandler oncut;
   [SetterThrows] attribute EventHandler onpaste;
   [SetterThrows] attribute EventHandler onbeforescriptexecute;
   [SetterThrows] attribute EventHandler onafterscriptexecute;
   /**
    * True if this document is synthetic : stand alone image, video, audio file,
@@ -441,8 +329,10 @@ partial interface Document {
   [Creator, Pref="dom.w3c_touch_events.expose"]
   TouchList createTouchList();
   [Creator, Pref="dom.w3c_touch_events.expose"]
   TouchList createTouchList(sequence<Touch> touches);
   */
 };
 
 Document implements XPathEvaluator;
+Document implements GlobalEventHandlers;
+Document implements NodeEventHandlers;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/DummyBinding.webidl
@@ -0,0 +1,20 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+// Dummy bindings that we need to force generation of things that
+// aren't actually referenced anywhere in IDL yet but are used in C++.
+
+interface DummyInterface {
+  readonly attribute OnErrorEventHandlerNonNull onErrorEventHandler;
+  FilePropertyBag fileBag();
+  RTCIceServer rtcIceServer();
+  CFStateChangeEventDict cfstateChangeEvent();
+  USSDReceivedEventDict ussdReceivedEvent();
+};
+
+interface DummyInterfaceWorkers {
+  BlobPropertyBag blobBag();
+};
--- a/dom/webidl/EventHandler.webidl
+++ b/dom/webidl/EventHandler.webidl
@@ -16,8 +16,178 @@ typedef EventHandlerNonNull? EventHandle
 
 [TreatNonCallableAsNull]
 callback BeforeUnloadEventHandlerNonNull = DOMString? (Event event);
 typedef BeforeUnloadEventHandlerNonNull? BeforeUnloadEventHandler;
 
 [TreatNonCallableAsNull]
 callback OnErrorEventHandlerNonNull = boolean ((Event or DOMString) event, optional DOMString source, optional unsigned long lineno, optional unsigned long column);
 typedef OnErrorEventHandlerNonNull? OnErrorEventHandler;
+
+[NoInterfaceObject]
+interface GlobalEventHandlers {
+           [SetterThrows]
+           attribute EventHandler onabort;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler oncancel;
+           [SetterThrows]
+           attribute EventHandler oncanplay;
+           [SetterThrows]
+           attribute EventHandler oncanplaythrough;
+           [SetterThrows]
+           attribute EventHandler onchange;
+           [SetterThrows]
+           attribute EventHandler onclick;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler onclose;
+           [SetterThrows]
+           attribute EventHandler oncontextmenu;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler oncuechange;
+           [SetterThrows]
+           attribute EventHandler ondblclick;
+           [SetterThrows]
+           attribute EventHandler ondrag;
+           [SetterThrows]
+           attribute EventHandler ondragend;
+           [SetterThrows]
+           attribute EventHandler ondragenter;
+           [SetterThrows]
+           attribute EventHandler ondragleave;
+           [SetterThrows]
+           attribute EventHandler ondragover;
+           [SetterThrows]
+           attribute EventHandler ondragstart;
+           [SetterThrows]
+           attribute EventHandler ondrop;
+           [SetterThrows]
+           attribute EventHandler ondurationchange;
+           [SetterThrows]
+           attribute EventHandler onemptied;
+           [SetterThrows]
+           attribute EventHandler onended;
+           [SetterThrows]
+           attribute EventHandler oninput;
+           [SetterThrows]
+           attribute EventHandler oninvalid;
+           [SetterThrows]
+           attribute EventHandler onkeydown;
+           [SetterThrows]
+           attribute EventHandler onkeypress;
+           [SetterThrows]
+           attribute EventHandler onkeyup;
+           [SetterThrows]
+           attribute EventHandler onloadeddata;
+           [SetterThrows]
+           attribute EventHandler onloadedmetadata;
+           [SetterThrows]
+           attribute EventHandler onloadstart;
+           [SetterThrows]
+           attribute EventHandler onmousedown;
+           [SetterThrows]
+           attribute EventHandler onmousemove;
+           [SetterThrows]
+           attribute EventHandler onmouseout;
+           [SetterThrows]
+           attribute EventHandler onmouseover;
+           [SetterThrows]
+           attribute EventHandler onmouseup;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler onmousewheel;
+           [SetterThrows]
+           attribute EventHandler onpause;
+           [SetterThrows]
+           attribute EventHandler onplay;
+           [SetterThrows]
+           attribute EventHandler onplaying;
+           [SetterThrows]
+           attribute EventHandler onprogress;
+           [SetterThrows]
+           attribute EventHandler onratechange;
+           [SetterThrows]
+           attribute EventHandler onreset;
+           [SetterThrows]
+           attribute EventHandler onseeked;
+           [SetterThrows]
+           attribute EventHandler onseeking;
+           [SetterThrows]
+           attribute EventHandler onselect;
+           [SetterThrows]
+           attribute EventHandler onshow;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler onsort;
+           [SetterThrows]
+           attribute EventHandler onstalled;
+           [SetterThrows]
+           attribute EventHandler onsubmit;
+           [SetterThrows]
+           attribute EventHandler onsuspend;
+           [SetterThrows]
+           attribute EventHandler ontimeupdate;
+           [SetterThrows]
+           attribute EventHandler onvolumechange;
+           [SetterThrows]
+           attribute EventHandler onwaiting;
+
+           // Mozilla-specific handlers
+           [SetterThrows]
+           attribute EventHandler onmozfullscreenchange;
+           [SetterThrows]
+           attribute EventHandler onmozfullscreenerror;
+           [SetterThrows]
+           attribute EventHandler onmozpointerlockchange;
+           [SetterThrows]
+           attribute EventHandler onmozpointerlockerror;
+};
+
+[NoInterfaceObject]
+interface NodeEventHandlers {
+           [SetterThrows]
+           attribute EventHandler onblur;
+  // We think the spec is wrong here.
+  //         attribute OnErrorEventHandler onerror;
+           [SetterThrows]
+           attribute EventHandler onerror;
+           [SetterThrows]
+           attribute EventHandler onfocus;
+           [SetterThrows]
+           attribute EventHandler onload;
+           [SetterThrows]
+           attribute EventHandler onscroll;
+};
+
+[NoInterfaceObject]
+interface WindowEventHandlers {
+           [SetterThrows]
+           attribute EventHandler onafterprint;
+           [SetterThrows]
+           attribute EventHandler onbeforeprint;
+           [SetterThrows]
+           attribute BeforeUnloadEventHandler onbeforeunload;
+  //       For now, onerror comes from NodeEventHandlers
+  //       When we convert Window to WebIDL this may need to change.
+  //       [SetterThrows]
+  //       attribute OnErrorEventHandler onerror;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler onfullscreenchange;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler onfullscreenerror;
+           [SetterThrows]
+           attribute EventHandler onhashchange;
+           [SetterThrows]
+           attribute EventHandler onmessage;
+           [SetterThrows]
+           attribute EventHandler onoffline;
+           [SetterThrows]
+           attribute EventHandler ononline;
+           [SetterThrows]
+           attribute EventHandler onpagehide;
+           [SetterThrows]
+           attribute EventHandler onpageshow;
+           [SetterThrows]
+           attribute EventHandler onpopstate;
+           [SetterThrows]
+           attribute EventHandler onresize;
+           //(Not implemented)[SetterThrows]
+           //(Not implemented)attribute EventHandler onstorage;
+           [SetterThrows]
+           attribute EventHandler onunload;
+};
--- a/dom/webidl/HTMLBodyElement.webidl
+++ b/dom/webidl/HTMLBodyElement.webidl
@@ -7,54 +7,20 @@
  * http://www.whatwg.org/specs/web-apps/current-work/
  *
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 interface HTMLBodyElement : HTMLElement {
-  [SetterThrows]
-  attribute EventHandler onafterprint;
-  [SetterThrows]
-  attribute EventHandler onbeforeprint;
-  [SetterThrows]
-  attribute BeforeUnloadEventHandler onbeforeunload;
-  //[SetterThrows]
-  //attribute EventHandler onblur;
-  //[SetterThrows]
-  //attribute OnErrorEventHandler onerror;
-  //[SetterThrows]
-  //attribute EventHandler onfocus;
-  [SetterThrows]
-  attribute EventHandler onhashchange;
-  //[SetterThrows]
-  //attribute EventHandler onload;
-  [SetterThrows]
-  attribute EventHandler onmessage;
-  [SetterThrows]
-  attribute EventHandler onoffline;
-  [SetterThrows]
-  attribute EventHandler ononline;
-  [SetterThrows]
-  attribute EventHandler onpopstate;
-  [SetterThrows]
-  attribute EventHandler onpagehide;
-  [SetterThrows]
-  attribute EventHandler onpageshow;
-  [SetterThrows]
-  attribute EventHandler onresize;
-  //[SetterThrows]
-  //attribute EventHandler onscroll;
-  //[SetterThrows]
-  //attribute EventHandler onstorage;
-  [SetterThrows]
-  attribute EventHandler onunload;
 };
 
 partial interface HTMLBodyElement {
   [TreatNullAs=EmptyString, SetterThrows] attribute DOMString text;
   [TreatNullAs=EmptyString, SetterThrows] attribute DOMString link;
   [TreatNullAs=EmptyString, SetterThrows] attribute DOMString vLink;
   [TreatNullAs=EmptyString, SetterThrows] attribute DOMString aLink;
   [TreatNullAs=EmptyString, SetterThrows] attribute DOMString bgColor;
   [SetterThrows]                          attribute DOMString background;
 };
+
+HTMLBodyElement implements WindowEventHandlers;
--- a/dom/webidl/HTMLElement.webidl
+++ b/dom/webidl/HTMLElement.webidl
@@ -10,16 +10,17 @@
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 interface DOMStringMap;
 interface HTMLMenuElement;
 
+// Hack to make sure that we initialize the touch prefs properly
 [PrefControlled]
 interface HTMLElement : Element {
   // metadata attributes
            attribute DOMString title;
            attribute DOMString lang;
   //         attribute boolean translate;
   [SetterThrows]
            attribute DOMString dir;
@@ -71,156 +72,20 @@ interface HTMLElement : Element {
   //readonly attribute boolean? commandHidden;
   //readonly attribute boolean? commandDisabled;
   //readonly attribute boolean? commandChecked;
 
   // styling
   [Constant]
   readonly attribute CSSStyleDeclaration style;
 
-  // event handler IDL attributes
-  [SetterThrows]
-           attribute EventHandler onabort;
-  [SetterThrows]
-           attribute EventHandler onblur;
-  //[SetterThrows]
-  //         attribute EventHandler oncancel;
-  [SetterThrows]
-           attribute EventHandler oncanplay;
-  [SetterThrows]
-           attribute EventHandler oncanplaythrough;
-  [SetterThrows]
-           attribute EventHandler onchange;
-  [SetterThrows]
-           attribute EventHandler onclick;
-  //[SetterThrows]
-  //         attribute EventHandler onclose;
-  [SetterThrows]
-           attribute EventHandler oncontextmenu;
-  //[SetterThrows]
-  //         attribute EventHandler oncuechange;
-  [SetterThrows]
-           attribute EventHandler ondblclick;
-  [SetterThrows]
-           attribute EventHandler ondrag;
-  [SetterThrows]
-           attribute EventHandler ondragend;
-  [SetterThrows]
-           attribute EventHandler ondragenter;
-  [SetterThrows]
-           attribute EventHandler ondragleave;
-  [SetterThrows]
-           attribute EventHandler ondragover;
-  [SetterThrows]
-           attribute EventHandler ondragstart;
-  [SetterThrows]
-           attribute EventHandler ondrop;
-  [SetterThrows]
-           attribute EventHandler ondurationchange;
-  [SetterThrows]
-           attribute EventHandler onemptied;
-  [SetterThrows]
-           attribute EventHandler onended;
-  // We think the spec is wrong here.
-  //         attribute OnErrorEventHandler onerror;
-  [SetterThrows]
-           attribute EventHandler onerror;
-  [SetterThrows]
-           attribute EventHandler onfocus;
-  [SetterThrows]
-           attribute EventHandler oninput;
-  [SetterThrows]
-           attribute EventHandler oninvalid;
-  [SetterThrows]
-           attribute EventHandler onkeydown;
-  [SetterThrows]
-           attribute EventHandler onkeypress;
-  [SetterThrows]
-           attribute EventHandler onkeyup;
-  [SetterThrows]
-           attribute EventHandler onload;
-  [SetterThrows]
-           attribute EventHandler onloadeddata;
-  [SetterThrows]
-           attribute EventHandler onloadedmetadata;
-  [SetterThrows]
-           attribute EventHandler onloadstart;
-  [SetterThrows]
-           attribute EventHandler onmousedown;
-  [SetterThrows]
-           attribute EventHandler onmousemove;
-  [SetterThrows]
-           attribute EventHandler onmouseout;
-  [SetterThrows]
-           attribute EventHandler onmouseover;
-  [SetterThrows]
-           attribute EventHandler onmouseup;
-  //[SetterThrows]
-  //         attribute EventHandler onmousewheel;
-  [SetterThrows]
-           attribute EventHandler onpause;
-  [SetterThrows]
-           attribute EventHandler onplay;
-  [SetterThrows]
-           attribute EventHandler onplaying;
-  [SetterThrows]
-           attribute EventHandler onprogress;
-  [SetterThrows]
-           attribute EventHandler onratechange;
-  [SetterThrows]
-           attribute EventHandler onreset;
-  [SetterThrows]
-           attribute EventHandler onscroll;
-  [SetterThrows]
-           attribute EventHandler onseeked;
-  [SetterThrows]
-           attribute EventHandler onseeking;
-  [SetterThrows]
-           attribute EventHandler onselect;
-  [SetterThrows]
-           attribute EventHandler onshow;
-  [SetterThrows]
-           attribute EventHandler onstalled;
-  [SetterThrows]
-           attribute EventHandler onsubmit;
-  [SetterThrows]
-           attribute EventHandler onsuspend;
-  [SetterThrows]
-           attribute EventHandler ontimeupdate;
-  [SetterThrows]
-           attribute EventHandler onvolumechange;
-  [SetterThrows]
-           attribute EventHandler onwaiting;
-
-  [SetterThrows]
-           attribute EventHandler onmozfullscreenchange;
-  [SetterThrows]
-           attribute EventHandler onmozfullscreenerror;
-  [SetterThrows]
-           attribute EventHandler onmozpointerlockchange;
-  [SetterThrows]
-           attribute EventHandler onmozpointerlockerror;
-
   // Mozilla specific stuff
   // FIXME Bug 810677 Move className from HTMLElement to Element
            attribute DOMString className;
 
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchstart;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchend;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchmove;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchenter;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchleave;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchcancel;
-
   [SetterThrows]
            attribute EventHandler oncopy;
   [SetterThrows]
            attribute EventHandler oncut;
   [SetterThrows]
            attribute EventHandler onpaste;
 };
 
@@ -228,9 +93,29 @@ interface HTMLElement : Element {
 partial interface HTMLElement {
   readonly attribute Element? offsetParent;
   readonly attribute long offsetTop;
   readonly attribute long offsetLeft;
   readonly attribute long offsetWidth;
   readonly attribute long offsetHeight;
 };
 
+[NoInterfaceObject]
+interface TouchEventHandlers {
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchstart;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchend;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchmove;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchenter;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchleave;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchcancel;
+};
+
+HTMLElement implements GlobalEventHandlers;
+HTMLElement implements NodeEventHandlers;
+HTMLElement implements TouchEventHandlers;
+
 interface HTMLUnknownElement : HTMLElement {};
--- a/dom/webidl/HTMLFrameSetElement.webidl
+++ b/dom/webidl/HTMLFrameSetElement.webidl
@@ -11,44 +11,11 @@
  * and create derivative works of this document.
  */
 
 interface HTMLFrameSetElement : HTMLElement {
   [SetterThrows]
   attribute DOMString cols;
   [SetterThrows]
   attribute DOMString rows;
-  [SetterThrows]
-  attribute EventHandler onafterprint;
-  [SetterThrows]
-  attribute EventHandler onbeforeprint;
-  [SetterThrows]
-  attribute BeforeUnloadEventHandler onbeforeunload;
-  //[SetterThrows]
-  //attribute EventHandler onblur;
-  //[SetterThrows]
-  //attribute EventHandler onerror;
-  //[SetterThrows]
-  //attribute EventHandler onfocus;
-  [SetterThrows]
-  attribute EventHandler onhashchange;
-  //attribute EventHandler onload;
-  [SetterThrows]
-  attribute EventHandler onmessage;
-  [SetterThrows]
-  attribute EventHandler onoffline;
-  [SetterThrows]
-  attribute EventHandler ononline;
-  [SetterThrows]
-  attribute EventHandler onpagehide;
-  [SetterThrows]
-  attribute EventHandler onpageshow;
-  [SetterThrows]
-  attribute EventHandler onpopstate;
-  [SetterThrows]
-  attribute EventHandler onresize;
-  //[SetterThrows]
-  //attribute EventHandler onscroll;
-  //[SetterThrows]
-  //attribute EventHandler onstorage;
-  [SetterThrows]
-  attribute EventHandler onunload;
 };
+
+HTMLFrameSetElement implements WindowEventHandlers;
--- a/dom/webidl/SVGElement.webidl
+++ b/dom/webidl/SVGElement.webidl
@@ -29,151 +29,19 @@ interface SVGElement : Element {
   attribute DOMString xmllang;
   [SetterThrows]
   attribute DOMString xmlspace;*/
 
   [Throws]
   readonly attribute SVGSVGElement? ownerSVGElement;
   readonly attribute SVGElement? viewportElement;
 
-  // event handler IDL attributes
-  [SetterThrows]
-           attribute EventHandler onabort;
-  [SetterThrows]
-           attribute EventHandler onblur;
-  //[SetterThrows]
-  //         attribute EventHandler oncancel;
-  [SetterThrows]
-           attribute EventHandler oncanplay;
-  [SetterThrows]
-           attribute EventHandler oncanplaythrough;
-  [SetterThrows]
-           attribute EventHandler onchange;
-  [SetterThrows]
-           attribute EventHandler onclick;
-  //[SetterThrows]
-  //         attribute EventHandler onclose;
-  [SetterThrows]
-           attribute EventHandler oncontextmenu;
-  //[SetterThrows]
-  //         attribute EventHandler oncuechange;
-  [SetterThrows]
-           attribute EventHandler ondblclick;
-  [SetterThrows]
-           attribute EventHandler ondrag;
-  [SetterThrows]
-           attribute EventHandler ondragend;
-  [SetterThrows]
-           attribute EventHandler ondragenter;
-  [SetterThrows]
-           attribute EventHandler ondragleave;
-  [SetterThrows]
-           attribute EventHandler ondragover;
-  [SetterThrows]
-           attribute EventHandler ondragstart;
-  [SetterThrows]
-           attribute EventHandler ondrop;
-  [SetterThrows]
-           attribute EventHandler ondurationchange;
-  [SetterThrows]
-           attribute EventHandler onemptied;
-  [SetterThrows]
-           attribute EventHandler onended;
-  // We think the spec is wrong here.
-  //         attribute OnErrorEventHandler onerror;
-  [SetterThrows]
-           attribute EventHandler onerror;
-  [SetterThrows]
-           attribute EventHandler onfocus;
-  [SetterThrows]
-           attribute EventHandler oninput;
-  [SetterThrows]
-           attribute EventHandler oninvalid;
-  [SetterThrows]
-           attribute EventHandler onkeydown;
-  [SetterThrows]
-           attribute EventHandler onkeypress;
-  [SetterThrows]
-           attribute EventHandler onkeyup;
-  [SetterThrows]
-           attribute EventHandler onload;
-  [SetterThrows]
-           attribute EventHandler onloadeddata;
-  [SetterThrows]
-           attribute EventHandler onloadedmetadata;
-  [SetterThrows]
-           attribute EventHandler onloadstart;
-  [SetterThrows]
-           attribute EventHandler onmousedown;
-  [SetterThrows]
-           attribute EventHandler onmousemove;
-  [SetterThrows]
-           attribute EventHandler onmouseout;
-  [SetterThrows]
-           attribute EventHandler onmouseover;
-  [SetterThrows]
-           attribute EventHandler onmouseup;
-  //[SetterThrows]
-  //         attribute EventHandler onmousewheel;
-  [SetterThrows]
-           attribute EventHandler onpause;
-  [SetterThrows]
-           attribute EventHandler onplay;
-  [SetterThrows]
-           attribute EventHandler onplaying;
-  [SetterThrows]
-           attribute EventHandler onprogress;
-  [SetterThrows]
-           attribute EventHandler onratechange;
-  [SetterThrows]
-           attribute EventHandler onreset;
-  [SetterThrows]
-           attribute EventHandler onscroll;
-  [SetterThrows]
-           attribute EventHandler onseeked;
-  [SetterThrows]
-           attribute EventHandler onseeking;
-  [SetterThrows]
-           attribute EventHandler onselect;
-  [SetterThrows]
-           attribute EventHandler onshow;
-  [SetterThrows]
-           attribute EventHandler onstalled;
-  [SetterThrows]
-           attribute EventHandler onsubmit;
-  [SetterThrows]
-           attribute EventHandler onsuspend;
-  [SetterThrows]
-           attribute EventHandler ontimeupdate;
-  [SetterThrows]
-           attribute EventHandler onvolumechange;
-  [SetterThrows]
-           attribute EventHandler onwaiting;
-
-  [SetterThrows]
-           attribute EventHandler onmozfullscreenchange;
-  [SetterThrows]
-           attribute EventHandler onmozfullscreenerror;
-  [SetterThrows]
-           attribute EventHandler onmozpointerlockchange;
-  [SetterThrows]
-           attribute EventHandler onmozpointerlockerror;
-
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchstart;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchend;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchmove;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchenter;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchleave;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchcancel;
-
   [SetterThrows]
            attribute EventHandler oncopy;
   [SetterThrows]
            attribute EventHandler oncut;
   [SetterThrows]
            attribute EventHandler onpaste;
 };
+
+SVGElement implements GlobalEventHandlers;
+SVGElement implements NodeEventHandlers;
+SVGElement implements TouchEventHandlers;
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -17,16 +17,17 @@ webidl_files = \
   AudioNode.webidl \
   AudioParam.webidl \
   AudioSourceNode.webidl \
   BiquadFilterNode.webidl \
   Blob.webidl \
   CanvasRenderingContext2D.webidl \
   CaretPosition.webidl \
   CDATASection.webidl \
+  CFStateChangeEvent.webidl \
   CharacterData.webidl \
   ClientRectList.webidl \
   Comment.webidl \
   CSS.webidl \
   CSSPrimitiveValue.webidl \
   CSSStyleDeclaration.webidl \
   CSSValue.webidl \
   CSSValueList.webidl \
@@ -35,16 +36,17 @@ webidl_files = \
   DocumentFragment.webidl \
   DocumentType.webidl \
   DOMImplementation.webidl \
   DOMParser.webidl \
   DOMSettableTokenList.webidl \
   DOMStringMap.webidl \
   DOMTokenList.webidl \
   DOMTransaction.webidl \
+  DummyBinding.webidl \
   DynamicsCompressorNode.webidl \
   Element.webidl \
   EventHandler.webidl \
   EventListener.webidl \
   EventSource.webidl \
   EventTarget.webidl \
   File.webidl \
   FileHandle.webidl \
@@ -92,16 +94,17 @@ webidl_files = \
   PaintRequestList.webidl \
   PannerNode.webidl \
   Performance.webidl \
   PerformanceNavigation.webidl \
   PerformanceTiming.webidl \
   ProcessingInstruction.webidl \
   Rect.webidl \
   RGBColor.webidl \
+  RTCIceServer.webidl \
   Screen.webidl \
   SVGAElement.webidl \
   SVGAltGlyphElement.webidl \
   SVGAngle.webidl \
   SVGAnimatedAngle.webidl \
   SVGAnimatedBoolean.webidl \
   SVGAnimatedLength.webidl \
   SVGAnimatedLengthList.webidl \
@@ -170,40 +173,34 @@ webidl_files = \
   SVGZoomAndPan.webidl \
   Text.webidl \
   TextDecoder.webidl \
   TextEncoder.webidl \
   URL.webidl \
   ValidityState.webidl \
   WebSocket.webidl \
   UndoManager.webidl \
+  USSDReceivedEvent.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
   XMLSerializer.webidl \
   XPathEvaluator.webidl \
+  XULElement.webidl \
   $(NULL)
 
 ifdef MOZ_WEBGL
 webidl_files += \
   WebGLRenderingContext.webidl \
   $(NULL)
 endif
 
 ifdef MOZ_WEBRTC
 webidl_files += \
   MediaStreamList.webidl \
-  RTCIceServer.webidl \
-  $(NULL)
-endif
-
-ifdef MOZ_B2G_RIL
-webidl_files += \
-  USSDReceivedEvent.webidl \
-  CFStateChangeEvent.webidl \
   $(NULL)
 endif
 
 ifdef ENABLE_TESTS
 test_webidl_files := \
   TestCodeGen.webidl \
   TestDictionary.webidl \
   TestExampleGen.webidl \
new file mode 100644
--- /dev/null
+++ b/dom/webidl/XULElement.webidl
@@ -0,0 +1,134 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+interface MozBoxObject;
+interface MozControllers;
+interface MozFrameLoader;
+interface MozRDFCompositeDataSource;
+interface MozRDFResource;
+interface MozXULTemplateBuilder;
+
+// Hack to make sure that we initialize the touch prefs properly
+[PrefControlled]
+interface XULElement : Element {
+  [SetterThrows]
+  attribute DOMString className;
+
+  // Layout properties
+  [SetterThrows]
+  attribute DOMString align;
+  [SetterThrows]
+  attribute DOMString dir;
+  [SetterThrows]
+  attribute DOMString flex;
+  [SetterThrows]
+  attribute DOMString flexGroup;
+  [SetterThrows]
+  attribute DOMString ordinal;
+  [SetterThrows]
+  attribute DOMString orient;
+  [SetterThrows]
+  attribute DOMString pack;
+
+  // Properties for hiding elements.
+  attribute boolean hidden;
+  attribute boolean collapsed;
+
+  // Property for hooking up to broadcasters
+  [SetterThrows]
+  attribute DOMString observes;
+
+  // Properties for hooking up to popups
+  [SetterThrows]
+  attribute DOMString menu;
+  [SetterThrows]
+  attribute DOMString contextMenu;
+  [SetterThrows]
+  attribute DOMString tooltip;
+
+  // Width/height properties
+  [SetterThrows]
+  attribute DOMString width;
+  [SetterThrows]
+  attribute DOMString height;
+  [SetterThrows]
+  attribute DOMString minWidth;
+  [SetterThrows]
+  attribute DOMString minHeight;
+  [SetterThrows]
+  attribute DOMString maxWidth;
+  [SetterThrows]
+  attribute DOMString maxHeight;
+
+  // Persistence
+  [SetterThrows]
+  attribute DOMString persist;
+
+  // Position properties for
+  // * popups - these are screen coordinates
+  // * other elements - these are client coordinates relative to parent stack.
+  [SetterThrows]
+  attribute DOMString left;
+  [SetterThrows]
+  attribute DOMString top;
+
+  // XUL Template Builder
+  [SetterThrows]
+  attribute DOMString datasources;
+  [SetterThrows]
+  attribute DOMString ref;
+
+  // Tooltip and status info
+  [SetterThrows]
+  attribute DOMString tooltipText;
+  [SetterThrows]
+  attribute DOMString statusText;
+
+  attribute boolean allowEvents;
+
+  readonly attribute MozRDFCompositeDataSource? database;
+  readonly attribute MozXULTemplateBuilder?     builder;
+  [Throws]
+  readonly attribute MozRDFResource?            resource;
+  [Throws]
+  readonly attribute MozControllers             controllers;
+  [Throws]
+  readonly attribute MozBoxObject?              boxObject;
+
+  [Throws]
+  void                      focus();
+  [Throws]
+  void                      blur();
+  [Throws]
+  void                      click();
+  void                      doCommand();
+
+  // XXXbz this isn't really a nodelist!  See bug 818548
+  NodeList            getElementsByAttribute(DOMString name,
+                                             DOMString value);
+  // XXXbz this isn't really a nodelist!  See bug 818548
+  [Throws]
+  NodeList            getElementsByAttributeNS(DOMString namespaceURI,
+                                               DOMString name,
+                                               DOMString value);
+  [Constant]
+  readonly attribute CSSStyleDeclaration style;
+};
+
+// And the things from nsIFrameLoaderOwner
+[NoInterfaceObject]
+interface MozFrameLoaderOwner {
+  [ChromeOnly]
+  readonly attribute MozFrameLoader? frameLoader;
+
+  [ChromeOnly, Throws]
+  void swapFrameLoaders(XULElement aOtherOwner);
+};
+
+XULElement implements GlobalEventHandlers;
+XULElement implements NodeEventHandlers;
+XULElement implements TouchEventHandlers;
+XULElement implements MozFrameLoaderOwner;
--- a/editor/libeditor/base/nsEditPropertyAtomList.h
+++ b/editor/libeditor/base/nsEditPropertyAtomList.h
@@ -109,16 +109,17 @@ EDITOR_ATOM(html, "html")
 EDITOR_ATOM(i, "i")
 EDITOR_ATOM(img, "img")
 EDITOR_ATOM(input, "input")
 EDITOR_ATOM(kbd, "kbd")
 EDITOR_ATOM(keygen, "keygen")
 EDITOR_ATOM(label, "label")
 EDITOR_ATOM(legend, "legend")
 EDITOR_ATOM(li, "li")
+EDITOR_ATOM(main, "main")
 EDITOR_ATOM(map, "map")
 EDITOR_ATOM(mark, "mark")
 EDITOR_ATOM(meter, "meter")
 EDITOR_ATOM(menuitem, "menuitem")
 EDITOR_ATOM(mozdirty, "_moz_dirty")
 EDITOR_ATOM(mozEditorBogusNode, "_moz_editor_bogus_node")
 EDITOR_ATOM(name, "name")
 EDITOR_ATOM(nav, "nav")
--- a/editor/libeditor/html/nsHTMLEditUtils.cpp
+++ b/editor/libeditor/html/nsHTMLEditUtils.cpp
@@ -529,17 +529,17 @@ nsHTMLEditUtils::SupportsAlignAttr(nsIDO
 // progress, q, script, span, sub, sup
 #define GROUP_SPECIAL          (1 << 5)
 
 // button, form, input, label, select, textarea
 #define GROUP_FORMCONTROL      (1 << 6)
 
 // address, applet, article, aside, blockquote, button, center, del, dir, div,
 // dl, fieldset, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup,
-// hr, iframe, ins, map, menu, nav, noframes, noscript, object, ol, p,
+// hr, iframe, ins, main, map, menu, nav, noframes, noscript, object, ol, p,
 // pre, table, section, ul
 #define GROUP_BLOCK            (1 << 7)
 
 // frame, frameset
 #define GROUP_FRAME            (1 << 8)
 
 // col, tbody
 #define GROUP_TABLE_CONTENT    (1 << 9)
@@ -692,16 +692,17 @@ static const nsElementInfo kElements[eHT
   ELEM(ins, true, true, GROUP_PHRASE | GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(kbd, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(keygen, false, false, GROUP_FORMCONTROL, GROUP_NONE),
   ELEM(label, true, false, GROUP_FORMCONTROL, GROUP_INLINE_ELEMENT),
   ELEM(legend, true, true, GROUP_NONE, GROUP_INLINE_ELEMENT),
   ELEM(li, true, false, GROUP_LI, GROUP_FLOW_ELEMENT),
   ELEM(link, false, false, GROUP_HEAD_CONTENT, GROUP_NONE),
   ELEM(listing, false, false, GROUP_NONE, GROUP_NONE),
+  ELEM(main, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(map, true, true, GROUP_SPECIAL, GROUP_BLOCK | GROUP_MAP_CONTENT),
   ELEM(mark, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(marquee, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(menu, true, true, GROUP_BLOCK, GROUP_LI | GROUP_FLOW_ELEMENT),
   ELEM(menuitem, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(meta, false, false, GROUP_HEAD_CONTENT, GROUP_NONE),
   ELEM(meter, true, false, GROUP_SPECIAL, GROUP_FLOW_ELEMENT),
   ELEM(multicol, false, false, GROUP_NONE, GROUP_NONE),
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -1122,27 +1122,28 @@ IonCompile(JSContext *cx, JSScript *scri
     ScopedJSDeletePtr<LifoAlloc> autoDelete(alloc);
 
     TempAllocator *temp = alloc->new_<TempAllocator>(alloc);
     if (!temp)
         return AbortReason_Alloc;
 
     IonContext ictx(cx, cx->compartment, temp);
 
+    types::AutoEnterAnalysis enter(cx);
+
     if (!cx->compartment->ensureIonCompartmentExists(cx))
         return AbortReason_Alloc;
 
     MIRGraph *graph = alloc->new_<MIRGraph>(temp);
     ExecutionMode executionMode = compileContext.executionMode();
     CompileInfo *info = alloc->new_<CompileInfo>(script, fun, osrPc, constructing,
                                                  executionMode);
     if (!info)
         return AbortReason_Alloc;
 
-    types::AutoEnterAnalysis enter(cx);
     TypeInferenceOracle oracle;
 
     if (!oracle.init(cx, script))
         return AbortReason_Disable;
 
     AutoFlushCache afc("IonCompile");
 
     types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode));
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -865,17 +865,16 @@ IonBuilder::inspectOpcode(JSOp op)
         return jsop_notearg();
 
       case JSOP_GETARG:
       case JSOP_CALLARG:
         current->pushArg(GET_SLOTNO(pc));
         return true;
 
       case JSOP_SETARG:
-        JS_ASSERT(inliningDepth == 0);
         // To handle this case, we should spill the arguments to the space where
         // actual arguments are stored. The tricky part is that if we add a MIR
         // to wrap the spilling action, we don't want the spilling to be
         // captured by the GETARG and by the resume point, only by
         // MGetArgument.
         if (info().hasArguments())
             return abort("NYI: arguments & setarg.");
         current->setArg(GET_SLOTNO(pc));
--- a/js/src/ion/IonFrameIterator-inl.h
+++ b/js/src/ion/IonFrameIterator-inl.h
@@ -10,17 +10,17 @@
 
 #include "ion/IonFrameIterator.h"
 
 namespace js {
 namespace ion {
 
 template <class Op>
 inline void
-SnapshotIterator::readFrameArgs(Op op, const Value *argv, Value *scopeChain, Value *thisv,
+SnapshotIterator::readFrameArgs(Op &op, const Value *argv, Value *scopeChain, Value *thisv,
                                 unsigned start, unsigned formalEnd, unsigned iterEnd)
 {
     if (scopeChain)
         *scopeChain = read();
     else
         skip();
 
     if (thisv)
@@ -57,36 +57,43 @@ InlineFrameIterator::forEachCanonicalAct
 
     unsigned end = start + count;
     unsigned nformal = callee()->nargs;
 
     JS_ASSERT(start <= end && end <= nactual);
 
     if (more()) {
         // There is still a parent frame of this inlined frame.
-        // Take arguments of the caller (parent inlined frame) it holds all actual
-        // arguments, needed in case of overflow, and because the analyze phase
-        // disable Ion inlining if the function redefine its arguments with JSOP_SETARG.
+        // The not overflown arguments are taken from the inlined frame,
+        // because it will have the updated value when JSOP_SETARG is done.
+        // All arguments (also the overflown) are the last pushed values in the parent frame.
+        // To get the overflown arguments, we need to take them from there.
 
-        InlineFrameIterator it(cx, this);
-        ++it;
-        SnapshotIterator s(it.snapshotIterator());
+        // Get the non overflown arguments
+        unsigned formal_end = (end < nformal) ? end : nformal;
+        SnapshotIterator s(si_);
+        s.readFrameArgs(op, NULL, NULL, NULL, start, nformal, formal_end);
 
-        // Skip over all slots untill we get to the arguments slots
+        // The overflown arguments are not available in current frame.
+        // They are the last pushed arguments in the parent frame of this inlined frame.
+        InlineFrameIterator it(cx, this);
+        SnapshotIterator parent_s((++it).snapshotIterator());
+
+        // Skip over all slots untill we get to the last slots (= arguments slots of callee)
         // the +2 is for [this] and [scopechain]
-        JS_ASSERT(s.slots() >= nactual + 2);
-        unsigned skip = s.slots() - nactual - 2;
+        JS_ASSERT(parent_s.slots() >= nactual + 2);
+        unsigned skip = parent_s.slots() - nactual - 2;
         for (unsigned j = 0; j < skip; j++)
-            s.skip();
+            parent_s.skip();
 
-        s.readFrameArgs(op, NULL, NULL, NULL, start, nactual, end);
+        // Get the overflown arguments
+        parent_s.readFrameArgs(op, NULL, NULL, NULL, nformal, nactual, end);
     } else {
         SnapshotIterator s(si_);
         Value *argv = frame_->actualArgs();
         s.readFrameArgs(op, argv, NULL, NULL, start, nformal, end);
     }
-
 }
 
 } // namespace ion
 } // namespace js
 
 #endif // jsion_frame_iterator_inl_h__
--- a/js/src/ion/IonFrameIterator.h
+++ b/js/src/ion/IonFrameIterator.h
@@ -233,17 +233,17 @@ class SnapshotIterator : public Snapshot
         if (slotReadable(s))
             return slotValue(s);
         if (!silentFailure)
             warnUnreadableSlot();
         return UndefinedValue();
     }
 
     template <class Op>
-    inline void readFrameArgs(Op op, const Value *argv, Value *scopeChain, Value *thisv,
+    inline void readFrameArgs(Op &op, const Value *argv, Value *scopeChain, Value *thisv,
                               unsigned start, unsigned formalEnd, unsigned iterEnd);
 
     Value maybeReadSlotByIndex(size_t index) {
         while (index--) {
             JS_ASSERT(moreSlots());
             skip();
         }
 
--- a/js/src/ion/Lowering.cpp
+++ b/js/src/ion/Lowering.cpp
@@ -495,19 +495,21 @@ LIRGenerator::visitTest(MTest *test)
         }
 
         // Compare and branch Int32 or Object pointers.
         if (comp->compareType() == MCompare::Compare_Int32 ||
             comp->compareType() == MCompare::Compare_Object)
         {
             JSOp op = ReorderComparison(comp->jsop(), &left, &right);
             LAllocation lhs = useRegister(left);
-            LAllocation rhs = useRegister(right);
+            LAllocation rhs;
             if (comp->compareType() == MCompare::Compare_Int32)
                 rhs = useAnyOrConstant(right);
+            else
+                rhs = useRegister(right);
             LCompareAndBranch *lir = new LCompareAndBranch(op, lhs, rhs, ifTrue, ifFalse);
             return add(lir, comp);
         }
 
         // Compare and branch doubles.
         if (comp->compareType() == MCompare::Compare_Double) {
             LAllocation lhs = useRegister(left);
             LAllocation rhs = useRegister(right);
@@ -639,19 +641,21 @@ LIRGenerator::visitCompare(MCompare *com
     }
 
     // Compare Int32 or Object pointers.
     if (comp->compareType() == MCompare::Compare_Int32 ||
         comp->compareType() == MCompare::Compare_Object)
     {
         JSOp op = ReorderComparison(comp->jsop(), &left, &right);
         LAllocation lhs = useRegister(left);
-        LAllocation rhs = useRegister(right);
+        LAllocation rhs;
         if (comp->compareType() == MCompare::Compare_Int32)
             rhs = useAnyOrConstant(right);
+        else
+            rhs = useRegister(right);
         return define(new LCompare(op, lhs, rhs), comp);
     }
 
     // Compare doubles.
     if (comp->compareType() == MCompare::Compare_Double)
         return define(new LCompareD(useRegister(left), useRegister(right)), comp);
 
     // Compare values.
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js
@@ -0,0 +1,11 @@
+// |jit-test| debug
+
+function g() {
+    var x = 100;
+    return evalInFrame(2, "x");
+}
+function f() {
+    var x = 42;
+    return evalInFrame.call(null, 0, "g()");
+}
+assertEq(f.call(), 42);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug835178.js
@@ -0,0 +1,30 @@
+function boo() { return foo.arguments[0] }
+function foo(a,b,c) { if (a == 0) {a = 2; return boo();} return a }
+function inlined() { return foo.apply({}, arguments); }
+function test(a,b,c) { return inlined(a,b,c) }
+
+assertEq(test(1,2,3), 1);
+assertEq(test(0,2,3), 2);
+
+function g(a) { if (g.arguments[1]) return true; return false; };
+function f() { return g(false, true); };
+function h() { return f(false, false); }
+
+assertEq(h(false, false), true);
+assertEq(h(false, false), true);
+
+function g2(a) { if (a) { if (g2.arguments[1]) return true; return false; } return true; };
+function f2(a) { return g2(a, true); };
+function h2(a) { return f2(a, false); }
+
+assertEq(h2(false, false), true);
+assertEq(h2(true, false), true);
+
+// Currently disabled for now, but in testsuite to be sure
+function g3(a) { return a };
+function f3(a) { a = 3; return g3.apply({}, arguments); };
+function h3(a) { return f3(a); }
+
+assertEq(h3(0), 3);
+assertEq(h3(0), 3);
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug835496.js
@@ -0,0 +1,6 @@
+// |jit-test| error: TypeError
+
+(function([{x}]) {})({
+    t: 0,
+    "1": 0
+})
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -442,17 +442,17 @@ ScriptAnalysis::analyzeBytecode(JSContex
                 localsAliasStack_ = true;
                 break;
             }
             break;
           }
 
           case JSOP_SETARG:
             modifiesArguments_ = true;
-            isIonInlineable = isJaegerInlineable = false;
+            isJaegerInlineable = false;
             break;
 
           case JSOP_GETPROP:
           case JSOP_CALLPROP:
           case JSOP_LENGTH:
           case JSOP_GETELEM:
           case JSOP_CALLELEM:
             numPropertyReads_++;
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -195,19 +195,19 @@ class JSFunction : public JSObject
     inline void initEnvironment(JSObject *obj);
 
     static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
     static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); }
 
     js::UnrootedScript getOrCreateScript(JSContext *cx) {
         JS_ASSERT(isInterpreted());
         if (isInterpretedLazy()) {
+            js::RootedFunction self(cx, this);
             js::MaybeCheckStackRoots(cx);
-            js::RootedFunction self(cx, this);
-            if (!initializeLazyScript(cx))
+            if (!self->initializeLazyScript(cx))
                 return js::UnrootedScript(NULL);
             return self->u.i.script_;
         }
         JS_ASSERT(hasScript());
         return u.i.script_;
     }
 
     static bool maybeGetOrCreateScript(JSContext *cx, js::HandleFunction fun,
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3243,17 +3243,17 @@ TypeCompartment::fixObjectType(JSContext
     /*
      * Use the same type object for all singleton/JSON arrays with the same
      * base shape, i.e. the same fields written in the same order. If there
      * is a type mismatch with previous objects of the same shape, use the
      * generic unknown type.
      */
     JS_ASSERT(obj->isObject());
 
-    if (obj->slotSpan() == 0 || obj->inDictionaryMode())
+    if (obj->slotSpan() == 0 || obj->inDictionaryMode() || !obj->hasEmptyElements())
         return;
 
     ObjectTypeTable::AddPtr p = objectTypeTable->lookupForAdd(obj.get());
     Shape *baseShape = obj->lastProperty();
 
     if (p) {
         /* The lookup ensures the shape matches, now check that the types match. */
         Type *types = p->value.types;
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -61,16 +61,19 @@
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 using namespace js::unicode;
 
 using mozilla::CheckedInt;
 
+typedef Rooted<JSLinearString*> RootedLinearString;
+typedef Handle<JSLinearString*> HandleLinearString;
+
 static JSLinearString *
 ArgToRootedString(JSContext *cx, CallArgs &args, unsigned argno)
 {
     if (argno >= args.length())
         return cx->names().undefined;
 
     Value &arg = args[argno];
     JSString *str = ToString<CanGC>(cx, arg);
@@ -1849,18 +1852,18 @@ js::str_match(JSContext *cx, unsigned ar
         return false;
 
     if (!g.normalizeRegExp(cx, false, 1, args))
         return false;
 
     RootedObject array(cx);
     MatchArgType arg = array.address();
     RegExpStatics *res = cx->regExpStatics();
-    Value rval;
-    if (!DoMatch(cx, res, str, g.regExp(), MatchCallback, arg, MATCH_ARGS, &rval))
+    RootedValue rval(cx);
+    if (!DoMatch(cx, res, str, g.regExp(), MatchCallback, arg, MATCH_ARGS, rval.address()))
         return false;
 
     if (g.regExp().global())
         args.rval().setObjectOrNull(array);
     else
         args.rval().set(rval);
     return true;
 }
@@ -2008,32 +2011,32 @@ FindReplaceLength(JSContext *cx, RegExpS
          * 'function(a) { return b[a]; }' for the base object b.  b will not change
          * in the course of the replace unless we end up making a scripted call due
          * to accessing a scripted getter or a value with a scripted toString.
          */
         JS_ASSERT(rdata.lambda);
         JS_ASSERT(!rdata.elembase->getOps()->lookupProperty);
         JS_ASSERT(!rdata.elembase->getOps()->getProperty);
 
-        Value match;
-        if (!res->createLastMatch(cx, &match))
+        RootedValue match(cx);
+        if (!res->createLastMatch(cx, match.address()))
             return false;
         JSString *str = match.toString();
 
         JSAtom *atom;
         if (str->isAtom()) {
             atom = &str->asAtom();
         } else {
             atom = AtomizeString<CanGC>(cx, str);
             if (!atom)
                 return false;
         }
 
-        Value v;
-        if (HasDataProperty(cx, rdata.elembase, AtomToId(atom), &v) && v.isString()) {
+        RootedValue v(cx);
+        if (HasDataProperty(cx, rdata.elembase, AtomToId(atom), v.address()) && v.isString()) {
             rdata.repstr = v.toString()->ensureLinear(cx);
             if (!rdata.repstr)
                 return false;
             *sizep = rdata.repstr->length();
             return true;
         }
 
         /*
@@ -3153,17 +3156,17 @@ str_slice(JSContext *cx, unsigned argc, 
     return true;
 }
 
 #if JS_HAS_STR_HTML_HELPERS
 /*
  * HTML composition aids.
  */
 static bool
-tagify(JSContext *cx, const char *begin, JSLinearString *param, const char *end,
+tagify(JSContext *cx, const char *begin, HandleLinearString param, const char *end,
        CallReceiver call)
 {
     JSString *thisstr = ThisToStringForStringProto(cx, call);
     if (!thisstr)
         return false;
 
     JSLinearString *str = thisstr->ensureLinear(cx);
     if (!str)
@@ -3226,39 +3229,39 @@ tagify(JSContext *cx, const char *begin,
 
     call.rval().setString(retstr);
     return true;
 }
 
 static JSBool
 tagify_value(JSContext *cx, CallArgs args, const char *begin, const char *end)
 {
-    JSLinearString *param = ArgToRootedString(cx, args, 0);
+    RootedLinearString param(cx, ArgToRootedString(cx, args, 0));
     if (!param)
         return false;
 
     return tagify(cx, begin, param, end, args);
 }
 
 static JSBool
 str_bold(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "b", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "b", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_italics(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "i", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "i", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_fixed(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "tt", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "tt", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_fontsize(JSContext *cx, unsigned argc, Value *vp)
 {
     return tagify_value(cx, CallArgsFromVp(argc, vp), "font size", "font");
 }
 
@@ -3278,47 +3281,47 @@ static JSBool
 str_anchor(JSContext *cx, unsigned argc, Value *vp)
 {
     return tagify_value(cx, CallArgsFromVp(argc, vp), "a name", "a");
 }
 
 static JSBool
 str_strike(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "strike", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "strike", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_small(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "small", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "small", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_big(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "big", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "big", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_blink(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "blink", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "blink", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_sup(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "sup", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "sup", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 
 static JSBool
 str_sub(JSContext *cx, unsigned argc, Value *vp)
 {
-    return tagify(cx, "sub", NULL, NULL, CallReceiverFromVp(vp));
+    return tagify(cx, "sub", NullPtr(), NULL, CallReceiverFromVp(vp));
 }
 #endif /* JS_HAS_STR_HTML_HELPERS */
 
 static JSFunctionSpec string_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN("quote",             str_quote,             0,JSFUN_GENERIC_NATIVE),
     JS_FN(js_toSource_str,     str_toSource,          0,0),
 #endif
@@ -4275,18 +4278,18 @@ Decode(JSContext *cx, JSString *str, con
 static JSBool
 str_decodeURI(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     JSLinearString *str = ArgToRootedString(cx, args, 0);
     if (!str)
         return false;
 
-    Value result;
-    if (!Decode(cx, str, js_uriReservedPlusPound_ucstr, &result))
+    RootedValue result(cx);
+    if (!Decode(cx, str, js_uriReservedPlusPound_ucstr, result.address()))
         return false;
 
     args.rval().set(result);
     return true;
 }
 
 static JSBool
 str_decodeURI_Component(JSContext *cx, unsigned argc, Value *vp)
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -2496,17 +2496,17 @@ TypedArrayTemplate<double>::copyIndexToV
      * canonical nans are stored into jsvals, which means user code could
      * confuse the engine into interpreting a double-typed jsval as an
      * object-typed jsval.
      */
     vp.setDouble(JS_CANONICALIZE_NAN(val));
 }
 
 JSBool
-DataViewObject::construct(JSContext *cx, JSObject *bufobj, const CallArgs &args, JSObject *proto)
+DataViewObject::construct(JSContext *cx, JSObject *bufobj, const CallArgs &args, HandleObject proto)
 {
     if (!bufobj->isArrayBuffer()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_EXPECTED_TYPE,
                              "DataView", "ArrayBuffer", bufobj->getClass()->name);
         return false;
     }
 
     Rooted<ArrayBufferObject*> buffer(cx, &bufobj->asArrayBuffer());
@@ -2580,17 +2580,17 @@ DataViewObject::class_constructor(JSCont
         PodCopy(ag.array(), args.array(), args.length());
         ag[argc] = ObjectValue(*proto);
         if (!Invoke(cx, ag))
             return false;
         args.rval().set(ag.rval());
         return true;
     }
 
-    return construct(cx, bufobj, args, NULL);
+    return construct(cx, bufobj, args, NullPtr());
 }
 
 /* static */ bool
 DataViewObject::getDataPointer(JSContext *cx, Handle<DataViewObject*> obj,
                                CallArgs args, size_t typeSize, uint8_t **data)
 {
     uint32_t offset;
     JS_ASSERT(args.length() > 0);
--- a/js/src/jstypedarray.h
+++ b/js/src/jstypedarray.h
@@ -334,17 +334,17 @@ private:
 
     static inline Value bufferValue(DataViewObject &view);
     static inline Value byteOffsetValue(DataViewObject &view);
     static inline Value byteLengthValue(DataViewObject &view);
 
     static JSBool class_constructor(JSContext *cx, unsigned argc, Value *vp);
     static JSBool constructWithProto(JSContext *cx, unsigned argc, Value *vp);
     static JSBool construct(JSContext *cx, JSObject *bufobj, const CallArgs &args,
-                            JSObject *proto);
+                            HandleObject proto);
 
     static inline DataViewObject *
     create(JSContext *cx, uint32_t byteOffset, uint32_t byteLength,
            Handle<ArrayBufferObject*> arrayBuffer, JSObject *proto);
 
     static bool getInt8Impl(JSContext *cx, CallArgs args);
     static JSBool fun_getInt8(JSContext *cx, unsigned argc, Value *vp);
 
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -271,17 +271,17 @@ WeakMap_set_impl(JSContext *cx, CallArgs
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
                              "WeakMap.set", "0", "s");
         return false;
     }
     RootedObject key(cx, GetKeyArg(cx, args));
     if (!key)
         return false;
 
-    Value value = (args.length() > 1) ? args[1] : UndefinedValue();
+    RootedValue value(cx, (args.length() > 1) ? args[1] : UndefinedValue());
 
     Rooted<JSObject*> thisObj(cx, &args.thisv().toObject());
     ObjectValueMap *map = GetObjectMap(thisObj);
     if (!map) {
         map = cx->new_<ObjectValueMap>(cx, thisObj.get());
         if (!map->init()) {
             js_delete(map);
             JS_ReportOutOfMemory(cx);
@@ -317,18 +317,19 @@ WeakMap_set_impl(JSContext *cx, CallArgs
 JSBool
 WeakMap_set(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsWeakMap, WeakMap_set_impl>(cx, args);
 }
 
 JS_FRIEND_API(JSBool)
-JS_NondeterministicGetWeakMapKeys(JSContext *cx, JSObject *obj, JSObject **ret)
+JS_NondeterministicGetWeakMapKeys(JSContext *cx, JSObject *objArg, JSObject **ret)
 {
+    RootedObject obj(cx, objArg);
     obj = UnwrapObject(obj);
     if (!obj || !obj->isWeakMap()) {
         *ret = NULL;
         return true;
     }
     RootedObject arr(cx, NewDenseEmptyArray(cx));
     if (!arr)
         return false;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -557,18 +557,18 @@ Debugger::slowPathOnLeaveFrame(JSContext
                 status = dbg->handleUncaughtException(ac, NULL, false);
                 break;
             }
 
             /* Call the onPop handler. */
             Value rval;
             bool hookOk = Invoke(cx, ObjectValue(*frameobj), handler, 1, completion.address(),
                                  &rval);
-            Value nextValue;
-            JSTrapStatus nextStatus = dbg->parseResumptionValue(ac, hookOk, rval, &nextValue);
+            RootedValue nextValue(cx);
+            JSTrapStatus nextStatus = dbg->parseResumptionValue(ac, hookOk, rval, nextValue.address());
 
             /*
              * At this point, we are back in the debuggee compartment, and any error has
              * been wrapped up as a completion value.
              */
             JS_ASSERT(cx->compartment == global->compartment());
             JS_ASSERT(!cx->isExceptionPending());
 
@@ -1252,17 +1252,17 @@ Debugger::onSingleStep(JSContext *cx, Va
         ~PreserveIterValue() {
             cx->iterValue = savedIterValue;
         }
     };
     PreserveIterValue piv(cx);
 
     /* Call all the onStep handlers we found. */
     for (JSObject **p = frames.begin(); p != frames.end(); p++) {
-        JSObject *frame = *p;
+        RootedObject frame(cx, *p);
         Debugger *dbg = Debugger::fromChildJSObject(frame);
 
         Maybe<AutoCompartment> ac;
         ac.construct(cx, dbg->object);
 
         const Value &handler = frame->getReservedSlot(JSSLOT_DEBUGFRAME_ONSTEP_HANDLER);
         Value rval;
         bool ok = Invoke(cx, ObjectValue(*frame), handler, 0, NULL, &rval);
@@ -4327,21 +4327,21 @@ DebuggerObject_defineProperties(JSContex
 /*
  * This does a non-strict delete, as a matter of API design. The case where the
  * property is non-configurable isn't necessarily exceptional here.
  */
 static JSBool
 DebuggerObject_deleteProperty(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "deleteProperty", args, dbg, obj);
-    Value nameArg = argc > 0 ? args[0] : UndefinedValue();
+    RootedValue nameArg(cx, argc > 0 ? args[0] : UndefinedValue());
 
     Maybe<AutoCompartment> ac;
     ac.construct(cx, obj);
-    if (!cx->compartment->wrap(cx, &nameArg))
+    if (!cx->compartment->wrap(cx, nameArg.address()))
         return false;
 
     ErrorCopier ec(ac, dbg->toJSObject());
     return JSObject::deleteByValue(cx, obj, nameArg, args.rval(), false);
 }
 
 enum SealHelperOp { Seal, Freeze, PreventExtensions };
 
@@ -4437,17 +4437,17 @@ static JSBool
 ApplyOrCall(JSContext *cx, unsigned argc, Value *vp, ApplyOrCallMode mode)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "apply", args, dbg, obj);
 
     /*
      * Any JS exceptions thrown must be in the debugger compartment, so do
      * sanity checks and fallible conversions before entering the debuggee.
      */
-    Value calleev = ObjectValue(*obj);
+    RootedValue calleev(cx, ObjectValue(*obj));
     if (!obj->isCallable()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
                              "Debugger.Object", "apply", obj->getClass()->name);
         return false;
     }
 
     /*
      * Unwrap Debugger.Objects. This happens in the debugger's compartment since
@@ -4486,17 +4486,17 @@ ApplyOrCall(JSContext *cx, unsigned argc
     }
 
     /*
      * Enter the debuggee compartment and rewrap all input value for that compartment.
      * (Rewrapping always takes place in the destination compartment.)
      */
     Maybe<AutoCompartment> ac;
     ac.construct(cx, obj);
-    if (!cx->compartment->wrap(cx, &calleev) || !cx->compartment->wrap(cx, thisv.address()))
+    if (!cx->compartment->wrap(cx, calleev.address()) || !cx->compartment->wrap(cx, thisv.address()))
         return false;
     for (unsigned i = 0; i < callArgc; i++) {
         if (!cx->compartment->wrap(cx, &callArgv[i]))
             return false;
     }
 
     /*
      * Call the function. Use receiveCompletionValue to return to the debugger
--- a/js/src/vm/ObjectImpl.cpp
+++ b/js/src/vm/ObjectImpl.cpp
@@ -72,17 +72,17 @@ CheckArgCompartment(JSContext *cx, JSObj
     return true;
 }
 
 /*
  * Convert Debugger.Objects in desc to debuggee values.
  * Reject non-callable getters and setters.
  */
 bool
-PropDesc::unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, JSObject *obj,
+PropDesc::unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
                                     PropDesc *unwrapped) const
 {
     MOZ_ASSERT(!isUndefined());
 
     *unwrapped = *this;
 
     if (unwrapped->hasValue()) {
         RootedValue value(cx, unwrapped->value_);
@@ -118,17 +118,17 @@ PropDesc::unwrapDebuggerObjectsInto(JSCo
 }
 
 /*
  * Rewrap *idp and the fields of *desc for the current compartment.  Also:
  * defining a property on a proxy requires pd_ to contain a descriptor object,
  * so reconstitute desc->pd_ if needed.
  */
 bool
-PropDesc::wrapInto(JSContext *cx, JSObject *obj, const jsid &id, jsid *wrappedId,
+PropDesc::wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
                    PropDesc *desc) const
 {
     MOZ_ASSERT(!isUndefined());
 
     JSCompartment *comp = cx->compartment;
 
     *wrappedId = id;
     if (!comp->wrapId(cx, wrappedId))
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -284,20 +284,20 @@ struct PropDesc {
     /*
      * Throw a TypeError if a getter/setter is present and is neither callable
      * nor undefined. These methods do exactly the type checks that are skipped
      * by passing false as the checkAccessors parameter of initialize.
      */
     bool checkGetter(JSContext *cx);
     bool checkSetter(JSContext *cx);
 
-    bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, JSObject *obj,
+    bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
                                    PropDesc *unwrapped) const;
 
-    bool wrapInto(JSContext *cx, JSObject *obj, const jsid &id, jsid *wrappedId,
+    bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
                   PropDesc *wrappedDesc) const;
 
     class AutoRooter : private AutoGCRooter
     {
       public:
         explicit AutoRooter(JSContext *cx, PropDesc *pd_
                             MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
           : AutoGCRooter(cx, PROPDESC), pd(pd_), skip(cx, pd_)
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1368,17 +1368,19 @@ StackIter::settleOnNewState()
         bool containsCall = data_.seg_->contains(data_.calls_);
         while (!containsFrame && !containsCall) {
             /* Eval-in-frame can cross contexts, so use prevInMemory. */
             data_.seg_ = data_.seg_->prevInMemory();
             containsFrame = data_.seg_->contains(data_.fp_);
             containsCall = data_.seg_->contains(data_.calls_);
 
             /* Eval-in-frame allows jumping into the middle of a segment. */
-            if (containsFrame && data_.seg_->fp() != data_.fp_) {
+            if (containsFrame &&
+                (data_.seg_->fp() != data_.fp_ || data_.seg_->maybeCalls() != data_.calls_))
+            {
                 /* Avoid duplicating logic; seg_ contains fp_, so no iloop. */
                 StackIter tmp = *this;
                 tmp.startOnSegment(data_.seg_);
                 while (!tmp.isScript() || tmp.data_.fp_ != data_.fp_)
                     ++tmp;
                 JS_ASSERT(tmp.isScript() &&
                           tmp.data_.seg_ == data_.seg_ &&
                           tmp.data_.fp_ == data_.fp_);
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -74,24 +74,16 @@ XPCConvert::GetISupportsFromJSObject(JSO
         *iface = (nsISupports*) xpc_GetJSPrivate(obj);
         return true;
     }
     return UnwrapDOMObjectToISupports(obj, *iface);
 }
 
 /***************************************************************************/
 
-static void
-FinalizeXPCOMUCString(const JSStringFinalizer *fin, jschar *chars)
-{
-    nsMemory::Free(chars);
-}
-
-static const JSStringFinalizer sXPCOMUCStringFinalizer = { FinalizeXPCOMUCString };
-
 // static
 JSBool
 XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
                           const nsXPTType& type, const nsID* iid, nsresult* pErr)
 {
     NS_PRECONDITION(s, "bad param");
     NS_PRECONDITION(d, "bad param");
 
@@ -240,68 +232,80 @@ XPCConvert::NativeData2JS(XPCLazyCallCon
                 JSString* str;
                 if (!(str = JS_NewUCStringCopyZ(cx, p)))
                     return false;
                 *d = STRING_TO_JSVAL(str);
                 break;
             }
         case nsXPTType::T_UTF8STRING:
             {
-                const nsACString* cString = *((const nsACString**)s);
+                const nsACString* utf8String = *((const nsACString**)s);
 
-                if (!cString)
+                if (!utf8String || utf8String->IsVoid())
                     break;
 
-                if (!cString->IsVoid()) {
-                    uint32_t len;
-                    jschar *p = (jschar *)UTF8ToNewUnicode(*cString, &len);
-
-                    if (!p)
-                        return false;
-
-                    JSString* jsString =
-                        JS_NewExternalString(cx, p, len,
-                                             &sXPCOMUCStringFinalizer);
-
-                    if (!jsString) {
-                        nsMemory::Free(p);
-                        return false;
-                    }
-
-                    *d = STRING_TO_JSVAL(jsString);
+                if (utf8String->IsEmpty()) {
+                    *d = JS_GetEmptyStringValue(cx);
+                    break;
                 }
 
+                const uint32_t len = CalcUTF8ToUnicodeLength(*utf8String);
+                // The cString is not empty at this point, but the calculated
+                // UTF-16 length is zero, meaning no valid conversion exists.
+                if (!len)
+                    return false;
+
+                const size_t buffer_size = (len + 1) * sizeof(PRUnichar);
+                PRUnichar* buffer =
+                    static_cast<PRUnichar*>(JS_malloc(cx, buffer_size));
+                if (!buffer)
+                    return false;
+
+                uint32_t copied;
+                if (!UTF8ToUnicodeBuffer(*utf8String, buffer, &copied) ||
+                    len != copied) {
+                    // Copy or conversion during copy failed. Did not copy the
+                    // whole string.
+                    JS_free(cx, buffer);
+                    return false;
+                }
+
+                // JS_NewUCString takes ownership on success, i.e. a
+                // successful call will make it the responsiblity of the JS VM
+                // to free the buffer.
+                JSString* str = JS_NewUCString(cx, (jschar*)buffer, len);
+                if (!str) {
+                    JS_free(cx, buffer);
+                    return false;
+                }
+
+                *d = STRING_TO_JSVAL(str);
                 break;
-
             }
         case nsXPTType::T_CSTRING:
             {
                 const nsACString* cString = *((const nsACString**)s);
 
-                if (!cString)
+                if (!cString || cString->IsVoid())
                     break;
 
-                if (!cString->IsVoid()) {
-                    PRUnichar* unicodeString = ToNewUnicode(*cString);
-                    if (!unicodeString)
-                        return false;
-
-                    JSString* jsString = JS_NewExternalString(cx,
-                                                              (jschar*)unicodeString,
-                                                              cString->Length(),
-                                                              &sXPCOMUCStringFinalizer);
-
-                    if (!jsString) {
-                        nsMemory::Free(unicodeString);
-                        return false;
-                    }
-
-                    *d = STRING_TO_JSVAL(jsString);
+                if (cString->IsEmpty()) {
+                    *d = JS_GetEmptyStringValue(cx);
+                    break;
                 }
 
+                // c-strings (binary blobs) are deliberately not converted from
+                // UTF-8 to UTF-16. T_UTF8Sting is for UTF-8 encoded strings
+                // with automatic conversion.
+                JSString* str = JS_NewStringCopyN(cx, cString->Data(),
+                                                  cString->Length());
+                if (!str)
+                    return false;
+
+                *d = STRING_TO_JSVAL(str);
                 break;
             }
 
         case nsXPTType::T_INTERFACE:
         case nsXPTType::T_INTERFACE_IS:
             {
                 nsISupports* iface = *((nsISupports**)s);
                 if (iface) {
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -481,29 +481,19 @@ nsJSIID::HasInstance(nsIXPConnectWrapped
             if (!MorphSlimWrapper(cx, obj))
                 return NS_ERROR_FAILURE;
         } else {
             JSObject* unsafeObj =
                 XPCWrapper::Unwrap(cx, obj, /* stopAtOuter = */ false);
             JSObject* cur = unsafeObj ? unsafeObj : obj;
             nsISupports *identity;
             if (mozilla::dom::UnwrapDOMObjectToISupports(cur, identity)) {
-                nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(identity);
-                if (!ci) {
-                    // No classinfo means we're not implementing interfaces and all
-                    return NS_OK;
-                }
-
-                XPCCallContext ccx(JS_CALLER, cx);
-
-                AutoMarkingNativeSetPtr set(ccx);
-                set = XPCNativeSet::GetNewOrUsed(ccx, ci);
-                if (!set)
-                    return NS_ERROR_FAILURE;
-                *bp = set->HasInterfaceWithAncestor(iid);
+                nsCOMPtr<nsISupports> supp;
+                identity->QueryInterface(*iid, getter_AddRefs(supp));
+                *bp = supp;
                 return NS_OK;
             }
         }
 
         XPCWrappedNative* other_wrapper =
            XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
 
         if (!other_wrapper)
--- a/js/xpconnect/src/XPCString.cpp
+++ b/js/xpconnect/src/XPCString.cpp
@@ -21,37 +21,38 @@
 #include "xpcprivate.h"
 #include "nsStringBuffer.h"
 
 // One-slot cache, because it turns out it's common for web pages to
 // get the same string a few times in a row.  We get about a 40% cache
 // hit rate on this cache last it was measured.  We'd get about 70%
 // hit rate with a hashtable with removal on finalization, but that
 // would take a lot more machinery.
-static nsStringBuffer* sCachedBuffer = nullptr;
-static JSString* sCachedString = nullptr;
+nsStringBuffer* XPCStringConvert::sCachedBuffer = nullptr;
+JSString* XPCStringConvert::sCachedString = nullptr;
 
 // Called from GC finalize callback to make sure we don't hand out a pointer to
 // a JSString that's about to be finalized by incremental sweeping.
 // static
 void
 XPCStringConvert::ClearCache()
 {
     sCachedBuffer = nullptr;
     sCachedString = nullptr;
 }
 
-static void
-FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
+void
+XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
 {
     nsStringBuffer* buf = nsStringBuffer::FromData(chars);
     buf->Release();
 }
 
-static const JSStringFinalizer sDOMStringFinalizer = { FinalizeDOMString };
+const JSStringFinalizer XPCStringConvert::sDOMStringFinalizer =
+    { XPCStringConvert::FinalizeDOMString };
 
 // convert a readable to a JSString, copying string data
 // static
 jsval
 XPCStringConvert::ReadableToJSVal(JSContext *cx,
                                   const nsAString &readable,
                                   nsStringBuffer** sharedBuffer)
 {
@@ -60,49 +61,45 @@ XPCStringConvert::ReadableToJSVal(JSCont
 
     uint32_t length = readable.Length();
 
     if (length == 0)
         return JS_GetEmptyStringValue(cx);
 
     nsStringBuffer *buf = nsStringBuffer::FromString(readable);
     if (buf) {
-        if (buf == sCachedBuffer &&
-            js::GetGCThingCompartment(sCachedString) == js::GetContextCompartment(cx)) {
-            // We're done.  Just return our existing string.
-            return JS::StringValue(sCachedString);
+        JS::Value val;
+        bool shared;
+        bool ok = StringBufferToJSVal(cx, buf, length, &val, &shared);
+        if (!ok) {
+            return JS::NullValue();
         }
 
-        // yay, we can share the string's buffer!
-
-        str = JS_NewExternalString(cx,
-                                   reinterpret_cast<jschar *>(buf->Data()),
-                                   length, &sDOMStringFinalizer);
+        if (shared) {
+            *sharedBuffer = buf;
+        }
+        return val;
+    }
 
-        if (str) {
-            *sharedBuffer = buf;
-            sCachedString = str;
-            sCachedBuffer = buf;
-        }
-    } else {
-        // blech, have to copy.
+    // blech, have to copy.
+
+    jschar *chars = reinterpret_cast<jschar *>
+                                    (JS_malloc(cx, (length + 1) *
+                                               sizeof(jschar)));
+    if (!chars)
+        return JS::NullValue();
 
-        jschar *chars = reinterpret_cast<jschar *>
-                                        (JS_malloc(cx, (length + 1) *
-                                                   sizeof(jschar)));
-        if (!chars)
-            return JSVAL_NULL;
+    if (length && !CopyUnicodeTo(readable, 0,
+                                 reinterpret_cast<PRUnichar *>(chars),
+                                 length)) {
+        JS_free(cx, chars);
+        return JS::NullValue();
+    }
 
-        if (length && !CopyUnicodeTo(readable, 0,
-                                     reinterpret_cast<PRUnichar *>(chars),
-                                     length)) {
-            JS_free(cx, chars);
-            return JSVAL_NULL;
-        }
+    chars[length] = 0;
 
-        chars[length] = 0;
+    str = JS_NewUCString(cx, chars, length);
+    if (!str) {
+        JS_free(cx, chars);
+    }
 
-        str = JS_NewUCString(cx, chars, length);
-        if (!str)
-            JS_free(cx, chars);
-    }
     return str ? STRING_TO_JSVAL(str) : JSVAL_NULL;
 }
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -3752,16 +3752,21 @@ static uint32_t sSlimWrappers;
 JSBool
 ConstructSlimWrapper(XPCCallContext &ccx,
                      xpcObjectHelper &aHelper,
                      XPCWrappedNativeScope* xpcScope, jsval *rval)
 {
     nsISupports *identityObj = aHelper.GetCanonical();
     nsXPCClassInfo *classInfoHelper = aHelper.GetXPCClassInfo();
 
+    if (!classInfoHelper) {
+        SLIM_LOG_NOT_CREATED(ccx, identityObj, "No classinfo helper");
+        return false;
+    }
+
     XPCNativeScriptableFlags flags(classInfoHelper->GetScriptableFlags());
 
     NS_ASSERTION(flags.DontAskInstanceForScriptable(),
                  "Not supported for cached wrappers!");
 
     JSObject* parent = xpcScope->GetGlobalJSObject();
     if (!flags.WantPreCreate()) {
         SLIM_LOG_NOT_CREATED(ccx, identityObj,
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -41,51 +41,34 @@ members = [
     'nsIDOMWindow.scrollByLines',
     'nsIDOMWindow.getComputedStyle',
     'nsIDOMWindow.sessionStorage',
     'nsIDOMWindow.localStorage',
     'nsIDOMWindow.onmouseenter',
     'nsIDOMWindow.onmouseleave',
     'nsIDOMWindowPerformance.performance',
     'nsIDOMJSWindow.dump',
-    'nsIDOMScreen.top',
-    'nsIDOMScreen.height',
-    'nsIDOMScreen.width',
-    'nsIDOMScreen.left',
     'nsIDOMClientRect.*',
-    'nsIDOMPaintRequest.*',
     # nsLocationSH has ~ALLOW_PROP_MODS_TO_PROTOTYPE, so don't try.
     #'nsIDOMLocation.hostname',
     #'nsIDOMLocation.href',
 
     # dom/interfaces/canvas
     #
     # canvas friends
     'nsIDOMTextMetrics.*',
     'nsIDOMCanvasGradient.*',
     'nsIDOMCanvasPattern.*',
 
     # dom/interfaces/core
-    'nsIDOMCharacterData.data',
-    'nsIDOMCharacterData.length',
     'nsIDOMNamedNodeMap.item',
     'nsIDOMNamedNodeMap.length',
-    'nsIDOMText.splitText',
     'nsIDOMDOMStringList.*',
     'nsIDOMXULDocument.getBoxObjectFor',
 
-    # dom/interfaces/css
-    'nsIDOMElementCSSInlineStyle.*',
-    'nsIDOMRect.*',
-
-    # dom/interfaces/events
-    'nsIDOMEventTarget.addEventListener',
-    'nsIDOMEventTarget.removeEventListener',
-    'nsIDOMEventTarget.dispatchEvent',
-
     'nsIDOMEvent.type',
     'nsIDOMEvent.target',
     'nsIDOMEvent.currentTarget',
     'nsIDOMEvent.eventPhase',
     'nsIDOMEvent.bubbles',
     'nsIDOMEvent.cancelable',
     'nsIDOMEvent.timeStamp',
     'nsIDOMEvent.stopPropagation',
@@ -241,19 +224,16 @@ members = [
     'nsIDOMXPathResult.snapshotLength',
     'nsIDOMXPathResult.resultType',
     'nsIDOMXPathResult.numberValue',
     'nsIDOMXPathResult.stringValue',
     'nsIDOMXPathResult.booleanValue',
     'nsIDOMXPathResult.singleNodeValue',
     'nsIDOMNSXPathExpression.evaluateWithContext',
 
-    # dom/interfaces/xul
-    'nsIDOMXULElement.*',
-
     # layout/xul/base/public
     'nsIBoxObject.x',
     'nsIBoxObject.y',
     'nsIBoxObject.screenX',
     'nsIBoxObject.screenY',
     'nsIBoxObject.width',
     'nsIBoxObject.height',
 
@@ -311,37 +291,26 @@ irregularFilenames = {
     'nsIDOMTouchList': 'nsIDOMTouchEvent',
 
     'nsITelephoneCallback': 'nsITelephone',
 
     'nsIDOMWindowPerformance': 'nsIDOMWindow',
     }
 
 customIncludes = [
-    'nsINode.h',
-    'nsIContent.h',
-    'nsIDocument.h',
-    'nsCSSPropertiesQS.h',
-    'nsDOMTokenList.h',
-    'nsGenericDOMDataNode.h',
-    'mozilla/dom/Element.h',
-    'nsGenericHTMLElement.h',
-    'nsSVGElement.h',
     'nsDOMQS.h',
-    'nsDOMStringMap.h',
-    'HTMLPropertiesCollection.h',
     'nsHTMLMenuElement.h',
-    'nsICSSDeclaration.h',
     'mozilla/dom/NodeBinding.h',
     'mozilla/dom/ElementBinding.h',
     'mozilla/dom/HTMLElementBinding.h',
     'mozilla/dom/DocumentBinding.h',
     'mozilla/dom/SVGElementBinding.h',
     'nsPerformance.h',
     'mozilla/dom/HTMLDocumentBinding.h',
+    'mozilla/dom/EventTargetBinding.h',
     ]
 
 customReturnInterfaces = [
     'nsIDOMCanvasPattern',
     'nsIDOMCanvasGradient',
     ]
 
 nsIDOMStorage_Clear_customMethodCallCode = """
@@ -349,25 +318,16 @@ nsIDOMStorage_Clear_customMethodCallCode
     if (NS_SUCCEEDED(rv))
         JS_ClearNonGlobalObject(cx, obj);
 """
 
 customMethodCalls = {
     'nsIDOMStorage_Clear': {
         'code': nsIDOMStorage_Clear_customMethodCallCode
         },
-    'nsIDOMElementCSSInlineStyle_GetStyle': {
-        'thisType': 'nsStyledElement',
-        'code': '    /* XXXbz MathML elements inherit from nsStyledElement but\n'
-                '       don\'t actually implement GetStyle. */\n'
-                '    if (self->GetNameSpaceID() == kNameSpaceID_MathML)\n'
-                '      return xpc_qsThrow(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n'
-                '    nsIDOMCSSStyleDeclaration* result = self->Style();',
-        'canFail': False
-        },
     'nsIDOMWindow_GetOnmouseenter' : {
         'thisType' : 'nsIDOMWindow',
         'unwrapThisFailureFatal' : False
         },
     'nsIDOMWindow_SetOnmouseenter' : {
         'thisType' : 'nsIDOMWindow',
         'unwrapThisFailureFatal' : False
         },
@@ -388,9 +348,10 @@ customMethodCalls = {
 
 newBindingProperties = {
     'nsIDOMNode': 'mozilla::dom::NodeBinding::sNativePropertyHooks.mNativeProperties.regular',
     'nsIDOMElement': 'mozilla::dom::ElementBinding::sNativePropertyHooks.mNativeProperties.regular',
     'nsIDOMHTMLElement': 'mozilla::dom::HTMLElementBinding::sNativePropertyHooks.mNativeProperties.regular',
     'nsIDOMDocument': 'mozilla::dom::DocumentBinding::sNativePropertyHooks.mNativeProperties.regular',
     'nsIDOMSVGElement': 'mozilla::dom::SVGElementBinding::sNativePropertyHooks.mNativeProperties.regular',
     'nsIDOMHTMLDocument': 'mozilla::dom::HTMLDocumentBinding::sNativePropertyHooks.mNativeProperties.regular',
+    'nsIDOMEventTarget': 'mozilla::dom::EventTargetBinding::sNativePropertyHooks.mNativeProperties.regular',
     }
deleted file mode 100644
--- a/js/xpconnect/src/nsCSSPropertiesQS.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsCSSPropertiesQS_h__
-#define nsCSSPropertiesQS_h__
-
-#include "nsICSSDeclaration.h"
-
-#define CSS_PROP_DOMPROP_PREFIXED(prop_) Moz ## prop_
-#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
-                 stylestruct_, stylestructoffset_, animtype_)                 \
-static const nsCSSProperty QS_CSS_PROP_##method_ = eCSSProperty_##id_;
-
-#define CSS_PROP_LIST_EXCLUDE_INTERNAL
-#define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_)	\
-  CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X)
-#include "nsCSSPropList.h"
-
-#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
-  CSS_PROP(X, propid_, aliasmethod_, X, pref_, X, X, X, X, X)
-#include "nsCSSPropAliasList.h"
-#undef CSS_PROP_ALIAS
-
-#undef CSS_PROP_SHORTHAND
-#undef CSS_PROP_LIST_EXCLUDE_INTERNAL
-#undef CSS_PROP
-#undef CSS_PROP_DOMPROP_PREFIXED
-
-#endif /* nsCSSPropertiesQS_h__ */
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3418,35 +3418,16 @@ public:
                                        jsval *jsExceptionPtr);
 
 private:
     XPCConvert(); // not implemented
 
 };
 
 /***************************************************************************/
-
-// readable string conversions, static methods only
-class XPCStringConvert
-{
-public:
-
-    // If the string shares the readable's buffer, that buffer will
-    // get assigned to *sharedBuffer.  Otherwise null will be
-    // assigned.
-    static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
-                                 nsStringBuffer** sharedBuffer);
-
-    static void ClearCache();
-
-private:
-    XPCStringConvert();         // not implemented
-};
-
-/***************************************************************************/
 // code for throwing exceptions into JS
 
 class XPCThrower
 {
 public:
     static void Throw(nsresult rv, JSContext* cx);
     static void Throw(nsresult rv, XPCCallContext& ccx);
     static void ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx);
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -19,16 +19,18 @@
 
 #include "nsISupports.h"
 #include "nsIPrincipal.h"
 #include "nsWrapperCache.h"
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 #include "mozilla/dom/DOMJSClass.h"
 #include "nsMathUtils.h"
+#include "nsStringBuffer.h"
+#include "mozilla/dom/BindingDeclarations.h"
 
 class nsIPrincipal;
 class nsIXPConnectWrappedJS;
 class nsScriptNameSpaceManager;
 
 #ifndef BAD_TLS_INDEX
 #define BAD_TLS_INDEX ((uint32_t) -1)
 #endif
@@ -201,16 +203,64 @@ xpc_UnmarkSkippableJSHolders();
 
 // No JS can be on the stack when this is called. Probably only useful from
 // xpcshell.
 NS_EXPORT_(void)
 xpc_ActivateDebugMode();
 
 class nsIMemoryMultiReporterCallback;
 
+// readable string conversions, static methods and members only
+class XPCStringConvert
+{
+public:
+
+    // If the string shares the readable's buffer, that buffer will
+    // get assigned to *sharedBuffer.  Otherwise null will be
+    // assigned.
+    static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
+                                 nsStringBuffer** sharedBuffer);
+
+    // Convert the given stringbuffer/length pair to a jsval
+    static MOZ_ALWAYS_INLINE bool
+    StringBufferToJSVal(JSContext* cx, nsStringBuffer* buf, uint32_t length,
+                        JS::Value* rval, bool* sharedBuffer)
+    {
+        if (buf == sCachedBuffer &&
+            js::GetGCThingCompartment(sCachedString) == js::GetContextCompartment(cx)) {
+            *rval = JS::StringValue(sCachedString);
+            *sharedBuffer = false;
+            return true;
+        }
+
+        JSString *str = JS_NewExternalString(cx,
+                                             static_cast<jschar*>(buf->Data()),
+                                             length, &sDOMStringFinalizer);
+        if (!str) {
+            return false;
+        }
+        *rval = JS::StringValue(str);
+        sCachedString = str;
+        sCachedBuffer = buf;
+        *sharedBuffer = true;
+        return true;
+    }
+
+    static void ClearCache();
+
+private:
+    static nsStringBuffer* sCachedBuffer;
+    static JSString* sCachedString;
+    static const JSStringFinalizer sDOMStringFinalizer;
+
+    static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars);
+
+    XPCStringConvert();         // not implemented
+};
+
 namespace xpc {
 
 bool DeferredRelease(nsISupports *obj);
 
 // If these functions return false, then an exception will be set on cx.
 NS_EXPORT_(bool) Base64Encode(JSContext *cx, JS::Value val, JS::Value *out);
 NS_EXPORT_(bool) Base64Decode(JSContext *cx, JS::Value val, JS::Value *out);
 
@@ -225,16 +275,58 @@ inline bool StringToJsval(JSContext *cx,
     // From the T_DOMSTRING case in XPCConvert::NativeData2JS.
     if (str.IsVoid()) {
         *rval = JSVAL_NULL;
         return true;
     }
     return NonVoidStringToJsval(cx, str, rval);
 }
 
+/**
+ * As above, but for mozilla::dom::DOMString.
+ */
+MOZ_ALWAYS_INLINE
+bool NonVoidStringToJsval(JSContext* cx, mozilla::dom::DOMString& str,
+                          JS::Value *rval)
+{
+    if (!str.HasStringBuffer()) {
+        // It's an actual XPCOM string
+        return NonVoidStringToJsval(cx, str.AsAString(), rval);
+    }
+
+    uint32_t length = str.StringBufferLength();
+    if (length == 0) {
+        *rval = JS_GetEmptyStringValue(cx);
+        return true;
+    }
+
+    nsStringBuffer* buf = str.StringBuffer();
+    bool shared;
+    if (!XPCStringConvert::StringBufferToJSVal(cx, buf, length, rval,
+                                               &shared)) {
+        return false;
+    }
+    if (shared) {
+        // JS now needs to hold a reference to the buffer
+        buf->AddRef();
+    }
+    return true;
+}
+
+MOZ_ALWAYS_INLINE
+bool StringToJsval(JSContext* cx, mozilla::dom::DOMString& str,
+                   JS::Value *rval)
+{
+    if (str.IsNull()) {
+        *rval = JS::NullValue();
+        return true;
+    }
+    return NonVoidStringToJsval(cx, str, rval);
+}
+
 nsIPrincipal *GetCompartmentPrincipal(JSCompartment *compartment);
 
 void DumpJSHeap(FILE* file);
 
 void SetLocationForGlobal(JSObject *global, const nsACString& location);
 void SetLocationForGlobal(JSObject *global, nsIURI *locationURI);
 
 /**
--- a/layout/style/html.css
+++ b/layout/style/html.css
@@ -57,16 +57,17 @@ h5, h5[dir],
 h6, h6[dir],
 header, header[dir],
 hgroup, hgroup[dir],
 hr, hr[dir],
 html, html[dir],
 legend, legend[dir],
 li, li[dir],
 listing, listing[dir],
+main, main[dir],
 marquee, marquee[dir],
 menu, menu[dir],
 nav, nav[dir],
 noframes, noframes[dir],
 ol, ol[dir],
 p, p[dir],
 plaintext, plaintext[dir],
 pre, pre[dir],
@@ -102,16 +103,17 @@ aside,
 div,
 dt,
 figcaption,
 footer,
 form,
 header,
 hgroup,
 html,
+main,
 nav,
 section {
   display: block;
 }
 
 body {
   display: block;
   margin: 8px;
--- a/media/libsoundtouch/update.sh
+++ b/media/libsoundtouch/update.sh
@@ -23,17 +23,17 @@ cp $1/source/SoundTouch/sse_optimized.cp
 cp $1/source/SoundTouch/TDStretch.cpp src
 cp $1/source/SoundTouch/TDStretch.h src
 cp $1/include/SoundTouch.h src
 cp $1/include/FIFOSampleBuffer.h src
 cp $1/include/FIFOSamplePipe.h src
 cp $1/include/SoundTouch.h src
 cp $1/include/STTypes.h src
 
-# Remote the Windows line ending characters from the files.
+# Remove the Windows line ending characters from the files.
 for i in src/*
 do
   cat $i | tr -d '\015' > $i.lf
   mv $i.lf $i
 done
 
 # Patch the imported files.
 patch -p1 < moz-libsoundtouch.patch
--- a/media/mtransport/transportlayer.h
+++ b/media/mtransport/transportlayer.h
@@ -6,16 +6,17 @@
 
 // Original author: ekr@rtfm.com
 
 #ifndef transportlayer_h__
 #define transportlayer_h__
 
 #include "sigslot.h"
 
+#include "mozilla/DebugOnly.h"
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIEventTarget.h"
 #include "nsThreadUtils.h"
 
 #include "m_cpp_utils.h"
 
 namespace mozilla {
@@ -60,17 +61,17 @@ class TransportLayer : public sigslot::h
   TransportLayer *downward() { return downward_; }
 
   // Dispatch a call onto our thread (or run on the same thread if
   // thread is not set). This is always synchronous.
   nsresult RunOnThread(nsIRunnable *event) {
     if (target_) {
       nsIThread *thr;
 
-      nsresult rv = NS_GetCurrentThread(&thr);
+      DebugOnly<nsresult> rv = NS_GetCurrentThread(&thr);
       MOZ_ASSERT(NS_SUCCEEDED(rv));
 
       if (target_ != thr) {
         return target_->Dispatch(event, NS_DISPATCH_SYNC);
       }
     }
 
     return event->Run();
--- a/media/mtransport/transportlayerdtls.h
+++ b/media/mtransport/transportlayerdtls.h
@@ -54,17 +54,17 @@ class TransportLayerDtls : public Transp
       ssl_fd_(nullptr),
       auth_hook_called_(false),
       cert_ok_(false) {}
 
   virtual ~TransportLayerDtls();
 
   enum Role { CLIENT, SERVER};
   enum Verification { VERIFY_UNSET, VERIFY_ALLOW_ALL, VERIFY_DIGEST};
-  const static int kMaxDigestLength = HASH_LENGTH_MAX;
+  const static size_t kMaxDigestLength = HASH_LENGTH_MAX;
 
   // DTLS-specific operations
   void SetRole(Role role) { role_ = role;}
   Role role() { return role_; }
 
   void SetIdentity(const RefPtr<DtlsIdentity>& identity) {
     identity_ = identity;
   }
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -346,16 +346,18 @@ PeerConnectionImpl::ConvertRTCConfigurat
   }
   JSObject& servers = jsServers.toObject();
   uint32_t len;
   if (!(IsArrayLike(aCx, &servers) && JS_GetArrayLength(aCx, &servers, &len))) {
     return NS_ERROR_FAILURE;
   }
   for (uint32_t i = 0; i < len; i++) {
     nsresult rv;
+    // XXXbz once this moves to WebIDL, remove the RTCIceServer hack
+    // in DummyBinding.webidl.
     RTCIceServer server;
     {
       JS::Value v;
       if (!(JS_GetElement(aCx, &servers, i, &v) && server.Init(aCx, nullptr, v))) {
         return NS_ERROR_FAILURE;
       }
     }
     if (!server.mUrl.WasPassed()) {
--- a/mobile/android/base/MemoryMonitor.java
+++ b/mobile/android/base/MemoryMonitor.java
@@ -148,17 +148,25 @@ class MemoryMonitor extends BroadcastRec
             return;
         }
 
         // TODO hook in memory-reduction stuff for different levels here
         if (level >= MEMORY_PRESSURE_MEDIUM) {
             if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
                 GeckoAppShell.onLowMemory();
             }
-            GeckoAppShell.geckoEventSync();
+
+            if (level >= MEMORY_PRESSURE_HIGH) {
+                // We need to wait on Gecko here, because this is normally called
+                // from Activity.onLowMemory. If we haven't reduced memory usage
+                // enough when we return from that, Android will kill us.
+                // Activity.onTrimMemory is more of a suggestion.
+                GeckoAppShell.geckoEventSync();
+            }
+
             Favicons.getInstance().clearMemCache();
         }
     }
 
     private boolean decreaseMemoryPressure() {
         int newLevel;
         synchronized (this) {
             if (mMemoryPressure <= 0) {
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -337,16 +337,19 @@ pref("accessibility.typeaheadfind.prefil
 pref("gfx.use_text_smoothing_setting", false);
 
 // loading and rendering of framesets and iframes
 pref("browser.frames.enabled", true);
 
 // Number of characters to consider emphasizing for rich autocomplete results
 pref("toolkit.autocomplete.richBoundaryCutoff", 200);
 
+// Variable controlling logging for osfile.
+pref("toolkit.osfile.log", false);
+
 pref("toolkit.scrollbox.smoothScroll", true);
 pref("toolkit.scrollbox.scrollIncrement", 20);
 pref("toolkit.scrollbox.verticalScrollDistance", 3);
 pref("toolkit.scrollbox.horizontalScrollDistance", 5);
 pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150);
 
 // Telemetry
 #ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -263,16 +263,21 @@ NeckoParent::DeallocPWebSocket(PWebSocke
 
 PTCPSocketParent*
 NeckoParent::AllocPTCPSocket(const nsString& aHost,
                              const uint16_t& aPort,
                              const bool& useSSL,
                              const nsString& aBinaryType,
                              PBrowserParent* aBrowser)
 {
+  if (UsingNeckoIPCSecurity() && !aBrowser) {
+    printf_stderr("NeckoParent::AllocPTCPSocket: FATAL error: no browser present \
+                   KILLING CHILD PROCESS\n");
+    return nullptr;
+  }
   TCPSocketParent* p = new TCPSocketParent();
   p->AddRef();
   return p;
 }
 
 bool
 NeckoParent::RecvPTCPSocketConstructor(PTCPSocketParent* aActor,
                                        const nsString& aHost,
--- a/parser/html/javasrc/ElementName.java
+++ b/parser/html/javasrc/ElementName.java
@@ -343,17 +343,17 @@ public final class ElementName
 //            case TreeBuilder.EMBED_OR_IMG:
 //                return "EMBED_OR_IMG";
 //            case TreeBuilder.AREA_OR_WBR:
 //                return "AREA_OR_WBR";
 //            case TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
 //                return "DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU";
 //            case TreeBuilder.FIELDSET:
 //                return "FIELDSET";
-//            case TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY:
+//            case TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY:
 //                return "ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY";
 //            case TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
 //                return "RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR";
 //            case TreeBuilder.RT_OR_RP:
 //                return "RT_OR_RP";
 //            case TreeBuilder.COMMAND:
 //                return "COMMAND";
 //            case TreeBuilder.PARAM_OR_SOURCE_OR_TRACK:
@@ -456,17 +456,17 @@ public final class ElementName
     public static final ElementName BIG = new ElementName("big", "big", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
     public static final ElementName BDO = new ElementName("bdo", "bdo", TreeBuilder.OTHER);
     public static final ElementName CSC = new ElementName("csc", "csc", TreeBuilder.OTHER);
     public static final ElementName COL = new ElementName("col", "col", TreeBuilder.COL | SPECIAL);
     public static final ElementName COS = new ElementName("cos", "cos", TreeBuilder.OTHER);
     public static final ElementName COT = new ElementName("cot", "cot", TreeBuilder.OTHER);
     public static final ElementName DEL = new ElementName("del", "del", TreeBuilder.OTHER);
     public static final ElementName DFN = new ElementName("dfn", "dfn", TreeBuilder.OTHER);
-    public static final ElementName DIR = new ElementName("dir", "dir", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName DIR = new ElementName("dir", "dir", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName DIV = new ElementName("div", "div", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
     public static final ElementName EXP = new ElementName("exp", "exp", TreeBuilder.OTHER);
     public static final ElementName GCD = new ElementName("gcd", "gcd", TreeBuilder.OTHER);
     public static final ElementName GEQ = new ElementName("geq", "geq", TreeBuilder.OTHER);
     public static final ElementName IMG = new ElementName("img", "img", TreeBuilder.EMBED_OR_IMG | SPECIAL);
     public static final ElementName INS = new ElementName("ins", "ins", TreeBuilder.OTHER);
     public static final ElementName INT = new ElementName("int", "int", TreeBuilder.OTHER);
     public static final ElementName KBD = new ElementName("kbd", "kbd", TreeBuilder.OTHER);
@@ -475,17 +475,17 @@ public final class ElementName
     public static final ElementName LEQ = new ElementName("leq", "leq", TreeBuilder.OTHER);
     public static final ElementName MTD = new ElementName("mtd", "mtd", TreeBuilder.OTHER);
     public static final ElementName MIN = new ElementName("min", "min", TreeBuilder.OTHER);
     public static final ElementName MAP = new ElementName("map", "map", TreeBuilder.OTHER);
     public static final ElementName MTR = new ElementName("mtr", "mtr", TreeBuilder.OTHER);
     public static final ElementName MAX = new ElementName("max", "max", TreeBuilder.OTHER);
     public static final ElementName NEQ = new ElementName("neq", "neq", TreeBuilder.OTHER);
     public static final ElementName NOT = new ElementName("not", "not", TreeBuilder.OTHER);
-    public static final ElementName NAV = new ElementName("nav", "nav", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName NAV = new ElementName("nav", "nav", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName PRE = new ElementName("pre", "pre", TreeBuilder.PRE_OR_LISTING | SPECIAL);
     public static final ElementName REM = new ElementName("rem", "rem", TreeBuilder.OTHER);
     public static final ElementName SUB = new ElementName("sub", "sub", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
     public static final ElementName SEC = new ElementName("sec", "sec", TreeBuilder.OTHER);
     public static final ElementName SVG = new ElementName("svg", "svg", TreeBuilder.SVG);
     public static final ElementName SUM = new ElementName("sum", "sum", TreeBuilder.OTHER);
     public static final ElementName SIN = new ElementName("sin", "sin", TreeBuilder.OTHER);
     public static final ElementName SEP = new ElementName("sep", "sep", TreeBuilder.OTHER);
@@ -522,16 +522,17 @@ public final class ElementName
     public static final ElementName LIST = new ElementName("list", "list", TreeBuilder.OTHER);
     public static final ElementName META = new ElementName("meta", "meta", TreeBuilder.META | SPECIAL);
     public static final ElementName MSUB = new ElementName("msub", "msub", TreeBuilder.OTHER);
     public static final ElementName MODE = new ElementName("mode", "mode", TreeBuilder.OTHER);
     public static final ElementName MATH = new ElementName("math", "math", TreeBuilder.MATH);
     public static final ElementName MARK = new ElementName("mark", "mark", TreeBuilder.OTHER);
     public static final ElementName MASK = new ElementName("mask", "mask", TreeBuilder.OTHER);
     public static final ElementName MEAN = new ElementName("mean", "mean", TreeBuilder.OTHER);
+    public static final ElementName MAIN = new ElementName("main", "main", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName MSUP = new ElementName("msup", "msup", TreeBuilder.OTHER);
     public static final ElementName MENU = new ElementName("menu", "menu", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
     public static final ElementName MROW = new ElementName("mrow", "mrow", TreeBuilder.OTHER);
     public static final ElementName NONE = new ElementName("none", "none", TreeBuilder.OTHER);
     public static final ElementName NOBR = new ElementName("nobr", "nobr", TreeBuilder.NOBR);
     public static final ElementName NEST = new ElementName("nest", "nest", TreeBuilder.OTHER);
     public static final ElementName PATH = new ElementName("path", "path", TreeBuilder.OTHER);
     public static final ElementName PLUS = new ElementName("plus", "plus", TreeBuilder.OTHER);
@@ -548,17 +549,17 @@ public final class ElementName
     public static final ElementName STOP = new ElementName("stop", "stop", TreeBuilder.OTHER);
     public static final ElementName SDEV = new ElementName("sdev", "sdev", TreeBuilder.OTHER);
     public static final ElementName TIME = new ElementName("time", "time", TreeBuilder.OTHER);
     public static final ElementName TRUE = new ElementName("true", "true", TreeBuilder.OTHER);
     public static final ElementName TREF = new ElementName("tref", "tref", TreeBuilder.OTHER);
     public static final ElementName TANH = new ElementName("tanh", "tanh", TreeBuilder.OTHER);
     public static final ElementName TEXT = new ElementName("text", "text", TreeBuilder.OTHER);
     public static final ElementName VIEW = new ElementName("view", "view", TreeBuilder.OTHER);
-    public static final ElementName ASIDE = new ElementName("aside", "aside", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName ASIDE = new ElementName("aside", "aside", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName AUDIO = new ElementName("audio", "audio", TreeBuilder.OTHER);
     public static final ElementName APPLY = new ElementName("apply", "apply", TreeBuilder.OTHER);
     public static final ElementName EMBED = new ElementName("embed", "embed", TreeBuilder.EMBED_OR_IMG | SPECIAL);
     public static final ElementName FRAME = new ElementName("frame", "frame", TreeBuilder.FRAME | SPECIAL);
     public static final ElementName FALSE = new ElementName("false", "false", TreeBuilder.OTHER);
     public static final ElementName FLOOR = new ElementName("floor", "floor", TreeBuilder.OTHER);
     public static final ElementName GLYPH = new ElementName("glyph", "glyph", TreeBuilder.OTHER);
     public static final ElementName HKERN = new ElementName("hkern", "hkern", TreeBuilder.OTHER);
@@ -606,22 +607,22 @@ public final class ElementName
     public static final ElementName CENTER = new ElementName("center", "center", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
     public static final ElementName CURSOR = new ElementName("cursor", "cursor", TreeBuilder.OTHER);
     public static final ElementName CANVAS = new ElementName("canvas", "canvas", TreeBuilder.OTHER);
     public static final ElementName DIVIDE = new ElementName("divide", "divide", TreeBuilder.OTHER);
     public static final ElementName DEGREE = new ElementName("degree", "degree", TreeBuilder.OTHER);
     public static final ElementName DOMAIN = new ElementName("domain", "domain", TreeBuilder.OTHER);
     public static final ElementName EXISTS = new ElementName("exists", "exists", TreeBuilder.OTHER);
     public static final ElementName FETILE = new ElementName("fetile", "feTile", TreeBuilder.OTHER);
-    public static final ElementName FIGURE = new ElementName("figure", "figure", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName FIGURE = new ElementName("figure", "figure", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName FORALL = new ElementName("forall", "forall", TreeBuilder.OTHER);
     public static final ElementName FILTER = new ElementName("filter", "filter", TreeBuilder.OTHER);
-    public static final ElementName FOOTER = new ElementName("footer", "footer", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName HGROUP = new ElementName("hgroup", "hgroup", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName HEADER = new ElementName("header", "header", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName FOOTER = new ElementName("footer", "footer", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName HGROUP = new ElementName("hgroup", "hgroup", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName HEADER = new ElementName("header", "header", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName IFRAME = new ElementName("iframe", "iframe", TreeBuilder.IFRAME | SPECIAL);
     public static final ElementName KEYGEN = new ElementName("keygen", "keygen", TreeBuilder.KEYGEN);
     public static final ElementName LAMBDA = new ElementName("lambda", "lambda", TreeBuilder.OTHER);
     public static final ElementName LEGEND = new ElementName("legend", "legend", TreeBuilder.OTHER);
     public static final ElementName MSPACE = new ElementName("mspace", "mspace", TreeBuilder.OTHER);
     public static final ElementName MTABLE = new ElementName("mtable", "mtable", TreeBuilder.OTHER);
     public static final ElementName MSTYLE = new ElementName("mstyle", "mstyle", TreeBuilder.OTHER);
     public static final ElementName MGLYPH = new ElementName("mglyph", "mglyph", TreeBuilder.MGLYPH_OR_MALIGNMARK);
@@ -640,35 +641,35 @@ public final class ElementName
     public static final ElementName STRONG = new ElementName("strong", "strong", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
     public static final ElementName SWITCH = new ElementName("switch", "switch", TreeBuilder.OTHER);
     public static final ElementName SYMBOL = new ElementName("symbol", "symbol", TreeBuilder.OTHER);
     public static final ElementName SELECT = new ElementName("select", "select", TreeBuilder.SELECT | SPECIAL);
     public static final ElementName SUBSET = new ElementName("subset", "subset", TreeBuilder.OTHER);
     public static final ElementName SCRIPT = new ElementName("script", "script", TreeBuilder.SCRIPT | SPECIAL);
     public static final ElementName TBREAK = new ElementName("tbreak", "tbreak", TreeBuilder.OTHER);
     public static final ElementName VECTOR = new ElementName("vector", "vector", TreeBuilder.OTHER);
-    public static final ElementName ARTICLE = new ElementName("article", "article", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName ARTICLE = new ElementName("article", "article", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName ANIMATE = new ElementName("animate", "animate", TreeBuilder.OTHER);
     public static final ElementName ARCSECH = new ElementName("arcsech", "arcsech", TreeBuilder.OTHER);
     public static final ElementName ARCCSCH = new ElementName("arccsch", "arccsch", TreeBuilder.OTHER);
     public static final ElementName ARCTANH = new ElementName("arctanh", "arctanh", TreeBuilder.OTHER);
     public static final ElementName ARCSINH = new ElementName("arcsinh", "arcsinh", TreeBuilder.OTHER);
     public static final ElementName ARCCOSH = new ElementName("arccosh", "arccosh", TreeBuilder.OTHER);
     public static final ElementName ARCCOTH = new ElementName("arccoth", "arccoth", TreeBuilder.OTHER);
     public static final ElementName ACRONYM = new ElementName("acronym", "acronym", TreeBuilder.OTHER);
-    public static final ElementName ADDRESS = new ElementName("address", "address", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName ADDRESS = new ElementName("address", "address", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName BGSOUND = new ElementName("bgsound", "bgsound", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
     public static final ElementName COMMAND = new ElementName("command", "command", TreeBuilder.COMMAND | SPECIAL);
     public static final ElementName COMPOSE = new ElementName("compose", "compose", TreeBuilder.OTHER);
     public static final ElementName CEILING = new ElementName("ceiling", "ceiling", TreeBuilder.OTHER);
     public static final ElementName CSYMBOL = new ElementName("csymbol", "csymbol", TreeBuilder.OTHER);
     public static final ElementName CAPTION = new ElementName("caption", "caption", TreeBuilder.CAPTION | SPECIAL | SCOPING);
     public static final ElementName DISCARD = new ElementName("discard", "discard", TreeBuilder.OTHER);
     public static final ElementName DECLARE = new ElementName("declare", "declare", TreeBuilder.OTHER);
-    public static final ElementName DETAILS = new ElementName("details", "details", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName DETAILS = new ElementName("details", "details", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName ELLIPSE = new ElementName("ellipse", "ellipse", TreeBuilder.OTHER);
     public static final ElementName FEFUNCA = new ElementName("fefunca", "feFuncA", TreeBuilder.OTHER);
     public static final ElementName FEFUNCB = new ElementName("fefuncb", "feFuncB", TreeBuilder.OTHER);
     public static final ElementName FEBLEND = new ElementName("feblend", "feBlend", TreeBuilder.OTHER);
     public static final ElementName FEFLOOD = new ElementName("feflood", "feFlood", TreeBuilder.OTHER);
     public static final ElementName FEIMAGE = new ElementName("feimage", "feImage", TreeBuilder.OTHER);
     public static final ElementName FEMERGE = new ElementName("femerge", "feMerge", TreeBuilder.OTHER);
     public static final ElementName FEFUNCG = new ElementName("fefuncg", "feFuncG", TreeBuilder.OTHER);
@@ -684,18 +685,18 @@ public final class ElementName
     public static final ElementName MARQUEE = new ElementName("marquee", "marquee", TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
     public static final ElementName MACTION = new ElementName("maction", "maction", TreeBuilder.OTHER);
     public static final ElementName MSUBSUP = new ElementName("msubsup", "msubsup", TreeBuilder.OTHER);
     public static final ElementName NOEMBED = new ElementName("noembed", "noembed", TreeBuilder.NOEMBED | SPECIAL);
     public static final ElementName POLYGON = new ElementName("polygon", "polygon", TreeBuilder.OTHER);
     public static final ElementName PATTERN = new ElementName("pattern", "pattern", TreeBuilder.OTHER);
     public static final ElementName PRODUCT = new ElementName("product", "product", TreeBuilder.OTHER);
     public static final ElementName SETDIFF = new ElementName("setdiff", "setdiff", TreeBuilder.OTHER);
-    public static final ElementName SECTION = new ElementName("section", "section", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName SUMMARY = new ElementName("summary", "summary", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName SECTION = new ElementName("section", "section", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName SUMMARY = new ElementName("summary", "summary", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName TENDSTO = new ElementName("tendsto", "tendsto", TreeBuilder.OTHER);
     public static final ElementName UPLIMIT = new ElementName("uplimit", "uplimit", TreeBuilder.OTHER);
     public static final ElementName ALTGLYPH = new ElementName("altglyph", "altGlyph", TreeBuilder.OTHER);
     public static final ElementName BASEFONT = new ElementName("basefont", "basefont", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
     public static final ElementName CLIPPATH = new ElementName("clippath", "clipPath", TreeBuilder.OTHER);
     public static final ElementName CODOMAIN = new ElementName("codomain", "codomain", TreeBuilder.OTHER);
     public static final ElementName COLGROUP = new ElementName("colgroup", "colgroup", TreeBuilder.COLGROUP | SPECIAL | OPTIONAL_END_TAG);
     public static final ElementName EMPTYSET = new ElementName("emptyset", "emptyset", TreeBuilder.OTHER);
@@ -742,17 +743,17 @@ public final class ElementName
     public static final ElementName RATIONALS = new ElementName("rationals", "rationals", TreeBuilder.OTHER);
     public static final ElementName SEMANTICS = new ElementName("semantics", "semantics", TreeBuilder.OTHER);
     public static final ElementName TRANSPOSE = new ElementName("transpose", "transpose", TreeBuilder.OTHER);
     public static final ElementName ANNOTATION = new ElementName("annotation", "annotation", TreeBuilder.OTHER);
     public static final ElementName BLOCKQUOTE = new ElementName("blockquote", "blockquote", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
     public static final ElementName DIVERGENCE = new ElementName("divergence", "divergence", TreeBuilder.OTHER);
     public static final ElementName EULERGAMMA = new ElementName("eulergamma", "eulergamma", TreeBuilder.OTHER);
     public static final ElementName EQUIVALENT = new ElementName("equivalent", "equivalent", TreeBuilder.OTHER);
-    public static final ElementName FIGCAPTION = new ElementName("figcaption", "figcaption", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+    public static final ElementName FIGCAPTION = new ElementName("figcaption", "figcaption", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
     public static final ElementName IMAGINARYI = new ElementName("imaginaryi", "imaginaryi", TreeBuilder.OTHER);
     public static final ElementName MALIGNMARK = new ElementName("malignmark", "malignmark", TreeBuilder.MGLYPH_OR_MALIGNMARK);
     public static final ElementName MUNDEROVER = new ElementName("munderover", "munderover", TreeBuilder.OTHER);
     public static final ElementName MLABELEDTR = new ElementName("mlabeledtr", "mlabeledtr", TreeBuilder.OTHER);
     public static final ElementName NOTANUMBER = new ElementName("notanumber", "notanumber", TreeBuilder.OTHER);
     public static final ElementName SOLIDCOLOR = new ElementName("solidcolor", "solidcolor", TreeBuilder.OTHER);
     public static final ElementName ALTGLYPHDEF = new ElementName("altglyphdef", "altGlyphDef", TreeBuilder.OTHER);
     public static final ElementName DETERMINANT = new ElementName("determinant", "determinant", TreeBuilder.OTHER);
@@ -915,16 +916,17 @@ public final class ElementName
     LIST,
     META,
     MSUB,
     MODE,
     MATH,
     MARK,
     MASK,
     MEAN,
+    MAIN,
     MSUP,
     MENU,
     MROW,
     NONE,
     NOBR,
     NEST,
     PATH,
     PLUS,
@@ -1309,16 +1311,17 @@ public final class ElementName
     147475756,
     147902637,
     147936877,
     148017645,
     148131885,
     148228141,
     148229165,
     148309165,
+    148317229,
     148395629,
     148551853,
     148618829,
     149076462,
     149490158,
     149572782,
     151277616,
     151639440,
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -164,17 +164,17 @@ public abstract class TreeBuilder<T> imp
     final static int IFRAME = 47;
 
     final static int EMBED_OR_IMG = 48;
 
     final static int AREA_OR_WBR = 49;
 
     final static int DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU = 50;
 
-    final static int ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY = 51;
+    final static int ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY = 51;
 
     final static int RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR = 52;
 
     final static int RT_OR_RP = 53;
 
     final static int COMMAND = 54;
 
     final static int PARAM_OR_SOURCE_OR_TRACK = 55;
@@ -1923,17 +1923,17 @@ public abstract class TreeBuilder<T> imp
                                 }
                                 if (addAttributesToBody(attributes)) {
                                     attributes = null; // CPP
                                 }
                                 break starttagloop;
                             case P:
                             case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
                             case UL_OR_OL_OR_DL:
-                            case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY:
+                            case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY:
                                 implicitlyCloseP();
                                 appendToCurrentNodeAndPushElementMayFoster(
                                         elementName,
                                         attributes);
                                 attributes = null; // CPP
                                 break starttagloop;
                             case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
                                 implicitlyCloseP();
@@ -3418,17 +3418,17 @@ public abstract class TreeBuilder<T> imp
                             }
                             mode = AFTER_BODY;
                             continue;
                         case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
                         case UL_OR_OL_OR_DL:
                         case PRE_OR_LISTING:
                         case FIELDSET:
                         case BUTTON:
-                        case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY:
+                        case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY:
                             eltPos = findLastInScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 errStrayEndTag(name);
                             } else {
                                 generateImpliedEndTags();
                                 if (errorHandler != null && !isCurrent(name)) {
                                     errUnclosedElements(eltPos, name);
                                 }
--- a/parser/html/nsHtml5AtomList.h
+++ b/parser/html/nsHtml5AtomList.h
@@ -793,16 +793,17 @@ HTML5_ATOM(defs, "defs")
 HTML5_ATOM(font, "font")
 HTML5_ATOM(grad, "grad")
 HTML5_ATOM(line, "line")
 HTML5_ATOM(meta, "meta")
 HTML5_ATOM(msub, "msub")
 HTML5_ATOM(math, "math")
 HTML5_ATOM(mark, "mark")
 HTML5_ATOM(mean, "mean")
+HTML5_ATOM(main, "main")
 HTML5_ATOM(msup, "msup")
 HTML5_ATOM(menu, "menu")
 HTML5_ATOM(mrow, "mrow")
 HTML5_ATOM(none, "none")
 HTML5_ATOM(nest, "nest")
 HTML5_ATOM(plus, "plus")
 HTML5_ATOM(rule, "rule")
 HTML5_ATOM(real, "real")
--- a/parser/html/nsHtml5ElementName.cpp
+++ b/parser/html/nsHtml5ElementName.cpp
@@ -249,16 +249,17 @@ nsHtml5ElementName* nsHtml5ElementName::
 nsHtml5ElementName* nsHtml5ElementName::ELT_LIST = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_META = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MSUB = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MODE = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MATH = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MARK = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MASK = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MEAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MAIN = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MSUP = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MENU = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_MROW = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_NONE = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_NOBR = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_NEST = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_PATH = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_PLUS = nullptr;
@@ -522,17 +523,17 @@ nsHtml5ElementName* nsHtml5ElementName::
 nsHtml5ElementName* nsHtml5ElementName::ELT_FONT_FACE_FORMAT = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_FECONVOLVEMATRIX = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_FEDIFFUSELIGHTING = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_FEDISPLACEMENTMAP = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_FESPECULARLIGHTING = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_DOMAINOFAPPLICATION = nullptr;
 nsHtml5ElementName* nsHtml5ElementName::ELT_FECOMPONENTTRANSFER = nullptr;
 nsHtml5ElementName** nsHtml5ElementName::ELEMENT_NAMES = 0;
-static int32_t const ELEMENT_HASHES_DATA[] = { 1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189107250, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210261490, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238172205, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 252317348, 255007012, 255278388, 255641645, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282498697, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 342310196, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819 };
+static int32_t const ELEMENT_HASHES_DATA[] = { 1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148317229, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189107250, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210261490, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238172205, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 252317348, 255007012, 255278388, 255641645, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282498697, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 342310196, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819 };
 staticJArray<int32_t,int32_t> nsHtml5ElementName::ELEMENT_HASHES = { ELEMENT_HASHES_DATA, NS_ARRAY_LENGTH(ELEMENT_HASHES_DATA) };
 void
 nsHtml5ElementName::initializeStatics()
 {
   ELT_NULL_ELEMENT_NAME = new nsHtml5ElementName(nullptr);
   ELT_A = new nsHtml5ElementName(nsHtml5Atoms::a, nsHtml5Atoms::a, NS_HTML5TREE_BUILDER_A);
   ELT_B = new nsHtml5ElementName(nsHtml5Atoms::b, nsHtml5Atoms::b, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
   ELT_G = new nsHtml5ElementName(nsHtml5Atoms::g, nsHtml5Atoms::g, NS_HTML5TREE_BUILDER_OTHER);
@@ -582,17 +583,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_BIG = new nsHtml5ElementName(nsHtml5Atoms::big, nsHtml5Atoms::big, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
   ELT_BDO = new nsHtml5ElementName(nsHtml5Atoms::bdo, nsHtml5Atoms::bdo, NS_HTML5TREE_BUILDER_OTHER);
   ELT_CSC = new nsHtml5ElementName(nsHtml5Atoms::csc, nsHtml5Atoms::csc, NS_HTML5TREE_BUILDER_OTHER);
   ELT_COL = new nsHtml5ElementName(nsHtml5Atoms::col, nsHtml5Atoms::col, NS_HTML5TREE_BUILDER_COL | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_COS = new nsHtml5ElementName(nsHtml5Atoms::cos, nsHtml5Atoms::cos, NS_HTML5TREE_BUILDER_OTHER);
   ELT_COT = new nsHtml5ElementName(nsHtml5Atoms::cot, nsHtml5Atoms::cot, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DEL = new nsHtml5ElementName(nsHtml5Atoms::del, nsHtml5Atoms::del, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DFN = new nsHtml5ElementName(nsHtml5Atoms::dfn, nsHtml5Atoms::dfn, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_DIR = new nsHtml5ElementName(nsHtml5Atoms::dir, nsHtml5Atoms::dir, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_DIR = new nsHtml5ElementName(nsHtml5Atoms::dir, nsHtml5Atoms::dir, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_DIV = new nsHtml5ElementName(nsHtml5Atoms::div, nsHtml5Atoms::div, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_EXP = new nsHtml5ElementName(nsHtml5Atoms::exp, nsHtml5Atoms::exp, NS_HTML5TREE_BUILDER_OTHER);
   ELT_GCD = new nsHtml5ElementName(nsHtml5Atoms::gcd, nsHtml5Atoms::gcd, NS_HTML5TREE_BUILDER_OTHER);
   ELT_GEQ = new nsHtml5ElementName(nsHtml5Atoms::geq, nsHtml5Atoms::geq, NS_HTML5TREE_BUILDER_OTHER);
   ELT_IMG = new nsHtml5ElementName(nsHtml5Atoms::img, nsHtml5Atoms::img, NS_HTML5TREE_BUILDER_EMBED_OR_IMG | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_INS = new nsHtml5ElementName(nsHtml5Atoms::ins, nsHtml5Atoms::ins, NS_HTML5TREE_BUILDER_OTHER);
   ELT_INT = new nsHtml5ElementName(nsHtml5Atoms::int_, nsHtml5Atoms::int_, NS_HTML5TREE_BUILDER_OTHER);
   ELT_KBD = new nsHtml5ElementName(nsHtml5Atoms::kbd, nsHtml5Atoms::kbd, NS_HTML5TREE_BUILDER_OTHER);
@@ -601,17 +602,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_LEQ = new nsHtml5ElementName(nsHtml5Atoms::leq, nsHtml5Atoms::leq, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MTD = new nsHtml5ElementName(nsHtml5Atoms::mtd, nsHtml5Atoms::mtd, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MIN = new nsHtml5ElementName(nsHtml5Atoms::min, nsHtml5Atoms::min, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MAP = new nsHtml5ElementName(nsHtml5Atoms::map, nsHtml5Atoms::map, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MTR = new nsHtml5ElementName(nsHtml5Atoms::mtr, nsHtml5Atoms::mtr, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MAX = new nsHtml5ElementName(nsHtml5Atoms::max, nsHtml5Atoms::max, NS_HTML5TREE_BUILDER_OTHER);
   ELT_NEQ = new nsHtml5ElementName(nsHtml5Atoms::neq, nsHtml5Atoms::neq, NS_HTML5TREE_BUILDER_OTHER);
   ELT_NOT = new nsHtml5ElementName(nsHtml5Atoms::not_, nsHtml5Atoms::not_, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_NAV = new nsHtml5ElementName(nsHtml5Atoms::nav, nsHtml5Atoms::nav, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_NAV = new nsHtml5ElementName(nsHtml5Atoms::nav, nsHtml5Atoms::nav, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_PRE = new nsHtml5ElementName(nsHtml5Atoms::pre, nsHtml5Atoms::pre, NS_HTML5TREE_BUILDER_PRE_OR_LISTING | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_REM = new nsHtml5ElementName(nsHtml5Atoms::rem, nsHtml5Atoms::rem, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SUB = new nsHtml5ElementName(nsHtml5Atoms::sub, nsHtml5Atoms::sub, NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
   ELT_SEC = new nsHtml5ElementName(nsHtml5Atoms::sec, nsHtml5Atoms::sec, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SVG = new nsHtml5ElementName(nsHtml5Atoms::svg, nsHtml5Atoms::svg, NS_HTML5TREE_BUILDER_SVG);
   ELT_SUM = new nsHtml5ElementName(nsHtml5Atoms::sum, nsHtml5Atoms::sum, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SIN = new nsHtml5ElementName(nsHtml5Atoms::sin, nsHtml5Atoms::sin, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SEP = new nsHtml5ElementName(nsHtml5Atoms::sep, nsHtml5Atoms::sep, NS_HTML5TREE_BUILDER_OTHER);
@@ -648,16 +649,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_LIST = new nsHtml5ElementName(nsHtml5Atoms::list, nsHtml5Atoms::list, NS_HTML5TREE_BUILDER_OTHER);
   ELT_META = new nsHtml5ElementName(nsHtml5Atoms::meta, nsHtml5Atoms::meta, NS_HTML5TREE_BUILDER_META | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_MSUB = new nsHtml5ElementName(nsHtml5Atoms::msub, nsHtml5Atoms::msub, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MODE = new nsHtml5ElementName(nsHtml5Atoms::mode, nsHtml5Atoms::mode, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MATH = new nsHtml5ElementName(nsHtml5Atoms::math, nsHtml5Atoms::math, NS_HTML5TREE_BUILDER_MATH);
   ELT_MARK = new nsHtml5ElementName(nsHtml5Atoms::mark, nsHtml5Atoms::mark, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MASK = new nsHtml5ElementName(nsHtml5Atoms::mask, nsHtml5Atoms::mask, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MEAN = new nsHtml5ElementName(nsHtml5Atoms::mean, nsHtml5Atoms::mean, NS_HTML5TREE_BUILDER_OTHER);
+  ELT_MAIN = new nsHtml5ElementName(nsHtml5Atoms::main, nsHtml5Atoms::main, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_MSUP = new nsHtml5ElementName(nsHtml5Atoms::msup, nsHtml5Atoms::msup, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MENU = new nsHtml5ElementName(nsHtml5Atoms::menu, nsHtml5Atoms::menu, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_MROW = new nsHtml5ElementName(nsHtml5Atoms::mrow, nsHtml5Atoms::mrow, NS_HTML5TREE_BUILDER_OTHER);
   ELT_NONE = new nsHtml5ElementName(nsHtml5Atoms::none, nsHtml5Atoms::none, NS_HTML5TREE_BUILDER_OTHER);
   ELT_NOBR = new nsHtml5ElementName(nsHtml5Atoms::nobr, nsHtml5Atoms::nobr, NS_HTML5TREE_BUILDER_NOBR);
   ELT_NEST = new nsHtml5ElementName(nsHtml5Atoms::nest, nsHtml5Atoms::nest, NS_HTML5TREE_BUILDER_OTHER);
   ELT_PATH = new nsHtml5ElementName(nsHtml5Atoms::path, nsHtml5Atoms::path, NS_HTML5TREE_BUILDER_OTHER);
   ELT_PLUS = new nsHtml5ElementName(nsHtml5Atoms::plus, nsHtml5Atoms::plus, NS_HTML5TREE_BUILDER_OTHER);
@@ -674,17 +676,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_STOP = new nsHtml5ElementName(nsHtml5Atoms::stop, nsHtml5Atoms::stop, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SDEV = new nsHtml5ElementName(nsHtml5Atoms::sdev, nsHtml5Atoms::sdev, NS_HTML5TREE_BUILDER_OTHER);
   ELT_TIME = new nsHtml5ElementName(nsHtml5Atoms::time, nsHtml5Atoms::time, NS_HTML5TREE_BUILDER_OTHER);
   ELT_TRUE = new nsHtml5ElementName(nsHtml5Atoms::true_, nsHtml5Atoms::true_, NS_HTML5TREE_BUILDER_OTHER);
   ELT_TREF = new nsHtml5ElementName(nsHtml5Atoms::tref, nsHtml5Atoms::tref, NS_HTML5TREE_BUILDER_OTHER);
   ELT_TANH = new nsHtml5ElementName(nsHtml5Atoms::tanh, nsHtml5Atoms::tanh, NS_HTML5TREE_BUILDER_OTHER);
   ELT_TEXT = new nsHtml5ElementName(nsHtml5Atoms::text, nsHtml5Atoms::text, NS_HTML5TREE_BUILDER_OTHER);
   ELT_VIEW = new nsHtml5ElementName(nsHtml5Atoms::view, nsHtml5Atoms::view, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_ASIDE = new nsHtml5ElementName(nsHtml5Atoms::aside, nsHtml5Atoms::aside, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_ASIDE = new nsHtml5ElementName(nsHtml5Atoms::aside, nsHtml5Atoms::aside, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_AUDIO = new nsHtml5ElementName(nsHtml5Atoms::audio, nsHtml5Atoms::audio, NS_HTML5TREE_BUILDER_OTHER);
   ELT_APPLY = new nsHtml5ElementName(nsHtml5Atoms::apply, nsHtml5Atoms::apply, NS_HTML5TREE_BUILDER_OTHER);
   ELT_EMBED = new nsHtml5ElementName(nsHtml5Atoms::embed, nsHtml5Atoms::embed, NS_HTML5TREE_BUILDER_EMBED_OR_IMG | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_FRAME = new nsHtml5ElementName(nsHtml5Atoms::frame, nsHtml5Atoms::frame, NS_HTML5TREE_BUILDER_FRAME | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_FALSE = new nsHtml5ElementName(nsHtml5Atoms::false_, nsHtml5Atoms::false_, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FLOOR = new nsHtml5ElementName(nsHtml5Atoms::floor, nsHtml5Atoms::floor, NS_HTML5TREE_BUILDER_OTHER);
   ELT_GLYPH = new nsHtml5ElementName(nsHtml5Atoms::glyph, nsHtml5Atoms::glyph, NS_HTML5TREE_BUILDER_OTHER);
   ELT_HKERN = new nsHtml5ElementName(nsHtml5Atoms::hkern, nsHtml5Atoms::hkern, NS_HTML5TREE_BUILDER_OTHER);
@@ -732,22 +734,22 @@ nsHtml5ElementName::initializeStatics()
   ELT_CENTER = new nsHtml5ElementName(nsHtml5Atoms::center, nsHtml5Atoms::center, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_CURSOR = new nsHtml5ElementName(nsHtml5Atoms::cursor, nsHtml5Atoms::cursor, NS_HTML5TREE_BUILDER_OTHER);
   ELT_CANVAS = new nsHtml5ElementName(nsHtml5Atoms::canvas, nsHtml5Atoms::canvas, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DIVIDE = new nsHtml5ElementName(nsHtml5Atoms::divide, nsHtml5Atoms::divide, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DEGREE = new nsHtml5ElementName(nsHtml5Atoms::degree, nsHtml5Atoms::degree, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DOMAIN = new nsHtml5ElementName(nsHtml5Atoms::domain, nsHtml5Atoms::domain, NS_HTML5TREE_BUILDER_OTHER);
   ELT_EXISTS = new nsHtml5ElementName(nsHtml5Atoms::exists, nsHtml5Atoms::exists, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FETILE = new nsHtml5ElementName(nsHtml5Atoms::fetile, nsHtml5Atoms::feTile, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_FIGURE = new nsHtml5ElementName(nsHtml5Atoms::figure, nsHtml5Atoms::figure, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_FIGURE = new nsHtml5ElementName(nsHtml5Atoms::figure, nsHtml5Atoms::figure, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_FORALL = new nsHtml5ElementName(nsHtml5Atoms::forall, nsHtml5Atoms::forall, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FILTER = new nsHtml5ElementName(nsHtml5Atoms::filter, nsHtml5Atoms::filter, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_FOOTER = new nsHtml5ElementName(nsHtml5Atoms::footer, nsHtml5Atoms::footer, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
-  ELT_HGROUP = new nsHtml5ElementName(nsHtml5Atoms::hgroup, nsHtml5Atoms::hgroup, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
-  ELT_HEADER = new nsHtml5ElementName(nsHtml5Atoms::header, nsHtml5Atoms::header, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_FOOTER = new nsHtml5ElementName(nsHtml5Atoms::footer, nsHtml5Atoms::footer, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_HGROUP = new nsHtml5ElementName(nsHtml5Atoms::hgroup, nsHtml5Atoms::hgroup, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_HEADER = new nsHtml5ElementName(nsHtml5Atoms::header, nsHtml5Atoms::header, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_IFRAME = new nsHtml5ElementName(nsHtml5Atoms::iframe, nsHtml5Atoms::iframe, NS_HTML5TREE_BUILDER_IFRAME | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_KEYGEN = new nsHtml5ElementName(nsHtml5Atoms::keygen, nsHtml5Atoms::keygen, NS_HTML5TREE_BUILDER_KEYGEN);
   ELT_LAMBDA = new nsHtml5ElementName(nsHtml5Atoms::lambda, nsHtml5Atoms::lambda, NS_HTML5TREE_BUILDER_OTHER);
   ELT_LEGEND = new nsHtml5ElementName(nsHtml5Atoms::legend, nsHtml5Atoms::legend, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MSPACE = new nsHtml5ElementName(nsHtml5Atoms::mspace, nsHtml5Atoms::mspace, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MTABLE = new nsHtml5ElementName(nsHtml5Atoms::mtable, nsHtml5Atoms::mtable, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MSTYLE = new nsHtml5ElementName(nsHtml5Atoms::mstyle, nsHtml5Atoms::mstyle, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MGLYPH = new nsHtml5ElementName(nsHtml5Atoms::mglyph, nsHtml5Atoms::mglyph, NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK);
@@ -766,35 +768,35 @@ nsHtml5ElementName::initializeStatics()
   ELT_STRONG = new nsHtml5ElementName(nsHtml5Atoms::strong, nsHtml5Atoms::strong, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
   ELT_SWITCH = new nsHtml5ElementName(nsHtml5Atoms::switch_, nsHtml5Atoms::switch_, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SYMBOL = new nsHtml5ElementName(nsHtml5Atoms::symbol, nsHtml5Atoms::symbol, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SELECT = new nsHtml5ElementName(nsHtml5Atoms::select, nsHtml5Atoms::select, NS_HTML5TREE_BUILDER_SELECT | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_SUBSET = new nsHtml5ElementName(nsHtml5Atoms::subset, nsHtml5Atoms::subset, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SCRIPT = new nsHtml5ElementName(nsHtml5Atoms::script, nsHtml5Atoms::script, NS_HTML5TREE_BUILDER_SCRIPT | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_TBREAK = new nsHtml5ElementName(nsHtml5Atoms::tbreak, nsHtml5Atoms::tbreak, NS_HTML5TREE_BUILDER_OTHER);
   ELT_VECTOR = new nsHtml5ElementName(nsHtml5Atoms::vector, nsHtml5Atoms::vector, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_ARTICLE = new nsHtml5ElementName(nsHtml5Atoms::article, nsHtml5Atoms::article, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_ARTICLE = new nsHtml5ElementName(nsHtml5Atoms::article, nsHtml5Atoms::article, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_ANIMATE = new nsHtml5ElementName(nsHtml5Atoms::animate, nsHtml5Atoms::animate, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ARCSECH = new nsHtml5ElementName(nsHtml5Atoms::arcsech, nsHtml5Atoms::arcsech, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ARCCSCH = new nsHtml5ElementName(nsHtml5Atoms::arccsch, nsHtml5Atoms::arccsch, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ARCTANH = new nsHtml5ElementName(nsHtml5Atoms::arctanh, nsHtml5Atoms::arctanh, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ARCSINH = new nsHtml5ElementName(nsHtml5Atoms::arcsinh, nsHtml5Atoms::arcsinh, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ARCCOSH = new nsHtml5ElementName(nsHtml5Atoms::arccosh, nsHtml5Atoms::arccosh, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ARCCOTH = new nsHtml5ElementName(nsHtml5Atoms::arccoth, nsHtml5Atoms::arccoth, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ACRONYM = new nsHtml5ElementName(nsHtml5Atoms::acronym, nsHtml5Atoms::acronym, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_ADDRESS = new nsHtml5ElementName(nsHtml5Atoms::address, nsHtml5Atoms::address, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_ADDRESS = new nsHtml5ElementName(nsHtml5Atoms::address, nsHtml5Atoms::address, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_BGSOUND = new nsHtml5ElementName(nsHtml5Atoms::bgsound, nsHtml5Atoms::bgsound, NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_COMMAND = new nsHtml5ElementName(nsHtml5Atoms::command, nsHtml5Atoms::command, NS_HTML5TREE_BUILDER_COMMAND | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_COMPOSE = new nsHtml5ElementName(nsHtml5Atoms::compose, nsHtml5Atoms::compose, NS_HTML5TREE_BUILDER_OTHER);
   ELT_CEILING = new nsHtml5ElementName(nsHtml5Atoms::ceiling, nsHtml5Atoms::ceiling, NS_HTML5TREE_BUILDER_OTHER);
   ELT_CSYMBOL = new nsHtml5ElementName(nsHtml5Atoms::csymbol, nsHtml5Atoms::csymbol, NS_HTML5TREE_BUILDER_OTHER);
   ELT_CAPTION = new nsHtml5ElementName(nsHtml5Atoms::caption, nsHtml5Atoms::caption, NS_HTML5TREE_BUILDER_CAPTION | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
   ELT_DISCARD = new nsHtml5ElementName(nsHtml5Atoms::discard, nsHtml5Atoms::discard, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DECLARE = new nsHtml5ElementName(nsHtml5Atoms::declare, nsHtml5Atoms::declare, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_DETAILS = new nsHtml5ElementName(nsHtml5Atoms::details, nsHtml5Atoms::details, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_DETAILS = new nsHtml5ElementName(nsHtml5Atoms::details, nsHtml5Atoms::details, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_ELLIPSE = new nsHtml5ElementName(nsHtml5Atoms::ellipse, nsHtml5Atoms::ellipse, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEFUNCA = new nsHtml5ElementName(nsHtml5Atoms::fefunca, nsHtml5Atoms::feFuncA, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEFUNCB = new nsHtml5ElementName(nsHtml5Atoms::fefuncb, nsHtml5Atoms::feFuncB, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEBLEND = new nsHtml5ElementName(nsHtml5Atoms::feblend, nsHtml5Atoms::feBlend, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEFLOOD = new nsHtml5ElementName(nsHtml5Atoms::feflood, nsHtml5Atoms::feFlood, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEIMAGE = new nsHtml5ElementName(nsHtml5Atoms::feimage, nsHtml5Atoms::feImage, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEMERGE = new nsHtml5ElementName(nsHtml5Atoms::femerge, nsHtml5Atoms::feMerge, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEFUNCG = new nsHtml5ElementName(nsHtml5Atoms::fefuncg, nsHtml5Atoms::feFuncG, NS_HTML5TREE_BUILDER_OTHER);
@@ -810,18 +812,18 @@ nsHtml5ElementName::initializeStatics()
   ELT_MARQUEE = new nsHtml5ElementName(nsHtml5Atoms::marquee, nsHtml5Atoms::marquee, NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
   ELT_MACTION = new nsHtml5ElementName(nsHtml5Atoms::maction, nsHtml5Atoms::maction, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MSUBSUP = new nsHtml5ElementName(nsHtml5Atoms::msubsup, nsHtml5Atoms::msubsup, NS_HTML5TREE_BUILDER_OTHER);
   ELT_NOEMBED = new nsHtml5ElementName(nsHtml5Atoms::noembed, nsHtml5Atoms::noembed, NS_HTML5TREE_BUILDER_NOEMBED | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_POLYGON = new nsHtml5ElementName(nsHtml5Atoms::polygon, nsHtml5Atoms::polygon, NS_HTML5TREE_BUILDER_OTHER);
   ELT_PATTERN = new nsHtml5ElementName(nsHtml5Atoms::pattern, nsHtml5Atoms::pattern, NS_HTML5TREE_BUILDER_OTHER);
   ELT_PRODUCT = new nsHtml5ElementName(nsHtml5Atoms::product, nsHtml5Atoms::product, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SETDIFF = new nsHtml5ElementName(nsHtml5Atoms::setdiff, nsHtml5Atoms::setdiff, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_SECTION = new nsHtml5ElementName(nsHtml5Atoms::section, nsHtml5Atoms::section, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
-  ELT_SUMMARY = new nsHtml5ElementName(nsHtml5Atoms::summary, nsHtml5Atoms::summary, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_SECTION = new nsHtml5ElementName(nsHtml5Atoms::section, nsHtml5Atoms::section, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_SUMMARY = new nsHtml5ElementName(nsHtml5Atoms::summary, nsHtml5Atoms::summary, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_TENDSTO = new nsHtml5ElementName(nsHtml5Atoms::tendsto, nsHtml5Atoms::tendsto, NS_HTML5TREE_BUILDER_OTHER);
   ELT_UPLIMIT = new nsHtml5ElementName(nsHtml5Atoms::uplimit, nsHtml5Atoms::uplimit, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ALTGLYPH = new nsHtml5ElementName(nsHtml5Atoms::altglyph, nsHtml5Atoms::altGlyph, NS_HTML5TREE_BUILDER_OTHER);
   ELT_BASEFONT = new nsHtml5ElementName(nsHtml5Atoms::basefont, nsHtml5Atoms::basefont, NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_CLIPPATH = new nsHtml5ElementName(nsHtml5Atoms::clippath, nsHtml5Atoms::clipPath, NS_HTML5TREE_BUILDER_OTHER);
   ELT_CODOMAIN = new nsHtml5ElementName(nsHtml5Atoms::codomain, nsHtml5Atoms::codomain, NS_HTML5TREE_BUILDER_OTHER);
   ELT_COLGROUP = new nsHtml5ElementName(nsHtml5Atoms::colgroup, nsHtml5Atoms::colgroup, NS_HTML5TREE_BUILDER_COLGROUP | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
   ELT_EMPTYSET = new nsHtml5ElementName(nsHtml5Atoms::emptyset, nsHtml5Atoms::emptyset, NS_HTML5TREE_BUILDER_OTHER);
@@ -868,17 +870,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_RATIONALS = new nsHtml5ElementName(nsHtml5Atoms::rationals, nsHtml5Atoms::rationals, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SEMANTICS = new nsHtml5ElementName(nsHtml5Atoms::semantics, nsHtml5Atoms::semantics, NS_HTML5TREE_BUILDER_OTHER);
   ELT_TRANSPOSE = new nsHtml5ElementName(nsHtml5Atoms::transpose, nsHtml5Atoms::transpose, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ANNOTATION = new nsHtml5ElementName(nsHtml5Atoms::annotation, nsHtml5Atoms::annotation, NS_HTML5TREE_BUILDER_OTHER);
   ELT_BLOCKQUOTE = new nsHtml5ElementName(nsHtml5Atoms::blockquote, nsHtml5Atoms::blockquote, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_DIVERGENCE = new nsHtml5ElementName(nsHtml5Atoms::divergence, nsHtml5Atoms::divergence, NS_HTML5TREE_BUILDER_OTHER);
   ELT_EULERGAMMA = new nsHtml5ElementName(nsHtml5Atoms::eulergamma, nsHtml5Atoms::eulergamma, NS_HTML5TREE_BUILDER_OTHER);
   ELT_EQUIVALENT = new nsHtml5ElementName(nsHtml5Atoms::equivalent, nsHtml5Atoms::equivalent, NS_HTML5TREE_BUILDER_OTHER);
-  ELT_FIGCAPTION = new nsHtml5ElementName(nsHtml5Atoms::figcaption, nsHtml5Atoms::figcaption, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+  ELT_FIGCAPTION = new nsHtml5ElementName(nsHtml5Atoms::figcaption, nsHtml5Atoms::figcaption, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_IMAGINARYI = new nsHtml5ElementName(nsHtml5Atoms::imaginaryi, nsHtml5Atoms::imaginaryi, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MALIGNMARK = new nsHtml5ElementName(nsHtml5Atoms::malignmark, nsHtml5Atoms::malignmark, NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK);
   ELT_MUNDEROVER = new nsHtml5ElementName(nsHtml5Atoms::munderover, nsHtml5Atoms::munderover, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MLABELEDTR = new nsHtml5ElementName(nsHtml5Atoms::mlabeledtr, nsHtml5Atoms::mlabeledtr, NS_HTML5TREE_BUILDER_OTHER);
   ELT_NOTANUMBER = new nsHtml5ElementName(nsHtml5Atoms::notanumber, nsHtml5Atoms::notanumber, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SOLIDCOLOR = new nsHtml5ElementName(nsHtml5Atoms::solidcolor, nsHtml5Atoms::solidcolor, NS_HTML5TREE_BUILDER_OTHER);
   ELT_ALTGLYPHDEF = new nsHtml5ElementName(nsHtml5Atoms::altglyphdef, nsHtml5Atoms::altGlyphDef, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DETERMINANT = new nsHtml5ElementName(nsHtml5Atoms::determinant, nsHtml5Atoms::determinant, NS_HTML5TREE_BUILDER_OTHER);
@@ -920,17 +922,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_CARTESIANPRODUCT = new nsHtml5ElementName(nsHtml5Atoms::cartesianproduct, nsHtml5Atoms::cartesianproduct, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FONT_FACE_FORMAT = new nsHtml5ElementName(nsHtml5Atoms::font_face_format, nsHtml5Atoms::font_face_format, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FECONVOLVEMATRIX = new nsHtml5ElementName(nsHtml5Atoms::feconvolvematrix, nsHtml5Atoms::feConvolveMatrix, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEDIFFUSELIGHTING = new nsHtml5ElementName(nsHtml5Atoms::fediffuselighting, nsHtml5Atoms::feDiffuseLighting, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FEDISPLACEMENTMAP = new nsHtml5ElementName(nsHtml5Atoms::fedisplacementmap, nsHtml5Atoms::feDisplacementMap, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FESPECULARLIGHTING = new nsHtml5ElementName(nsHtml5Atoms::fespecularlighting, nsHtml5Atoms::feSpecularLighting, NS_HTML5TREE_BUILDER_OTHER);
   ELT_DOMAINOFAPPLICATION = new nsHtml5ElementName(nsHtml5Atoms::domainofapplication, nsHtml5Atoms::domainofapplication, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FECOMPONENTTRANSFER = new nsHtml5ElementName(nsHtml5Atoms::fecomponenttransfer, nsHtml5Atoms::feComponentTransfer, NS_HTML5TREE_BUILDER_OTHER);
-  ELEMENT_NAMES = new nsHtml5ElementName*[392];
+  ELEMENT_NAMES = new nsHtml5ElementName*[393];
   ELEMENT_NAMES[0] = ELT_A;
   ELEMENT_NAMES[1] = ELT_B;
   ELEMENT_NAMES[2] = ELT_G;
   ELEMENT_NAMES[3] = ELT_I;
   ELEMENT_NAMES[4] = ELT_P;
   ELEMENT_NAMES[5] = ELT_Q;
   ELEMENT_NAMES[6] = ELT_S;
   ELEMENT_NAMES[7] = ELT_U;
@@ -1041,288 +1043,289 @@ nsHtml5ElementName::initializeStatics()
   ELEMENT_NAMES[112] = ELT_LIST;
   ELEMENT_NAMES[113] = ELT_META;
   ELEMENT_NAMES[114] = ELT_MSUB;
   ELEMENT_NAMES[115] = ELT_MODE;
   ELEMENT_NAMES[116] = ELT_MATH;
   ELEMENT_NAMES[117] = ELT_MARK;
   ELEMENT_NAMES[118] = ELT_MASK;
   ELEMENT_NAMES[119] = ELT_MEAN;
-  ELEMENT_NAMES[120] = ELT_MSUP;
-  ELEMENT_NAMES[121] = ELT_MENU;
-  ELEMENT_NAMES[122] = ELT_MROW;
-  ELEMENT_NAMES[123] = ELT_NONE;
-  ELEMENT_NAMES[124] = ELT_NOBR;
-  ELEMENT_NAMES[125] = ELT_NEST;
-  ELEMENT_NAMES[126] = ELT_PATH;
-  ELEMENT_NAMES[127] = ELT_PLUS;
-  ELEMENT_NAMES[128] = ELT_RULE;
-  ELEMENT_NAMES[129] = ELT_REAL;
-  ELEMENT_NAMES[130] = ELT_RELN;
-  ELEMENT_NAMES[131] = ELT_RECT;
-  ELEMENT_NAMES[132] = ELT_ROOT;
-  ELEMENT_NAMES[133] = ELT_RUBY;
-  ELEMENT_NAMES[134] = ELT_SECH;
-  ELEMENT_NAMES[135] = ELT_SINH;
-  ELEMENT_NAMES[136] = ELT_SPAN;
-  ELEMENT_NAMES[137] = ELT_SAMP;
-  ELEMENT_NAMES[138] = ELT_STOP;
-  ELEMENT_NAMES[139] = ELT_SDEV;
-  ELEMENT_NAMES[140] = ELT_TIME;
-  ELEMENT_NAMES[141] = ELT_TRUE;
-  ELEMENT_NAMES[142] = ELT_TREF;
-  ELEMENT_NAMES[143] = ELT_TANH;
-  ELEMENT_NAMES[144] = ELT_TEXT;
-  ELEMENT_NAMES[145] = ELT_VIEW;
-  ELEMENT_NAMES[146] = ELT_ASIDE;
-  ELEMENT_NAMES[147] = ELT_AUDIO;
-  ELEMENT_NAMES[148] = ELT_APPLY;
-  ELEMENT_NAMES[149] = ELT_EMBED;
-  ELEMENT_NAMES[150] = ELT_FRAME;
-  ELEMENT_NAMES[151] = ELT_FALSE;
-  ELEMENT_NAMES[152] = ELT_FLOOR;
-  ELEMENT_NAMES[153] = ELT_GLYPH;
-  ELEMENT_NAMES[154] = ELT_HKERN;
-  ELEMENT_NAMES[155] = ELT_IMAGE;
-  ELEMENT_NAMES[156] = ELT_IDENT;
-  ELEMENT_NAMES[157] = ELT_INPUT;
-  ELEMENT_NAMES[158] = ELT_LABEL;
-  ELEMENT_NAMES[159] = ELT_LIMIT;
-  ELEMENT_NAMES[160] = ELT_MFRAC;
-  ELEMENT_NAMES[161] = ELT_MPATH;
-  ELEMENT_NAMES[162] = ELT_METER;
-  ELEMENT_NAMES[163] = ELT_MOVER;
-  ELEMENT_NAMES[164] = ELT_MINUS;
-  ELEMENT_NAMES[165] = ELT_MROOT;
-  ELEMENT_NAMES[166] = ELT_MSQRT;
-  ELEMENT_NAMES[167] = ELT_MTEXT;
-  ELEMENT_NAMES[168] = ELT_NOTIN;
-  ELEMENT_NAMES[169] = ELT_PIECE;
-  ELEMENT_NAMES[170] = ELT_PARAM;
-  ELEMENT_NAMES[171] = ELT_POWER;
-  ELEMENT_NAMES[172] = ELT_REALS;
-  ELEMENT_NAMES[173] = ELT_STYLE;
-  ELEMENT_NAMES[174] = ELT_SMALL;
-  ELEMENT_NAMES[175] = ELT_THEAD;
-  ELEMENT_NAMES[176] = ELT_TABLE;
-  ELEMENT_NAMES[177] = ELT_TITLE;
-  ELEMENT_NAMES[178] = ELT_TRACK;
-  ELEMENT_NAMES[179] = ELT_TSPAN;
-  ELEMENT_NAMES[180] = ELT_TIMES;
-  ELEMENT_NAMES[181] = ELT_TFOOT;
-  ELEMENT_NAMES[182] = ELT_TBODY;
-  ELEMENT_NAMES[183] = ELT_UNION;
-  ELEMENT_NAMES[184] = ELT_VKERN;
-  ELEMENT_NAMES[185] = ELT_VIDEO;
-  ELEMENT_NAMES[186] = ELT_ARCSEC;
-  ELEMENT_NAMES[187] = ELT_ARCCSC;
-  ELEMENT_NAMES[188] = ELT_ARCTAN;
-  ELEMENT_NAMES[189] = ELT_ARCSIN;
-  ELEMENT_NAMES[190] = ELT_ARCCOS;
-  ELEMENT_NAMES[191] = ELT_APPLET;
-  ELEMENT_NAMES[192] = ELT_ARCCOT;
-  ELEMENT_NAMES[193] = ELT_APPROX;
-  ELEMENT_NAMES[194] = ELT_BUTTON;
-  ELEMENT_NAMES[195] = ELT_CIRCLE;
-  ELEMENT_NAMES[196] = ELT_CENTER;
-  ELEMENT_NAMES[197] = ELT_CURSOR;
-  ELEMENT_NAMES[198] = ELT_CANVAS;
-  ELEMENT_NAMES[199] = ELT_DIVIDE;
-  ELEMENT_NAMES[200] = ELT_DEGREE;
-  ELEMENT_NAMES[201] = ELT_DOMAIN;
-  ELEMENT_NAMES[202] = ELT_EXISTS;
-  ELEMENT_NAMES[203] = ELT_FETILE;
-  ELEMENT_NAMES[204] = ELT_FIGURE;
-  ELEMENT_NAMES[205] = ELT_FORALL;
-  ELEMENT_NAMES[206] = ELT_FILTER;
-  ELEMENT_NAMES[207] = ELT_FOOTER;
-  ELEMENT_NAMES[208] = ELT_HGROUP;
-  ELEMENT_NAMES[209] = ELT_HEADER;
-  ELEMENT_NAMES[210] = ELT_IFRAME;
-  ELEMENT_NAMES[211] = ELT_KEYGEN;
-  ELEMENT_NAMES[212] = ELT_LAMBDA;
-  ELEMENT_NAMES[213] = ELT_LEGEND;
-  ELEMENT_NAMES[214] = ELT_MSPACE;
-  ELEMENT_NAMES[215] = ELT_MTABLE;
-  ELEMENT_NAMES[216] = ELT_MSTYLE;
-  ELEMENT_NAMES[217] = ELT_MGLYPH;
-  ELEMENT_NAMES[218] = ELT_MEDIAN;
-  ELEMENT_NAMES[219] = ELT_MUNDER;
-  ELEMENT_NAMES[220] = ELT_MARKER;
-  ELEMENT_NAMES[221] = ELT_MERROR;
-  ELEMENT_NAMES[222] = ELT_MOMENT;
-  ELEMENT_NAMES[223] = ELT_MATRIX;
-  ELEMENT_NAMES[224] = ELT_OPTION;
-  ELEMENT_NAMES[225] = ELT_OBJECT;
-  ELEMENT_NAMES[226] = ELT_OUTPUT;
-  ELEMENT_NAMES[227] = ELT_PRIMES;
-  ELEMENT_NAMES[228] = ELT_SOURCE;
-  ELEMENT_NAMES[229] = ELT_STRIKE;
-  ELEMENT_NAMES[230] = ELT_STRONG;
-  ELEMENT_NAMES[231] = ELT_SWITCH;
-  ELEMENT_NAMES[232] = ELT_SYMBOL;
-  ELEMENT_NAMES[233] = ELT_SELECT;
-  ELEMENT_NAMES[234] = ELT_SUBSET;
-  ELEMENT_NAMES[235] = ELT_SCRIPT;
-  ELEMENT_NAMES[236] = ELT_TBREAK;
-  ELEMENT_NAMES[237] = ELT_VECTOR;
-  ELEMENT_NAMES[238] = ELT_ARTICLE;
-  ELEMENT_NAMES[239] = ELT_ANIMATE;
-  ELEMENT_NAMES[240] = ELT_ARCSECH;
-  ELEMENT_NAMES[241] = ELT_ARCCSCH;
-  ELEMENT_NAMES[242] = ELT_ARCTANH;
-  ELEMENT_NAMES[243] = ELT_ARCSINH;
-  ELEMENT_NAMES[244] = ELT_ARCCOSH;
-  ELEMENT_NAMES[245] = ELT_ARCCOTH;
-  ELEMENT_NAMES[246] = ELT_ACRONYM;
-  ELEMENT_NAMES[247] = ELT_ADDRESS;
-  ELEMENT_NAMES[248] = ELT_BGSOUND;
-  ELEMENT_NAMES[249] = ELT_COMMAND;
-  ELEMENT_NAMES[250] = ELT_COMPOSE;
-  ELEMENT_NAMES[251] = ELT_CEILING;
-  ELEMENT_NAMES[252] = ELT_CSYMBOL;
-  ELEMENT_NAMES[253] = ELT_CAPTION;
-  ELEMENT_NAMES[254] = ELT_DISCARD;
-  ELEMENT_NAMES[255] = ELT_DECLARE;
-  ELEMENT_NAMES[256] = ELT_DETAILS;
-  ELEMENT_NAMES[257] = ELT_ELLIPSE;
-  ELEMENT_NAMES[258] = ELT_FEFUNCA;
-  ELEMENT_NAMES[259] = ELT_FEFUNCB;
-  ELEMENT_NAMES[260] = ELT_FEBLEND;
-  ELEMENT_NAMES[261] = ELT_FEFLOOD;
-  ELEMENT_NAMES[262] = ELT_FEIMAGE;
-  ELEMENT_NAMES[263] = ELT_FEMERGE;
-  ELEMENT_NAMES[264] = ELT_FEFUNCG;
-  ELEMENT_NAMES[265] = ELT_FEFUNCR;
-  ELEMENT_NAMES[266] = ELT_HANDLER;
-  ELEMENT_NAMES[267] = ELT_INVERSE;
-  ELEMENT_NAMES[268] = ELT_IMPLIES;
-  ELEMENT_NAMES[269] = ELT_ISINDEX;
-  ELEMENT_NAMES[270] = ELT_LOGBASE;
-  ELEMENT_NAMES[271] = ELT_LISTING;
-  ELEMENT_NAMES[272] = ELT_MFENCED;
-  ELEMENT_NAMES[273] = ELT_MPADDED;
-  ELEMENT_NAMES[274] = ELT_MARQUEE;
-  ELEMENT_NAMES[275] = ELT_MACTION;
-  ELEMENT_NAMES[276] = ELT_MSUBSUP;
-  ELEMENT_NAMES[277] = ELT_NOEMBED;
-  ELEMENT_NAMES[278] = ELT_POLYGON;
-  ELEMENT_NAMES[279] = ELT_PATTERN;
-  ELEMENT_NAMES[280] = ELT_PRODUCT;
-  ELEMENT_NAMES[281] = ELT_SETDIFF;
-  ELEMENT_NAMES[282] = ELT_SECTION;
-  ELEMENT_NAMES[283] = ELT_SUMMARY;
-  ELEMENT_NAMES[284] = ELT_TENDSTO;
-  ELEMENT_NAMES[285] = ELT_UPLIMIT;
-  ELEMENT_NAMES[286] = ELT_ALTGLYPH;
-  ELEMENT_NAMES[287] = ELT_BASEFONT;
-  ELEMENT_NAMES[288] = ELT_CLIPPATH;
-  ELEMENT_NAMES[289] = ELT_CODOMAIN;
-  ELEMENT_NAMES[290] = ELT_COLGROUP;
-  ELEMENT_NAMES[291] = ELT_EMPTYSET;
-  ELEMENT_NAMES[292] = ELT_FACTOROF;
-  ELEMENT_NAMES[293] = ELT_FIELDSET;
-  ELEMENT_NAMES[294] = ELT_FRAMESET;
-  ELEMENT_NAMES[295] = ELT_FEOFFSET;
-  ELEMENT_NAMES[296] = ELT_GLYPHREF;
-  ELEMENT_NAMES[297] = ELT_INTERVAL;
-  ELEMENT_NAMES[298] = ELT_INTEGERS;
-  ELEMENT_NAMES[299] = ELT_INFINITY;
-  ELEMENT_NAMES[300] = ELT_LISTENER;
-  ELEMENT_NAMES[301] = ELT_LOWLIMIT;
-  ELEMENT_NAMES[302] = ELT_METADATA;
-  ELEMENT_NAMES[303] = ELT_MENCLOSE;
-  ELEMENT_NAMES[304] = ELT_MENUITEM;
-  ELEMENT_NAMES[305] = ELT_MPHANTOM;
-  ELEMENT_NAMES[306] = ELT_NOFRAMES;
-  ELEMENT_NAMES[307] = ELT_NOSCRIPT;
-  ELEMENT_NAMES[308] = ELT_OPTGROUP;
-  ELEMENT_NAMES[309] = ELT_POLYLINE;
-  ELEMENT_NAMES[310] = ELT_PREFETCH;
-  ELEMENT_NAMES[311] = ELT_PROGRESS;
-  ELEMENT_NAMES[312] = ELT_PRSUBSET;
-  ELEMENT_NAMES[313] = ELT_QUOTIENT;
-  ELEMENT_NAMES[314] = ELT_SELECTOR;
-  ELEMENT_NAMES[315] = ELT_TEXTAREA;
-  ELEMENT_NAMES[316] = ELT_TEXTPATH;
-  ELEMENT_NAMES[317] = ELT_VARIANCE;
-  ELEMENT_NAMES[318] = ELT_ANIMATION;
-  ELEMENT_NAMES[319] = ELT_CONJUGATE;
-  ELEMENT_NAMES[320] = ELT_CONDITION;
-  ELEMENT_NAMES[321] = ELT_COMPLEXES;
-  ELEMENT_NAMES[322] = ELT_FONT_FACE;
-  ELEMENT_NAMES[323] = ELT_FACTORIAL;
-  ELEMENT_NAMES[324] = ELT_INTERSECT;
-  ELEMENT_NAMES[325] = ELT_IMAGINARY;
-  ELEMENT_NAMES[326] = ELT_LAPLACIAN;
-  ELEMENT_NAMES[327] = ELT_MATRIXROW;
-  ELEMENT_NAMES[328] = ELT_NOTSUBSET;
-  ELEMENT_NAMES[329] = ELT_OTHERWISE;
-  ELEMENT_NAMES[330] = ELT_PIECEWISE;
-  ELEMENT_NAMES[331] = ELT_PLAINTEXT;
-  ELEMENT_NAMES[332] = ELT_RATIONALS;
-  ELEMENT_NAMES[333] = ELT_SEMANTICS;
-  ELEMENT_NAMES[334] = ELT_TRANSPOSE;
-  ELEMENT_NAMES[335] = ELT_ANNOTATION;
-  ELEMENT_NAMES[336] = ELT_BLOCKQUOTE;
-  ELEMENT_NAMES[337] = ELT_DIVERGENCE;
-  ELEMENT_NAMES[338] = ELT_EULERGAMMA;
-  ELEMENT_NAMES[339] = ELT_EQUIVALENT;
-  ELEMENT_NAMES[340] = ELT_FIGCAPTION;
-  ELEMENT_NAMES[341] = ELT_IMAGINARYI;
-  ELEMENT_NAMES[342] = ELT_MALIGNMARK;
-  ELEMENT_NAMES[343] = ELT_MUNDEROVER;
-  ELEMENT_NAMES[344] = ELT_MLABELEDTR;
-  ELEMENT_NAMES[345] = ELT_NOTANUMBER;
-  ELEMENT_NAMES[346] = ELT_SOLIDCOLOR;
-  ELEMENT_NAMES[347] = ELT_ALTGLYPHDEF;
-  ELEMENT_NAMES[348] = ELT_DETERMINANT;
-  ELEMENT_NAMES[349] = ELT_FEMERGENODE;
-  ELEMENT_NAMES[350] = ELT_FECOMPOSITE;
-  ELEMENT_NAMES[351] = ELT_FESPOTLIGHT;
-  ELEMENT_NAMES[352] = ELT_MALIGNGROUP;
-  ELEMENT_NAMES[353] = ELT_MPRESCRIPTS;
-  ELEMENT_NAMES[354] = ELT_MOMENTABOUT;
-  ELEMENT_NAMES[355] = ELT_NOTPRSUBSET;
-  ELEMENT_NAMES[356] = ELT_PARTIALDIFF;
-  ELEMENT_NAMES[357] = ELT_ALTGLYPHITEM;
-  ELEMENT_NAMES[358] = ELT_ANIMATECOLOR;
-  ELEMENT_NAMES[359] = ELT_DATATEMPLATE;
-  ELEMENT_NAMES[360] = ELT_EXPONENTIALE;
-  ELEMENT_NAMES[361] = ELT_FETURBULENCE;
-  ELEMENT_NAMES[362] = ELT_FEPOINTLIGHT;
-  ELEMENT_NAMES[363] = ELT_FEMORPHOLOGY;
-  ELEMENT_NAMES[364] = ELT_OUTERPRODUCT;
-  ELEMENT_NAMES[365] = ELT_ANIMATEMOTION;
-  ELEMENT_NAMES[366] = ELT_COLOR_PROFILE;
-  ELEMENT_NAMES[367] = ELT_FONT_FACE_SRC;
-  ELEMENT_NAMES[368] = ELT_FONT_FACE_URI;
-  ELEMENT_NAMES[369] = ELT_FOREIGNOBJECT;
-  ELEMENT_NAMES[370] = ELT_FECOLORMATRIX;
-  ELEMENT_NAMES[371] = ELT_MISSING_GLYPH;
-  ELEMENT_NAMES[372] = ELT_MMULTISCRIPTS;
-  ELEMENT_NAMES[373] = ELT_SCALARPRODUCT;
-  ELEMENT_NAMES[374] = ELT_VECTORPRODUCT;
-  ELEMENT_NAMES[375] = ELT_ANNOTATION_XML;
-  ELEMENT_NAMES[376] = ELT_DEFINITION_SRC;
-  ELEMENT_NAMES[377] = ELT_FONT_FACE_NAME;
-  ELEMENT_NAMES[378] = ELT_FEGAUSSIANBLUR;
-  ELEMENT_NAMES[379] = ELT_FEDISTANTLIGHT;
-  ELEMENT_NAMES[380] = ELT_LINEARGRADIENT;
-  ELEMENT_NAMES[381] = ELT_NATURALNUMBERS;
-  ELEMENT_NAMES[382] = ELT_RADIALGRADIENT;
-  ELEMENT_NAMES[383] = ELT_ANIMATETRANSFORM;
-  ELEMENT_NAMES[384] = ELT_CARTESIANPRODUCT;
-  ELEMENT_NAMES[385] = ELT_FONT_FACE_FORMAT;
-  ELEMENT_NAMES[386] = ELT_FECONVOLVEMATRIX;
-  ELEMENT_NAMES[387] = ELT_FEDIFFUSELIGHTING;
-  ELEMENT_NAMES[388] = ELT_FEDISPLACEMENTMAP;
-  ELEMENT_NAMES[389] = ELT_FESPECULARLIGHTING;
-  ELEMENT_NAMES[390] = ELT_DOMAINOFAPPLICATION;
-  ELEMENT_NAMES[391] = ELT_FECOMPONENTTRANSFER;
+  ELEMENT_NAMES[120] = ELT_MAIN;
+  ELEMENT_NAMES[121] = ELT_MSUP;
+  ELEMENT_NAMES[122] = ELT_MENU;
+  ELEMENT_NAMES[123] = ELT_MROW;
+  ELEMENT_NAMES[124] = ELT_NONE;
+  ELEMENT_NAMES[125] = ELT_NOBR;
+  ELEMENT_NAMES[126] = ELT_NEST;
+  ELEMENT_NAMES[127] = ELT_PATH;
+  ELEMENT_NAMES[128] = ELT_PLUS;
+  ELEMENT_NAMES[129] = ELT_RULE;
+  ELEMENT_NAMES[130] = ELT_REAL;
+  ELEMENT_NAMES[131] = ELT_RELN;
+  ELEMENT_NAMES[132] = ELT_RECT;
+  ELEMENT_NAMES[133] = ELT_ROOT;
+  ELEMENT_NAMES[134] = ELT_RUBY;
+  ELEMENT_NAMES[135] = ELT_SECH;
+  ELEMENT_NAMES[136] = ELT_SINH;
+  ELEMENT_NAMES[137] = ELT_SPAN;
+  ELEMENT_NAMES[138] = ELT_SAMP;
+  ELEMENT_NAMES[139] = ELT_STOP;
+  ELEMENT_NAMES[140] = ELT_SDEV;
+  ELEMENT_NAMES[141] = ELT_TIME;
+  ELEMENT_NAMES[142] = ELT_TRUE;
+  ELEMENT_NAMES[143] = ELT_TREF;
+  ELEMENT_NAMES[144] = ELT_TANH;
+  ELEMENT_NAMES[145] = ELT_TEXT;
+  ELEMENT_NAMES[146] = ELT_VIEW;
+  ELEMENT_NAMES[147] = ELT_ASIDE;
+  ELEMENT_NAMES[148] = ELT_AUDIO;
+  ELEMENT_NAMES[149] = ELT_APPLY;
+  ELEMENT_NAMES[150] = ELT_EMBED;
+  ELEMENT_NAMES[151] = ELT_FRAME;
+  ELEMENT_NAMES[152] = ELT_FALSE;
+  ELEMENT_NAMES[153] = ELT_FLOOR;
+  ELEMENT_NAMES[154] = ELT_GLYPH;
+  ELEMENT_NAMES[155] = ELT_HKERN;
+  ELEMENT_NAMES[156] = ELT_IMAGE;
+  ELEMENT_NAMES[157] = ELT_IDENT;
+  ELEMENT_NAMES[158] = ELT_INPUT;
+  ELEMENT_NAMES[159] = ELT_LABEL;
+  ELEMENT_NAMES[160] = ELT_LIMIT;
+  ELEMENT_NAMES[161] = ELT_MFRAC;
+  ELEMENT_NAMES[162] = ELT_MPATH;
+  ELEMENT_NAMES[163] = ELT_METER;
+  ELEMENT_NAMES[164] = ELT_MOVER;
+  ELEMENT_NAMES[165] = ELT_MINUS;
+  ELEMENT_NAMES[166] = ELT_MROOT;
+  ELEMENT_NAMES[167] = ELT_MSQRT;
+  ELEMENT_NAMES[168] = ELT_MTEXT;
+  ELEMENT_NAMES[169] = ELT_NOTIN;
+  ELEMENT_NAMES[170] = ELT_PIECE;
+  ELEMENT_NAMES[171] = ELT_PARAM;
+  ELEMENT_NAMES[172] = ELT_POWER;
+  ELEMENT_NAMES[173] = ELT_REALS;
+  ELEMENT_NAMES[174] = ELT_STYLE;
+  ELEMENT_NAMES[175] = ELT_SMALL;
+  ELEMENT_NAMES[176] = ELT_THEAD;
+  ELEMENT_NAMES[177] = ELT_TABLE;
+  ELEMENT_NAMES[178] = ELT_TITLE;
+  ELEMENT_NAMES[179] = ELT_TRACK;
+  ELEMENT_NAMES[180] = ELT_TSPAN;
+  ELEMENT_NAMES[181] = ELT_TIMES;
+  ELEMENT_NAMES[182] = ELT_TFOOT;
+  ELEMENT_NAMES[183] = ELT_TBODY;
+  ELEMENT_NAMES[184] = ELT_UNION;
+  ELEMENT_NAMES[185] = ELT_VKERN;
+  ELEMENT_NAMES[186] = ELT_VIDEO;
+  ELEMENT_NAMES[187] = ELT_ARCSEC;
+  ELEMENT_NAMES[188] = ELT_ARCCSC;
+  ELEMENT_NAMES[189] = ELT_ARCTAN;
+  ELEMENT_NAMES[190] = ELT_ARCSIN;
+  ELEMENT_NAMES[191] = ELT_ARCCOS;
+  ELEMENT_NAMES[192] = ELT_APPLET;
+  ELEMENT_NAMES[193] = ELT_ARCCOT;
+  ELEMENT_NAMES[194] = ELT_APPROX;
+  ELEMENT_NAMES[195] = ELT_BUTTON;
+  ELEMENT_NAMES[196] = ELT_CIRCLE;
+  ELEMENT_NAMES[197] = ELT_CENTER;
+  ELEMENT_NAMES[198] = ELT_CURSOR;
+  ELEMENT_NAMES[199] = ELT_CANVAS;
+  ELEMENT_NAMES[200] = ELT_DIVIDE;
+  ELEMENT_NAMES[201] = ELT_DEGREE;
+  ELEMENT_NAMES[202] = ELT_DOMAIN;
+  ELEMENT_NAMES[203] = ELT_EXISTS;
+  ELEMENT_NAMES[204] = ELT_FETILE;
+  ELEMENT_NAMES[205] = ELT_FIGURE;
+  ELEMENT_NAMES[206] = ELT_FORALL;
+  ELEMENT_NAMES[207] = ELT_FILTER;
+  ELEMENT_NAMES[208] = ELT_FOOTER;
+  ELEMENT_NAMES[209] = ELT_HGROUP;
+  ELEMENT_NAMES[210] = ELT_HEADER;
+  ELEMENT_NAMES[211] = ELT_IFRAME;
+  ELEMENT_NAMES[212] = ELT_KEYGEN;
+  ELEMENT_NAMES[213] = ELT_LAMBDA;
+  ELEMENT_NAMES[214] = ELT_LEGEND;
+  ELEMENT_NAMES[215] = ELT_MSPACE;
+  ELEMENT_NAMES[216] = ELT_MTABLE;
+  ELEMENT_NAMES[217] = ELT_MSTYLE;
+  ELEMENT_NAMES[218] = ELT_MGLYPH;
+  ELEMENT_NAMES[219] = ELT_MEDIAN;
+  ELEMENT_NAMES[220] = ELT_MUNDER;
+  ELEMENT_NAMES[221] = ELT_MARKER;
+  ELEMENT_NAMES[222] = ELT_MERROR;
+  ELEMENT_NAMES[223] = ELT_MOMENT;
+  ELEMENT_NAMES[224] = ELT_MATRIX;
+  ELEMENT_NAMES[225] = ELT_OPTION;
+  ELEMENT_NAMES[226] = ELT_OBJECT;
+  ELEMENT_NAMES[227] = ELT_OUTPUT;
+  ELEMENT_NAMES[228] = ELT_PRIMES;
+  ELEMENT_NAMES[229] = ELT_SOURCE;
+  ELEMENT_NAMES[230] = ELT_STRIKE;
+  ELEMENT_NAMES[231] = ELT_STRONG;
+  ELEMENT_NAMES[232] = ELT_SWITCH;
+  ELEMENT_NAMES[233] = ELT_SYMBOL;
+  ELEMENT_NAMES[234] = ELT_SELECT;
+  ELEMENT_NAMES[235] = ELT_SUBSET;
+  ELEMENT_NAMES[236] = ELT_SCRIPT;
+  ELEMENT_NAMES[237] = ELT_TBREAK;
+  ELEMENT_NAMES[238] = ELT_VECTOR;
+  ELEMENT_NAMES[239] = ELT_ARTICLE;
+  ELEMENT_NAMES[240] = ELT_ANIMATE;
+  ELEMENT_NAMES[241] = ELT_ARCSECH;
+  ELEMENT_NAMES[242] = ELT_ARCCSCH;
+  ELEMENT_NAMES[243] = ELT_ARCTANH;
+  ELEMENT_NAMES[244] = ELT_ARCSINH;
+  ELEMENT_NAMES[245] = ELT_ARCCOSH;
+  ELEMENT_NAMES[246] = ELT_ARCCOTH;
+  ELEMENT_NAMES[247] = ELT_ACRONYM;
+  ELEMENT_NAMES[248] = ELT_ADDRESS;
+  ELEMENT_NAMES[249] = ELT_BGSOUND;
+  ELEMENT_NAMES[250] = ELT_COMMAND;
+  ELEMENT_NAMES[251] = ELT_COMPOSE;
+  ELEMENT_NAMES[252] = ELT_CEILING;
+  ELEMENT_NAMES[253] = ELT_CSYMBOL;
+  ELEMENT_NAMES[254] = ELT_CAPTION;
+  ELEMENT_NAMES[255] = ELT_DISCARD;
+  ELEMENT_NAMES[256] = ELT_DECLARE;
+  ELEMENT_NAMES[257] = ELT_DETAILS;
+  ELEMENT_NAMES[258] = ELT_ELLIPSE;
+  ELEMENT_NAMES[259] = ELT_FEFUNCA;
+  ELEMENT_NAMES[260] = ELT_FEFUNCB;
+  ELEMENT_NAMES[261] = ELT_FEBLEND;
+  ELEMENT_NAMES[262] = ELT_FEFLOOD;
+  ELEMENT_NAMES[263] = ELT_FEIMAGE;
+  ELEMENT_NAMES[264] = ELT_FEMERGE;
+  ELEMENT_NAMES[265] = ELT_FEFUNCG;
+  ELEMENT_NAMES[266] = ELT_FEFUNCR;
+  ELEMENT_NAMES[267] = ELT_HANDLER;
+  ELEMENT_NAMES[268] = ELT_INVERSE;
+  ELEMENT_NAMES[269] = ELT_IMPLIES;
+  ELEMENT_NAMES[270] = ELT_ISINDEX;
+  ELEMENT_NAMES[271] = ELT_LOGBASE;
+  ELEMENT_NAMES[272] = ELT_LISTING;
+  ELEMENT_NAMES[273] = ELT_MFENCED;
+  ELEMENT_NAMES[274] = ELT_MPADDED;
+  ELEMENT_NAMES[275] = ELT_MARQUEE;
+  ELEMENT_NAMES[276] = ELT_MACTION;
+  ELEMENT_NAMES[277] = ELT_MSUBSUP;
+  ELEMENT_NAMES[278] = ELT_NOEMBED;
+  ELEMENT_NAMES[279] = ELT_POLYGON;
+  ELEMENT_NAMES[280] = ELT_PATTERN;
+  ELEMENT_NAMES[281] = ELT_PRODUCT;
+  ELEMENT_NAMES[282] = ELT_SETDIFF;
+  ELEMENT_NAMES[283] = ELT_SECTION;
+  ELEMENT_NAMES[284] = ELT_SUMMARY;
+  ELEMENT_NAMES[285] = ELT_TENDSTO;
+  ELEMENT_NAMES[286] = ELT_UPLIMIT;
+  ELEMENT_NAMES[287] = ELT_ALTGLYPH;
+  ELEMENT_NAMES[288] = ELT_BASEFONT;
+  ELEMENT_NAMES[289] = ELT_CLIPPATH;
+  ELEMENT_NAMES[290] = ELT_CODOMAIN;
+  ELEMENT_NAMES[291] = ELT_COLGROUP;
+  ELEMENT_NAMES[292] = ELT_EMPTYSET;
+  ELEMENT_NAMES[293] = ELT_FACTOROF;
+  ELEMENT_NAMES[294] = ELT_FIELDSET;
+  ELEMENT_NAMES[295] = ELT_FRAMESET;
+  ELEMENT_NAMES[296] = ELT_FEOFFSET;
+  ELEMENT_NAMES[297] = ELT_GLYPHREF;
+  ELEMENT_NAMES[298] = ELT_INTERVAL;
+  ELEMENT_NAMES[299] = ELT_INTEGERS;
+  ELEMENT_NAMES[300] = ELT_INFINITY;
+  ELEMENT_NAMES[301] = ELT_LISTENER;
+  ELEMENT_NAMES[302] = ELT_LOWLIMIT;
+  ELEMENT_NAMES[303] = ELT_METADATA;
+  ELEMENT_NAMES[304] = ELT_MENCLOSE;
+  ELEMENT_NAMES[305] = ELT_MENUITEM;
+  ELEMENT_NAMES[306] = ELT_MPHANTOM;
+  ELEMENT_NAMES[307] = ELT_NOFRAMES;
+  ELEMENT_NAMES[308] = ELT_NOSCRIPT;
+  ELEMENT_NAMES[309] = ELT_OPTGROUP;
+  ELEMENT_NAMES[310] = ELT_POLYLINE;
+  ELEMENT_NAMES[311] = ELT_PREFETCH;
+  ELEMENT_NAMES[312] = ELT_PROGRESS;
+  ELEMENT_NAMES[313] = ELT_PRSUBSET;
+  ELEMENT_NAMES[314] = ELT_QUOTIENT;
+  ELEMENT_NAMES[315] = ELT_SELECTOR;
+  ELEMENT_NAMES[316] = ELT_TEXTAREA;
+  ELEMENT_NAMES[317] = ELT_TEXTPATH;
+  ELEMENT_NAMES[318] = ELT_VARIANCE;
+  ELEMENT_NAMES[319] = ELT_ANIMATION;
+  ELEMENT_NAMES[320] = ELT_CONJUGATE;
+  ELEMENT_NAMES[321] = ELT_CONDITION;
+  ELEMENT_NAMES[322] = ELT_COMPLEXES;
+  ELEMENT_NAMES[323] = ELT_FONT_FACE;
+  ELEMENT_NAMES[324] = ELT_FACTORIAL;
+  ELEMENT_NAMES[325] = ELT_INTERSECT;
+  ELEMENT_NAMES[326] = ELT_IMAGINARY;
+  ELEMENT_NAMES[327] = ELT_LAPLACIAN;
+  ELEMENT_NAMES[328] = ELT_MATRIXROW;
+  ELEMENT_NAMES[329] = ELT_NOTSUBSET;
+  ELEMENT_NAMES[330] = ELT_OTHERWISE;
+  ELEMENT_NAMES[331] = ELT_PIECEWISE;
+  ELEMENT_NAMES[332] = ELT_PLAINTEXT;
+  ELEMENT_NAMES[333] = ELT_RATIONALS;
+  ELEMENT_NAMES[334] = ELT_SEMANTICS;
+  ELEMENT_NAMES[335] = ELT_TRANSPOSE;
+  ELEMENT_NAMES[336] = ELT_ANNOTATION;
+  ELEMENT_NAMES[337] = ELT_BLOCKQUOTE;
+  ELEMENT_NAMES[338] = ELT_DIVERGENCE;
+  ELEMENT_NAMES[339] = ELT_EULERGAMMA;
+  ELEMENT_NAMES[340] = ELT_EQUIVALENT;
+  ELEMENT_NAMES[341] = ELT_FIGCAPTION;
+  ELEMENT_NAMES[342] = ELT_IMAGINARYI;
+  ELEMENT_NAMES[343] = ELT_MALIGNMARK;
+  ELEMENT_NAMES[344] = ELT_MUNDEROVER;
+  ELEMENT_NAMES[345] = ELT_MLABELEDTR;
+  ELEMENT_NAMES[346] = ELT_NOTANUMBER;
+  ELEMENT_NAMES[347] = ELT_SOLIDCOLOR;
+  ELEMENT_NAMES[348] = ELT_ALTGLYPHDEF;
+  ELEMENT_NAMES[349] = ELT_DETERMINANT;
+  ELEMENT_NAMES[350] = ELT_FEMERGENODE;
+  ELEMENT_NAMES[351] = ELT_FECOMPOSITE;
+  ELEMENT_NAMES[352] = ELT_FESPOTLIGHT;
+  ELEMENT_NAMES[353] = ELT_MALIGNGROUP;
+  ELEMENT_NAMES[354] = ELT_MPRESCRIPTS;
+  ELEMENT_NAMES[355] = ELT_MOMENTABOUT;
+  ELEMENT_NAMES[356] = ELT_NOTPRSUBSET;
+  ELEMENT_NAMES[357] = ELT_PARTIALDIFF;
+  ELEMENT_NAMES[358] = ELT_ALTGLYPHITEM;
+  ELEMENT_NAMES[359] = ELT_ANIMATECOLOR;
+  ELEMENT_NAMES[360] = ELT_DATATEMPLATE;
+  ELEMENT_NAMES[361] = ELT_EXPONENTIALE;
+  ELEMENT_NAMES[362] = ELT_FETURBULENCE;
+  ELEMENT_NAMES[363] = ELT_FEPOINTLIGHT;
+  ELEMENT_NAMES[364] = ELT_FEMORPHOLOGY;
+  ELEMENT_NAMES[365] = ELT_OUTERPRODUCT;
+  ELEMENT_NAMES[366] = ELT_ANIMATEMOTION;
+  ELEMENT_NAMES[367] = ELT_COLOR_PROFILE;
+  ELEMENT_NAMES[368] = ELT_FONT_FACE_SRC;
+  ELEMENT_NAMES[369] = ELT_FONT_FACE_URI;
+  ELEMENT_NAMES[370] = ELT_FOREIGNOBJECT;
+  ELEMENT_NAMES[371] = ELT_FECOLORMATRIX;
+  ELEMENT_NAMES[372] = ELT_MISSING_GLYPH;
+  ELEMENT_NAMES[373] = ELT_MMULTISCRIPTS;
+  ELEMENT_NAMES[374] = ELT_SCALARPRODUCT;
+  ELEMENT_NAMES[375] = ELT_VECTORPRODUCT;
+  ELEMENT_NAMES[376] = ELT_ANNOTATION_XML;
+  ELEMENT_NAMES[377] = ELT_DEFINITION_SRC;
+  ELEMENT_NAMES[378] = ELT_FONT_FACE_NAME;
+  ELEMENT_NAMES[379] = ELT_FEGAUSSIANBLUR;
+  ELEMENT_NAMES[380] = ELT_FEDISTANTLIGHT;
+  ELEMENT_NAMES[381] = ELT_LINEARGRADIENT;
+  ELEMENT_NAMES[382] = ELT_NATURALNUMBERS;
+  ELEMENT_NAMES[383] = ELT_RADIALGRADIENT;
+  ELEMENT_NAMES[384] = ELT_ANIMATETRANSFORM;
+  ELEMENT_NAMES[385] = ELT_CARTESIANPRODUCT;
+  ELEMENT_NAMES[386] = ELT_FONT_FACE_FORMAT;
+  ELEMENT_NAMES[387] = ELT_FECONVOLVEMATRIX;
+  ELEMENT_NAMES[388] = ELT_FEDIFFUSELIGHTING;
+  ELEMENT_NAMES[389] = ELT_FEDISPLACEMENTMAP;
+  ELEMENT_NAMES[390] = ELT_FESPECULARLIGHTING;
+  ELEMENT_NAMES[391] = ELT_DOMAINOFAPPLICATION;
+  ELEMENT_NAMES[392] = ELT_FECOMPONENTTRANSFER;
 }
 
 void
 nsHtml5ElementName::releaseStatics()
 {
   delete ELT_NULL_ELEMENT_NAME;
   delete ELT_A;
   delete ELT_B;
@@ -1439,16 +1442,17 @@ nsHtml5ElementName::releaseStatics()
   delete ELT_LIST;
   delete ELT_META;
   delete ELT_MSUB;
   delete ELT_MODE;
   delete ELT_MATH;
   delete ELT_MARK;
   delete ELT_MASK;
   delete ELT_MEAN;
+  delete ELT_MAIN;
   delete ELT_MSUP;
   delete ELT_MENU;
   delete ELT_MROW;
   delete ELT_NONE;
   delete ELT_NOBR;
   delete ELT_NEST;
   delete ELT_PATH;
   delete ELT_PLUS;
--- a/parser/html/nsHtml5ElementName.h
+++ b/parser/html/nsHtml5ElementName.h
@@ -193,16 +193,17 @@ class nsHtml5ElementName
     static nsHtml5ElementName* ELT_LIST;
     static nsHtml5ElementName* ELT_META;
     static nsHtml5ElementName* ELT_MSUB;
     static nsHtml5ElementName* ELT_MODE;
     static nsHtml5ElementName* ELT_MATH;
     static nsHtml5ElementName* ELT_MARK;
     static nsHtml5ElementName* ELT_MASK;
     static nsHtml5ElementName* ELT_MEAN;
+    static nsHtml5ElementName* ELT_MAIN;
     static nsHtml5ElementName* ELT_MSUP;
     static nsHtml5ElementName* ELT_MENU;
     static nsHtml5ElementName* ELT_MROW;
     static nsHtml5ElementName* ELT_NONE;
     static nsHtml5ElementName* ELT_NOBR;
     static nsHtml5ElementName* ELT_NEST;
     static nsHtml5ElementName* ELT_PATH;
     static nsHtml5ElementName* ELT_PLUS;
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -926,17 +926,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
               if (addAttributesToBody(attributes)) {
                 attributes = nullptr;
               }
               NS_HTML5_BREAK(starttagloop);
             }
             case NS_HTML5TREE_BUILDER_P:
             case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
             case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
-            case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY: {
+            case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: {
               implicitlyCloseP();
               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
               attributes = nullptr;
               NS_HTML5_BREAK(starttagloop);
             }
             case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
               implicitlyCloseP();
               if (stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
@@ -2330,17 +2330,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
             mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
             continue;
           }
           case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
           case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
           case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
           case NS_HTML5TREE_BUILDER_FIELDSET:
           case NS_HTML5TREE_BUILDER_BUTTON:
-          case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY: {
+          case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: {
             eltPos = findLastInScope(name);
             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
               errStrayEndTag(name);
             } else {
               generateImpliedEndTags();
               if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
                 errUnclosedElements(eltPos, name);
               }
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -298,17 +298,17 @@ class nsHtml5TreeBuilder : public nsAHtm
 #define NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET 43
 #define NS_HTML5TREE_BUILDER_PRE_OR_LISTING 44
 #define NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U 45
 #define NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL 46
 #define NS_HTML5TREE_BUILDER_IFRAME 47
 #define NS_HTML5TREE_BUILDER_EMBED_OR_IMG 48
 #define NS_HTML5TREE_BUILDER_AREA_OR_WBR 49
 #define NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU 50
-#define NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY 51
+#define NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY 51
 #define NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR 52
 #define NS_HTML5TREE_BUILDER_RT_OR_RP 53
 #define NS_HTML5TREE_BUILDER_COMMAND 54
 #define NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK 55
 #define NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK 56
 #define NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT 57
 #define NS_HTML5TREE_BUILDER_ANNOTATION_XML 58
 #define NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC 59
--- a/parser/htmlparser/public/nsHTMLTagList.h
+++ b/parser/htmlparser/public/nsHTMLTagList.h
@@ -101,16 +101,17 @@ HTML_TAG(input, Input)
 HTML_TAG(ins, Mod)
 HTML_HTMLELEMENT_TAG(kbd)
 HTML_TAG(keygen, Span)
 HTML_TAG(label, Label)
 HTML_TAG(legend, Legend)
 HTML_TAG(li, LI)
 HTML_TAG(link, Link)
 HTML_HTMLELEMENT_TAG(listing)
+HTML_HTMLELEMENT_TAG(main)
 HTML_TAG(map, Map)
 HTML_HTMLELEMENT_TAG(mark)
 HTML_TAG(marquee, Div)
 HTML_TAG(menu, Menu)
 HTML_TAG(menuitem, MenuItem)
 HTML_TAG(meta, Meta)
 HTML_TAG(meter, Meter)
 HTML_TAG(multicol, Span)
--- a/parser/htmlparser/src/nsElementTable.cpp
+++ b/parser/htmlparser/src/nsElementTable.cpp
@@ -782,16 +782,25 @@ const nsHTMLElement gHTMLElements[] = {
     /*req-parent excl-parent*/          eHTMLTag_unknown,eHTMLTag_unknown,
     /*rootnodes,endrootnodes*/          &gRootTags,&gRootTags,
     /*autoclose starttags and endtags*/ 0,0,0,0,
     /*parent,incl,exclgroups*/          kPreformatted, (kSelf|kFlowEntity), kNone,  //add flowentity to fix 54993
     /*special props, prop-range*/       0,kDefaultPropRange,
     /*special parents,kids*/            0,0,
   },
   {
+    /*tag*/                             eHTMLTag_main,
+    /*req-parent excl-parent*/          eHTMLTag_unknown,eHTMLTag_unknown,
+    /*rootnodes,endrootnodes*/          &gRootTags,&gRootTags,
+    /*autoclose starttags and endtags*/ 0,0,0,0,
+    /*parent,incl,exclgroups*/          kBlock, (kSelf|kFlowEntity), kNone,
+    /*special props, prop-range*/       0,kDefaultPropRange,
+    /*special parents,kids*/            0,0,
+  },
+  {
     /*tag*/                             eHTMLTag_map,
     /*req-parent excl-parent*/          eHTMLTag_unknown,eHTMLTag_unknown,
     /*rootnodes,endrootnodes*/          &gRootTags,&gRootTags,
     /*autoclose starttags and endtags*/ 0,0,0,0,
     /*parent,incl,exclgroups*/          kSpecial, kInlineEntity|kBlockEntity, kNone,
     /*special props, prop-range*/       0, kDefaultPropRange,
     /*special parents,kids*/            0,&gMapKids,
   },
--- a/parser/htmlparser/src/nsHTMLTags.cpp
+++ b/parser/htmlparser/src/nsHTMLTags.cpp
@@ -156,16 +156,18 @@ static const PRUnichar sHTMLTagUnicodeNa
 static const PRUnichar sHTMLTagUnicodeName_legend[] =
   {'l', 'e', 'g', 'e', 'n', 'd', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_li[] =
   {'l', 'i', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_link[] =
   {'l', 'i', 'n', 'k', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_listing[] =
   {'l', 'i', 's', 't', 'i', 'n', 'g', '\0'};
+static const PRUnichar sHTMLTagUnicodeName_main[] =
+  {'m', 'a', 'i', 'n', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_map[] =
   {'m', 'a', 'p', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_mark[] =
   {'m', 'a', 'r', 'k', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_marquee[] =
   {'m', 'a', 'r', 'q', 'u', 'e', 'e', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_menu[] =
   {'m', 'e', 'n', 'u', '\0'};
--- a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile.in
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile.in
@@ -54,11 +54,12 @@ MOCHITEST_FILES =	adoption01.dat \
 		tests6.dat \
 		tests7.dat \
 		tests8.dat \
 		tests9.dat \
 		tests_innerHTML_1.dat \
 		tricky01.dat \
 		webkit01.dat \
 		webkit02.dat \
+		main-element.dat \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/main-element.dat
@@ -0,0 +1,29 @@
+#data
+<!doctype html><p>foo<main>bar<p>baz
+#errors
+36: End of file seen and there were open elements.
+27: Unclosed element “main”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       "foo"
+|     <main>
+|       "bar"
+|       <p>
+|         "baz"
+
+#data
+<!doctype html><main><p>foo</main>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <main>
+|       <p>
+|         "foo"
+|     "bar"
--- a/parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html
+++ b/parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html
@@ -30,17 +30,18 @@ https://bugzilla.mozilla.org/show_bug.cg
                          "tests4.dat",
                          "tests5.dat",
                          "tests6.dat",
                          "tests8.dat",
                          "tests9.dat",
                          "tests_innerHTML_1.dat",
                          "tricky01.dat",
                          "webkit01.dat",
-                         "webkit02.dat"];
+                         "webkit02.dat",
+                         "main-element.dat"];
     const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
     const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
     if (!isOSXLion && !isOSXMtnLion) {
       parserDatFiles.push("tests19.dat");
       parserDatFiles.push("tests7.dat");
     }
 
   </script>
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug820508-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<title>main { display: block; }</title>
+<style>div {
+  border: 2px solid blue;
+}</style>
+<div>foo</div><div>bar</div>
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug820508-1.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<title>main { display: block; }</title>
+<style>main {
+  border: 2px solid blue;
+}</style>
+<main>foo</main><main>bar</main>
--- a/parser/htmlparser/tests/reftest/reftest.list
+++ b/parser/htmlparser/tests/reftest/reftest.list
@@ -16,8 +16,9 @@ fuzzy-if(/^Windows\x20NT\x206\.1/.test(h
 == bug659763-5.html bug659763-5-ref.html
 == bug659763-6.html bug659763-6-ref.html
 skip-if(B2G) == view-source:bug673094-1.html view-source:bug673094-1-ref.html
 == bug696651-1.html bug696651-1-ref.html
 skip-if(B2G) == bug696651-2.html bug696651-2-ref.html
 == view-source:bug700260-1.html view-source:bug700260-1-ref.html
 == view-source:bug704667-1.html bug704667-1-ref.html
 == view-source:bug731234-1.html bug731234-1-ref.html
+== bug820508-1.html bug820508-1-ref.html
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -453,51 +453,54 @@ class Marionette(object):
                     unwrapped = HTMLElement(self, value[key])
                 else:
                     unwrapped[key] = self.unwrapValue(value[key])
         else:
             unwrapped = value
 
         return unwrapped
 
-    def execute_js_script(self, script, script_args=None, async=True, new_sandbox=True, special_powers=False):
+    def execute_js_script(self, script, script_args=None, async=True, new_sandbox=True, special_powers=False, script_timeout=None):
         if script_args is None:
             script_args = []
         args = self.wrapArguments(script_args)
         response = self._send_message('executeJSScript',
                                       'value',
                                       value=script,
                                       args=args,
                                       async=async,
                                       newSandbox=new_sandbox,
-                                      specialPowers=special_powers)
+                                      specialPowers=special_powers, 
+                                      scriptTimeout=script_timeout)
         return self.unwrapValue(response)
 
-    def execute_script(self, script, script_args=None, new_sandbox=True, special_powers=False):
+    def execute_script(self, script, script_args=None, new_sandbox=True, special_powers=False, script_timeout=None):
         if script_args is None:
             script_args = []
         args = self.wrapArguments(script_args)
         response = self._send_message('executeScript',
                                      'value',
                                       value=script,
                                       args=args,
                                       newSandbox=new_sandbox,
-                                      specialPowers=special_powers)
+                                      specialPowers=special_powers,
+                                      scriptTimeout=script_timeout)
         return self.unwrapValue(response)
 
-    def execute_async_script(self, script, script_args=None, new_sandbox=True, special_powers=False):
+    def execute_async_script(self, script, script_args=None, new_sandbox=True, special_powers=False, script_timeout=None):
         if script_args is None:
             script_args = []
         args = self.wrapArguments(script_args)
         response = self._send_message('executeAsyncScript',
                                       'value',
                                       value=script,
                                       args=args,
                                       newSandbox=new_sandbox,
-                                      specialPowers=special_powers)
+                                      specialPowers=special_powers,
+                                      scriptTimeout=script_timeout)
         return self.unwrapValue(response)
 
     def find_element(self, method, target, id=None):
         kwargs = { 'value': target, 'using': method }
         if id:
             kwargs['element'] = id
         response = self._send_message('findElement', 'value', **kwargs)
         element = HTMLElement(self, response)
--- a/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py
+++ b/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py
@@ -1,37 +1,40 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from marionette_test import MarionetteTestCase, skip_if_b2g
+from marionette_test import MarionetteTestCase
 from errors import JavascriptException, MarionetteException, ScriptTimeoutException
 
 class TestExecuteAsyncContent(MarionetteTestCase):
     def setUp(self):
         super(TestExecuteAsyncContent, self).setUp()
         self.marionette.set_script_timeout(1000)
 
     def test_execute_async_simple(self):
         self.assertEqual(1, self.marionette.execute_async_script("arguments[arguments.length-1](1);"))
 
     def test_execute_async_ours(self):
         self.assertEqual(1, self.marionette.execute_async_script("marionetteScriptFinished(1);"))
 
     def test_execute_async_timeout(self):
         self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "var x = 1;")
 
+    def test_execute_async_unique_timeout(self):
+        self.assertEqual(2, self.marionette.execute_async_script("setTimeout(function() {marionetteScriptFinished(2);}, 2000);", script_timeout=5000))
+        self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "setTimeout(function() {marionetteScriptFinished(3);}, 2000);")
+
     def test_no_timeout(self):
         self.marionette.set_script_timeout(10000)
         self.assertTrue(self.marionette.execute_async_script("""
             var callback = arguments[arguments.length - 1];
             setTimeout(function() { callback(true); }, 500);
             """))
 
-    @skip_if_b2g
     def test_execute_async_unload(self):
         self.marionette.set_script_timeout(5000)
         unload = """
                 window.location.href = "about:blank";
                  """
         self.assertRaises(JavascriptException, self.marionette.execute_async_script, unload)
 
     def test_check_window(self):
@@ -64,17 +67,17 @@ class TestExecuteAsyncContent(Marionette
         self.assertTrue(self.marionette.execute_async_script("""
             marionetteScriptFinished(true);
             """))
 
     def test_execute_permission(self):
         self.assertRaises(JavascriptException, self.marionette.execute_async_script, """
 let prefs = Components.classes["@mozilla.org/preferences-service;1"]
                               .getService(Components.interfaces.nsIPrefBranch);
-marionetteScriptFinished(1);
+marionetteScriptFinished(4);
 """)
 
     def test_sandbox_reuse(self):
         # Sandboxes between `execute_script()` invocations are shared.
         self.marionette.execute_async_script("this.foobar = [23, 42];"
                                              "marionetteScriptFinished();")
         self.assertEqual(self.marionette.execute_async_script(
             "marionetteScriptFinished(this.foobar);", new_sandbox=False), [23, 42])
@@ -92,16 +95,15 @@ class TestExecuteAsyncChrome(TestExecute
 
     def test_execute_async_unload(self):
         pass
 
     def test_same_context(self):
         pass
 
     def test_execute_permission(self):
-        self.assertEqual(1, self.marionette.execute_async_script("""
+        self.assertEqual(5, self.marionette.execute_async_script("""
 var c = Components.classes;
-marionetteScriptFinished(1);
+marionetteScriptFinished(5);
 """))
 
     def test_sandbox_reuse(self):
         pass
-
--- a/testing/marionette/marionette-actors.js
+++ b/testing/marionette/marionette-actors.js
@@ -670,20 +670,20 @@ MarionetteDriverActor.prototype = {
    * @param boolean directInject
    *        If true, then the script will be run as is,
    *        and not as a function body (as you would
    *        do using the WebDriver spec)
    * @param boolean async
    *        True if the script is asynchronous
    */
   executeScriptInSandbox: function MDA_executeScriptInSandbox(sandbox, script,
-     directInject, async, command_id) {
+     directInject, async, command_id, timeout) {
 
     if (directInject && async &&
-        (this.scriptTimeout == null || this.scriptTimeout == 0)) {
+        (timeout == null || timeout == 0)) {
       this.sendError("Please set a timeout", 21, null, command_id);
       return;
     }
 
     if (this.importedScripts.exists()) {
       let stream = Cc["@mozilla.org/network/file-input-stream;1"].  
                     createInstance(Ci.nsIFileInputStream);
       stream.init(this.importedScripts, -1, 0, 0);
@@ -712,37 +712,38 @@ MarionetteDriverActor.prototype = {
    * @param object aRequest
    *        'value' member is the script to run
    *        'args' member holds the arguments to the script
    * @param boolean directInject
    *        if true, it will be run directly and not as a 
    *        function body
    */
   execute: function MDA_execute(aRequest, directInject) {
+    let timeout = aRequest.scriptTimeout ? aRequest.scriptTimeout : this.scriptTimeout;
     let command_id = this.command_id = this.getCommandId();
     this.logRequest("execute", aRequest);
     if (aRequest.newSandbox == undefined) {
       //if client does not send a value in newSandbox, 
       //then they expect the same behaviour as webdriver
       aRequest.newSandbox = true;
     }
     if (this.context == "content") {
       this.sendAsync("executeScript", {value: aRequest.value,
                                        args: aRequest.args,
                                        newSandbox: aRequest.newSandbox,
-                                       timeout: this.scriptTimeout,
+                                       timeout: timeout,
                                        command_id: command_id,
                                        specialPowers: aRequest.specialPowers});
       return;
     }
 
     let curWindow = this.getCurrentWindow();
     let marionette = new Marionette(this, curWindow, "chrome",
                                     this.marionetteLog, this.marionettePerf,
-                                    this.scriptTimeout, this.testName);
+                                    timeout, this.testName);
     let _chromeSandbox = this.createExecuteSandbox(curWindow,
                                                    marionette,
                                                    aRequest.args,
                                                    aRequest.specialPowers);
     if (!_chromeSandbox)
       return;
 
     try {
@@ -756,17 +757,17 @@ MarionetteDriverActor.prototype = {
       }
       else {
         script = "let func = function() {" +
                        aRequest.value + 
                      "};" +
                      "func.apply(null, __marionetteParams);";
       }
       this.executeScriptInSandbox(_chromeSandbox, script, directInject,
-                                  false, command_id);
+                                  false, command_id, timeout);
     }
     catch (e) {
       this.sendError(e.name + ': ' + e.message, 17, e.stack, command_id);
     }
   },
 
   /**
    * Set the timeout for asynchronous script execution
@@ -790,16 +791,17 @@ MarionetteDriverActor.prototype = {
    * execute pure JS script. Used to execute 'mochitest'-style Marionette tests.
    *
    * @param object aRequest
    *        'value' member holds the script to execute
    *        'args' member holds the arguments to the script
    *        'timeout' member will be used as the script timeout if it is given
    */
   executeJSScript: function MDA_executeJSScript(aRequest) {
+    let timeout = aRequest.scriptTimeout ? aRequest.scriptTimeout : this.scriptTimeout;
     let command_id = this.command_id = this.getCommandId();
     //all pure JS scripts will need to call Marionette.finish() to complete the test.
     if (aRequest.newSandbox == undefined) {
       //if client does not send a value in newSandbox, 
       //then they expect the same behaviour as webdriver
       aRequest.newSandbox = true;
     }
     if (this.context == "chrome") {
@@ -810,17 +812,17 @@ MarionetteDriverActor.prototype = {
         this.execute(aRequest, true);
       }
     }
     else {
       this.sendAsync("executeJSScript", { value: aRequest.value,
                                           args: aRequest.args,
                                           newSandbox: aRequest.newSandbox,
                                           async: aRequest.async,
-                                          timeout: this.scriptTimeout,
+                                          timeout: timeout,
                                           command_id: command_id,
                                           specialPowers: aRequest.specialPowers });
    }
   },
 
   /**
    * This function is used by executeAsync and executeJSScript to execute a script
    * in a sandbox. 
@@ -832,40 +834,42 @@ MarionetteDriverActor.prototype = {
    * @param object aRequest
    *        'value' member holds the script to execute
    *        'args' member holds the arguments for the script
    * @param boolean directInject
    *        if true, it will be run directly and not as a 
    *        function body
    */
   executeWithCallback: function MDA_executeWithCallback(aRequest, directInject) {
+    let timeout = aRequest.scriptTimeout ? aRequest.scriptTimeout : this.scriptTimeout;
     let command_id = this.command_id = this.getCommandId();
     if (aRequest.newSandbox == undefined) {
       //if client does not send a value in newSandbox, 
       //then they expect the same behaviour as webdriver
       aRequest.newSandbox = true;
     }
 
     if (this.context == "content") {
       this.sendAsync("executeAsyncScript", {value: aRequest.value,
                                             args: aRequest.args,
                                             id: this.command_id,
                                             newSandbox: aRequest.newSandbox,
-                                            timeout: this.scriptTimeout,
+                                            timeout: timeout,
                                             command_id: command_id,
                                             specialPowers: aRequest.specialPowers});
       return;
     }
 
     let curWindow = this.getCurrentWindow();
     let original_onerror = curWindow.onerror;
     let that = this;
+    that.timeout = timeout;
     let marionette = new Marionette(this, curWindow, "chrome",
                                     this.marionetteLog, this.marionettePerf,
-                                    this.scriptTimeout, this.testName);
+                                    timeout, this.testName);
     marionette.command_id = this.command_id;
 
     function chromeAsyncReturnFunc(value, status) {
       if (that._emu_cbs && Object.keys(that._emu_cbs).length) {
         value = "Emulator callback still pending when finish() called";
         status = 500;
         that._emu_cbs = null;
       }
@@ -906,17 +910,17 @@ MarionetteDriverActor.prototype = {
       return;
 
     try {
 
       this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
       if (this.timer != null) {
         this.timer.initWithCallback(function() {
           chromeAsyncReturnFunc("timed out", 28);
-        }, that.scriptTimeout, Ci.nsITimer.TYPE_ONESHOT);
+        }, that.timeout, Ci.nsITimer.TYPE_ONESHOT);
       }
 
       _chromeSandbox.returnFunc = chromeAsyncReturnFunc;
       _chromeSandbox.finish = chromeAsyncFinish;
 
       let script;
       if (directInject) {
         script = aRequest.value;
@@ -924,17 +928,17 @@ MarionetteDriverActor.prototype = {
       else {
         script =  '__marionetteParams.push(returnFunc);'
                 + 'let marionetteScriptFinished = returnFunc;'
                 + 'let __marionetteFunc = function() {' + aRequest.value + '};'
                 + '__marionetteFunc.apply(null, __marionetteParams);';
       }
 
       this.executeScriptInSandbox(_chromeSandbox, script, directInject,
-                                  true, command_id);
+                                  true, command_id, timeout);
     } catch (e) {
       chromeAsyncReturnFunc(e.name + ": " + e.message, 17);
     }
   },
 
   /**
    * Navigates to given url
    *
--- a/testing/xpcshell/xpcshell.ini
+++ b/testing/xpcshell/xpcshell.ini
@@ -44,16 +44,17 @@ skip-if = os == "android"
 [include:toolkit/components/places/tests/unit/xpcshell.ini]
 [include:toolkit/components/places/tests/network/xpcshell.ini]
 [include:toolkit/components/urlformatter/tests/unit/xpcshell.ini]
 [include:toolkit/components/ctypes/tests/unit/xpcshell.ini]
 [include:toolkit/components/autocomplete/tests/unit/xpcshell.ini]
 [include:toolkit/components/satchel/test/unit/xpcshell.ini]
 [include:toolkit/components/downloads/test/unit/xpcshell.ini]
 [include:toolkit/components/downloads/test/schema_migration/xpcshell.ini]
+[include:toolkit/components/jsdownloads/test/unit/xpcshell.ini]
 [include:toolkit/components/startup/tests/unit/xpcshell.ini]
 [include:toolkit/components/telemetry/tests/unit/xpcshell.ini]
 [include:toolkit/components/social/test/xpcshell/xpcshell.ini]
 [include:toolkit/components/mediasniffer/test/unit/xpcshell.ini]
 [include:toolkit/forgetaboutsite/test/unit/xpcshell.ini]
 [include:toolkit/content/tests/unit/xpcshell.ini]
 [include:toolkit/identity/tests/unit/xpcshell.ini]
 [include:toolkit/modules/tests/xpcshell/xpcshell.ini]
--- a/toolkit/components/Makefile.in
+++ b/toolkit/components/Makefile.in
@@ -57,16 +57,20 @@ endif
 ifdef MOZ_FEEDS
 PARALLEL_DIRS += feeds
 endif
 
 ifdef MOZ_HELP_VIEWER
 PARALLEL_DIRS += help
 endif
 
+ifdef MOZ_JSDOWNLOADS
+PARALLEL_DIRS += jsdownloads
+endif
+
 ifdef NS_PRINTING
 PARALLEL_DIRS += printing
 endif
 
 ifdef MOZ_XUL
 PARALLEL_DIRS += \
   autocomplete \
   satchel \
new file mode 100644
--- /dev/null
+++ b/toolkit/components/jsdownloads/Makefile.in
@@ -0,0 +1,16 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH     = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = src
+
+TEST_DIRS += test
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * This file includes the following constructors and global objects:
+ *
+ * Download
+ * Represents a single download, with associated state and actions.  This object
+ * is transient, though it can be included in a DownloadList so that it can be
+ * managed by the user interface and persisted across sessions.
+ *
+ * DownloadSource
+ * Represents the source of a download, for example a document or an URI.
+ *
+ * DownloadTarget
+ * Represents the target of a download, for example a file in the global
+ * downloads directory, or a file in the system temporary directory.
+ *
+ * DownloadSaver
+ * Template for an object that actually transfers the data for the download.
+ *
+ * DownloadCopySaver
+ * Saver object that simply copies the entire source file to the target.
+ */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = [
+  "Download",
+  "DownloadSource",
+  "DownloadTarget",
+  "DownloadSaver",
+  "DownloadCopySaver",
+];
+
+////////////////////////////////////////////////////////////////////////////////
+//// Globals
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
+                                  "resource://gre/modules/NetUtil.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Promise",
+                                  "resource://gre/modules/commonjs/promise/core.js");
+XPCOMUtils.defineLazyModuleGetter(this, "Task",
+                                  "resource://gre/modules/Task.jsm");
+
+const BackgroundFileSaverStreamListener = Components.Constructor(
+      "@mozilla.org/network/background-file-saver;1?mode=streamlistener",
+      "nsIBackgroundFileSaver");
+
+////////////////////////////////////////////////////////////////////////////////
+//// Download
+
+/**
+ * Represents a single download, with associated state and actions.  This object
+ * is transient, though it can be included in a DownloadList so that it can be
+ * managed by the user interface and persisted across sessions.
+ */
+function Download()
+{
+  this._deferDone = Promise.defer();
+}
+
+Download.prototype = {
+  /**
+   * DownloadSource object associated with this download.
+   */
+  source: null,
+
+  /**
+   * DownloadTarget object associated with this download.
+   */
+  target: null,
+
+  /**
+   * DownloadSaver object associated with this download.
+   */
+  saver: null,
+
+  /**
+   * Becomes true when the download has been completed successfully, failed, or
+   * has been canceled.  This property can become true, then it can be reset to
+   * false when a failed or canceled download is resumed.  This property remains
+   * false while the download is paused.
+   */
+  done: false,
+
+  /**
+   * Indicates whether this download's "progress" property is able to report
+   * partial progress while the download proceeds, and whether the value in
+   * totalBytes is relevant.  This depends on the saver and the download source.
+   */
+  hasProgress: false,
+
+  /**
+   * Progress percent, from 0 to 100.  Intermediate values are reported only if
+   * hasProgress is true.
+   *
+   * @note You shouldn't rely on this property being equal to 100 to determine
+   *       whether the download is completed.  You should use the individual
+   *       state properties instead.
+   */
+  progress: 0,
+
+  /**
+   * When hasProgress is true, indicates the total number of bytes to be
+   * transferred before the download finishes, that can be zero for empty files.
+   *
+   * When hasProgress is false, this property is always zero.
+   */
+  totalBytes: 0,
+
+  /**
+   * Number of bytes currently transferred.  This value starts at zero, and may
+   * be updated regardless of the value of hasProgress.
+   *
+   * @note You shouldn't rely on this property being equal to totalBytes to
+   *       determine whether the download is completed.  You should use the
+   *       individual state properties instead.
+   */
+  currentBytes: 0,
+
+  /**
+   * This can be set to a function that is called when other properties change.
+   */
+  onchange: null,
+
+  /**
+   * Raises the onchange notification.
+   */
+  _notifyChange: function D_notifyChange() {
+    try {
+      if (this.onchange) {
+        this.onchange();
+      }
+    } catch (ex) {
+      Cu.reportError(ex);
+    }
+  },
+
+  /**
+   * This deferred object is resolved when this download finishes successfully,
+   * and rejected if this download fails.
+   */
+  _deferDone: null,
+
+  /**
+   * Starts the download.
+   *
+   * @return {Promise}
+   * @resolves When the download has finished successfully.
+   * @rejects JavaScript exception if the download failed.
+   */
+  start: function D_start()
+  {
+    this._deferDone.resolve(Task.spawn(function task_D_start() {
+      try {
+        yield this.saver.execute();
+        this.progress = 100;
+      } finally {
+        this.done = true;
+        this._notifyChange();
+      }
+    }.bind(this)));
+
+    return this.whenDone();
+  },
+
+  /**
+   * Waits for the download to finish.
+   *
+   * @return {Promise}
+   * @resolves When the download has finished successfully.
+   * @rejects JavaScript exception if the download failed.
+   */
+  whenDone: function D_whenDone() {
+    return this._deferDone.promise;
+  },
+
+  /**
+   * Updates progress notifications based on the number of bytes transferred.
+   *
+   * @param aCurrentBytes
+   *        Number of bytes transferred until now.
+   * @param aTotalBytes
+   *        Total number of bytes to be transferred, or -1 if unknown.
+   */
+  _setBytes: function D_setBytes(aCurrentBytes, aTotalBytes) {
+    this.currentBytes = aCurrentBytes;
+    if (aTotalBytes != -1) {
+      this.hasProgress = true;
+      this.totalBytes = aTotalBytes;
+      if (aTotalBytes > 0) {
+        this.progress = Math.floor(aCurrentBytes / aTotalBytes * 100);
+      }
+    }
+    this._notifyChange();
+  },
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// DownloadSource
+
+/**
+ * Represents the source of a download, for example a document or an URI.
+ */
+function DownloadSource() { }
+
+DownloadSource.prototype = {
+  /**
+   * The nsIURI for the download source.
+   */
+  uri: null,
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// DownloadTarget
+
+/**
+ * Represents the target of a download, for example a file in the global
+ * downloads directory, or a file in the system temporary directory.
+ */
+function DownloadTarget() { }
+
+DownloadTarget.prototype = {
+  /**
+   * The nsIFile for the download target.
+   */
+  file: null,
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// DownloadSaver
+
+/**
+ * Template for an object that actually transfers the data for the download.
+ */
+function DownloadSaver() { }
+
+DownloadSaver.prototype = {
+  /**
+   * Download object for raising notifications and reading properties.
+   */
+  download: null,
+
+  /**
+   * Executes the download.
+   *
+   * @return {Promise}
+   * @resolves When the download has finished successfully.
+   * @rejects JavaScript exception if the download failed.
+   */
+  execute: function DS_execute()
+  {
+    throw new Error("Not implemented.");
+  }
+};