Merge inbound to mozilla-central r=merge a=merge
authorMargareta Eliza Balazs <ebalazs@mozilla.com>
Mon, 20 Nov 2017 11:40:32 +0200
changeset 437185 5c48b5edfc4ca945a2eaa5896454f3f4efa9052a
parent 437184 b828f7a6c2bf49b0d6d1161190b9b80f0ba78418 (current diff)
parent 437158 98646e193600531078091d7da9a64df32e008661 (diff)
child 437186 54749fccb7b69d014281861c454cf6cbe7978cf6
child 437216 4366a7680ac83cb7cf11ecf3f003cda6dd7402f6
child 437237 619507d38af9544df797105241bf7008b8a8ed55
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewersmerge, merge
milestone59.0a1
Merge inbound to mozilla-central r=merge a=merge
parser/htmlparser/nsIExtendedExpatSink.idl
--- a/dom/media/mediasource/SourceBufferResource.h
+++ b/dom/media/mediasource/SourceBufferResource.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 MOZILLA_SOURCEBUFFERRESOURCE_H_
 #define MOZILLA_SOURCEBUFFERRESOURCE_H_
 
+#include "mozilla/AbstractThread.h"
 #include "mozilla/Logging.h"
 #include "MediaResource.h"
 #include "nsIPrincipal.h"
 #include "ResourceQueue.h"
 
 #define UNIMPLEMENTED() { /* Logging this is too spammy to do by default */ }
 
 namespace mozilla {
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -4,16 +4,17 @@
  * 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 "TrackBuffersManager.h"
 #include "ContainerParser.h"
 #include "MediaPrefs.h"
 #include "MediaSourceDemuxer.h"
 #include "MediaSourceUtils.h"
+#include "mozilla/ErrorResult.h"
 #include "mozilla/Preferences.h"
 #include "SourceBuffer.h"
 #include "SourceBufferResource.h"
 #include "SourceBufferTask.h"
 #include "WebMDemuxer.h"
 
 #ifdef MOZ_FMP4
 #include "MP4Demuxer.h"
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -112,23 +112,18 @@ using namespace mozilla;
   }
 
 #endif // DEBUG
 
 //===========================================================================
 // The old low-level prefs API
 //===========================================================================
 
-struct PrefHashEntry;
-
 typedef nsTArray<nsCString> PrefSaveData;
 
-static PrefHashEntry*
-pref_HashTableLookup(const char* aKey);
-
 // 1 MB should be enough for everyone.
 static const uint32_t MAX_PREF_LENGTH = 1 * 1024 * 1024;
 // Actually, 4kb should be enough for everyone.
 static const uint32_t MAX_ADVISABLE_PREF_LENGTH = 4 * 1024;
 
 union PrefValue {
   const char* mStringVal;
   int32_t mIntVal;
@@ -160,210 +155,269 @@ PrefTypeToString(PrefType aType)
     case PrefType::Bool:
       return "bool";
     default:
       MOZ_CRASH("Unhandled enum value");
   }
 }
 #endif
 
-// Keep the type of the preference, as well as the flags guiding its behaviour.
-class PrefTypeFlags
+static ArenaAllocator<8192, 1> gPrefNameArena;
+
+class PrefHashEntry : public PLDHashEntryHdr
 {
 public:
-  PrefTypeFlags()
-    : mValue(AsInt(PrefType::Invalid))
-  {
-  }
-
-  explicit PrefTypeFlags(PrefType aType)
-    : mValue(AsInt(aType))
-  {
-  }
-
-  PrefTypeFlags& Reset()
+  PrefHashEntry(const char* aName, PrefType aType)
   {
-    mValue = AsInt(PrefType::Invalid);
-    return *this;
-  }
-
-  bool IsTypeValid() const { return !IsPrefType(PrefType::Invalid); }
-  bool IsTypeString() const { return IsPrefType(PrefType::String); }
-  bool IsTypeInt() const { return IsPrefType(PrefType::Int); }
-  bool IsTypeBool() const { return IsPrefType(PrefType::Bool); }
-  bool IsPrefType(PrefType type) const { return GetPrefType() == type; }
-
-  void SetPrefType(PrefType aType)
-  {
-    mValue = mValue - AsInt(GetPrefType()) + AsInt(aType);
+    mName = ArenaStrdup(aName, gPrefNameArena);
+    SetType(aType);
+    // We don't set the other fields because PLDHashTable always zeroes new
+    // entries.
   }
 
-  PrefType GetPrefType() const
+  const char* Name() { return mName; }
+
+  // Types.
+
+  PrefType Type() const { return static_cast<PrefType>(mType); }
+  void SetType(PrefType aType) { mType = static_cast<uint32_t>(aType); }
+
+  bool IsType(PrefType aType) const { return Type() == aType; }
+  bool IsTypeString() const { return IsType(PrefType::String); }
+  bool IsTypeInt() const { return IsType(PrefType::Int); }
+  bool IsTypeBool() const { return IsType(PrefType::Bool); }
+
+  // Other properties.
+
+  bool IsSticky() const { return mIsSticky; }
+  void SetIsSticky(bool aValue) { mIsSticky = aValue; }
+
+  bool IsLocked() const { return mIsLocked; }
+  void SetIsLocked(bool aValue) { mIsLocked = aValue; }
+
+  bool HasDefaultValue() const { return mHasDefaultValue; }
+  void SetHasDefaultValue(bool aValue) { mHasDefaultValue = aValue; }
+
+  bool HasUserValue() const { return mHasUserValue; }
+  void SetHasUserValue(bool aValue) { mHasUserValue = aValue; }
+
+  // Other operations.
+
+  static bool MatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey)
   {
-    return (PrefType)(mValue & (AsInt(PrefType::String) | AsInt(PrefType::Int) |
-                                AsInt(PrefType::Bool)));
-  }
-
-  bool HasDefaultValue() const { return mValue & PREF_FLAG_HAS_DEFAULT_VALUE; }
-
-  void SetHasDefaultValue(bool aSetOrUnset)
-  {
-    SetFlag(PREF_FLAG_HAS_DEFAULT_VALUE, aSetOrUnset);
+    auto pref = static_cast<const PrefHashEntry*>(aEntry);
+    auto key = static_cast<const char*>(aKey);
+
+    if (pref->mName == aKey) {
+      return true;
+    }
+
+    if (!pref->mName || !aKey) {
+      return false;
+    }
+
+    return strcmp(pref->mName, key) == 0;
   }
 
