Bug 1279218 - Additional applet tag logic removal; r?bz draft
authorKyle Machulis <kyle@nonpolynomial.com>
Fri, 28 Jul 2017 16:44:39 -0700
changeset 617914 523eb0af58b6835f7c7acdfc1f535b1f2a83c9a1
parent 617654 1d454b720d7231c8d4a80155b5a65981fa88af77
child 617915 ca1ef0702046e5a3aaf23262e47821131e89bd7e
child 617924 85c3640060e78d20fa3b53de6b2a97b0cb7aa62f
child 618004 0fa4c6dad66e52ef64a30813e905358bb1853c7d
child 618005 fd8de5da5630b9bb9f9a24825279da267a0dd445
push id71154
push userkmachulis@mozilla.com
push dateFri, 28 Jul 2017 23:48:43 +0000
reviewersbz
bugs1279218
milestone56.0a1
Bug 1279218 - Additional applet tag logic removal; r?bz I've been having problems with interdiffs on mozreview lately, so for ease of review, this patch is being submitted as a seperate patch for review. Once it is r+'d, it will be folded into the first patch in this set before landing. MozReview-Commit-ID: CS9MngaXlBd
accessible/html/HTMLTableAccessible.cpp
dom/base/Element.cpp
dom/base/nsContentList.cpp
dom/base/nsContentList.h
dom/base/nsHTMLContentSerializer.cpp
dom/base/nsIContent.h
dom/base/nsIDocument.h
dom/base/nsObjectLoadingContent.cpp
dom/base/nsObjectLoadingContent.h
dom/base/nsSandboxFlags.h
dom/base/nsXHTMLContentSerializer.cpp
dom/events/EventStateManager.cpp
dom/html/HTMLAllCollection.cpp
dom/html/HTMLSharedObjectElement.cpp
dom/html/nsGenericHTMLElement.h
dom/html/nsHTMLDocument.cpp
dom/html/nsHTMLDocument.h
dom/html/test/mochitest.ini
dom/html/test/test_bug1279218.html
dom/html/test/test_bug579079.html
dom/html/test/test_documentAll.html
dom/plugins/base/nsIPluginInstanceOwner.idl
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginInstanceOwner.h
dom/xml/nsXMLContentSink.cpp
dom/xslt/xslt/txMozillaXMLOutput.cpp
editor/libeditor/HTMLEditUtils.cpp
layout/generic/nsPluginFrame.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/generic/nsSubDocumentFrame.h
layout/svg/nsSVGOuterSVGFrame.cpp
layout/svg/nsSVGOuterSVGFrame.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -1104,19 +1104,18 @@ HTMLTableAccessible::IsProbablyLayoutTab
 
   // Two column rules
   if (rowCount * colCount <= 10) {
     RETURN_LAYOUT_ANSWER(true, "2-4 columns, 10 cells or less, non-bordered");
   }
 
   if (HasDescendant(NS_LITERAL_STRING("embed")) ||
       HasDescendant(NS_LITERAL_STRING("object")) ||
-      HasDescendant(NS_LITERAL_STRING("applet")) ||
       HasDescendant(NS_LITERAL_STRING("iframe"))) {
-    RETURN_LAYOUT_ANSWER(true, "Has no borders, and has iframe, object, applet or iframe, typical of advertisements");
+    RETURN_LAYOUT_ANSWER(true, "Has no borders, and has iframe, object, or iframe, typical of advertisements");
   }
 
   RETURN_LAYOUT_ANSWER(false, "no layout factor strong enough, so will guess data");
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLCaptionAccessible
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -483,21 +483,20 @@ Element::ClearStyleStateLocks()
 }
 
 bool
 Element::GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult)
 {
   // If we have a frame the frame has already loaded the binding.  And
   // otherwise, don't do anything else here unless we're dealing with
   // XUL or an HTML element that may have a plugin-related overlay
-  // (i.e. object, embed, or applet).
+  // (i.e. object or embed).
   bool isXULorPluginElement = (IsXULElement() ||
                                IsHTMLElement(nsGkAtoms::object) ||
-                               IsHTMLElement(nsGkAtoms::embed) ||
-                               IsHTMLElement(nsGkAtoms::applet));
+                               IsHTMLElement(nsGkAtoms::embed));
   nsIPresShell* shell = aDocument->GetShell();
   if (!shell || GetPrimaryFrame() || !isXULorPluginElement) {
     *aResult = nullptr;
     return true;
   }
 
   // Get the computed -moz-binding directly from the style context
   RefPtr<nsStyleContext> sc =
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -147,16 +147,77 @@ NS_IMPL_ADDREF_INHERITED(nsSimpleContent
 NS_IMPL_RELEASE_INHERITED(nsSimpleContentList, nsBaseContentList)
 
 JSObject*
 nsSimpleContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
   return NodeListBinding::Wrap(cx, this, aGivenProto);
 }
 
