dom/html/nsHTMLDocument.h
author Jan de Mooij <jdemooij@mozilla.com>
Thu, 15 Aug 2019 16:13:57 +0000
changeset 488278 8bf0e43c0df043e3527a419e095e641ff52bfcb4
parent 487597 53bd948e892d744cfee7cc7094dabcb8e292ba8a
child 489204 fccf3343d88dd40d04e601c05fdc2293fa149dde
permissions -rw-r--r--
Bug 1505689 part 6 - Merge TraceJitScripts into JitScript::trace. r=tcampbell This also removes BaselineScript::Trace and IonScript::Trace that were just forwarding to the non-static trace(). Differential Revision: https://phabricator.services.mozilla.com/D41708

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 nsHTMLDocument_h___
#define nsHTMLDocument_h___

#include "mozilla/Attributes.h"
#include "nsContentList.h"
#include "mozilla/dom/Document.h"
#include "nsIHTMLCollection.h"
#include "nsIScriptElement.h"
#include "nsTArray.h"

#include "PLDHashTable.h"
#include "nsIHttpChannel.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/HTMLSharedElement.h"
#include "mozilla/dom/BindingDeclarations.h"

class nsCommandManager;
class nsIURI;
class nsIDocShell;
class nsICachingChannel;
class nsILoadGroup;

namespace mozilla {
namespace dom {
template <typename T>
struct Nullable;
class WindowProxyHolder;
}  // namespace dom
}  // namespace mozilla

class nsHTMLDocument : public mozilla::dom::Document {
 protected:
  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
  typedef mozilla::dom::Document Document;
  typedef mozilla::Encoding Encoding;
  template <typename T>
  using NotNull = mozilla::NotNull<T>;

 public:
  using Document::GetPlugins;
  using Document::SetDocumentURI;

  nsHTMLDocument();
  virtual nsresult Init() override;

  // Document
  virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override;
  virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
                          nsIPrincipal* aPrincipal,
                          nsIPrincipal* aStoragePrincipal) override;

  virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
                                     nsILoadGroup* aLoadGroup,
                                     nsISupports* aContainer,
                                     nsIStreamListener** aDocListener,
                                     bool aReset = true,
                                     nsIContentSink* aSink = nullptr) override;

 protected:
  virtual bool UseWidthDeviceWidthFallbackViewport() const override;

 public:
  virtual Element* GetUnfocusedKeyEventTarget() override;

  nsContentList* GetExistingForms() const { return mForms; }

  // Returns whether an object was found for aName.
  bool ResolveName(JSContext* aCx, const nsAString& aName,
                   JS::MutableHandle<JS::Value> aRetval,
                   mozilla::ErrorResult& aError);

  /**
   * Called when form->BindToTree() is called so that document knows
   * immediately when a form is added
   */
  void AddedForm();
  /**
   * Called when form->SetDocument() is called so that document knows
   * immediately when a form is removed
   */
  void RemovedForm();
  /**
   * Called to get a better count of forms than document.forms can provide
   * without calling FlushPendingNotifications (bug 138892).
   */
  // XXXbz is this still needed now that we can flush just content,
  // not the rest?
  int32_t GetNumFormsSynchronous();
  void SetIsXHTML(bool aXHTML) { mType = (aXHTML ? eXHTML : eHTML); }

  virtual nsresult Clone(mozilla::dom::NodeInfo*,
                         nsINode** aResult) const override;

  using mozilla::dom::DocumentOrShadowRoot::GetElementById;

  virtual void DocAddSizeOfExcludingThis(
      nsWindowSizes& aWindowSizes) const override;
  // DocAddSizeOfIncludingThis is inherited from Document.

  virtual bool WillIgnoreCharsetOverride() override;

  // WebIDL API
  virtual JSObject* WrapNode(JSContext* aCx,
                             JS::Handle<JSObject*> aGivenProto) override;
  bool IsRegistrableDomainSuffixOfOrEqualTo(const nsAString& aHostSuffixString,
                                            const nsACString& aOrigHost);
  void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
                   JS::MutableHandle<JSObject*> aRetval,
                   mozilla::ErrorResult& rv) {
    JS::Rooted<JS::Value> v(cx);
    if ((aFound = ResolveName(cx, aName, &v, rv))) {
      SetDocumentAndPageUseCounter(
          mozilla::eUseCounter_custom_HTMLDocumentNamedGetterHit);
      aRetval.set(v.toObjectOrNull());
    }
  }
  void GetSupportedNames(nsTArray<nsString>& aNames);
  // We're picking up GetLocation from Document
  already_AddRefed<mozilla::dom::Location> GetLocation() const {
    return Document::GetLocation();
  }

  static bool MatchFormControls(Element* aElement, int32_t aNamespaceID,
                                nsAtom* aAtom, void* aData);

  void GetFormsAndFormControls(nsContentList** aFormList,
                               nsContentList** aFormControlList);

 protected:
  ~nsHTMLDocument();

  nsresult GetBodySize(int32_t* aWidth, int32_t* aHeight);

  nsIContent* MatchId(nsIContent* aContent, const nsAString& aId);

  static void DocumentWriteTerminationFunc(nsISupports* aRef);

  // A helper class to keep nsContentList objects alive for a short period of
  // time. Note, when the final Release is called on an nsContentList object, it
  // removes itself from MutationObserver list.
  class ContentListHolder : public mozilla::Runnable {
   public:
    ContentListHolder(nsHTMLDocument* aDocument, nsContentList* aFormList,
                      nsContentList* aFormControlList)
        : mozilla::Runnable("ContentListHolder"),
          mDocument(aDocument),
          mFormList(aFormList),
          mFormControlList(aFormControlList) {}

    ~ContentListHolder() {
      MOZ_ASSERT(!mDocument->mContentListHolder ||
                 mDocument->mContentListHolder == this);
      mDocument->mContentListHolder = nullptr;
    }

    RefPtr<nsHTMLDocument> mDocument;
    RefPtr<nsContentList> mFormList;
    RefPtr<nsContentList> mFormControlList;
  };

  friend class ContentListHolder;
  ContentListHolder* mContentListHolder;

  /** # of forms in the document, synchronously set */
  int32_t mNumForms;

  static void TryHintCharset(nsIContentViewer* aContentViewer,
                             int32_t& aCharsetSource,
                             NotNull<const Encoding*>& aEncoding);
  void TryUserForcedCharset(nsIContentViewer* aCv, nsIDocShell* aDocShell,
                            int32_t& aCharsetSource,
                            NotNull<const Encoding*>& aEncoding);
  static void TryCacheCharset(nsICachingChannel* aCachingChannel,
                              int32_t& aCharsetSource,
                              NotNull<const Encoding*>& aEncoding);
  void TryParentCharset(nsIDocShell* aDocShell, int32_t& charsetSource,
                        NotNull<const Encoding*>& aEncoding);
  void TryTLD(int32_t& aCharsetSource, NotNull<const Encoding*>& aCharset);
  static void TryFallback(int32_t& aCharsetSource,
                          NotNull<const Encoding*>& aEncoding);

  // Load flags of the document's channel
  uint32_t mLoadFlags;

  bool mWarnedWidthHeight;

  /**
   * Set to true once we know that we are loading plain text content.
   */
  bool mIsPlainText;
};

namespace mozilla {
namespace dom {

inline nsHTMLDocument* Document::AsHTMLDocument() {
  MOZ_ASSERT(IsHTMLOrXHTML());
  return static_cast<nsHTMLDocument*>(this);
}

}  // namespace dom
}  // namespace mozilla

#endif /* nsHTMLDocument_h___ */