-  bool IsSticky() const { return mValue & PREF_FLAG_STICKY; }
-
-  void SetIsSticky(bool aSetOrUnset)
+  static void ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
   {
-    SetFlag(PREF_FLAG_STICKY, aSetOrUnset);
-  }
-
-  bool IsLocked() const { return mValue & PREF_FLAG_LOCKED; }
-
-  void SetLocked(bool aSetOrUnset) { SetFlag(PREF_FLAG_LOCKED, aSetOrUnset); }
-
-  bool HasUserValue() const { return mValue & PREF_FLAG_HAS_USER_VALUE; }
-
-  void SetHasUserValue(bool aSetOrUnset)
-  {
-    SetFlag(PREF_FLAG_HAS_USER_VALUE, aSetOrUnset);
+    auto pref = static_cast<PrefHashEntry*>(aEntry);
+
+    if (pref->IsTypeString()) {
+      free(const_cast<char*>(pref->mDefaultValue.mStringVal));
+      free(const_cast<char*>(pref->mUserValue.mStringVal));
+    }
+
+    // Don't need to free this because it's allocated in memory owned by
+    // gPrefNameArena.
+    pref->mName = nullptr;
+    memset(aEntry, 0, aTable->EntrySize());
   }
 
 private:
-  static uint16_t AsInt(PrefType aType) { return (uint16_t)aType; }
-
-  void SetFlag(uint16_t aFlag, bool aSetOrUnset)
+  static void AssignPrefValueToDomPrefValue(PrefType aType,
+                                            PrefValue* aValue,
+                                            dom::PrefValue* aDomValue)
   {
-    mValue = aSetOrUnset ? mValue | aFlag : mValue & ~aFlag;
+    switch (aType) {
+      case PrefType::String:
+        *aDomValue = nsDependentCString(aValue->mStringVal);
+        return;
+
+      case PrefType::Int:
+        *aDomValue = aValue->mIntVal;
+        return;
+
+      case PrefType::Bool:
+        *aDomValue = !!aValue->mBoolVal;
+        return;
+
+      default:
+        MOZ_CRASH();
+    }
   }
 