+NS_IMPL_CYCLE_COLLECTION_INHERITED(nsEmptyContentList, nsBaseContentList, mRoot)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsEmptyContentList)
+NS_INTERFACE_MAP_END_INHERITING(nsBaseContentList)
+
+
+NS_IMPL_ADDREF_INHERITED(nsEmptyContentList, nsBaseContentList)
+NS_IMPL_RELEASE_INHERITED(nsEmptyContentList, nsBaseContentList)
+
+JSObject*
+nsEmptyContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
+{
+  return NodeListBinding::Wrap(cx, this, aGivenProto);
+}
+
+NS_IMETHODIMP
+nsEmptyContentList::GetLength(uint32_t* aLength)
+{
+  *aLength = 0;
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsEmptyContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
+{
+  *aReturn = nullptr;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsEmptyContentList::NamedItem(const nsAString& aName, nsIDOMNode** aReturn)
+{
+  *aReturn = nullptr;
+  return NS_OK;
+}
+
+mozilla::dom::Element*
+nsEmptyContentList::GetElementAt(uint32_t index)
+{
+  return nullptr;
+}
+
+mozilla::dom::Element*
+nsEmptyContentList::GetFirstNamedElement(const nsAString& aName, bool& aFound)
+{
+  aFound = false;
+  return nullptr;
+}
+
+void
+nsEmptyContentList::GetSupportedNames(nsTArray<nsString>& aNames)
+{
+}
+
+nsIContent*
+nsEmptyContentList::Item(uint32_t aIndex)
+{
+  return nullptr;
+}
+
 // Hashtable for storing nsContentLists
 static PLDHashTable* gContentListHashTable;
 
 #define RECENTLY_USED_CONTENT_LIST_CACHE_SIZE 31
 static nsContentList*
   sRecentlyUsedContentLists[RECENTLY_USED_CONTENT_LIST_CACHE_SIZE] = {};
 
 static MOZ_ALWAYS_INLINE uint32_t
--- a/dom/base/nsContentList.h
+++ b/dom/base/nsContentList.h
@@ -134,16 +134,62 @@ public:
 protected:
   virtual ~nsSimpleContentList() {}
 
 private:
   // This has to be a strong reference, the root might go away before the list.
   nsCOMPtr<nsINode> mRoot;
 };
 
+// Used for returning lists that will always be empty, such as the applets list
+// in HTML Documents
+class nsEmptyContentList: public nsBaseContentList,
+                          public nsIHTMLCollection
+{
+public:
+  explicit nsEmptyContentList(nsINode* aRoot) : nsBaseContentList(),
+                                                mRoot(aRoot)
+  {
+  }
+
+  // nsIDOMHTMLCollection
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsEmptyContentList,
+                                           nsBaseContentList)
+  NS_DECL_NSIDOMHTMLCOLLECTION
+
+  virtual nsINode* GetParentObject() override
+  {
+    return mRoot;
+  }
+
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
+
+  virtual JSObject* GetWrapperPreserveColorInternal() override
+  {
+    return nsWrapperCache::GetWrapperPreserveColor();
+  }
+  virtual void PreserveWrapperInternal(nsISupports* aScriptObjectHolder) override
+  {
+    nsWrapperCache::PreserveWrapper(aScriptObjectHolder);
+  }
+
+  virtual nsIContent* Item(uint32_t aIndex) override;
+  virtual mozilla::dom::Element* GetElementAt(uint32_t index) override;
+  virtual mozilla::dom::Element*
+  GetFirstNamedElement(const nsAString& aName, bool& aFound) override;
+  virtual void GetSupportedNames(nsTArray<nsString>& aNames) override;
+
+protected:
+  virtual ~nsEmptyContentList() {}
+private:
+  // This has to be a strong reference, the root might go away before the list.
+  nsCOMPtr<nsINode> mRoot;
+};
+
 /**
  * Class that's used as the key to hash nsContentList implementations
  * for fast retrieval
  */
 struct nsContentListKey
 {
   // We have to take an aIsHTMLDocument arg for two reasons:
   // 1) We don't want to include nsIDocument.h in this header.
--- a/dom/base/nsHTMLContentSerializer.cpp
+++ b/dom/base/nsHTMLContentSerializer.cpp
@@ -113,20 +113,19 @@ nsHTMLContentSerializer::SerializeHTMLAt
     bool isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
 
     if (((attrName == nsGkAtoms::href &&
           (namespaceID == kNameSpaceID_None ||
            namespaceID == kNameSpaceID_XLink)) ||
          (attrName == nsGkAtoms::src && namespaceID == kNameSpaceID_None))) {
       // Make all links absolute when converting only the selection:
       if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
-        // Would be nice to handle OBJECT and APPLET tags,
-        // but that gets more complicated since we have to
-        // search the tag list for CODEBASE as well.
-        // For now, just leave them relative.
+        // Would be nice to handle OBJECT tags, but that gets more complicated
+        // since we have to search the tag list for CODEBASE as well. For now,
+        // just leave them relative.
         nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
         if (uri) {
           nsAutoString absURI;
           rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
           if (NS_SUCCEEDED(rv)) {
             valueStr = absURI;
           }
         }
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -817,42 +817,44 @@ public:
   virtual void BeginAddingChildren()
   {
   }
 
   /**
    * This method is called when the parser finishes creating the element's children,
    * if any are present.
    *
-   * NOTE: this is currently only called for textarea, select, applet, and
-   * object elements in the HTML content sink.  If you want
-   * to call it on your element, modify the content sink of your
-   * choice to do so.  This is an efficiency measure.
+   * NOTE: this is currently only called for textarea, select, and object
+   * elements in the HTML content sink. If you want to call it on your element,
+   * modify the content sink of your choice to do so. This is an efficiency
+   * measure.
    *
    * If you also need to determine whether the parser is the one creating your
    * element (through createElement() or cloneNode() generally) then add a
    * boolean aFromParser to the NS_NewXXX() constructor for your element and
    * have the parser pass true.  See HTMLInputElement.cpp and
    * nsHTMLContentSink::MakeContentObject().
    *
    * @param aHaveNotified Whether there has been a
    *        ContentInserted/ContentAppended notification for this content node
    *        yet.
    */
   virtual void DoneAddingChildren(bool aHaveNotified)
   {
   }
 
   /**
-   * For HTML textarea, select, applet, and object elements, returns
-   * true if all children have been added OR if the element was not
-   * created by the parser. Returns true for all other elements.
+   * For HTML textarea, select, and object elements, returns true if all
+   * children have been added OR if the element was not created by the parser.
+   * Returns true for all other elements.
+   *
    * @returns false if the element was created by the parser and
-   *                   it is an HTML textarea, select, applet, or object
+   *                   it is an HTML textarea, select, or object
    *                   element and not all children have been added.
+   *
    * @returns true otherwise.
    */
   virtual bool IsDoneAddingChildren()
   {
     return true;
   }
 
   /**
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3087,19 +3087,20 @@ protected:
   RefPtr<mozilla::css::Loader> mCSSLoader;
   RefPtr<mozilla::css::ImageLoader> mStyleImageLoader;
   RefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
   RefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
 
   // Tracking for images in the document.
   RefPtr<mozilla::dom::ImageTracker> mImageTracker;
 
-  // The set of all object, embed, applet, video/audio elements or
-  // nsIObjectLoadingContent or nsIDocumentActivity for which this is the
-  // owner document. (They might not be in the document.)
+  // The set of all object, embed, video/audio elements or
+  // nsIObjectLoadingContent or nsIDocumentActivity for which this is the owner
+  // document. (They might not be in the document.)
+  //
   // These are non-owning pointers, the elements are responsible for removing
   // themselves when they go away.
   nsAutoPtr<nsTHashtable<nsPtrHashKey<nsISupports> > > mActivityObservers;
 
   // The array of all links that need their status resolved.  Links must add themselves
   // to this set by calling RegisterPendingLinkUpdate when added to a document.
   static const size_t kSegmentSize = 128;
   mozilla::SegmentedVector<nsCOMPtr<mozilla::dom::Link>,
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -2935,18 +2935,17 @@ nsObjectLoadingContent::LoadFallback(Fal
   // child embeds as we find them in the upcoming loop.
   mType = eType_Null;
 
   bool thisIsObject = thisContent->IsHTMLElement(nsGkAtoms::object);
 
   // Do a depth-first traverse of node tree with the current element as root,
   // looking for <embed> or <object> elements that might now need to load.
   nsTArray<nsINodeList*> childNodes;
-  if ((thisContent->IsHTMLElement(nsGkAtoms::object) ||
-       thisContent->IsHTMLElement(nsGkAtoms::applet)) &&
+  if (thisContent->IsHTMLElement(nsGkAtoms::object) &&
       (aType == eFallbackUnsupported ||
        aType == eFallbackDisabled ||
        aType == eFallbackBlocklisted ||
        aType == eFallbackAlternate))
   {
     for (nsIContent* child = thisContent->GetFirstChild(); child; ) {
       // When we advance to our next child, we don't want to traverse subtrees
       // under descendant <object> and <embed> elements; those will handle
@@ -3767,21 +3766,16 @@ nsObjectLoadingContent::MaybeFireErrorEv
   }
 }
 
 bool
 nsObjectLoadingContent::BlockEmbedOrObjectContentLoading()
 {
   nsCOMPtr<nsIContent> thisContent =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
-  if (!thisContent->IsHTMLElement(nsGkAtoms::embed) &&
-      !thisContent->IsHTMLElement(nsGkAtoms::object)) {
-    // Doesn't apply to other elements (i.e. <applet>)
-    return false;
-  }
 
   // Traverse up the node tree to see if we have any ancestors that may block us
   // from loading
   for (nsIContent* parent = thisContent->GetParent();
        parent;
        parent = parent->GetParent()) {
     if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
       return true;
--- a/dom/base/nsObjectLoadingContent.h
+++ b/dom/base/nsObjectLoadingContent.h
@@ -2,17 +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/. */
 
 /*
  * A base class implementing nsIObjectLoadingContent for use by
  * various content nodes that want to provide plugin/document/image
- * loading functionality (eg <embed>, <object>, <applet>, etc).
+ * loading functionality (eg <embed>, <object>, etc).
  */
 
 #ifndef NSOBJECTLOADINGCONTENT_H_
 #define NSOBJECTLOADINGCONTENT_H_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "nsImageLoadingContent.h"
@@ -257,18 +257,18 @@ class nsObjectLoadingContent : public ns
 
     void PresetOpenerWindow(mozIDOMWindowProxy* aOpenerWindow, mozilla::ErrorResult& aRv);
 
   protected:
     /**
      * Begins loading the object when called
      *
      * Attributes of |this| QI'd to nsIContent will be inspected, depending on
-     * the node type. This function currently assumes it is a <applet>,
-     * <object>, or <embed> tag.
+     * the node type. This function currently assumes it is a <object> or
+     * <embed> tag.
      *
      * The instantiated plugin depends on:
      * - The URI (<embed src>, <object data>)
      * - The type 'hint' (type attribute)
      * - The mime type returned by opening the URI
      * - Enabled plugins claiming the ultimate mime type
      * - The capabilities returned by GetCapabilities
      * - The classid attribute, if eSupportClassID is among the capabilities
--- a/dom/base/nsSandboxFlags.h
+++ b/dom/base/nsSandboxFlags.h
@@ -37,19 +37,18 @@ const unsigned long SANDBOXED_AUXILIARY_
 /**
  * This flag prevents content from navigating their top-level browsing
  * context.
  */
 const unsigned long SANDBOXED_TOPLEVEL_NAVIGATION = 0x4;
 
 /**
  * This flag prevents content from instantiating plugins, whether using the
- * embed element, the object element, the applet element, or through
- * navigation of a nested browsing context, unless those plugins can be
- * secured.
+ * embed element, the object element, or through navigation of a nested browsing
+ * context, unless those plugins can be secured.
  */
 const unsigned long SANDBOXED_PLUGINS = 0x8;
 
 /**
  * This flag forces content into a unique origin, thus preventing it from
  * accessing other content from the same origin.
  * This flag also prevents script from reading from or writing to the
  * document.cookie IDL attribute, and blocks access to localStorage.
--- a/dom/base/nsXHTMLContentSerializer.cpp
+++ b/dom/base/nsXHTMLContentSerializer.cpp
@@ -294,17 +294,17 @@ nsXHTMLContentSerializer::SerializeAttri
 
       isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
 
       if (namespaceID == kNameSpaceID_None &&
           ((attrName == nsGkAtoms::href) ||
           (attrName == nsGkAtoms::src))) {
         // Make all links absolute when converting only the selection:
         if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
-          // Would be nice to handle OBJECT and APPLET tags,
+          // Would be nice to handle OBJECT tags,
           // but that gets more complicated since we have to
           // search the tag list for CODEBASE as well.
           // For now, just leave them relative.
           nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
           if (uri) {
             nsAutoString absURI;
             rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
             if (NS_SUCCEEDED(rv)) {
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -1566,18 +1566,17 @@ EventStateManager::FireContextClick()
     }
     else if (mGestureDownContent->IsHTMLElement()) {
       nsCOMPtr<nsIFormControl> formCtrl(do_QueryInterface(mGestureDownContent));
 
       if (formCtrl) {
         allowedToDispatch = formCtrl->IsTextOrNumberControl(/*aExcludePassword*/ false) ||
                             formCtrl->ControlType() == NS_FORM_INPUT_FILE;
       }