-  // We pack both the value of type (PrefType) and flags into the same int. The
-  // flag enum starts at 4 so that the PrefType can occupy the bottom two bits.
-  enum
+public:
+  void ToSetting(dom::PrefSetting* aSetting)
   {
-    PREF_FLAG_LOCKED = 4,
-    PREF_FLAG_HAS_USER_VALUE = 8,
-    PREF_FLAG_HAS_DEFAULT_VALUE = 16,
-    PREF_FLAG_STICKY = 32,
-  };
-  uint16_t mValue;
-};
-
-struct PrefHashEntry : PLDHashEntryHdr
-{
-  PrefTypeFlags mPrefFlags; // this field first to minimize 64-bit struct size
-  const char* mKey;
-  PrefValue mDefaultValue;
-  PrefValue mUserValue;
+    aSetting->name() = mName;
+
+    if (HasDefaultValue()) {
+      aSetting->defaultValue() = dom::PrefValue();
+      AssignPrefValueToDomPrefValue(
+        Type(), &mDefaultValue, &aSetting->defaultValue().get_PrefValue());
+    } else {
+      aSetting->defaultValue() = null_t();
+    }
+
+    if (HasUserValue()) {
+      aSetting->userValue() = dom::PrefValue();
+      AssignPrefValueToDomPrefValue(
+        Type(), &mUserValue, &aSetting->userValue().get_PrefValue());
+    } else {
+      aSetting->userValue() = null_t();
+    }
+
+    MOZ_ASSERT(aSetting->defaultValue().type() ==
+                 dom::MaybePrefValue::Tnull_t ||
+               aSetting->userValue().type() == dom::MaybePrefValue::Tnull_t ||
+               (aSetting->defaultValue().get_PrefValue().type() ==
+                aSetting->userValue().get_PrefValue().type()));
+  }
+
+  bool HasAdvisablySizedValues()
+  {
+    if (!IsTypeString()) {
+      return true;
+    }
+
+    const char* stringVal;
+    if (HasDefaultValue()) {
+      stringVal = mDefaultValue.mStringVal;
+      if (strlen(stringVal) > MAX_ADVISABLE_PREF_LENGTH) {
+        return false;
+      }
+    }
+
+    if (HasUserValue()) {
+      stringVal = mUserValue.mStringVal;
+      if (strlen(stringVal) > MAX_ADVISABLE_PREF_LENGTH) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  // Overwrite the type and value of an existing preference. Caller must ensure
+  // that they are not changing the type of a preference that has a default
+  // value.
+  void ReplaceValue(PrefValueKind aKind, PrefType aNewType, PrefValue aNewValue)
+  {
+    PrefValue* value =
+      aKind == PrefValueKind::Default ? &mDefaultValue : &mUserValue;
+
+    if (Type() == PrefType::String) {
+      free(const_cast<char*>(value->mStringVal));
+    }
+
+    SetType(aNewType);
+
+    if (aNewType == PrefType::String) {
+      MOZ_ASSERT(aNewValue.mStringVal);
+      value->mStringVal = moz_xstrdup(aNewValue.mStringVal);
+    } else {
+      *value = aNewValue;
+    }
+  }
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf)
   {
-    // Note: mKey is allocated in gPrefNameArena, measured elsewhere.
+    // Note: mName is allocated in gPrefNameArena, measured elsewhere.
     size_t n = 0;
-    if (mPrefFlags.IsTypeString()) {
-      if (mPrefFlags.HasDefaultValue()) {
+    if (IsTypeString()) {
+      if (HasDefaultValue()) {
         n += aMallocSizeOf(mDefaultValue.mStringVal);
       }
-      if (mPrefFlags.HasUserValue()) {
+      if (HasUserValue()) {
         n += aMallocSizeOf(mUserValue.mStringVal);
       }
     }
     return n;
   }
+
+private:
+  // These fields go first to minimize this struct's size on 64-bit. (Because
+  // this a subclass of PLDHashEntryHdr, there's a preceding 32-bit mKeyHash
+  // field.)
+  uint32_t mType : 2;
+  uint32_t mIsSticky : 1;
+  uint32_t mIsLocked : 1;
+  uint32_t mHasUserValue : 1;
+  uint32_t mHasDefaultValue : 1;
+
+  const char* mName;
+
+public:
+  PrefValue mDefaultValue;
+  PrefValue mUserValue;
 };
 
-static void
-ClearPrefEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
-{
-  auto pref = static_cast<PrefHashEntry*>(aEntry);
-  if (pref->mPrefFlags.IsTypeString()) {
-    free(const_cast<char*>(pref->mDefaultValue.mStringVal));
-    free(const_cast<char*>(pref->mUserValue.mStringVal));
-  }
-
-  // Don't need to free this because it's allocated in memory owned by
-  // gPrefNameArena.
-  pref->mKey = nullptr;
-  memset(aEntry, 0, aTable->EntrySize());
-}
-
-static bool
-MatchPrefEntry(const PLDHashEntryHdr* aEntry, const void* aKey)
-{
-  auto pref = static_cast<const PrefHashEntry*>(aEntry);
-
-  if (pref->mKey == aKey) {
-    return true;
-  }
-
-  if (!pref->mKey || !aKey) {
-    return false;
-  }
-
-  auto otherKey = static_cast<const char*>(aKey);
-  return (strcmp(pref->mKey, otherKey) == 0);
-}
-
 struct CallbackNode
 {
   const char* mDomain;
 
   // If someone attempts to remove the node from the callback list while
   // pref_DoCallback is running, |func| is set to nullptr. Such nodes will
   // be removed at the end of pref_DoCallback.
   PrefChangedFunc mFunc;
   void* mData;
   Preferences::MatchKind mMatchKind;
   CallbackNode* mNext;
 };
 
 static PLDHashTable* gHashTable;
 
-static ArenaAllocator<8192, 1> gPrefNameArena;
-
 // The callback list contains all the priority callbacks followed by the
 // non-priority callbacks. gLastPriorityNode records where the first part ends.
 static CallbackNode* gFirstCallback = nullptr;
 static CallbackNode* gLastPriorityNode = nullptr;
 
 static bool gIsAnyPrefLocked = false;
 
 // These are only used during the call to pref_DoCallback.
 static bool gCallbacksInProgress = false;
 static bool gShouldCleanupDeadNodes = false;
 
 static PLDHashTableOps pref_HashTableOps = {
   PLDHashTable::HashStringKey,
-  MatchPrefEntry,
+  PrefHashEntry::MatchEntry,
   PLDHashTable::MoveEntryStub,
-  ClearPrefEntry,
+  PrefHashEntry::ClearEntry,
   nullptr,
 };
 
 //---------------------------------------------------------------------------
 
+static PrefHashEntry*
+pref_HashTableLookup(const char* aPrefName);
+
 static bool
 pref_ValueChanged(PrefValue aOldValue, PrefValue aNewValue, PrefType aType);
 
 static nsresult
 pref_DoCallback(const char* aChangedPref);
 
 enum
 {
   kPrefSetDefault = 1,
   kPrefForceSet = 2,
   kPrefSticky = 4,
 };
 
-static nsresult
-pref_SetPref(const char* aKey,
-             PrefValue aValue,
-             PrefType aType,
-             uint32_t aFlags);
-
 #define PREF_HASHTABLE_INITIAL_LENGTH 1024
 
 // Assign to aResult a quoted, escaped copy of aOriginal.
 static void
 StrEscape(const char* aOriginal, nsCString& aResult)
 {
   if (aOriginal == nullptr) {
     aResult.AssignLiteral("\"\"");
@@ -418,153 +472,71 @@ pref_savePrefs()
   PrefSaveData savedPrefs(gHashTable->EntryCount());
 
   for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
     auto pref = static_cast<PrefHashEntry*>(iter.Get());
 
     // where we're getting our pref from
     PrefValue* sourceValue;
 
-    if (pref->mPrefFlags.HasUserValue() &&
-        (pref_ValueChanged(pref->mDefaultValue,
-                           pref->mUserValue,
-                           pref->mPrefFlags.GetPrefType()) ||
-         !pref->mPrefFlags.HasDefaultValue() ||
-         pref->mPrefFlags.IsSticky())) {
+    if (pref->HasUserValue() &&
+        (pref_ValueChanged(
+           pref->mDefaultValue, pref->mUserValue, pref->Type()) ||
+         !pref->HasDefaultValue() || pref->IsSticky())) {
       sourceValue = &pref->mUserValue;
     } else {
       // do not save default prefs that haven't changed
       continue;
     }
 
     nsAutoCString prefName;
-    StrEscape(pref->mKey, prefName);
+    StrEscape(pref->Name(), prefName);
 
     nsAutoCString prefValue;
-    if (pref->mPrefFlags.IsTypeString()) {
+    if (pref->IsTypeString()) {
       StrEscape(sourceValue->mStringVal, prefValue);
 
-    } else if (pref->mPrefFlags.IsTypeInt()) {
+    } else if (pref->IsTypeInt()) {
       prefValue.AppendInt(sourceValue->mIntVal);
 
-    } else if (pref->mPrefFlags.IsTypeBool()) {
+    } else if (pref->IsTypeBool()) {
       prefValue = sourceValue->mBoolVal ? "true" : "false";
     }
 
     nsPrintfCString str("user_pref(%s, %s);", prefName.get(), prefValue.get());
     savedPrefs.AppendElement(str);
   }
 
   return savedPrefs;
 }
 
 static bool
-pref_EntryHasAdvisablySizedValues(PrefHashEntry* aPref)
-{
-  if (aPref->mPrefFlags.GetPrefType() != PrefType::String) {
-    return true;
-  }
-
-  const char* stringVal;
-  if (aPref->mPrefFlags.HasDefaultValue()) {
-    stringVal = aPref->mDefaultValue.mStringVal;
-    if (strlen(stringVal) > MAX_ADVISABLE_PREF_LENGTH) {
-      return false;
-    }
-  }
-
-  if (aPref->mPrefFlags.HasUserValue()) {
-    stringVal = aPref->mUserValue.mStringVal;
-    if (strlen(stringVal) > MAX_ADVISABLE_PREF_LENGTH) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static void
-GetPrefValueFromEntry(PrefHashEntry* aPref,
-                      dom::PrefSetting* aSetting,
-                      PrefValueKind aKind)
-{
-  PrefValue* value;
-  dom::PrefValue* settingValue;
-  if (aKind == PrefValueKind::User) {
-    value = &aPref->mUserValue;
-    aSetting->userValue() = dom::PrefValue();
-    settingValue = &aSetting->userValue().get_PrefValue();
-  } else {
-    value = &aPref->mDefaultValue;
-    aSetting->defaultValue() = dom::PrefValue();
-    settingValue = &aSetting->defaultValue().get_PrefValue();
-  }
-
-  switch (aPref->mPrefFlags.GetPrefType()) {
-    case PrefType::String:
-      *settingValue = nsDependentCString(value->mStringVal);
-      return;
-    case PrefType::Int:
-      *settingValue = value->mIntVal;
-      return;
-    case PrefType::Bool:
-      *settingValue = !!value->mBoolVal;
-      return;
-    default:
-      MOZ_CRASH();
-  }
-}
-
-static void
-pref_GetPrefFromEntry(PrefHashEntry* aPref, dom::PrefSetting* aSetting)
-{
-  aSetting->name() = aPref->mKey;
-
-  if (aPref->mPrefFlags.HasDefaultValue()) {
-    GetPrefValueFromEntry(aPref, aSetting, PrefValueKind::Default);
-  } else {
-    aSetting->defaultValue() = null_t();
-  }
-
-  if (aPref->mPrefFlags.HasUserValue()) {
-    GetPrefValueFromEntry(aPref, aSetting, PrefValueKind::User);
-  } else {
-    aSetting->userValue() = null_t();
-  }
-
-  MOZ_ASSERT(aSetting->defaultValue().type() == dom::MaybePrefValue::Tnull_t ||
-             aSetting->userValue().type() == dom::MaybePrefValue::Tnull_t ||
-             (aSetting->defaultValue().get_PrefValue().type() ==
-              aSetting->userValue().get_PrefValue().type()));
-}
-
-static bool
 PREF_HasUserPref(const char* aPrefName)
 {
   if (!gHashTable) {
     return false;
   }
 
   PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
-  return pref && pref->mPrefFlags.HasUserValue();
+  return pref && pref->HasUserValue();
 }
 
 // Clears the given pref (reverts it to its default value).
 static nsresult
 PREF_ClearUserPref(const char* aPrefName)
 {
   if (!gHashTable) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
-  if (pref && pref->mPrefFlags.HasUserValue()) {
-    pref->mPrefFlags.SetHasUserValue(false);
-
-    if (!pref->mPrefFlags.HasDefaultValue()) {
+  if (pref && pref->HasUserValue()) {
+    pref->SetHasUserValue(false);
+
+    if (!pref->HasDefaultValue()) {
       gHashTable->RemoveEntry(pref);
     }
 
     pref_DoCallback(aPrefName);
     Preferences::HandleDirty();
   }
   return NS_OK;
 }
@@ -578,59 +550,59 @@ PREF_ClearAllUserPrefs()
   if (!gHashTable) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   Vector<const char*> prefNames;
   for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
     auto pref = static_cast<PrefHashEntry*>(iter.Get());
 
-    if (pref->mPrefFlags.HasUserValue()) {
-      if (!prefNames.append(pref->mKey)) {
+    if (pref->HasUserValue()) {
+      if (!prefNames.append(pref->Name())) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
 
-      pref->mPrefFlags.SetHasUserValue(false);
-      if (!pref->mPrefFlags.HasDefaultValue()) {
+      pref->SetHasUserValue(false);
+      if (!pref->HasDefaultValue()) {
         iter.Remove();
       }
     }
   }
 
   for (const char* prefName : prefNames) {
     pref_DoCallback(prefName);
   }
 
   Preferences::HandleDirty();
   return NS_OK;
 }
 
 // Function that sets whether or not the preference is locked and therefore
 // cannot be changed.
 static nsresult
-PREF_LockPref(const char* aKey, bool aLockIt)
+PREF_LockPref(const char* aPrefName, bool aLockIt)
 {
   if (!gHashTable) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  PrefHashEntry* pref = pref_HashTableLookup(aKey);
+  PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
   if (!pref) {
     return NS_ERROR_UNEXPECTED;
   }
 
   if (aLockIt) {
-    if (!pref->mPrefFlags.IsLocked()) {
-      pref->mPrefFlags.SetLocked(true);
+    if (!pref->IsLocked()) {
+      pref->SetIsLocked(true);
       gIsAnyPrefLocked = true;
-      pref_DoCallback(aKey);
+      pref_DoCallback(aPrefName);
     }
-  } else if (pref->mPrefFlags.IsLocked()) {
-    pref->mPrefFlags.SetLocked(false);
-    pref_DoCallback(aKey);
+  } else if (pref->IsLocked()) {
+    pref->SetIsLocked(false);
+    pref_DoCallback(aPrefName);
   }
 
   return NS_OK;
 }
 
 //
 // Hash table functions
 //
@@ -658,59 +630,42 @@ pref_ValueChanged(PrefValue aOldValue, P
     default:
       changed = false;
       break;
   }
 
   return changed;
 }
 
-// Overwrite the type and value of an existing preference. Caller must ensure
-// that they are not changing the type of a preference that has a default
-// value.
-static void
-pref_SetValue(PrefValue* aExistingValue,
-              PrefType aExistingType,
-              PrefValue aNewValue,
-              PrefType aNewType)
-{
-  if (aExistingType == PrefType::String) {
-    free(const_cast<char*>(aExistingValue->mStringVal));
-  }
-
-  if (aNewType == PrefType::String) {
-    MOZ_ASSERT(aNewValue.mStringVal);
-    aExistingValue->mStringVal =
-      aNewValue.mStringVal ? moz_xstrdup(aNewValue.mStringVal) : nullptr;
-  } else {
-    *aExistingValue = aNewValue;
-  }
-}
-
 #ifdef DEBUG
 
 static pref_initPhase gPhase = START;
 
 struct StringComparator
 {
-  const char* mKey;
-  explicit StringComparator(const char* aKey)
-    : mKey(aKey)
+  const char* mPrefName;
+
+  explicit StringComparator(const char* aPrefName)
+    : mPrefName(aPrefName)
   {
   }
-  int operator()(const char* aString) const { return strcmp(mKey, aString); }
+
+  int operator()(const char* aPrefName) const
+  {
+    return strcmp(mPrefName, aPrefName);
+  }
 };
 
 static bool
-InInitArray(const char* aKey)
+InInitArray(const char* aPrefName)
 {
   size_t prefsLen;
   size_t found;
   const char** list = mozilla::dom::ContentPrefs::GetContentPrefs(&prefsLen);
-  return BinarySearchIf(list, 0, prefsLen, StringComparator(aKey), &found);
+  return BinarySearchIf(list, 0, prefsLen, StringComparator(aPrefName), &found);
 }
 
 static bool gInstallingCallback = false;
 
 class AutoInstallingCallback
 {
 public:
   AutoInstallingCallback() { gInstallingCallback = true; }
@@ -747,120 +702,109 @@ pref_HashTableLookup(const char* aKey)
       "accessing non-init pref %s before the rest of the prefs are sent", aKey);
   }
 #endif
 
   return static_cast<PrefHashEntry*>(gHashTable->Search(aKey));
 }
 
 static nsresult
-pref_SetPref(const char* aKey,
+pref_SetPref(const char* aPrefName,
              PrefValue aValue,
              PrefType aType,
              uint32_t aFlags)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!gHashTable) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  auto pref = static_cast<PrefHashEntry*>(gHashTable->Add(aKey, fallible));
+  auto pref = static_cast<PrefHashEntry*>(gHashTable->Add(aPrefName, fallible));
   if (!pref) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  // New entry, need to initialize.
-  if (!pref->mKey) {
-    // Initialize the pref entry.
-    pref->mPrefFlags.Reset().SetPrefType(aType);
-    pref->mKey = ArenaStrdup(aKey, gPrefNameArena);
-    memset(&pref->mDefaultValue, 0, sizeof(pref->mDefaultValue));
-    memset(&pref->mUserValue, 0, sizeof(pref->mUserValue));
-
-  } else if (pref->mPrefFlags.HasDefaultValue() &&
-             !pref->mPrefFlags.IsPrefType(aType)) {
+  if (!pref->Name()) {
+    // New (zeroed) entry. Initialize it.
+    new (pref) PrefHashEntry(aPrefName, aType);
+
+  } else if (pref->HasDefaultValue() && !pref->IsType(aType)) {
     NS_WARNING(
       nsPrintfCString(
         "Ignoring attempt to overwrite value of default pref %s (type %s) with "
         "the wrong type (%s)!",
-        aKey,
-        PrefTypeToString(pref->mPrefFlags.GetPrefType()),
+        aPrefName,
+        PrefTypeToString(pref->Type()),
         PrefTypeToString(aType))
         .get());
 
     return NS_ERROR_UNEXPECTED;
   }
 
   bool valueChanged = false;
   if (aFlags & kPrefSetDefault) {
-    if (!pref->mPrefFlags.IsLocked()) {
+    if (!pref->IsLocked()) {
       // ?? change of semantics?
       if (pref_ValueChanged(pref->mDefaultValue, aValue, aType) ||
-          !pref->mPrefFlags.HasDefaultValue()) {
-        pref_SetValue(
-          &pref->mDefaultValue, pref->mPrefFlags.GetPrefType(), aValue, aType);
-        pref->mPrefFlags.SetPrefType(aType);
-        pref->mPrefFlags.SetHasDefaultValue(true);
+          !pref->HasDefaultValue()) {
+        pref->ReplaceValue(PrefValueKind::Default, aType, aValue);
+        pref->SetHasDefaultValue(true);
         if (aFlags & kPrefSticky) {
-          pref->mPrefFlags.SetIsSticky(true);
+          pref->SetIsSticky(true);
         }
-        if (!pref->mPrefFlags.HasUserValue()) {
+        if (!pref->HasUserValue()) {
           valueChanged = true;
         }
       }
       // What if we change the default to be the same as the user value?
       // Should we clear the user value?
     }
   } else {
     // If new value is same as the default value and it's not a "sticky" pref,
     // then un-set the user value. Otherwise, set the user value only if it has
     // changed.
-    if ((pref->mPrefFlags.HasDefaultValue()) &&
-        !(pref->mPrefFlags.IsSticky()) &&
+    if (pref->HasDefaultValue() && !pref->IsSticky() &&
         !pref_ValueChanged(pref->mDefaultValue, aValue, aType) &&
         !(aFlags & kPrefForceSet)) {
-      if (pref->mPrefFlags.HasUserValue()) {
+      if (pref->HasUserValue()) {
         // XXX should we free a user-set string value if there is one?
-        pref->mPrefFlags.SetHasUserValue(false);
-        if (!pref->mPrefFlags.IsLocked()) {
+        pref->SetHasUserValue(false);
+        if (!pref->IsLocked()) {
           Preferences::HandleDirty();
           valueChanged = true;
         }
       }
-    } else if (!pref->mPrefFlags.HasUserValue() ||
-               !pref->mPrefFlags.IsPrefType(aType) ||
+    } else if (!pref->HasUserValue() || !pref->IsType(aType) ||
                pref_ValueChanged(pref->mUserValue, aValue, aType)) {
-      pref_SetValue(
-        &pref->mUserValue, pref->mPrefFlags.GetPrefType(), aValue, aType);
-      pref->mPrefFlags.SetPrefType(aType);
-      pref->mPrefFlags.SetHasUserValue(true);
-      if (!pref->mPrefFlags.IsLocked()) {
+      pref->ReplaceValue(PrefValueKind::User, aType, aValue);
+      pref->SetHasUserValue(true);
+      if (!pref->IsLocked()) {
         Preferences::HandleDirty();
         valueChanged = true;
       }
     }
   }
 
   if (valueChanged) {
-    return pref_DoCallback(aKey);
+    return pref_DoCallback(aPrefName);
   }
 
   return NS_OK;
 }
 
 // Bool function that returns whether or not the preference is locked and
 // therefore cannot be changed.
 static bool
 PREF_PrefIsLocked(const char* aPrefName)
 {
   bool result = false;
   if (gIsAnyPrefLocked && gHashTable) {
     PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
-    if (pref && pref->mPrefFlags.IsLocked()) {
+    if (pref && pref->IsLocked()) {
       result = true;
     }
   }
 
   return result;
 }
 
 // Adds a node to the callback list; the position depends on aIsPriority. The
@@ -2007,17 +1951,17 @@ nsPrefBranch::GetPrefType(const char* aP
 {
   NS_ENSURE_ARG(aPrefName);
 
   const PrefName& prefName = GetPrefName(aPrefName);
   PrefType type = PrefType::Invalid;
   if (gHashTable) {
     PrefHashEntry* pref = pref_HashTableLookup(prefName.get());
     if (pref) {
-      type = pref->mPrefFlags.GetPrefType();
+      type = pref->Type();
     }
   }
 
   switch (type) {
     case PrefType::String:
       *aRetVal = PREF_STRING;
       break;
 
@@ -2573,21 +2517,21 @@ nsPrefBranch::DeleteBranch(const char* a
 
   const nsACString& branchNameNoDot =
     Substring(branchName, 0, branchName.Length() - 1);
 
   for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
     auto pref = static_cast<PrefHashEntry*>(iter.Get());
 
     // The first disjunct matches branches: e.g. a branch name "foo.bar."
-    // matches an mKey "foo.bar.baz" (but it won't match "foo.barrel.baz").
+    // matches a name "foo.bar.baz" (but it won't match "foo.barrel.baz").
     // The second disjunct matches leaf nodes: e.g. a branch name "foo.bar."
-    // matches an mKey "foo.bar" (by ignoring the trailing '.').
-    nsDependentCString key(pref->mKey);
-    if (StringBeginsWith(key, branchName) || key.Equals(branchNameNoDot)) {
+    // matches a name "foo.bar" (by ignoring the trailing '.').
+    nsDependentCString name(pref->Name());
+    if (StringBeginsWith(name, branchName) || name.Equals(branchNameNoDot)) {
       iter.Remove();
     }
   }
 
   Preferences::HandleDirty();
   return NS_OK;
 }
 
@@ -2610,18 +2554,18 @@ nsPrefBranch::GetChildList(const char* a
 
   // This will contain a list of all the pref name strings. Allocated on the
   // stack for speed.
 
   const PrefName& parent = GetPrefName(aStartingAt);
   size_t parentLen = parent.Length();
   for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
     auto pref = static_cast<PrefHashEntry*>(iter.Get());
-    if (strncmp(pref->mKey, parent.get(), parentLen) == 0) {
-      prefArray.AppendElement(pref->mKey);
+    if (strncmp(pref->Name(), parent.get(), parentLen) == 0) {
+      prefArray.AppendElement(pref->Name());
     }
   }
 
   // Now that we've built up the list, run the callback on all the matching
   // elements.
   numPrefs = prefArray.Length();
 
   if (numPrefs) {
@@ -3822,38 +3766,32 @@ Preferences::SetPreference(const PrefSet
   // NB: we should never try to clear a default value, that doesn't
   // make sense
 }
 
 void
 Preferences::GetPreference(PrefSetting* aSetting)
 {
   PrefHashEntry* pref = pref_HashTableLookup(aSetting->name().get());
-  if (!pref) {
-    return;
-  }
-
-  if (pref_EntryHasAdvisablySizedValues(pref)) {
-    pref_GetPrefFromEntry(pref, aSetting);
+  if (pref && pref->HasAdvisablySizedValues()) {
+    pref->ToSetting(aSetting);
   }
 }
 
 void
 Preferences::GetPreferences(InfallibleTArray<PrefSetting>* aSettings)
 {
   aSettings->SetCapacity(gHashTable->Capacity());
   for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
     auto pref = static_cast<PrefHashEntry*>(iter.Get());
 
-    if (!pref_EntryHasAdvisablySizedValues(pref)) {
-      continue;
+    if (pref->HasAdvisablySizedValues()) {
+      dom::PrefSetting* setting = aSettings->AppendElement();
+      pref->ToSetting(setting);
     }
-
-    dom::PrefSetting* setting = aSettings->AppendElement();
-    pref_GetPrefFromEntry(pref, setting);
   }
 }
 
 #ifdef DEBUG
 void
 Preferences::SetInitPhase(pref_initPhase aPhase)
 {
   gPhase = aPhase;
@@ -4499,25 +4437,25 @@ Preferences::InitInitialObjects()
 
 /* static */ nsresult
 Preferences::GetBool(const char* aPrefName, bool* aResult, PrefValueKind aKind)
 {
   NS_PRECONDITION(aResult, "aResult must not be NULL");
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
 
   PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
-  if (!pref || !pref->mPrefFlags.IsTypeBool()) {
+  if (!pref || !pref->IsTypeBool()) {
     return NS_ERROR_UNEXPECTED;
   }
 
-  if (aKind == PrefValueKind::Default || pref->mPrefFlags.IsLocked() ||
-      !pref->mPrefFlags.HasUserValue()) {
+  if (aKind == PrefValueKind::Default || pref->IsLocked() ||
+      !pref->HasUserValue()) {
 
     // Do we have a default?
-    if (!pref->mPrefFlags.HasDefaultValue()) {
+    if (!pref->HasDefaultValue()) {
       return NS_ERROR_UNEXPECTED;
     }
     *aResult = pref->mDefaultValue.mBoolVal;
   } else {
     *aResult = pref->mUserValue.mBoolVal;
   }
 
   return NS_OK;
@@ -4527,25 +4465,25 @@ Preferences::GetBool(const char* aPrefNa
 Preferences::GetInt(const char* aPrefName,
                     int32_t* aResult,
                     PrefValueKind aKind)
 {
   NS_PRECONDITION(aResult, "aResult must not be NULL");
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
 
   PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
-  if (!pref || !pref->mPrefFlags.IsTypeInt()) {
+  if (!pref || !pref->IsTypeInt()) {
     return NS_ERROR_UNEXPECTED;
   }
 
-  if (aKind == PrefValueKind::Default || pref->mPrefFlags.IsLocked() ||
-      !pref->mPrefFlags.HasUserValue()) {
+  if (aKind == PrefValueKind::Default || pref->IsLocked() ||
+      !pref->HasUserValue()) {
 
     // Do we have a default?
-    if (!pref->mPrefFlags.HasDefaultValue()) {
+    if (!pref->HasDefaultValue()) {
       return NS_ERROR_UNEXPECTED;
     }
     *aResult = pref->mDefaultValue.mIntVal;
   } else {
     *aResult = pref->mUserValue.mIntVal;
   }
 
   return NS_OK;
@@ -4571,26 +4509,26 @@ Preferences::GetCString(const char* aPre
                         nsACString& aResult,
                         PrefValueKind aKind)
 {
   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
 
   aResult.SetIsVoid(true);
 
   PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
-  if (!pref || !pref->mPrefFlags.IsTypeString()) {
+  if (!pref || !pref->IsTypeString()) {
     return NS_ERROR_UNEXPECTED;
   }
 
   const char* stringVal = nullptr;
-  if (aKind == PrefValueKind::Default || pref->mPrefFlags.IsLocked() ||
-      !pref->mPrefFlags.HasUserValue()) {
+  if (aKind == PrefValueKind::Default || pref->IsLocked() ||
+      !pref->HasUserValue()) {
 
     // Do we have a default?
-    if (!pref->mPrefFlags.HasDefaultValue()) {
+    if (!pref->HasDefaultValue()) {
       return NS_ERROR_UNEXPECTED;
     }
     stringVal = pref->mDefaultValue.mStringVal;
   } else {
     stringVal = pref->mUserValue.mStringVal;
   }
 
   if (!stringVal) {
--- a/parser/htmlparser/moz.build
+++ b/parser/htmlparser/moz.build
@@ -7,17 +7,16 @@
 with Files('**'):
     BUG_COMPONENT = ('Core', 'XML')
 
 MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
 BROWSER_CHROME_MANIFESTS += ['tests/mochitest/browser.ini']
 
 XPIDL_SOURCES += [
     'nsIExpatSink.idl',
-    'nsIExtendedExpatSink.idl',
 ]
 
 XPIDL_MODULE = 'htmlparser'
 
 EXPORTS += [
     'nsElementTable.h',
     'nsHTMLTagList.h',
     'nsHTMLTags.h',
--- a/parser/htmlparser/nsExpatDriver.cpp
+++ b/parser/htmlparser/nsExpatDriver.cpp
@@ -3,17 +3,16 @@
  * 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 "nsExpatDriver.h"
 #include "nsCOMPtr.h"
 #include "nsParserCIID.h"
 #include "CParserContext.h"
 #include "nsIExpatSink.h"
-#include "nsIExtendedExpatSink.h"
 #include "nsIContentSink.h"
 #include "nsParserMsgUtils.h"
 #include "nsIURL.h"
 #include "nsIUnicharInputStream.h"
 #include "nsIProtocolHandler.h"
 #include "nsNetUtil.h"
 #include "nsTextFormatter.h"
 #include "nsDirectoryServiceDefs.h"
@@ -178,70 +177,16 @@ Driver_HandleExternalEntityRef(void *aEx
 
   nsExpatDriver* driver = static_cast<nsExpatDriver*>
                                      (aExternalEntityRefHandler);
 
   return driver->HandleExternalEntityRef(aOpenEntityNames, aBase, aSystemId,
                                          aPublicId);
 }
 
-static void
-Driver_HandleStartNamespaceDecl(void *aUserData,
-                                const XML_Char *aPrefix,
-                                const XML_Char *aUri)
-{
-  NS_ASSERTION(aUserData, "expat driver should exist");
-  if (aUserData) {
-    static_cast<nsExpatDriver*>(aUserData)->
-      HandleStartNamespaceDecl(aPrefix, aUri);
-  }
-}
-
-static void
-Driver_HandleEndNamespaceDecl(void *aUserData,
-                              const XML_Char *aPrefix)
-{
-  NS_ASSERTION(aUserData, "expat driver should exist");
-  if (aUserData) {
-    static_cast<nsExpatDriver*>(aUserData)->
-      HandleEndNamespaceDecl(aPrefix);
-  }
-}
-
-static void
-Driver_HandleNotationDecl(void *aUserData,
-                          const XML_Char *aNotationName,
-                          const XML_Char *aBase,
-                          const XML_Char *aSysid,
-                          const XML_Char *aPubid)
-{
-  NS_ASSERTION(aUserData, "expat driver should exist");
-  if (aUserData) {
-    static_cast<nsExpatDriver*>(aUserData)->
-      HandleNotationDecl(aNotationName, aBase, aSysid, aPubid);
-  }
-}
-
-static void
-Driver_HandleUnparsedEntityDecl(void *aUserData,
-                                const XML_Char *aEntityName,
-                                const XML_Char *aBase,
-                                const XML_Char *aSysid,
-                                const XML_Char *aPubid,
-                                const XML_Char *aNotationName)
-{
-  NS_ASSERTION(aUserData, "expat driver should exist");
-  if (aUserData) {
-    static_cast<nsExpatDriver*>(aUserData)->
-      HandleUnparsedEntityDecl(aEntityName, aBase, aSysid, aPubid,
-                               aNotationName);
-  }
-}
-
-
 /***************************** END CALL BACKS ********************************/
 
 /***************************** CATALOG UTILS *********************************/
 
 // Initially added for bug 113400 to switch from the remote "XHTML 1.0 plus
 // MathML 2.0" DTD to the the lightweight customized version that Mozilla uses.
 // Since Mozilla is not validating, no need to fetch a *huge* file at each
 // click.
@@ -329,17 +274,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsITokenizer)
   NS_INTERFACE_MAP_ENTRY(nsIDTD)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDTD)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsExpatDriver)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsExpatDriver)
 
-NS_IMPL_CYCLE_COLLECTION(nsExpatDriver, mSink, mExtendedSink)
+NS_IMPL_CYCLE_COLLECTION(nsExpatDriver, mSink)
 
 nsExpatDriver::nsExpatDriver()
   : mExpatParser(nullptr),
     mInCData(false),
     mInInternalSubset(false),
     mInExternalDTD(false),
     mMadeFinalCallToExpat(false),
     mIsFinalChunk(false),
@@ -529,82 +474,25 @@ nsExpatDriver::HandleEndCdataSection()
     MaybeStopParser(rv);
   }
   mCDataText.Truncate();
 
   return NS_OK;
 }
 
 nsresult
-nsExpatDriver::HandleStartNamespaceDecl(const char16_t* aPrefix,
-                                        const char16_t* aUri)
-{
-  if (mExtendedSink) {
-    nsresult rv = mExtendedSink->HandleStartNamespaceDecl(aPrefix, aUri);
-    MaybeStopParser(rv);
-  }
-  return NS_OK;
-}
-
-nsresult
-nsExpatDriver::HandleEndNamespaceDecl(const char16_t* aPrefix)
-{
-  if (mExtendedSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
-    nsresult rv = mExtendedSink->HandleEndNamespaceDecl(aPrefix);
-    MaybeStopParser(rv);
-  }
-  return NS_OK;
-}
-
-nsresult
-nsExpatDriver::HandleNotationDecl(const char16_t* aNotationName,
-                                  const char16_t* aBase,
-                                  const char16_t* aSysid,
-                                  const char16_t* aPubid)
-{
-  if (mExtendedSink) {
-    nsresult rv = mExtendedSink->HandleNotationDecl(aNotationName, aSysid,
-                                                    aPubid);
-    MaybeStopParser(rv);
-  }
-  return NS_OK;
-}
-
-nsresult
-nsExpatDriver::HandleUnparsedEntityDecl(const char16_t* aEntityName,
-                                        const char16_t* aBase,
-                                        const char16_t* aSysid,
-                                        const char16_t* aPubid,
-                                        const char16_t* aNotationName)
-{
-  if (mExtendedSink) {
-    nsresult rv = mExtendedSink->HandleUnparsedEntityDecl(aEntityName,
-                                                          aSysid,
-                                                          aPubid,
-                                                          aNotationName);
-    MaybeStopParser(rv);
-  }
-  return NS_OK;
-}
-
-nsresult
 nsExpatDriver::HandleStartDoctypeDecl(const char16_t* aDoctypeName,
                                       const char16_t* aSysid,
                                       const char16_t* aPubid,
                                       bool aHasInternalSubset)
 {
   mDoctypeName = aDoctypeName;
   mSystemID = aSysid;
   mPublicID = aPubid;
 
-  if (mExtendedSink) {
-    nsresult rv = mExtendedSink->HandleStartDTD(aDoctypeName, aSysid, aPubid);
-    MaybeStopParser(rv);
-  }
-
   if (aHasInternalSubset) {
     // Consuming a huge internal subset translates to numerous
     // allocations. In an effort to avoid too many allocations
     // setting mInternalSubset's capacity to be 1K ( just a guesstimate! ).
     mInInternalSubset = true;
     mInternalSubset.SetCapacity(1024);
   } else {
     // Distinguish missing internal subset from an empty one
@@ -1269,29 +1157,16 @@ nsExpatDriver::WillBuildModel(const CPar
   XML_SetCdataSectionHandler(mExpatParser, Driver_HandleStartCdataSection,
                              Driver_HandleEndCdataSection);
 
   XML_SetParamEntityParsing(mExpatParser,
                             XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
   XML_SetDoctypeDeclHandler(mExpatParser, Driver_HandleStartDoctypeDecl,
                             Driver_HandleEndDoctypeDecl);
 
-  // If the sink is an nsIExtendedExpatSink,
-  // register some addtional handlers.
-  mExtendedSink = do_QueryInterface(mSink);
-  if (mExtendedSink) {
-    XML_SetNamespaceDeclHandler(mExpatParser,
-                                Driver_HandleStartNamespaceDecl,
-                                Driver_HandleEndNamespaceDecl);
-    XML_SetUnparsedEntityDeclHandler(mExpatParser,
-                                     Driver_HandleUnparsedEntityDecl);
-    XML_SetNotationDeclHandler(mExpatParser,
-                               Driver_HandleNotationDecl);
-  }
-
   // Set up the user data.
   XML_SetUserData(mExpatParser, this);
 
   return mInternalState;
 }
 
 NS_IMETHODIMP
 nsExpatDriver::BuildModel(nsITokenizer* aTokenizer, nsIContentSink* aSink)
@@ -1299,17 +1174,16 @@ nsExpatDriver::BuildModel(nsITokenizer* 
   return mInternalState;
 }
 
 NS_IMETHODIMP
 nsExpatDriver::DidBuildModel(nsresult anErrorCode)
 {
   mOriginalSink = nullptr;
   mSink = nullptr;
-  mExtendedSink = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsExpatDriver::WillTokenize(bool aIsFinalChunk)
 {
   mIsFinalChunk = aIsFinalChunk;
   return NS_OK;
--- a/parser/htmlparser/nsExpatDriver.h
+++ b/parser/htmlparser/nsExpatDriver.h
@@ -12,17 +12,16 @@
 #include "nsString.h"
 #include "nsIDTD.h"
 #include "nsITokenizer.h"
 #include "nsIInputStream.h"
 #include "nsIParser.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsIExpatSink;
-class nsIExtendedExpatSink;
 struct nsCatalogData;
 
 class nsExpatDriver : public nsIDTD,
                       public nsITokenizer
 {
   virtual ~nsExpatDriver();
 
 public:
@@ -49,28 +48,16 @@ public:
   nsresult HandleDefault(const char16_t *aData, const uint32_t aLength);
   nsresult HandleStartCdataSection();
   nsresult HandleEndCdataSection();
   nsresult HandleStartDoctypeDecl(const char16_t* aDoctypeName,
                                   const char16_t* aSysid,
                                   const char16_t* aPubid,
                                   bool aHasInternalSubset);
   nsresult HandleEndDoctypeDecl();
-  nsresult HandleStartNamespaceDecl(const char16_t* aPrefix,
-                                    const char16_t* aUri);
-  nsresult HandleEndNamespaceDecl(const char16_t* aPrefix);
-  nsresult HandleNotationDecl(const char16_t* aNotationName,
-                              const char16_t* aBase,
-                              const char16_t* aSysid,
-                              const char16_t* aPubid);
-  nsresult HandleUnparsedEntityDecl(const char16_t* aEntityName,
-                                    const char16_t* aBase,
-                                    const char16_t* aSysid,
-                                    const char16_t* aPubid,
-                                    const char16_t* aNotationName);
 
 private:
   // Load up an external stream to get external entity information
   nsresult OpenInputStreamFromExternalDTD(const char16_t* aFPIStr,
                                           const char16_t* aURLStr,
                                           const char16_t* aBaseURL,
                                           nsIInputStream** aStream,
                                           nsAString& aAbsURL);
@@ -125,17 +112,16 @@ private:
   // The length of the data in Expat's buffer (in number of PRUnichars).
   uint32_t         mExpatBuffered;
 
   // These sinks all refer the same conceptual object. mOriginalSink is
   // identical with the nsIContentSink* passed to WillBuildModel, and exists
   // only to avoid QI-ing back to nsIContentSink*.
   nsCOMPtr<nsIContentSink> mOriginalSink;
   nsCOMPtr<nsIExpatSink> mSink;
-  nsCOMPtr<nsIExtendedExpatSink> mExtendedSink;
 
   const nsCatalogData* mCatalogData; // weak
   nsString         mURISpec;
 
   // Used for error reporting.
   uint64_t         mInnerWindowID;
 };
 
deleted file mode 100644
--- a/parser/htmlparser/nsIExtendedExpatSink.idl
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- 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 "nsIExpatSink.idl"
-
-/**
- * This interface provides notification of syntax-level events.
- */
-[scriptable, uuid(5e3e4f0c-7b77-47ca-a7c5-a3d87f2a9c82)]
-interface nsIExtendedExpatSink : nsIExpatSink
-{
-  /**
-   * Called at the beginning of the DTD, before any entity or notation
-   * events.
-   * @param aDoctypeName The document type name.
-   * @param aSysid The declared system identifier for the external DTD subset,
-   *               or null if none was declared.
-   * @param aPubid The declared public identifier for the external DTD subset,
-   *               or null if none was declared.
-   */
-  void handleStartDTD(in wstring aDoctypeName,
-                      in wstring aSysid,
-                      in wstring aPubid);
-
-  /**
-   * Called when a prefix mapping starts to be in-scope, before any
-   * startElement events.
-   * @param aPrefix The Namespace prefix being declared. An empty string
-   *                is used for the default element namespace, which has
-   *                no prefix.
-   * @param aUri The Namespace URI the prefix is mapped to.
-   */
-  void handleStartNamespaceDecl(in wstring aPrefix,
-                                in wstring aUri);
-                              
-  /**
-   * Called when a prefix mapping is no longer in-scope, after any
-   * endElement events.
-   * @param aPrefix The prefix that was being mapped. This is the empty string
-   *                when a default mapping scope ends.
-   */
-  void handleEndNamespaceDecl(in wstring aPrefix);
-
-  /**
-   * This is called for a declaration of notation.  The base argument is
-   * whatever was set by XML_SetBase. aNotationName will never be
-   * null. The other arguments can be.
-   * @param aNotationName The notation name.
-   * @param aSysId The notation's system identifier, or null if none was given.
-   * @param aPubId The notation's pubilc identifier, or null if none was given.
-   */
-  void handleNotationDecl(in wstring aNotationName,
-                          in wstring aSysid,
-                          in wstring aPubid);
-                              
-  /**
-   * This is called for a declaration of an unparsed (NDATA) entity.
-   * aName, aSysid and aNotationName arguments will never be
-   * null. The other arguments may be.
-   * @param aName  The unparsed entity's name.
-   * @param aSysId The notation's system identifier.
-   * @param aPubId The notation's pubilc identifier, or null if none was given.
-   * @param aNotationName The name of the associated notation.
-   */
-  void handleUnparsedEntityDecl(in wstring aName,
-                                in wstring aSysid,
-                                in wstring aPubid,
-                                in wstring aNotationName);
-
-};