-      else if (mGestureDownContent->IsAnyOfHTMLElements(nsGkAtoms::applet,
-                                                        nsGkAtoms::embed,
+      else if (mGestureDownContent->IsAnyOfHTMLElements(nsGkAtoms::embed,
                                                         nsGkAtoms::object,
                                                         nsGkAtoms::label)) {
         allowedToDispatch = false;
       }
     }
 
     if (allowedToDispatch) {
       // init the event while mCurrentTarget is still good
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -65,17 +65,16 @@ HTMLAllCollection::Collection()
   }
   return mCollection;
 }
 
 static bool
 IsAllNamedElement(nsIContent* aContent)
 {
   return aContent->IsAnyOfHTMLElements(nsGkAtoms::a,
-                                       nsGkAtoms::applet,
                                        nsGkAtoms::button,
                                        nsGkAtoms::embed,
                                        nsGkAtoms::form,
                                        nsGkAtoms::iframe,
                                        nsGkAtoms::img,
                                        nsGkAtoms::input,
                                        nsGkAtoms::map,
                                        nsGkAtoms::meta,
--- a/dom/html/HTMLSharedObjectElement.cpp
+++ b/dom/html/HTMLSharedObjectElement.cpp
@@ -383,24 +383,17 @@ HTMLSharedObjectElement::WrapNode(JSCont
   JS::Rooted<JSObject*> rootedObj(aCx, obj);
   SetupProtoChain(aCx, rootedObj);
   return rootedObj;
 }
 
 nsContentPolicyType
 HTMLSharedObjectElement::GetContentPolicyType() const
 {
-  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
-    // We use TYPE_INTERNAL_OBJECT for applet too, since it is not exposed
-    // through RequestContext yet.
-    return nsIContentPolicy::TYPE_INTERNAL_OBJECT;
-  } else {
-    MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::embed));
-    return nsIContentPolicy::TYPE_INTERNAL_EMBED;
-  }
+  return nsIContentPolicy::TYPE_INTERNAL_EMBED;
 }
 
 NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Align, align)
 NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Width, width)
 NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Height, height)
 NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Name, name)
 NS_IMPL_URI_ATTR(HTMLSharedObjectElement, Src, src)
 NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Type, type)
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -691,31 +691,29 @@ public:
 
   static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
 
   static inline bool
   CanHaveName(nsIAtom* aTag)
   {
     return aTag == nsGkAtoms::img ||
            aTag == nsGkAtoms::form ||
-           aTag == nsGkAtoms::applet ||
            aTag == nsGkAtoms::embed ||
            aTag == nsGkAtoms::object;
   }
   static inline bool
   ShouldExposeNameAsHTMLDocumentProperty(Element* aElement)
   {
     return aElement->IsHTMLElement() &&
            CanHaveName(aElement->NodeInfo()->NameAtom());
   }
   static inline bool
   ShouldExposeIdAsHTMLDocumentProperty(Element* aElement)
   {
-    if (aElement->IsAnyOfHTMLElements(nsGkAtoms::applet,
-                                      nsGkAtoms::embed,
+    if (aElement->IsAnyOfHTMLElements(nsGkAtoms::embed,
                                       nsGkAtoms::object)) {
       return true;
     }
 
     // Per spec, <img> is exposed by id only if it also has a nonempty
     // name (which doesn't have to match the id or anything).
     // HasName() is true precisely when name is nonempty.
     return aElement->IsHTMLElement(nsGkAtoms::img) && aElement->HasName();
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1182,17 +1182,17 @@ nsHTMLDocument::GetApplets(nsIDOMHTMLCol
   NS_ADDREF(*aApplets = Applets());
   return NS_OK;
 }
 
 nsIHTMLCollection*
 nsHTMLDocument::Applets()
 {
   if (!mApplets) {
-    mApplets = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::applet, nsGkAtoms::applet);
+    mApplets = new nsEmptyContentList(this);
   }
   return mApplets;
 }
 
 bool
 nsHTMLDocument::MatchLinks(Element* aElement, int32_t aNamespaceID,
                            nsIAtom* aAtom, void* aData)
 {
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -304,17 +304,17 @@ protected:
   /**
    * Like IsEditingOn(), but will flush as needed first.
    */
   bool IsEditingOnAfterFlush();
 
   void *GenerateParserKey(void);
 
   RefPtr<nsContentList> mImages;
-  RefPtr<nsContentList> mApplets;
+  RefPtr<nsEmptyContentList> mApplets;
   RefPtr<nsContentList> mEmbeds;
   RefPtr<nsContentList> mLinks;
   RefPtr<nsContentList> mAnchors;
   RefPtr<nsContentList> mScripts;
   RefPtr<nsContentList> mForms;
   RefPtr<nsContentList> mFormControls;
 
   RefPtr<mozilla::dom::HTMLAllCollection> mAll;
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -606,8 +606,9 @@ skip-if = os == "android" # up/down arro
 [test_bug1310865.html]
 [test_bug1315146.html]
 [test_fakepath.html]
 [test_script_module.html]
 support-files =
   file_script_module.html
   file_script_nomodule.html
 [test_getElementsByName_after_mutation.html]
+[test_bug1279218.html]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/html/test/test_bug1279218.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <title>Test for Bug 1279218</title>
+    <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+    <script type="text/javascript">
+     function load() {
+       let applets = document.applets;
+       is(applets.length, 0, "Applet list length should be 0, even with applet tag in body");
+       SimpleTest.finish();
+     }
+
+     window.onload=load;
+
+     SimpleTest.waitForExplicitFinish();
+    </script>
+  </head>
+  <body>
+    <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1279218">Mozilla Bug 1279218</a>
+    <applet id="applet-test"></applet>
+  </body>
+</html>
--- a/dom/html/test/test_bug579079.html
+++ b/dom/html/test/test_bug579079.html
@@ -17,26 +17,23 @@ https://bugzilla.mozilla.org/show_bug.cg
   <embed name="embed1"></embed>
   <object name="object1"></object>
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 var img = document.img1;
 var form = document.form1;
-var applet = document.applet1;
 var embed = document.embed1;
 var object = document.object1;
 $("foo").innerHTML = $("foo").innerHTML;
 isnot(document.img1, img);
 ok(document.img1 instanceof HTMLImageElement);
 isnot(document.form1, form);
 ok(document.form1 instanceof HTMLFormElement);
-isnot(document.applet1, applet);
-ok(document.applet1 instanceof HTMLUnknownElement);
 isnot(document.embed1, embed);
 ok(document.embed1 instanceof HTMLEmbedElement);
 isnot(document.object1, object);
 ok(document.object1 instanceof HTMLObjectElement);
 </script>
 </pre>
 </body>
 </html>
--- a/dom/html/test/test_documentAll.html
+++ b/dom/html/test/test_documentAll.html
@@ -105,29 +105,29 @@ ok(testArraysSame(document.all, allElems
 length = document.all.length;
 expectedLength = length + p.getElementsByTagName("*").length + 1;
 p.appendChild(p.cloneNode(true));
 ok(testArraysSame(document.all, allElems), "arrays still same");
 is(document.all.length, expectedLength, "grew correctly");
 
 // Check which elements the 'name' attribute works on
 var elementNames =
-  ['applet','abbr','acronym','address','area','a','b','base',
+  ['abbr','acronym','address','area','a','b','base',
    'bgsound','big','blockquote','br','canvas','center','cite','code',
    'col','colgroup','dd','del','dfn','dir','div','dir','dl','dt','em','embed',
    'fieldset','font','form','frame','frameset','head','i','iframe','img',
    'input','ins','isindex','kbd','keygen','label','li','legend','link','menu',
    'multicol','noscript','noframes','object','spacer','table','td','td','th',
    'thead','tfoot','tr','textarea','select','option','spacer','param',
    'marquee','hr','title','hx','tt','u','ul','var','wbr','sub','sup','cite',
    'code','q','nobr','ol','p','pre','s','samp','small','body','html','map',
    'bdo','legend','listing','style','script','tbody','caption','meta',
    'optgroup','button','span','strike','strong','td'].sort();
 var hasName =
-  ['applet','a','embed','form','iframe','img','input','object','textarea',
+  ['a','embed','form','iframe','img','input','object','textarea',
    'select','map','meta','button','frame','frameset'].sort();
 
 elementNames.forEach(function (name) {
   nameval = 'namefor' + name;
 
   e = document.createElement(name);
   p.appendChild(e);
   e.setAttribute('name', nameval);
--- a/dom/plugins/base/nsIPluginInstanceOwner.idl
+++ b/dom/plugins/base/nsIPluginInstanceOwner.idl
@@ -12,18 +12,17 @@ interface nsIDocument;
 %{C++
 #include "npapi.h"
 #include "mozilla/EventForwards.h"
 class nsNPAPIPluginInstance;
 
 enum nsPluginTagType {
   nsPluginTagType_Unknown,
   nsPluginTagType_Embed,
-  nsPluginTagType_Object,
-  nsPluginTagType_Applet
+  nsPluginTagType_Object
 };
 %}
 
 [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
 
 // Do not make this interface scriptable, because the virtual functions in C++
 // blocks will make script call the wrong functions.
 [uuid(7d65452e-c167-4cba-a0e3-ddc61bdde8c3)]
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -740,17 +740,16 @@ nsPluginHost::InstantiatePluginInstance(
   nsPluginTagType tagType;
   rv = instanceOwner->GetTagType(&tagType);
   if (NS_FAILED(rv)) {
     instanceOwner->Destroy();
     return rv;
   }
 
   if (tagType != nsPluginTagType_Embed &&
-      tagType != nsPluginTagType_Applet &&
       tagType != nsPluginTagType_Object) {
     instanceOwner->Destroy();
     return NS_ERROR_FAILURE;
   }
 
   rv = SetUpPluginInstance(aMimeType, aURL, instanceOwner);
   if (NS_FAILED(rv)) {
     instanceOwner->Destroy();
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -74,17 +74,17 @@ public:
 
   NPError InitAsyncSurface(NPSize *size, NPImageFormat format,
                            void *initData, NPAsyncSurface *surface) override;
   NPError FinalizeAsyncSurface(NPAsyncSurface *surface) override;
   void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) override;
 
   /**
    * Get the type of the HTML tag that was used ot instantiate this
-   * plugin.  Currently supported tags are EMBED, OBJECT and APPLET.
+   * plugin.  Currently supported tags are EMBED or OBJECT.
    */
   NS_IMETHOD GetTagType(nsPluginTagType *aResult);
 
   void GetParameters(nsTArray<mozilla::dom::MozPluginParameter>& parameters);
   void GetAttributes(nsTArray<mozilla::dom::MozPluginParameter>& attributes);
 
   /**
    * Returns the DOM element corresponding to the tag which references
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -533,18 +533,17 @@ nsXMLContentSink::CloseElement(nsIConten
 
   // Some HTML nodes need DoneAddingChildren() called to initialize
   // properly (eg form state restoration).
   if ((nodeInfo->NamespaceID() == kNameSpaceID_XHTML &&
        (nodeInfo->NameAtom() == nsGkAtoms::select ||
         nodeInfo->NameAtom() == nsGkAtoms::textarea ||
         nodeInfo->NameAtom() == nsGkAtoms::video ||
         nodeInfo->NameAtom() == nsGkAtoms::audio ||
-        nodeInfo->NameAtom() == nsGkAtoms::object ||
-        nodeInfo->NameAtom() == nsGkAtoms::applet))
+        nodeInfo->NameAtom() == nsGkAtoms::object))
       || nodeInfo->NameAtom() == nsGkAtoms::title
       ) {
     aContent->DoneAddingChildren(HaveNotifiedForCurrentContent());
   }
 
   if (IsMonolithicContainer(nodeInfo)) {
     mInMonolithicContainer--;
   }
@@ -1555,18 +1554,17 @@ nsXMLContentSink::UpdateChildCounts()
 }
 
 bool
 nsXMLContentSink::IsMonolithicContainer(mozilla::dom::NodeInfo* aNodeInfo)
 {
   return ((aNodeInfo->NamespaceID() == kNameSpaceID_XHTML &&
           (aNodeInfo->NameAtom() == nsGkAtoms::tr ||
            aNodeInfo->NameAtom() == nsGkAtoms::select ||
-           aNodeInfo->NameAtom() == nsGkAtoms::object ||
-           aNodeInfo->NameAtom() == nsGkAtoms::applet)) ||
+           aNodeInfo->NameAtom() == nsGkAtoms::object)) ||
           (aNodeInfo->NamespaceID() == kNameSpaceID_MathML &&
           (aNodeInfo->NameAtom() == nsGkAtoms::math))
           );
 }
 
 void
 nsXMLContentSink::ContinueInterruptedParsingIfEnabled()
 {
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp
+++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp
@@ -283,17 +283,16 @@ txMozillaXMLOutput::endElement()
         if (element->IsHTMLElement()) {
             rv = endHTMLElement(element);
             NS_ENSURE_SUCCESS(rv, rv);
         }
 
         // Handle elements that are different when parser-created
         if (element->IsAnyOfHTMLElements(nsGkAtoms::title,
                                          nsGkAtoms::object,
-                                         nsGkAtoms::applet,
                                          nsGkAtoms::select,
                                          nsGkAtoms::textarea) ||
             element->IsSVGElement(nsGkAtoms::title)) {
             element->DoneAddingChildren(true);
         } else if (element->IsSVGElement(nsGkAtoms::script) ||
                    element->IsHTMLElement(nsGkAtoms::script)) {
             nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
             if (sele) {
--- a/editor/libeditor/HTMLEditUtils.cpp
+++ b/editor/libeditor/HTMLEditUtils.cpp
@@ -589,16 +589,20 @@ struct ElementInfo final
 #endif
 
 static const ElementInfo kElements[eHTMLTag_userdefined] = {
   ELEM(a, true, false, GROUP_SPECIAL, GROUP_INLINE_ELEMENT),
   ELEM(abbr, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(acronym, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(address, true, true, GROUP_BLOCK,
        GROUP_INLINE_ELEMENT | GROUP_P),
+  // While applet is no longer a valid tag, removing it here breaks the editor
+  // (compiles, but causes many tests to fail in odd ways). This list is tracked
+  // against the main HTML Tag list, so any changes will require more than just
+  // removing entries.
   ELEM(applet, true, true, GROUP_SPECIAL | GROUP_BLOCK,
        GROUP_FLOW_ELEMENT | GROUP_OBJECT_CONTENT),
   ELEM(area, false, false, GROUP_MAP_CONTENT, GROUP_NONE),
   ELEM(article, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(aside, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(audio, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(b, true, true, GROUP_FONTSTYLE, GROUP_INLINE_ELEMENT),
   ELEM(base, false, false, GROUP_HEAD_CONTENT, GROUP_NONE),
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -374,18 +374,17 @@ nsPluginFrame::PrepForDrawing(nsIWidget 
 #define EMBED_DEF_HEIGHT 200
 
 /* virtual */ nscoord
 nsPluginFrame::GetMinISize(gfxContext *aRenderingContext)
 {
   nscoord result = 0;
 
   if (!IsHidden(false)) {
-    if (mContent->IsAnyOfHTMLElements(nsGkAtoms::applet,
-                                      nsGkAtoms::embed)) {
+    if (mContent->IsHTMLElement(nsGkAtoms::embed)) {
       bool vertical = GetWritingMode().IsVertical();
       result = nsPresContext::CSSPixelsToAppUnits(
         vertical ? EMBED_DEF_HEIGHT : EMBED_DEF_WIDTH);
     }
   }
 
   DISPLAY_MIN_WIDTH(this, result);
   return result;
@@ -436,19 +435,18 @@ nsPluginFrame::GetDesiredSize(nsPresCont
 
   if (IsHidden(false)) {
     return;
   }
 
   aMetrics.Width() = aReflowInput.ComputedWidth();
   aMetrics.Height() = aReflowInput.ComputedHeight();
 
-  // for EMBED and APPLET, default to 240x200 for compatibility
-  if (mContent->IsAnyOfHTMLElements(nsGkAtoms::applet,
-                                    nsGkAtoms::embed)) {
+  // for EMBED, default to 240x200 for compatibility
+  if (mContent->IsHTMLElement(nsGkAtoms::embed)) {
     if (aMetrics.Width() == NS_UNCONSTRAINEDSIZE) {
       aMetrics.Width() = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH),
                                aReflowInput.ComputedMinWidth(),
                                aReflowInput.ComputedMaxWidth());
     }
     if (aMetrics.Height() == NS_UNCONSTRAINEDSIZE) {
       aMetrics.Height() = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_HEIGHT),
                                 aReflowInput.ComputedMinHeight(),
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -1250,17 +1250,17 @@ nsSubDocumentFrame::EnsureInnerView()
   return mInnerView;
 }
 
 nsIFrame*
 nsSubDocumentFrame::ObtainIntrinsicSizeFrame()
 {
   nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(GetContent());
   if (olc) {
-    // We are an HTML <object>, <embed> or <applet> (a replaced element).
+    // We are an HTML <object> or <embed> (a replaced element).
 
     // Try to get an nsIFrame for our sub-document's document element
     nsIFrame* subDocRoot = nullptr;
 
     nsCOMPtr<nsIDocShell> docShell;
     GetDocShell(getter_AddRefs(docShell));
     if (docShell) {
       nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
--- a/layout/generic/nsSubDocumentFrame.h
+++ b/layout/generic/nsSubDocumentFrame.h
@@ -148,17 +148,17 @@ protected:
   nscoord GetIntrinsicBSize();
 
   // Show our document viewer. The document viewer is hidden via a script
   // runner, so that we can save and restore the presentation if we're
   // being reframed.
   void ShowViewer();
 
   /* Obtains the frame we should use for intrinsic size information if we are
-   * an HTML <object>, <embed> or <applet> (a replaced element - not <iframe>)
+   * an HTML <object> or <embed>  (a replaced element - not <iframe>)
    * and our sub-document has an intrinsic size. The frame returned is the
    * frame for the document element of the document we're embedding.
    *
    * Called "Obtain*" and not "Get*" because of comment on GetDocShell that
    * says it should be called ObtainDocShell because of its side effects.
    */
   nsIFrame* ObtainIntrinsicSizeFrame();
 
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -925,18 +925,17 @@ nsSVGOuterSVGFrame::IsRootOfReplacedElem
     }
 
     if (window) {
       nsCOMPtr<nsIDOMElement> frameElement = window->GetFrameElement();
       nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(frameElement);
       nsCOMPtr<nsIDOMHTMLIFrameElement> iframeElement =
         do_QueryInterface(frameElement);
       if (olc || iframeElement) {
-        // Our document is inside an HTML 'object', 'embed', 'applet'
-        // or 'iframe' element
+        // Our document is inside an HTML 'object', 'embed' or 'iframe' element
         if (aEmbeddingFrame) {
           nsCOMPtr<nsIContent> element = do_QueryInterface(frameElement);
           *aEmbeddingFrame = element->GetPrimaryFrame();
           NS_ASSERTION(*aEmbeddingFrame, "Yikes, no embedding frame!");
         }
         return true;
       }
     }
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -166,17 +166,17 @@ public:
 
   nsRegion FindInvalidatedForeignObjectFrameChildren(nsIFrame* aFrame);
 
 protected:
 
   bool mCallingReflowSVG;
 
   /* Returns true if our content is the document element and our document is
-   * embedded in an HTML 'object', 'embed' or 'applet' element. Set
+   * embedded in an HTML 'object' or 'embed' element. Set
    * aEmbeddingFrame to obtain the nsIFrame for the embedding HTML element.
    */
   bool IsRootOfReplacedElementSubDoc(nsIFrame **aEmbeddingFrame = nullptr);
 
   /* Returns true if our content is the document element and our document is
    * being used as an image.
    */
   bool IsRootOfImage();
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -894,18 +894,19 @@ nsHtml5TreeBuilder::elementPopped(int32_
       treeOp->Init(eTreeOpSvgLoad, aElement);
     }
     return;
   }
   // we now have only HTML
   // Some HTML nodes need DoneAddingChildren() called to initialize
   // properly (e.g. form state restoration).
   // XXX expose ElementName group here and do switch
-  if (aName == nsGkAtoms::object || aName == nsGkAtoms::applet ||
-      aName == nsGkAtoms::select || aName == nsGkAtoms::textarea ||
+  if (aName == nsGkAtoms::object ||
+      aName == nsGkAtoms::select ||
+      aName == nsGkAtoms::textarea ||
       aName == nsGkAtoms::output) {
     if (mBuilder) {
       nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
       return;
     }
     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     treeOp->Init(eTreeOpDoneAddingChildren, aElement);