tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsContentUtils.h (155195B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* A namespace class for static content utilities. */
      8 
      9 #ifndef nsContentUtils_h___
     10 #define nsContentUtils_h___
     11 
     12 #if defined(XP_WIN)
     13 #  include <float.h>
     14 #endif
     15 
     16 #if defined(SOLARIS)
     17 #  include <ieeefp.h>
     18 #endif
     19 
     20 #include <cstddef>
     21 #include <cstdint>
     22 #include <functional>
     23 #include <tuple>
     24 
     25 #include "ErrorList.h"
     26 #include "Units.h"
     27 #include "js/Id.h"
     28 #include "js/RegExpFlags.h"
     29 #include "js/RootingAPI.h"
     30 #include "mozilla/AlreadyAddRefed.h"
     31 #include "mozilla/Assertions.h"
     32 #include "mozilla/Attributes.h"
     33 #include "mozilla/BasicEvents.h"
     34 #include "mozilla/CORSMode.h"
     35 #include "mozilla/CallState.h"
     36 #include "mozilla/FunctionRef.h"
     37 #include "mozilla/Maybe.h"
     38 #include "mozilla/RefPtr.h"
     39 #include "mozilla/SourceLocation.h"
     40 #include "mozilla/TimeStamp.h"
     41 #include "mozilla/dom/BindingDeclarations.h"
     42 #include "mozilla/dom/CacheExpirationTime.h"
     43 #include "mozilla/dom/FetchPriority.h"
     44 #include "mozilla/dom/FromParser.h"
     45 #include "mozilla/fallible.h"
     46 #include "mozilla/gfx/Point.h"
     47 #include "nsCOMPtr.h"
     48 #include "nsIContentPolicy.h"
     49 #include "nsINode.h"
     50 #include "nsIScriptError.h"
     51 #include "nsIThread.h"
     52 #include "nsLiteralString.h"
     53 #include "nsMargin.h"
     54 #include "nsPIDOMWindow.h"
     55 #include "nsRFPService.h"
     56 #include "nsStringFwd.h"
     57 #include "nsTArray.h"
     58 #include "nsTLiteralString.h"
     59 #include "prtime.h"
     60 
     61 #if defined(XP_WIN)
     62 // Undefine LoadImage to prevent naming conflict with Windows.
     63 #  undef LoadImage
     64 #endif
     65 
     66 class JSObject;
     67 class imgICache;
     68 class imgIContainer;
     69 class imgINotificationObserver;
     70 class imgIRequest;
     71 class imgLoader;
     72 class imgRequestProxy;
     73 class nsAtom;
     74 class nsAttrValue;
     75 class nsAutoScriptBlockerSuppressNodeRemoved;
     76 class nsContentList;
     77 class nsCycleCollectionTraversalCallback;
     78 class nsDocShell;
     79 class nsGlobalWindowInner;
     80 class nsHtml5StringParser;
     81 class nsIArray;
     82 class nsIBidiKeyboard;
     83 class nsIChannel;
     84 class nsIConsoleService;
     85 class nsIContent;
     86 class nsIDocShell;
     87 class nsIDocShellTreeItem;
     88 class nsIDocumentLoaderFactory;
     89 class nsIDragSession;
     90 class nsIFile;
     91 class nsIFragmentContentSink;
     92 class nsIFrame;
     93 class nsIHttpChannel;
     94 class nsIIOService;
     95 class nsIImageLoadingContent;
     96 class nsIInterfaceRequestor;
     97 class nsILoadGroup;
     98 class nsILoadInfo;
     99 class nsIObserver;
    100 class nsIPrincipal;
    101 class nsIReferrerInfo;
    102 class nsIRequest;
    103 class nsIRunnable;
    104 class nsIScreen;
    105 class nsIScriptContext;
    106 class nsIScriptSecurityManager;
    107 class nsISerialEventTarget;
    108 class nsIStringBundle;
    109 class nsIStringBundleService;
    110 class nsISupports;
    111 class nsITransferable;
    112 class nsIURI;
    113 class nsIWidget;
    114 class nsIWritableVariant;
    115 class nsIXPConnect;
    116 class nsNodeInfoManager;
    117 class nsParser;
    118 class nsPIWindowRoot;
    119 class nsPresContext;
    120 class nsWrapperCache;
    121 enum class WindowMediatorFilter : uint8_t;
    122 
    123 struct JSContext;
    124 struct nsPoint;
    125 
    126 namespace IPC {
    127 class Message;
    128 class MessageReader;
    129 class MessageWriter;
    130 }  // namespace IPC
    131 
    132 namespace JS {
    133 class Value;
    134 class PropertyDescriptor;
    135 }  // namespace JS
    136 
    137 namespace mozilla {
    138 class Dispatcher;
    139 class EditorBase;
    140 class ErrorResult;
    141 class EventListenerManager;
    142 class HTMLEditor;
    143 class LazyLogModule;
    144 class LogModule;
    145 class PresShell;
    146 class StringBuffer;
    147 class TextEditor;
    148 class WidgetDragEvent;
    149 class WidgetKeyboardEvent;
    150 
    151 struct InputEventOptions;
    152 
    153 template <typename ParentType, typename RefType>
    154 class RangeBoundaryBase;
    155 
    156 template <typename T>
    157 class NotNull;
    158 template <class T>
    159 class OwningNonNull;
    160 template <class T>
    161 class StaticRefPtr;
    162 
    163 namespace dom {
    164 class IPCImage;
    165 struct AutocompleteInfo;
    166 class BrowserChild;
    167 class BrowserParent;
    168 class BrowsingContext;
    169 class BrowsingContextGroup;
    170 class ContentChild;
    171 class ContentFrameMessageManager;
    172 class ContentParent;
    173 struct CustomElementDefinition;
    174 class CustomElementFormValue;
    175 class CustomElementRegistry;
    176 class DataTransfer;
    177 class Document;
    178 class DocumentFragment;
    179 class DOMArena;
    180 class Element;
    181 class Event;
    182 class EventTarget;
    183 class FragmentOrElement;
    184 class HTMLElement;
    185 class HTMLInputElement;
    186 class IPCTransferable;
    187 class IPCTransferableData;
    188 class IPCTransferableDataImageContainer;
    189 class IPCTransferableDataItem;
    190 struct LifecycleCallbackArgs;
    191 class MessageBroadcaster;
    192 class NodeInfo;
    193 class OwningFileOrUSVStringOrFormData;
    194 class Selection;
    195 struct SetHTMLOptions;
    196 struct SetHTMLUnsafeOptions;
    197 enum class ShadowRootMode : uint8_t;
    198 class ShadowRoot;
    199 struct StructuredSerializeOptions;
    200 struct SynthesizeMouseEventData;
    201 struct SynthesizeMouseEventOptions;
    202 class TrustedHTMLOrString;
    203 class VoidFunction;
    204 class WorkerPrivate;
    205 enum class ElementCallbackType;
    206 enum class ReferrerPolicy : uint8_t;
    207 }  // namespace dom
    208 
    209 namespace ipc {
    210 class BigBuffer;
    211 class IProtocol;
    212 }  // namespace ipc
    213 
    214 namespace gfx {
    215 class DataSourceSurface;
    216 enum class SurfaceFormat : int8_t;
    217 }  // namespace gfx
    218 
    219 class WindowRenderer;
    220 
    221 }  // namespace mozilla
    222 
    223 extern const char kLoadAsData[];
    224 
    225 // Stolen from nsReadableUtils, but that's OK, since we can declare the same
    226 // name multiple times.
    227 const nsString& EmptyString();
    228 const nsCString& EmptyCString();
    229 
    230 enum EventNameType {
    231  EventNameType_None = 0x0000,
    232  EventNameType_HTML = 0x0001,
    233  EventNameType_XUL = 0x0002,
    234  EventNameType_SVGGraphic = 0x0004,  // svg graphic elements
    235  EventNameType_SVGSVG = 0x0008,      // the svg element
    236  EventNameType_SMIL = 0x0010,        // smil elements
    237  EventNameType_HTMLBodyOrFramesetOnly = 0x0020,
    238  EventNameType_HTMLMedia = 0x0040,
    239 
    240  EventNameType_HTMLXUL = 0x0003,
    241  EventNameType_All = 0xFFFF
    242 };
    243 
    244 enum class TreeKind : uint8_t { DOM, ShadowIncludingDOM, Flat };
    245 
    246 enum class SerializeShadowRoots : uint8_t { Yes, No };
    247 
    248 struct EventNameMapping {
    249  // This holds pointers to nsGkAtoms members, and is therefore safe as a
    250  // non-owning reference.
    251  nsAtom* MOZ_NON_OWNING_REF mAtom;
    252  int32_t mType;
    253  mozilla::EventMessage mMessage;
    254  mozilla::EventClassID mEventClassID;
    255 };
    256 
    257 namespace mozilla::dom {
    258 enum JSONBehavior { UndefinedIsNullStringLiteral, UndefinedIsVoidString };
    259 }  // namespace mozilla::dom
    260 
    261 class nsContentUtils {
    262  friend class nsAutoScriptBlockerSuppressNodeRemoved;
    263  using Element = mozilla::dom::Element;
    264  using Document = mozilla::dom::Document;
    265  using Cancelable = mozilla::Cancelable;
    266  using CanBubble = mozilla::CanBubble;
    267  using Composed = mozilla::Composed;
    268  using ChromeOnlyDispatch = mozilla::ChromeOnlyDispatch;
    269  using EventMessage = mozilla::EventMessage;
    270  using TimeDuration = mozilla::TimeDuration;
    271  using Trusted = mozilla::Trusted;
    272  using JSONBehavior = mozilla::dom::JSONBehavior;
    273  using RFPTarget = mozilla::RFPTarget;
    274  using SystemGroupOnly = mozilla::SystemGroupOnly;
    275 
    276 public:
    277  static nsresult Init();
    278 
    279  static bool IsCallerChrome();
    280  static bool ThreadsafeIsCallerChrome();
    281  static bool IsCallerUAWidget();
    282  static bool IsFuzzingEnabled()
    283 #ifndef FUZZING
    284  {
    285    return false;
    286  }
    287 #else
    288      ;
    289 #endif
    290  static bool IsErrorPage(nsIURI* aURI);
    291 
    292  static bool IsCallerChromeOrFuzzingEnabled(JSContext* aCx, JSObject*) {
    293    return ThreadsafeIsSystemCaller(aCx) || IsFuzzingEnabled();
    294  }
    295 
    296  static bool IsCallerChromeOrElementTransformGettersEnabled(JSContext* aCx,
    297                                                             JSObject*);
    298 
    299  // The APIs for checking whether the caller is system (in the sense of system
    300  // principal) should only be used when the JSContext is known to accurately
    301  // represent the caller.  In practice, that means you should only use them in
    302  // two situations at the moment:
    303  //
    304  // 1) Functions used in WebIDL Func annotations.
    305  // 2) Bindings code or other code called directly from the JS engine.
    306  //
    307  // Use pretty much anywhere else is almost certainly wrong and should be
    308  // replaced with [NeedsCallerType] annotations in bindings.
    309 
    310  // Check whether the caller is system if you know you're on the main thread.
    311  static bool IsSystemCaller(JSContext* aCx);
    312 
    313  // Check whether the caller is system if you might be on a worker or worklet
    314  // thread.
    315  static bool ThreadsafeIsSystemCaller(JSContext* aCx);
    316 
    317  // In the traditional Gecko architecture, both C++ code and untrusted JS code
    318  // needed to rely on the same XPCOM method/getter/setter to get work done.
    319  // This required lots of security checks in the various exposed methods, which
    320  // in turn created difficulty in determining whether the caller was script
    321  // (whose access needed to be checked) and internal C++ platform code (whose
    322  // access did not need to be checked). To address this problem, Gecko had a
    323  // convention whereby the absence of script on the stack was interpretted as
    324  // "System Caller" and always granted unfettered access.
    325  //
    326  // Unfortunately, this created a bunch of footguns. For example, when the
    327  // implementation of a DOM method wanted to perform a privileged
    328  // sub-operation, it needed to "hide" the presence of script on the stack in
    329  // order for that sub-operation to be allowed. Additionally, if script could
    330  // trigger an API entry point to be invoked in some asynchronous way without
    331  // script on the stack, it could potentially perform privilege escalation.
    332  //
    333  // In the modern world, untrusted script should interact with the platform
    334  // exclusively over WebIDL APIs, and platform code has a lot more flexibility
    335  // in deciding whether or not to use XPCOM. This gives us the flexibility to
    336  // do something better.
    337  //
    338  // Going forward, APIs should be designed such that any security checks that
    339  // ask the question "is my caller allowed to do this?" should live in WebIDL
    340  // API entry points, with a separate method provided for internal callers
    341  // that just want to get the job done.
    342  //
    343  // To enforce this and catch bugs, nsContentUtils::SubjectPrincipal will crash
    344  // if it is invoked without script on the stack. To land that transition, it
    345  // was necessary to go through and whitelist a bunch of callers that were
    346  // depending on the old behavior. Those callers should be fixed up, and these
    347  // methods should not be used by new code without review from bholley or bz.
    348  static bool LegacyIsCallerNativeCode() { return !GetCurrentJSContext(); }
    349  static bool LegacyIsCallerChromeOrNativeCode() {
    350    return LegacyIsCallerNativeCode() || IsCallerChrome();
    351  }
    352  static nsIPrincipal* SubjectPrincipalOrSystemIfNativeCaller() {
    353    if (!GetCurrentJSContext()) {
    354      return GetSystemPrincipal();
    355    }
    356    return SubjectPrincipal();
    357  }
    358 
    359  static bool LookupBindingMember(
    360      JSContext* aCx, nsIContent* aContent, JS::Handle<jsid> aId,
    361      JS::MutableHandle<JS::PropertyDescriptor> aDesc);
    362 
    363  // Check whether we should avoid leaking distinguishing information to JS/CSS.
    364  // This function can be called both in the main thread and worker threads.
    365  static bool ShouldResistFingerprinting(bool aIsPrivateMode,
    366                                         RFPTarget aTarget);
    367  static bool ShouldResistFingerprinting(nsIGlobalObject* aGlobalObject,
    368                                         RFPTarget aTarget);
    369  // Similar to the function above, but always allows CallerType::System
    370  // callers.
    371  static bool ShouldResistFingerprinting(mozilla::dom::CallerType aCallerType,
    372                                         nsIGlobalObject* aGlobalObject,
    373                                         RFPTarget aTarget);
    374  static bool ShouldResistFingerprinting(nsIDocShell* aDocShell,
    375                                         RFPTarget aTarget);
    376  static bool ShouldResistFingerprinting(const Document* aDocument,
    377                                         RFPTarget aTarget);
    378  // These functions are the new, nuanced functions
    379  static bool ShouldResistFingerprinting(nsIChannel* aChannel,
    380                                         RFPTarget aTarget);
    381  // These functions are labeled as dangerous because they will do the wrong
    382  // thing in _most_ cases. They should only be used if you don't have a fully
    383  // constructed LoadInfo or Document.
    384  // A constant string used as justification is required when calling them,
    385  // it should explain why a Document, Channel, LoadInfo, or CookieJarSettings
    386  // does not exist in this context.
    387  // (see below for more on justification strings.)
    388  static bool ShouldResistFingerprinting_dangerous(
    389      nsIURI* aURI, const mozilla::OriginAttributes& aOriginAttributes,
    390      const char* aJustification, RFPTarget aTarget);
    391  static bool ShouldResistFingerprinting_dangerous(nsIPrincipal* aPrincipal,
    392                                                   const char* aJustification,
    393                                                   RFPTarget aTarget);
    394 
    395  /**
    396   * Implement a RFP function that only checks the pref, and does not take
    397   * into account any additional context such as PBM mode or Web Extensions.
    398   *
    399   * It requires an explanation for why the coarse check is being used instead
    400   * of the nuanced check. While there is a gradual cut over of
    401   * ShouldResistFingerprinting calls to a nuanced API, some features still
    402   * require a legacy function. (Additionally, we sometimes use the coarse
    403   * check first, to avoid running additional code to support a nuanced check.)
    404   */
    405  static bool ShouldResistFingerprinting(const char* aJustification,
    406                                         RFPTarget aTarget);
    407 
    408  static bool ETPSaysShouldNotResistFingerprinting(
    409      nsICookieJarSettings* aCookieJarSettings, bool aIsPBM);
    410 
    411  static bool ETPSaysShouldNotResistFingerprinting(nsIChannel* aChannel,
    412                                                   nsILoadInfo* aLoadInfo);
    413 
    414  // A helper function to calculate the rounded window size for fingerprinting
    415  // resistance. The rounded size is based on the chrome UI size and available
    416  // screen size. If the inputWidth/Height is greater than the available content
    417  // size, this will report the available content size. Otherwise, it will
    418  // round the size to the nearest upper 200x100.
    419  static void CalcRoundedWindowSizeForResistingFingerprinting(
    420      int32_t aChromeWidth, int32_t aChromeHeight, int32_t aScreenWidth,
    421      int32_t aScreenHeight, int32_t aInputWidth, int32_t aInputHeight,
    422      bool aSetOuterWidth, bool aSetOuterHeight, int32_t* aOutputWidth,
    423      int32_t* aOutputHeight);
    424 
    425  // Tell if we actually want to round size of new windows for RFP,
    426  // depending on letterboxing status and user's preference.
    427  static bool ShouldRoundWindowSizeForResistingFingerprinting();
    428 
    429  /**
    430   * Returns the parent node of aChild crossing document boundaries, but skips
    431   * any cross-process parent frames and continues with the nearest in-process
    432   * frame in the hierarchy.
    433   *
    434   * Uses the parent node in the composed document.
    435   */
    436  static nsINode* GetNearestInProcessCrossDocParentNode(nsINode* aChild);
    437 
    438  /**
    439   * Similar to nsINode::IsInclusiveDescendantOf, except will treat an
    440   * HTMLTemplateElement or ShadowRoot as an ancestor of things in the
    441   * corresponding DocumentFragment. See the concept of "host-including
    442   * inclusive ancestor" in the DOM specification.
    443   */
    444  static bool ContentIsHostIncludingDescendantOf(
    445      const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
    446 
    447  /**
    448   * Similar to nsINode::IsInclusiveDescendantOf except it crosses document
    449   * boundaries, this function uses ancestor/descendant relations in the
    450   * composed document (see shadow DOM spec).
    451   */
    452  static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
    453                                            nsINode* aPossibleAncestor);
    454 
    455  /**
    456   * As with ContentIsCrossDocDescendantOf but crosses shadow boundaries but not
    457   * cross document boundaries.
    458   *
    459   * @see nsINode::GetFlattenedTreeParentNode()
    460   */
    461  static bool ContentIsFlattenedTreeDescendantOf(
    462      const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
    463 
    464  /**
    465   * Same as `ContentIsFlattenedTreeDescendantOf`, but from the flattened tree
    466   * point of view of the style system
    467   *
    468   * @see nsINode::GetFlattenedTreeParentNodeForStyle()
    469   */
    470  static bool ContentIsFlattenedTreeDescendantOfForStyle(
    471      const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
    472 
    473  /**
    474   * Retarget an object A against an object B
    475   * @see https://dom.spec.whatwg.org/#retarget
    476   */
    477  static nsINode* Retarget(nsINode* aTargetA, const nsINode* aTargetB);
    478 
    479  /**
    480   * @see https://wicg.github.io/element-timing/#get-an-element
    481   */
    482  static Element* GetAnElementForTiming(Element* aTarget,
    483                                        const Document* aDocument,
    484                                        nsIGlobalObject* aGlobal);
    485 
    486  /*
    487   * https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor.
    488   *
    489   * This method fills the |aArray| with all ancestor nodes of |aNode|
    490   * including |aNode| at the zero index.
    491   *
    492   */
    493  static nsresult GetInclusiveAncestors(nsINode* aNode,
    494                                        nsTArray<nsINode*>& aArray);
    495 
    496  /*
    497   * https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor.
    498   *
    499   * This method fills |aAncestorNodes| with all ancestor nodes of |aNode|
    500   * including |aNode| (QI'd to nsIContent) at the zero index.
    501   * For each ancestor, there is a corresponding element in |aAncestorOffsets|
    502   * which is the ComputeIndexOf the child in relation to its parent.
    503   *
    504   * This method just sucks.
    505   */
    506  static nsresult GetInclusiveAncestorsAndOffsets(
    507      nsINode* aNode, uint32_t aOffset, nsTArray<nsIContent*>& aAncestorNodes,
    508      nsTArray<mozilla::Maybe<uint32_t>>& aAncestorOffsets);
    509 
    510  /*
    511   * Similar as the GetInclusiveAncestorsAndOffsets method, but for flat tree.
    512   *
    513   * When the current content is a ShadowRoot, the offset of it from
    514   * its ancestor (the host element) will be Nothing().
    515   */
    516  static nsresult GetFlattenedTreeAncestorsAndOffsets(
    517      nsINode* aNode, uint32_t aOffset, nsTArray<nsIContent*>& aAncestorNodes,
    518      nsTArray<mozilla::Maybe<uint32_t>>& aAncestorOffsets);
    519 
    520  /**
    521   * Returns the closest common inclusive ancestor
    522   * (https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor) , if any,
    523   * for two nodes.
    524   *
    525   * Returns null if the nodes are disconnected.
    526   */
    527  static nsINode* GetClosestCommonInclusiveAncestor(nsINode* aNode1,
    528                                                    nsINode* aNode2) {
    529    if (aNode1 == aNode2) {
    530      return aNode1;
    531    }
    532 
    533    return GetCommonAncestorHelper(aNode1, aNode2);
    534  }
    535 
    536  static nsINode* GetClosestCommonShadowIncludingInclusiveAncestor(
    537      nsINode* aNode1, nsINode* aNode2);
    538 
    539  /**
    540   * Returns the common flattened tree ancestor, if any, for two given content
    541   * nodes.
    542   */
    543  static nsIContent* GetCommonFlattenedTreeAncestor(nsIContent* aContent1,
    544                                                    nsIContent* aContent2) {
    545    if (aContent1 == aContent2) {
    546      return aContent1;
    547    }
    548 
    549    return GetCommonFlattenedTreeAncestorHelper(aContent1, aContent2);
    550  }
    551 
    552  /**
    553   * Returns the common flattened tree ancestor from the point of view of
    554   * the selection system, if any, for two given content nodes.
    555   */
    556  static nsINode* GetCommonFlattenedTreeAncestorForSelection(nsINode* aNode1,
    557                                                             nsINode* aNode2);
    558 
    559  /**
    560   * Returns the common flattened tree ancestor from the point of view of the
    561   * style system, if any, for two given content nodes.
    562   */
    563  static Element* GetCommonFlattenedTreeAncestorForStyle(Element* aElement1,
    564                                                         Element* aElement2);
    565 
    566  /**
    567   * Returns the common BrowserParent ancestor, if any, for two given
    568   * BrowserParent.
    569   */
    570  static mozilla::dom::BrowserParent* GetCommonBrowserParentAncestor(
    571      mozilla::dom::BrowserParent* aBrowserParent1,
    572      mozilla::dom::BrowserParent* aBrowserParent2);
    573 
    574  // https://html.spec.whatwg.org/#target-element
    575  // https://html.spec.whatwg.org/#find-a-potential-indicated-element
    576  static Element* GetTargetElement(Document* aDocument,
    577                                   const nsAString& aAnchorName);
    578  /** Returns true if aNode1 is before aNode2 in the same connected tree. */
    579  static bool PositionIsBefore(const nsINode* aNode1, const nsINode* aNode2) {
    580    return CompareTreePosition<TreeKind::DOM>(aNode1, aNode2, nullptr,
    581                                              nullptr) < 0;
    582  }
    583 
    584  /**
    585   * Cache implementation for ComparePoints().
    586   *
    587   * This cache keeps the last cache_size child/index combinations
    588   * in a stack-allocated array for fast lookup.
    589   * If the cache is full, the entries are overridden,
    590   * starting from the oldest entry.
    591   *
    592   * Note: This cache does not observe invalidation. As soon as script has
    593   * run, this cache must not be used anymore.
    594   * Also, this cache uses raw pointers. Beware!
    595   */
    596  template <size_t cache_size = 100>
    597  struct ResizableNodeIndexCache {
    598    /**
    599     * Looks up or computes two indices in one loop.
    600     */
    601    template <TreeKind aTreeKind>
    602    void ComputeIndicesOf(const nsINode* aParent, const nsINode* aChild1,
    603                          const nsINode* aChild2,
    604                          mozilla::Maybe<int32_t>& aChild1Index,
    605                          mozilla::Maybe<int32_t>& aChild2Index) {
    606      AssertTreeKind(aTreeKind);
    607      bool foundChild1 = false;
    608      bool foundChild2 = false;
    609      for (size_t cacheIndex = 0; cacheIndex < cache_size; ++cacheIndex) {
    610        if (foundChild1 && foundChild2) {
    611          return;
    612        }
    613        const nsINode* node = mNodes[cacheIndex];
    614        if (!node) {
    615          // reached the end of not-fully-populated cache.
    616          break;
    617        }
    618        if (!foundChild1 && node == aChild1) {
    619          aChild1Index = mIndices[cacheIndex];
    620          foundChild1 = true;
    621          continue;
    622        }
    623        if (!foundChild2 && node == aChild2) {
    624          aChild2Index = mIndices[cacheIndex];
    625          foundChild2 = true;
    626          continue;
    627        }
    628      }
    629      if (!foundChild1) {
    630        aChild1Index =
    631            ComputeAndInsertIndexIntoCache<aTreeKind>(aParent, aChild1);
    632      }
    633      if (!foundChild2) {
    634        aChild2Index =
    635            ComputeAndInsertIndexIntoCache<aTreeKind>(aParent, aChild2);
    636      }
    637    }
    638    /**
    639     * Looks up or computes child index.
    640     */
    641    template <TreeKind aTreeKind>
    642    mozilla::Maybe<int32_t> ComputeIndexOf(const nsINode* aParent,
    643                                           const nsINode* aChild) {
    644      AssertTreeKind(aTreeKind);
    645      for (size_t cacheIndex = 0; cacheIndex < cache_size; ++cacheIndex) {
    646        const nsINode* node = mNodes[cacheIndex];
    647        if (!node) {
    648          break;
    649        }
    650        if (node == aChild) {
    651          return mIndices[cacheIndex];
    652        }
    653      }
    654      return ComputeAndInsertIndexIntoCache<aTreeKind>(aParent, aChild);
    655    }
    656 
    657   private:
    658    /**
    659     * Computes the index of aChild in aParent, inserts the index into the
    660     * cache, and returns the index.
    661     */
    662    template <TreeKind aTreeKind>
    663    mozilla::Maybe<int32_t> ComputeAndInsertIndexIntoCache(
    664        const nsINode* aParent, const nsINode* aChild) {
    665      AssertTreeKind(aTreeKind);
    666      mozilla::Maybe<int32_t> childIndex =
    667          nsContentUtils::GetIndexInParent<aTreeKind>(aParent, aChild);
    668 
    669      mNodes[mNext] = aChild;
    670      mIndices[mNext] = childIndex;
    671 
    672      ++mNext;
    673      if (mNext == cache_size) {
    674        // the last element of the cache has been reached.
    675        // set mNext to 0 to start overriding the oldest cache entries.
    676        mNext = 0;
    677      }
    678      return childIndex;
    679    }
    680 
    681    /// Node storage. The array is initialized to null
    682    /// by the empty initializer list.
    683    const nsINode* mNodes[cache_size]{};
    684 
    685    mozilla::Maybe<int32_t> mIndices[cache_size];
    686 
    687    /// The next element in the cache that will be written to.
    688    /// If the cache is full (mNext == cache_size),
    689    /// the oldest entries in the cache will be overridden,
    690    /// ie. mNext will be set to 0.
    691    size_t mNext{0};
    692 
    693 #ifdef DEBUG
    694    mozilla::Maybe<TreeKind> mTreeKind;
    695 #endif
    696 
    697    void AssertTreeKind(TreeKind aKind) {
    698 #ifdef DEBUG
    699      MOZ_ASSERT(!mTreeKind || mTreeKind.value() == aKind, "Mixing queries");
    700      mTreeKind = mozilla::Some(aKind);
    701 #endif
    702    }
    703  };
    704 
    705  /**
    706   * Typedef with a reasonable default cache size.
    707   * If Caches of different sizes are needed,
    708   * ComparePoints would need to become templated.
    709   */
    710  using NodeIndexCache = ResizableNodeIndexCache<100>;
    711 
    712  /**
    713   *  Utility routine to compare two "points", where a point is a node/offset
    714   *  pair.
    715   *  Pass a cache object as aIndexCache if you expect to repeatedly
    716   *  call this function with the same value as aParent1 or aParent2.
    717   *
    718   *  @return -1 if point1 < point2,
    719   *          1 if point1 > point2,
    720   *          0 if point1 == point2.
    721   *          `Nothing` if the two nodes aren't in the same connected subtree.
    722   */
    723  template <TreeKind aKind = TreeKind::ShadowIncludingDOM,
    724            typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM ||
    725                                        aKind == TreeKind::Flat>>
    726  static mozilla::Maybe<int32_t> ComparePointsWithIndices(
    727      const nsINode* aParent1, uint32_t aOffset1, const nsINode* aParent2,
    728      uint32_t aOffset2, NodeIndexCache* aIndexCache = nullptr);
    729 
    730  /**
    731   *  Utility routine to compare two "points", where a point is a RangeBoundary.
    732   *  Pass a cache object as aIndexCache if you expect to repeatedly call this
    733   * function with the same value as aBoundary1 or aBoundary2.
    734   *
    735   *  @return -1 if point1 < point2,
    736   *          1 if point1 > point2,
    737   *          0 if point1 == point2.
    738   *          `Nothing` if the two nodes aren't in the same connected subtree.
    739   */
    740  template <TreeKind aKind = TreeKind::ShadowIncludingDOM, typename PT1,
    741            typename RT1, typename PT2, typename RT2,
    742            typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM ||
    743                                        aKind == TreeKind::Flat>>
    744  static mozilla::Maybe<int32_t> ComparePoints(
    745      const mozilla::RangeBoundaryBase<PT1, RT1>& aBoundary1,
    746      const mozilla::RangeBoundaryBase<PT2, RT2>& aBoundary2,
    747      NodeIndexCache* aIndexCache = nullptr);
    748 
    749  /**
    750   * DO NOT USE this method for comparing the points in new code.  this method
    751   * emulates same result as `ComparePoints` before bug 1741148.
    752   * When the old `ComparePoints` was called with offset value over `INT32_MAX`
    753   * or `-1` which is used as "not found" by some API, they were treated as-is
    754   * without checking whether the negative value or valid value.  Thus, this
    755   * handles the negative offset cases in the special paths to keep the
    756   * traditional behavior. If you want to use this in new code, it means that
    757   * you **should** check the offset values and call `ComparePoints` instead.
    758   */
    759  template <TreeKind aKind = TreeKind::ShadowIncludingDOM,
    760            typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM ||
    761                                        aKind == TreeKind::Flat>>
    762  static mozilla::Maybe<int32_t> ComparePoints_AllowNegativeOffsets(
    763      const nsINode* aParent1, int64_t aOffset1, const nsINode* aParent2,
    764      int64_t aOffset2) {
    765    if (MOZ_UNLIKELY(aOffset1 < 0 || aOffset2 < 0)) {
    766      // If in same container, just the offset is compared.
    767      if (aParent1 == aParent2) {
    768        const int32_t compOffsets =
    769            aOffset1 == aOffset2 ? 0 : (aOffset1 < aOffset2 ? -1 : 1);
    770        return mozilla::Some(compOffsets);
    771      }
    772      // Otherwise, aOffset1 is referred only when aParent2 is a descendant of
    773      // aParent1.
    774      if (aOffset1 < 0 && aParent2->IsInclusiveDescendantOf(aParent1)) {
    775        return mozilla::Some(-1);
    776      }
    777      // And also aOffset2 is referred only when aParent1 is a descendant of
    778      // aParent2.
    779      if (aOffset2 < 0 && aParent1->IsInclusiveDescendantOf(aParent2)) {
    780        return mozilla::Some(1);
    781      }
    782      // Otherwise, aOffset1 nor aOffset2 is referred so that any value is fine
    783      // if negative.
    784      return ComparePointsWithIndices<aKind>(
    785          aParent1,
    786          // Avoid warnings.
    787          aOffset1 < 0 ? aParent1->GetChildCount()
    788                       : std::min(static_cast<uint32_t>(aOffset1),
    789                                  aParent1->GetChildCount()),
    790          aParent2,
    791          // Avoid warnings.
    792          aOffset2 < 0 ? aParent2->GetChildCount()
    793                       : std::min(static_cast<uint32_t>(aOffset2),
    794                                  aParent2->GetChildCount()));
    795    }
    796    return ComparePointsWithIndices<aKind>(aParent1, aOffset1, aParent2,
    797                                           aOffset2);
    798  }
    799 
    800  /**
    801   * Brute-force search of the element subtree rooted at aContent for
    802   * an element with the given id.  aId must be nonempty, otherwise
    803   * this method may return nodes even if they have no id!
    804   */
    805  static Element* MatchElementId(nsIContent* aContent, const nsAString& aId);
    806 
    807  /**
    808   * Similar to above, but to be used if one already has an atom for the ID
    809   */
    810  static Element* MatchElementId(nsIContent* aContent, const nsAtom* aId);
    811 
    812  /**
    813   * Reverses the document position flags passed in.
    814   *
    815   * @param   aDocumentPosition   The document position flags to be reversed.
    816   *
    817   * @return  The reversed document position flags.
    818   *
    819   * @see Node
    820   */
    821  static uint16_t ReverseDocumentPosition(uint16_t aDocumentPosition);
    822 
    823  static const nsDependentSubstring TrimCharsInSet(const char* aSet,
    824                                                   const nsAString& aValue);
    825 
    826  template <bool IsWhitespace(char16_t)>
    827  static const nsDependentSubstring TrimWhitespace(const nsAString& aStr,
    828                                                   bool aTrimTrailing = true);
    829 
    830  /**
    831   * Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No
    832   */
    833  static bool IsAlphanumeric(uint32_t aChar);
    834  /**
    835   * Returns true if aChar is of class L*, N* or S* (for first-letter).
    836   */
    837  static bool IsAlphanumericOrSymbol(uint32_t aChar);
    838  /**
    839   * Returns true if aChar is a kind of hyphen.
    840   */
    841  static bool IsHyphen(uint32_t aChar);
    842 
    843  /*
    844   * Is the character an HTML whitespace character?
    845   *
    846   * We define whitespace using the list in HTML5 and css3-selectors:
    847   * U+0009, U+000A, U+000C, U+000D, U+0020
    848   *
    849   * HTML 4.01 also lists U+200B (zero-width space).
    850   */
    851  static bool IsHTMLWhitespace(char16_t aChar);
    852  static constexpr std::string_view kHTMLWhitespace{"\x09\x0a\x0c\x0d\x20"};
    853 
    854  /*
    855   * Returns whether the character is an HTML whitespace (see IsHTMLWhitespace)
    856   * or a nbsp character (U+00A0).
    857   */
    858  static bool IsHTMLWhitespaceOrNBSP(char16_t aChar);
    859 
    860  /**
    861   * https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
    862   */
    863  static bool IsHTMLBlockLevelElement(nsIContent* aContent);
    864 
    865  enum ParseHTMLIntegerResultFlags {
    866    eParseHTMLInteger_NoFlags = 0,
    867    // eParseHTMLInteger_NonStandard is set if the string representation of the
    868    // integer was not the canonical one, but matches at least one of the
    869    // following:
    870    //   * had leading whitespaces
    871    //   * had '+' sign
    872    //   * had leading '0'
    873    //   * was '-0'
    874    eParseHTMLInteger_NonStandard = 1 << 0,
    875    eParseHTMLInteger_DidNotConsumeAllInput = 1 << 1,
    876    // Set if one or more error flags were set.
    877    eParseHTMLInteger_Error = 1 << 2,
    878    eParseHTMLInteger_ErrorNoValue = 1 << 3,
    879    eParseHTMLInteger_ErrorOverflow = 1 << 4,
    880    // Use this flag to detect the difference between overflow and underflow
    881    eParseHTMLInteger_Negative = 1 << 5,
    882  };
    883  static int32_t ParseHTMLInteger(const nsAString& aValue,
    884                                  ParseHTMLIntegerResultFlags* aResult) {
    885    return ParseHTMLInteger(aValue.BeginReading(), aValue.EndReading(),
    886                            aResult);
    887  }
    888  static int32_t ParseHTMLInteger(const char16_t* aStart, const char16_t* aEnd,
    889                                  ParseHTMLIntegerResultFlags* aResult);
    890  static int32_t ParseHTMLInteger(const nsACString& aValue,
    891                                  ParseHTMLIntegerResultFlags* aResult) {
    892    return ParseHTMLInteger(aValue.BeginReading(), aValue.EndReading(),
    893                            aResult);
    894  }
    895  static int32_t ParseHTMLInteger(const char* aStart, const char* aEnd,
    896                                  ParseHTMLIntegerResultFlags* aResult);
    897 
    898 private:
    899  template <class CharT>
    900  static int32_t ParseHTMLIntegerImpl(const CharT* aStart, const CharT* aEnd,
    901                                      ParseHTMLIntegerResultFlags* aResult);
    902 
    903 public:
    904  /* Parse a float as per
    905   * https://html.spec.whatwg.org/#valid-floating-point-number */
    906  static mozilla::Maybe<double> ParseHTMLFloatingPointNumber(const nsAString&);
    907 
    908  /**
    909   * Parse the value of the <font size=""> attribute according to the HTML5
    910   * spec as of April 16, 2012.
    911   *
    912   * @param aValue the value to parse
    913   * @return 1 to 7, or 0 if the value couldn't be parsed
    914   */
    915  static int32_t ParseLegacyFontSize(const nsAString& aValue);
    916 
    917  static void Shutdown();
    918 
    919  /**
    920   * Checks whether two nodes come from the same origin.
    921   */
    922  static nsresult CheckSameOrigin(const nsINode* aTrustedNode,
    923                                  const nsINode* unTrustedNode);
    924 
    925  // Check if the (JS) caller can access aNode.
    926  static bool CanCallerAccess(const nsINode* aNode);
    927 
    928  // Check if the (JS) caller can access aWindow.
    929  // aWindow can be either outer or inner window.
    930  static bool CanCallerAccess(nsPIDOMWindowInner* aWindow);
    931 
    932  // Check if the principal is chrome or an addon with the permission.
    933  static bool PrincipalHasPermission(nsIPrincipal& aPrincipal,
    934                                     const nsAtom* aPerm);
    935 
    936  // Check if the JS caller is chrome or an addon with the permission.
    937  static bool CallerHasPermission(JSContext* aCx, const nsAtom* aPerm);
    938 
    939  /**
    940   * Returns the triggering principal which should be used for the given URL
    941   * attribute value with the given subject principal.
    942   *
    943   * If the attribute value is not an absolute URL, the subject principal will
    944   * be ignored, and the node principal of aContent will be used instead.
    945   * If aContent is non-null, this function will always return a principal.
    946   * Otherewise, it may return null if aSubjectPrincipal is null or is rejected
    947   * based on the attribute value.
    948   *
    949   * @param aContent The content on which the attribute is being set.
    950   * @param aAttrValue The URL value of the attribute. For parsed attribute
    951   *        values, such as `srcset`, this function should be called separately
    952   *        for each URL value it contains.
    953   * @param aSubjectPrincipal The subject principal of the scripted caller
    954   *        responsible for setting the attribute, or null if no scripted caller
    955   *        can be determined.
    956   */
    957  static nsIPrincipal* GetAttrTriggeringPrincipal(
    958      nsIContent* aContent, const nsAString& aAttrValue,
    959      nsIPrincipal* aSubjectPrincipal);
    960 
    961  /**
    962   * Returns true if the given string is guaranteed to be treated as an absolute
    963   * URL, rather than a relative URL. In practice, this means any complete URL
    964   * as supported by nsStandardURL, or any string beginning with a valid scheme
    965   * which is known to the IO service, and has the URI_NORELATIVE flag.
    966   *
    967   * If the URL may be treated as absolute in some cases, but relative in others
    968   * (for instance, "http:foo", which can be either an absolute or relative URL,
    969   * depending on the context), this function returns false.
    970   */
    971  static bool IsAbsoluteURL(const nsACString& aURL);
    972 
    973  // Check if a node is in the document prolog, i.e. before the document
    974  // element.
    975  static bool InProlog(nsINode* aNode);
    976 
    977  static nsIBidiKeyboard* GetBidiKeyboard();
    978 
    979  /**
    980   * Get the cache security manager service. Can return null if the layout
    981   * module has been shut down.
    982   */
    983  static nsIScriptSecurityManager* GetSecurityManager() {
    984    return sSecurityManager;
    985  }
    986 
    987  // Returns the subject principal from the JSContext. May only be called
    988  // from the main thread and assumes an existing compartment.
    989  static nsIPrincipal* SubjectPrincipal(JSContext* aCx);
    990 
    991  // Returns the subject principal. Guaranteed to return non-null. May only
    992  // be called when nsContentUtils is initialized.
    993  static nsIPrincipal* SubjectPrincipal();
    994 
    995  // Returns the prinipal of the given JS object. This may only be called on
    996  // the main thread for objects from the main thread's JSRuntime. The object
    997  // must not be a cross-compartment wrapper, because CCWs are not associated
    998  // with a single realm.
    999  static nsIPrincipal* ObjectPrincipal(JSObject* aObj);
   1000 
   1001  static void GenerateStateKey(nsIContent* aContent, Document* aDocument,
   1002                               nsACString& aKey);
   1003 
   1004  /**
   1005   * Create a new nsIURI from aSpec, using aBaseURI as the base.  The
   1006   * origin charset of the new nsIURI will be the document charset of
   1007   * aDocument.
   1008   */
   1009  static nsresult NewURIWithDocumentCharset(nsIURI** aResult,
   1010                                            const nsAString& aSpec,
   1011                                            Document* aDocument,
   1012                                            nsIURI* aBaseURI);
   1013 
   1014  /**
   1015   * Returns true if |aAtom| contains at least one |aChar|.
   1016   */
   1017  static bool ContainsChar(nsAtom* aAtom, char aChar);
   1018 
   1019  /**
   1020   * Returns true if |aName| is a name with dashes.
   1021   */
   1022  static bool IsNameWithDash(nsAtom* aName);
   1023 
   1024  /**
   1025   * Returns true if |aName| is a valid name to be registered via
   1026   * customElements.define.
   1027   */
   1028  static bool IsCustomElementName(nsAtom* aName, uint32_t aNameSpaceID);
   1029 
   1030  static nsresult CheckQName(const nsAString& aQualifiedName,
   1031                             bool aNamespaceAware = true,
   1032                             const char16_t** aColon = nullptr);
   1033 
   1034  static nsresult SplitQName(const nsIContent* aNamespaceResolver,
   1035                             const nsString& aQName, int32_t* aNamespace,
   1036                             nsAtom** aLocalName);
   1037 
   1038  static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
   1039                                       const nsAString& aQualifiedName,
   1040                                       nsNodeInfoManager* aNodeInfoManager,
   1041                                       uint16_t aNodeType,
   1042                                       mozilla::dom::NodeInfo** aNodeInfo);
   1043 
   1044  static void SplitExpatName(const char16_t* aExpatName, nsAtom** aPrefix,
   1045                             nsAtom** aTagName, int32_t* aNameSpaceID);
   1046 
   1047  // Get a permission-manager setting for the given principal and type.
   1048  // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
   1049  // returned, otherwise true is returned. Always returns true for the
   1050  // system principal, and false for a null principal.
   1051  static bool IsSitePermAllow(nsIPrincipal* aPrincipal,
   1052                              const nsACString& aType);
   1053 
   1054  // Get a permission-manager setting for the given principal and type.
   1055  // If the pref doesn't exist or if it isn't DENY_ACTION, false is
   1056  // returned, otherwise true is returned. Always returns false for the
   1057  // system principal, and true for a null principal.
   1058  static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const nsACString& aType);
   1059 
   1060  // Get a permission-manager setting for the given principal and type.
   1061  // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
   1062  // returned, otherwise true is returned. Always returns true for the
   1063  // system principal, and false for a null principal.
   1064  // This version checks the permission for an exact host match on
   1065  // the principal
   1066  static bool IsExactSitePermAllow(nsIPrincipal* aPrincipal,
   1067                                   const nsACString& aType);
   1068 
   1069  // Get a permission-manager setting for the given principal and type.
   1070  // If the pref doesn't exist or if it isn't DENY_ACTION, false is
   1071  // returned, otherwise true is returned. Always returns false for the
   1072  // system principal, and true for a null principal.
   1073  // This version checks the permission for an exact host match on
   1074  // the principal
   1075  static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal,
   1076                                  const nsACString& aType);
   1077 
   1078  // Returns true if the pref exists and is not UNKNOWN_ACTION.
   1079  static bool HasSitePerm(nsIPrincipal* aPrincipal, const nsACString& aType);
   1080 
   1081  // Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s.
   1082  static bool HaveEqualPrincipals(Document* aDoc1, Document* aDoc2);
   1083 
   1084  /**
   1085   * Regster aObserver as a shutdown observer. A strong reference is held
   1086   * to aObserver until UnregisterShutdownObserver is called.
   1087   */
   1088  static void RegisterShutdownObserver(nsIObserver* aObserver);
   1089  static void UnregisterShutdownObserver(nsIObserver* aObserver);
   1090 
   1091  /**
   1092   * @return true if aContent has an attribute aName in namespace aNameSpaceID,
   1093   * and the attribute value is non-empty.
   1094   */
   1095  static bool HasNonEmptyAttr(const nsIContent* aContent, int32_t aNameSpaceID,
   1096                              nsAtom* aName);
   1097 
   1098  /**
   1099   * Method that gets the primary presContext for the node.
   1100   *
   1101   * @param aContent The content node.
   1102   * @return the presContext, or nullptr if the content is not in a document
   1103   *         (if GetComposedDoc returns nullptr)
   1104   */
   1105  static nsPresContext* GetContextForContent(const nsIContent* aContent);
   1106 
   1107  /**
   1108   * Method that gets the pres shell for the node.
   1109   *
   1110   * @param aContent The content node.
   1111   * @return the pres shell, or nullptr if the content is not in a document
   1112   *         (if GetComposedDoc returns nullptr)
   1113   */
   1114  static mozilla::PresShell* GetPresShellForContent(const nsIContent* aContent);
   1115 
   1116  /**
   1117   * Returns true if objects in aDocument shouldn't initiate image loads.
   1118   */
   1119  static bool DocumentInactiveForImageLoads(Document* aDocument);
   1120 
   1121  /**
   1122   * Convert a CORSMode into the corresponding imgILoader flags for
   1123   * passing to LoadImage.
   1124   * @param aMode CORS mode to convert
   1125   * @return a bitfield suitable to bitwise OR with other nsIRequest flags
   1126   */
   1127  static int32_t CORSModeToLoadImageFlags(mozilla::CORSMode aMode);
   1128 
   1129  /**
   1130   * Method to start an image load.  This does not do any security checks.
   1131   * This method will attempt to make aURI immutable; a caller that wants to
   1132   * keep a mutable version around should pass in a clone.
   1133   *
   1134   * @param aURI uri of the image to be loaded
   1135   * @param aContext element of document where the result of this request
   1136   *                 will be used.
   1137   * @param aLoadingDocument the document we belong to
   1138   * @param aLoadingPrincipal the principal doing the load
   1139   * @param aReferrerInfo the referrerInfo use on channel creation
   1140   * @param aObserver the observer for the image load
   1141   * @param aLoadFlags the load flags to use.  See nsIRequest
   1142   * @param [aContentPolicyType=nsIContentPolicy::TYPE_INTERNAL_IMAGE]
   1143   * (Optional) The CP content type to use
   1144   * @param aUseUrgentStartForChannel,(Optional) a flag to mark on channel if it
   1145   *        is triggered by user input events.
   1146   * @return the imgIRequest for the image load
   1147   */
   1148  static nsresult LoadImage(
   1149      nsIURI* aURI, nsINode* aContext, Document* aLoadingDocument,
   1150      nsIPrincipal* aLoadingPrincipal, uint64_t aRequestContextID,
   1151      nsIReferrerInfo* aReferrerInfo, imgINotificationObserver* aObserver,
   1152      int32_t aLoadFlags, const nsAString& initiatorType,
   1153      imgRequestProxy** aRequest,
   1154      nsContentPolicyType aContentPolicyType =
   1155          nsIContentPolicy::TYPE_INTERNAL_IMAGE,
   1156      bool aUseUrgentStartForChannel = false, bool aLinkPreload = false,
   1157      uint64_t aEarlyHintPreloaderId = 0,
   1158      mozilla::dom::FetchPriority aFetchPriority =
   1159          mozilla::dom::FetchPriority::Auto);
   1160 
   1161  /**
   1162   * Obtain an image loader that respects the given document/channel's privacy
   1163   * status. Null document/channel arguments return the public image loader.
   1164   */
   1165  static imgLoader* GetImgLoaderForDocument(Document* aDoc);
   1166  static imgLoader* GetImgLoaderForChannel(nsIChannel* aChannel,
   1167                                           Document* aContext);
   1168 
   1169  /**
   1170   * Method to get an imgIContainer from an image loading content
   1171   *
   1172   * @param aContent The image loading content.  Must not be null.
   1173   * @param aRequest The image request [out]
   1174   * @return the imgIContainer corresponding to the first frame of the image
   1175   */
   1176  static already_AddRefed<imgIContainer> GetImageFromContent(
   1177      nsIImageLoadingContent* aContent, imgIRequest** aRequest = nullptr);
   1178 
   1179  /**
   1180   * Method that decides whether a content node is draggable
   1181   *
   1182   * @param aContent The content node to test.
   1183   * @return whether it's draggable
   1184   */
   1185  static bool ContentIsDraggable(nsIContent* aContent);
   1186 
   1187  /**
   1188   * Method that decides whether a content node is a draggable image
   1189   *
   1190   * @param aContent The content node to test.
   1191   * @return whether it's a draggable image
   1192   */
   1193  static bool IsDraggableImage(nsIContent* aContent);
   1194 
   1195  /**
   1196   * Method that decides whether a content node is a draggable link
   1197   *
   1198   * @param aContent The content node to test.
   1199   * @return whether it's a draggable link
   1200   */
   1201  static bool IsDraggableLink(const nsIContent* aContent);
   1202 
   1203  /**
   1204   * Convenience method to create a new nodeinfo that differs only by prefix and
   1205   * name from aNodeInfo. The new nodeinfo's name is set to aName, and prefix is
   1206   * set to null.
   1207   */
   1208  static nsresult QNameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsAtom* aName,
   1209                               mozilla::dom::NodeInfo** aResult);
   1210 
   1211  /**
   1212   * Returns the appropriate event argument names for the specified
   1213   * namespace and event name.  Added because we need to switch between
   1214   * SVG's "evt" and the rest of the world's "event", and because onerror
   1215   * on window takes 5 args.
   1216   */
   1217  static void GetEventArgNames(int32_t aNameSpaceID, nsAtom* aEventName,
   1218                               bool aIsForWindow, uint32_t* aArgCount,
   1219                               const char*** aArgNames);
   1220 
   1221  /**
   1222   * Returns true if this loadGroup uses Private Browsing.
   1223   */
   1224  static bool IsInPrivateBrowsing(nsILoadGroup* aLoadGroup);
   1225 
   1226  /**
   1227   * Returns whether a node is in the same tree as another one, accounting for
   1228   * anonymous roots.
   1229   *
   1230   * This method is particularly useful for callers who are trying to ensure
   1231   * that they are working with a non-anonymous descendant of a given node.  If
   1232   * aContent is a descendant of aNode, a return value of false from this
   1233   * method means that it's an anonymous descendant from aNode's point of view.
   1234   *
   1235   * Both arguments to this method must be non-null.
   1236   */
   1237  static bool IsInSameAnonymousTree(const nsINode* aNode,
   1238                                    const nsINode* aOtherNode);
   1239 
   1240  /*
   1241   * Traverse the parent chain from aElement up to aStop, and return true if
   1242   * there's an interactive html content; false otherwise.
   1243   *
   1244   * Note: This crosses shadow boundaries but not document boundaries.
   1245   */
   1246  static bool IsInInteractiveHTMLContent(const Element* aElement,
   1247                                         const Element* aStop);
   1248 
   1249  /**
   1250   * Return the nsIXPConnect service.
   1251   */
   1252  static nsIXPConnect* XPConnect() { return sXPConnect; }
   1253 
   1254  /**
   1255   * Report simple error message to the browser console
   1256   *   @param aErrorText the error message
   1257   *   @param aCategory Name of the module reporting error
   1258   *   @param aFromPrivateWindow Whether from private window or not
   1259   *   @param aFromChromeContext Whether from chrome context or not
   1260   *   @param [aErrorFlags] See nsIScriptError.
   1261   */
   1262  static void LogSimpleConsoleError(
   1263      const nsAString& aErrorText, const nsACString& aCategory,
   1264      bool aFromPrivateWindow, bool aFromChromeContext,
   1265      uint32_t aErrorFlags = nsIScriptError::errorFlag);
   1266 
   1267  /**
   1268   * Report a non-localized error message to the error console.
   1269   *   @param aErrorText the error message
   1270   *   @param aErrorFlags See nsIScriptError.
   1271   *   @param aCategory Name of module reporting error.
   1272   *   @param aDocument Reference to the document which triggered the message.
   1273   *   @param aLocation message location. Pass the empty location to omit it.
   1274   */
   1275  static nsresult ReportToConsoleNonLocalized(
   1276      const nsAString& aErrorText, uint32_t aErrorFlags,
   1277      const nsACString& aCategory, const Document* aDocument,
   1278      const mozilla::SourceLocation& aLocation =
   1279          mozilla::JSCallingLocation::Get());
   1280 
   1281  /**
   1282   * Report a non-localized error message to the error console base on the
   1283   * innerWindowID.
   1284   *   @param aErrorText the error message
   1285   *   @param aErrorFlags See nsIScriptError.
   1286   *   @param aCategory Name of module reporting error.
   1287   *   @param [aInnerWindowID] Inner window ID for document which triggered the
   1288   *          message.
   1289   *   @param aLocation message location. Pass the empty location to omit it.
   1290   */
   1291  static nsresult ReportToConsoleByWindowID(
   1292      const nsAString& aErrorText, uint32_t aErrorFlags,
   1293      const nsACString& aCategory, uint64_t aInnerWindowID,
   1294      const mozilla::SourceLocation& aLocation =
   1295          mozilla::JSCallingLocation::Get());
   1296 
   1297  /**
   1298   * Report a localized error message to the error console.
   1299   *   @param aErrorFlags See nsIScriptError.
   1300   *   @param aCategory Name of module reporting error.
   1301   *   @param aDocument Reference to the document which triggered the message.
   1302   *   @param aFile Properties file containing localized message.
   1303   *   @param aMessageName Name of localized message.
   1304   *   @param [aParams=empty-array] (Optional) Parameters to be substituted into
   1305              localized message.
   1306   *   @param aLocation message location. Pass the empty location to omit it.
   1307   */
   1308  enum PropertiesFile {
   1309    eCSS_PROPERTIES,
   1310    eXUL_PROPERTIES,
   1311    eLAYOUT_PROPERTIES,
   1312    eFORMS_PROPERTIES,
   1313    ePRINTING_PROPERTIES,
   1314    eDOM_PROPERTIES,
   1315    eHTMLPARSER_PROPERTIES,
   1316    eSVG_PROPERTIES,
   1317    eBRAND_PROPERTIES,
   1318    eCOMMON_DIALOG_PROPERTIES,
   1319    eMATHML_PROPERTIES,
   1320    eSECURITY_PROPERTIES,
   1321    eNECKO_PROPERTIES,
   1322    eFORMS_PROPERTIES_en_US,
   1323    eDOM_PROPERTIES_en_US,
   1324    eNECKO_PROPERTIES_en_US,
   1325    PropertiesFile_COUNT
   1326  };
   1327  static nsresult ReportToConsole(
   1328      uint32_t aErrorFlags, const nsACString& aCategory,
   1329      const Document* aDocument, PropertiesFile aFile, const char* aMessageName,
   1330      const nsTArray<nsString>& aParams = nsTArray<nsString>(),
   1331      const mozilla::SourceLocation& aLocation =
   1332          mozilla::JSCallingLocation::Get());
   1333 
   1334  static void ReportEmptyGetElementByIdArg(const Document* aDoc);
   1335 
   1336  static void LogMessageToConsole(const char* aMsg);
   1337 
   1338  /**
   1339   * Get the localized string named |aKey| in properties file |aFile|.
   1340   */
   1341  static nsresult GetLocalizedString(PropertiesFile aFile, const char* aKey,
   1342                                     nsAString& aResult);
   1343 
   1344  /**
   1345   * Same as GetLocalizedString, except that it might use en-US locale depending
   1346   * on SpoofLocaleEnglish() and whether the document is a built-in browser
   1347   * page.
   1348   */
   1349  static nsresult GetMaybeLocalizedString(PropertiesFile aFile,
   1350                                          const char* aKey, Document* aDocument,
   1351                                          nsAString& aResult);
   1352 
   1353  /**
   1354   * A helper function that parses a sandbox attribute (of an <iframe> or a CSP
   1355   * directive) and converts it to the set of flags used internally.
   1356   *
   1357   * @param aSandboxAttr  the sandbox attribute
   1358   * @return              the set of flags (SANDBOXED_NONE if aSandboxAttr is
   1359   *                      null)
   1360   */
   1361  static uint32_t ParseSandboxAttributeToFlags(const nsAttrValue* aSandboxAttr);
   1362 
   1363  /**
   1364   * A helper function that checks if a string matches a valid sandbox flag.
   1365   *
   1366   * @param aFlag   the potential sandbox flag.
   1367   * @return        true if the flag is a sandbox flag.
   1368   */
   1369  static bool IsValidSandboxFlag(const nsAString& aFlag);
   1370 
   1371  /**
   1372   * A helper function that returns a string attribute corresponding to the
   1373   * sandbox flags.
   1374   *
   1375   * @param aFlags    the sandbox flags
   1376   * @param aString   the attribute corresponding to the flags (null if aFlags
   1377   *                  is zero)
   1378   */
   1379  static void SandboxFlagsToString(uint32_t aFlags, nsAString& aString);
   1380 
   1381  static bool PrefetchPreloadEnabled(nsIDocShell* aDocShell);
   1382 
   1383  static bool ExtractExceptionValues(JSContext* aCx,
   1384                                     JS::Handle<JSObject*> aException,
   1385                                     nsACString& aFilename, uint32_t* aLineOut,
   1386                                     uint32_t* aColumnOut,
   1387                                     nsString& aMessageOut);
   1388 
   1389  static void ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,
   1390                                 nsACString& aSourceSpecOut, uint32_t* aLineOut,
   1391                                 uint32_t* aColumnOut, nsString& aMessageOut);
   1392 
   1393  static nsresult CalculateBufferSizeForImage(
   1394      const uint32_t& aStride, const mozilla::gfx::IntSize& aImageSize,
   1395      const mozilla::gfx::SurfaceFormat& aFormat, size_t* aMaxBufferSize,
   1396      size_t* aUsedBufferSize);
   1397 
   1398  // Returns true if the URI's host is contained in a list which is a comma
   1399  // separated domain list.  Each item may start with "*.".  If starts with
   1400  // "*.", it matches any sub-domains.
   1401  // The aList argument must be a lower-case string.
   1402  static bool IsURIInList(nsIURI* aURI, const nsCString& aList);
   1403 
   1404  // Returns true if the URI's host is contained in a pref list which is a comma
   1405  // separated domain list.  Each item may start with "*.".  If starts with
   1406  // "*.", it matches any sub-domains.
   1407  static bool IsURIInPrefList(nsIURI* aURI, const char* aPrefName);
   1408 
   1409  /*&
   1410   * A convenience version of FormatLocalizedString that can be used if all the
   1411   * params are in same-typed strings.  The variadic template args need to come
   1412   * at the end, so we put aResult at the beginning to make sure it's clear
   1413   * which is the output and which are the inputs.
   1414   */
   1415  template <typename... T>
   1416  static nsresult FormatLocalizedString(nsAString& aResult,
   1417                                        PropertiesFile aFile, const char* aKey,
   1418                                        const T&... aParams) {
   1419    static_assert(sizeof...(aParams) != 0, "Use GetLocalizedString()");
   1420    AutoTArray<nsString, sizeof...(aParams)> params = {
   1421        aParams...,
   1422    };
   1423    return FormatLocalizedString(aFile, aKey, params, aResult);
   1424  }
   1425 
   1426  /**
   1427   * Same as FormatLocalizedString template version, except that it might use
   1428   * en-US locale depending on SpoofLocaleEnglish() and whether the document is
   1429   * a built-in browser page.
   1430   */
   1431  template <typename... T>
   1432  static nsresult FormatMaybeLocalizedString(nsAString& aResult,
   1433                                             PropertiesFile aFile,
   1434                                             const char* aKey,
   1435                                             Document* aDocument,
   1436                                             const T&... aParams) {
   1437    static_assert(sizeof...(aParams) != 0, "Use GetMaybeLocalizedString()");
   1438    AutoTArray<nsString, sizeof...(aParams)> params = {
   1439        aParams...,
   1440    };
   1441    return FormatMaybeLocalizedString(aFile, aKey, aDocument, params, aResult);
   1442  }
   1443 
   1444  /**
   1445   * Fill (with the parameters given) the localized string named |aKey| in
   1446   * properties file |aFile| consuming an nsTArray of nsString parameters rather
   1447   * than a char16_t** for the sake of avoiding use-after-free errors involving
   1448   * temporaries.
   1449   */
   1450  static nsresult FormatLocalizedString(PropertiesFile aFile, const char* aKey,
   1451                                        const nsTArray<nsString>& aParamArray,
   1452                                        nsAString& aResult);
   1453 
   1454  /**
   1455   * Same as FormatLocalizedString, except that it might use en-US locale
   1456   * depending on SpoofLocaleEnglish() and whether the document is a built-in
   1457   * browser page.
   1458   */
   1459  static nsresult FormatMaybeLocalizedString(
   1460      PropertiesFile aFile, const char* aKey, Document* aDocument,
   1461      const nsTArray<nsString>& aParamArray, nsAString& aResult);
   1462 
   1463  /**
   1464   * Returns true if aDocument is a chrome document
   1465   */
   1466  static bool IsChromeDoc(const Document* aDocument);
   1467 
   1468  /**
   1469   * Returns true if aDocument is an addon document
   1470   */
   1471  static bool IsAddonDoc(const Document* aDocument);
   1472 
   1473  /**
   1474   * Returns true if aDocument is in a docshell whose parent is the same type
   1475   */
   1476  static bool IsChildOfSameType(Document* aDoc);
   1477 
   1478  /**
   1479   * Returns true if the content-type will be rendered as plain-text.
   1480   */
   1481  static bool IsPlainTextType(const nsACString& aContentType);
   1482 
   1483  /**
   1484   * Returns true iff the type is rendered as plain text and doesn't support
   1485   * non-UTF-8 encodings.
   1486   */
   1487  static bool IsUtf8OnlyPlainTextType(const nsACString& aContentType);
   1488 
   1489  /**
   1490   * Returns true if aDocument belongs to a chrome docshell for
   1491   * display purposes.  Returns false for null documents or documents
   1492   * which do not belong to a docshell.
   1493   */
   1494  static bool IsInChromeDocshell(const Document* aDocument);
   1495 
   1496  /**
   1497   * Return the content policy service
   1498   */
   1499  static nsIContentPolicy* GetContentPolicy();
   1500 
   1501  /**
   1502   * Map internal content policy types to external ones.
   1503   */
   1504  static inline ExtContentPolicyType InternalContentPolicyTypeToExternal(
   1505      nsContentPolicyType aType);
   1506 
   1507  /**
   1508   * check whether the Link header field applies to the context resource
   1509   * see <http://tools.ietf.org/html/rfc5988#section-5.2>
   1510   */
   1511  static bool LinkContextIsURI(const nsAString& aAnchor, nsIURI* aDocURI);
   1512 
   1513  /**
   1514   * Returns true if the content policy type is any of:
   1515   *   * TYPE_INTERNAL_SCRIPT_PRELOAD
   1516   *   * TYPE_INTERNAL_IMAGE_PRELOAD
   1517   *   * TYPE_INTERNAL_STYLESHEET_PRELOAD
   1518   */
   1519  static bool IsPreloadType(nsContentPolicyType aType);
   1520 
   1521  /**
   1522   * Synchronously fire a chrome only event to notify the DevTools of the
   1523   * removal of aRemovingNode. Only fires the event if
   1524   * aRemovingNode.ShouldNotifyDevToolsOfNodeRemovals() returns true.
   1525   *
   1526   * @param aRemovingNode   The node which will be removed.
   1527   */
   1528  MOZ_CAN_RUN_SCRIPT static void NotifyDevToolsOfNodeRemoval(
   1529      nsINode& aRemovingNode);
   1530 
   1531  /**
   1532   * These methods create and dispatch a trusted event.
   1533   * Works only with events which can be created by calling
   1534   * Document::CreateEvent() with parameter "Events".
   1535   * Note that don't use these methods for "input" event.  Use
   1536   * DispatchInputEvent() instead.
   1537   *
   1538   * @param aDoc           The document which will be used to create the event.
   1539   * @param aTarget        The target of the event.
   1540   * @param aEventName     The name of the event.
   1541   * @param aCanBubble     Whether the event can bubble.
   1542   * @param aCancelable    Is the event cancelable.
   1543   * @param aCopmosed      Is the event composed.
   1544   * @param aDefaultAction Set to true if default action should be taken,
   1545   *                       see EventTarget::DispatchEvent.
   1546   */
   1547  // TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
   1548  // (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
   1549  static nsresult DispatchTrustedEvent(
   1550      Document* aDoc, mozilla::dom::EventTarget* aTarget,
   1551      const nsAString& aEventName, CanBubble, Cancelable,
   1552      Composed aComposed = Composed::eDefault, bool* aDefaultAction = nullptr,
   1553      SystemGroupOnly aSystemGroupOnly = SystemGroupOnly::eNo);
   1554 
   1555  // TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
   1556  // (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
   1557  static nsresult DispatchTrustedEvent(
   1558      Document* aDoc, mozilla::dom::EventTarget* aTarget,
   1559      const nsAString& aEventName, CanBubble aCanBubble, Cancelable aCancelable,
   1560      bool* aDefaultAction,
   1561      SystemGroupOnly aSystemGroupOnly = SystemGroupOnly::eNo) {
   1562    return DispatchTrustedEvent(aDoc, aTarget, aEventName, aCanBubble,
   1563                                aCancelable, Composed::eDefault, aDefaultAction,
   1564                                aSystemGroupOnly);
   1565  }
   1566 
   1567  /**
   1568   * This method creates and dispatches a trusted event using an event message.
   1569   * @param aDoc           The document which will be used to create the event.
   1570   * @param aTarget        The target of the event.
   1571   * @param aEventMessage  The event message.
   1572   * @param aCanBubble     Whether the event can bubble.
   1573   * @param aCancelable    Is the event cancelable.
   1574   * @param aDefaultAction Set to true if default action should be taken,
   1575   *                       see EventTarget::DispatchEvent.
   1576   */
   1577  template <class WidgetEventType>
   1578  static nsresult DispatchTrustedEvent(
   1579      Document* aDoc, mozilla::dom::EventTarget* aTarget,
   1580      EventMessage aEventMessage, CanBubble aCanBubble, Cancelable aCancelable,
   1581      bool* aDefaultAction = nullptr,
   1582      ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo) {
   1583    WidgetEventType event(true, aEventMessage);
   1584    MOZ_ASSERT(GetEventClassIDFromMessage(aEventMessage) == event.mClass);
   1585    return DispatchEvent(aDoc, aTarget, event, aEventMessage, aCanBubble,
   1586                         aCancelable, Trusted::eYes, aDefaultAction,
   1587                         aOnlyChromeDispatch);
   1588  }
   1589 
   1590  /**
   1591   * This method dispatches "beforeinput" event with EditorInputEvent or
   1592   * "input" event with proper event class.  If it's unsafe to dispatch,
   1593   * this put the event into the script runner queue.  In such case, the
   1594   * event becomes not cancelable even if it's defined as cancelable by
   1595   * the spec.
   1596   * Input Events spec defines as:
   1597   *   Input events are dispatched on elements that act as editing hosts,
   1598   *   including elements with the contenteditable attribute set, textarea
   1599   *   elements, and input elements that permit text input.
   1600   *
   1601   * @param aEventTarget        The event target element of the "beforeinput"
   1602   *                            or "input" event.  Must not be nullptr.
   1603   * @param aEventMessage       Muse be eEditorBeforeInput or eEditorInput.
   1604   * @param aEditorInputType    The inputType value of InputEvent.
   1605   *                            If aEventTarget won't dispatch "input" event
   1606   *                            with InputEvent, set EditorInputType::eUnknown.
   1607   * @param aEditorBase         Optional.  If this is called by editor,
   1608   *                            editor should set this.  Otherwise, leave
   1609   *                            nullptr.
   1610   * @param aOptions            Optional.  If aEditorInputType value requires
   1611   *                            some additional data, they should be properly
   1612   *                            set with this argument.
   1613   * @param aEventStatus        Returns nsEventStatus_eConsumeNoDefault if
   1614   *                            the dispatching event is cancelable and the
   1615   *                            event was canceled by script (including
   1616   *                            chrome script).  Otherwise, returns given
   1617   *                            value.  Note that this can be nullptr only
   1618   *                            when the dispatching event is not cancelable.
   1619   */
   1620  MOZ_CAN_RUN_SCRIPT static nsresult DispatchInputEvent(Element* aEventTarget);
   1621  MOZ_CAN_RUN_SCRIPT static nsresult DispatchInputEvent(
   1622      Element* aEventTarget, mozilla::EventMessage aEventMessage,
   1623      mozilla::EditorInputType aEditorInputType,
   1624      mozilla::EditorBase* aEditorBase, mozilla::InputEventOptions&& aOptions,
   1625      nsEventStatus* aEventStatus = nullptr);
   1626 
   1627  /**
   1628   * This method creates and dispatches a untrusted event.
   1629   * Works only with events which can be created by calling
   1630   * Document::CreateEvent() with parameter "Events".
   1631   * @param aDoc           The document which will be used to create the event.
   1632   * @param aTarget        The target of the event.
   1633   * @param aEventName     The name of the event.
   1634   * @param aCanBubble     Whether the event can bubble.
   1635   * @param aCancelable    Is the event cancelable.
   1636   * @param aDefaultAction Set to true if default action should be taken,
   1637   *                       see EventTarget::DispatchEvent.
   1638   */
   1639  static nsresult DispatchUntrustedEvent(Document* aDoc,
   1640                                         mozilla::dom::EventTarget* aTarget,
   1641                                         const nsAString& aEventName, CanBubble,
   1642                                         Cancelable,
   1643                                         bool* aDefaultAction = nullptr);
   1644 
   1645  /**
   1646   * This method creates and dispatches a untrusted event using an event
   1647   * message.
   1648   * @param aDoc           The document which will be used to create the event.
   1649   * @param aTarget        The target of the event.
   1650   * @param aEventMessage  The event message.
   1651   * @param aCanBubble     Whether the event can bubble.
   1652   * @param aCancelable    Is the event cancelable.
   1653   * @param aDefaultAction Set to true if default action should be taken,
   1654   *                       see EventTarget::DispatchEvent.
   1655   */
   1656  template <class WidgetEventType>
   1657  static nsresult DispatchUntrustedEvent(
   1658      Document* aDoc, mozilla::dom::EventTarget* aTarget,
   1659      EventMessage aEventMessage, CanBubble aCanBubble, Cancelable aCancelable,
   1660      bool* aDefaultAction = nullptr,
   1661      ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo) {
   1662    WidgetEventType event(false, aEventMessage);
   1663    MOZ_ASSERT(GetEventClassIDFromMessage(aEventMessage) == event.mClass);
   1664    return DispatchEvent(aDoc, aTarget, event, aEventMessage, aCanBubble,
   1665                         aCancelable, Trusted::eNo, aDefaultAction,
   1666                         aOnlyChromeDispatch);
   1667  }
   1668 
   1669  /**
   1670   * This method creates and dispatches a trusted event to the chrome
   1671   * event handler (the parent object of the DOM Window in the event target
   1672   * chain). Note, chrome event handler is used even if aTarget is a chrome
   1673   * object. Use DispatchEventOnlyToChrome if the normal event dispatching is
   1674   * wanted in case aTarget is a chrome object.
   1675   * Works only with events which can be created by calling
   1676   * Document::CreateEvent() with parameter "Events".
   1677   * @param aDocument      The document which will be used to create the event,
   1678   *                       and whose window's chrome handler will be used to
   1679   *                       dispatch the event.
   1680   * @param aTarget        The target of the event, used for event->SetTarget()
   1681   * @param aEventName     The name of the event.
   1682   * @param aCanBubble     Whether the event can bubble.
   1683   * @param aCancelable    Is the event cancelable.
   1684   * @param aDefaultAction Set to true if default action should be taken,
   1685   *                       see EventTarget::DispatchEvent.
   1686   */
   1687  static nsresult DispatchChromeEvent(Document* aDoc,
   1688                                      mozilla::dom::EventTarget* aTarget,
   1689                                      const nsAString& aEventName, CanBubble,
   1690                                      Cancelable,
   1691                                      bool* aDefaultAction = nullptr);
   1692 
   1693  /**
   1694   * Helper to dispatch a "framefocusrequested" event to chrome, which will only
   1695   * bring the window to the foreground and switch tabs if aCanRaise is true.
   1696   */
   1697  MOZ_CAN_RUN_SCRIPT_BOUNDARY static void RequestFrameFocus(
   1698      Element& aFrameElement, bool aCanRaise,
   1699      mozilla::dom::CallerType aCallerType);
   1700 
   1701  /**
   1702   * This method creates and dispatches a trusted event.
   1703   * If aTarget is not a chrome object, the nearest chrome object in the
   1704   * propagation path will be used as the start of the event target chain.
   1705   * This method is different than DispatchChromeEvent, which always dispatches
   1706   * events to chrome event handler. DispatchEventOnlyToChrome works like
   1707   * DispatchTrustedEvent in the case aTarget is a chrome object.
   1708   * Works only with events which can be created by calling
   1709   * Document::CreateEvent() with parameter "Events".
   1710   * @param aDoc           The document which will be used to create the event.
   1711   * @param aTarget        The target of the event.
   1712   * @param aEventName     The name of the event.
   1713   * @param aCanBubble     Whether the event can bubble.
   1714   * @param aCancelable    Is the event cancelable.
   1715   * @param aComposed      Is the event composed.
   1716   * @param aDefaultAction Set to true if default action should be taken,
   1717   *                       see EventTarget::DispatchEvent.
   1718   */
   1719  static nsresult DispatchEventOnlyToChrome(
   1720      Document* aDoc, mozilla::dom::EventTarget* aTarget,
   1721      const nsAString& aEventName, CanBubble, Cancelable,
   1722      Composed aComposed = Composed::eDefault, bool* aDefaultAction = nullptr);
   1723 
   1724  static nsresult DispatchEventOnlyToChrome(Document* aDoc,
   1725                                            mozilla::dom::EventTarget* aTarget,
   1726                                            const nsAString& aEventName,
   1727                                            CanBubble aCanBubble,
   1728                                            Cancelable aCancelable,
   1729                                            bool* aDefaultAction) {
   1730    return DispatchEventOnlyToChrome(aDoc, aTarget, aEventName, aCanBubble,
   1731                                     aCancelable, Composed::eDefault,
   1732                                     aDefaultAction);
   1733  }
   1734 
   1735  /**
   1736   * Determines if an event attribute name (such as onclick) is valid for
   1737   * a given element type. Types are from the EventNameType enumeration
   1738   * defined above.
   1739   *
   1740   * @param aName the event name to look up
   1741   * @param aType the type of content
   1742   */
   1743  static bool IsEventAttributeName(nsAtom* aName, int32_t aType);
   1744 
   1745  /**
   1746   * Return the event message for the event with the given name. The name is
   1747   * the event name with the 'on' prefix. Returns eUnidentifiedEvent if the
   1748   * event doesn't match a known event name.
   1749   *
   1750   * @param aName the event name to look up
   1751   */
   1752  static EventMessage GetEventMessage(nsAtom* aName);
   1753 
   1754  /**
   1755   * Iterate through all event attribute names (such as onclick) that
   1756   * are valid for a given element type. Types are from the EventNameType
   1757   * enumeration defined above.
   1758   *
   1759   * @param aType the type of content
   1760   * @param aFunc iterator functor
   1761   */
   1762  static void ForEachEventAttributeName(
   1763      int32_t aType, const mozilla::FunctionRef<void(nsAtom*)> aFunc);
   1764 
   1765  /**
   1766   * Return the event type atom for a given event message.
   1767   */
   1768  static nsAtom* GetEventTypeFromMessage(EventMessage aEventMessage);
   1769 
   1770  /**
   1771   * Return the event type atom from a given event.
   1772   */
   1773  static already_AddRefed<nsAtom> GetEventType(
   1774      const mozilla::WidgetEvent* aEvent);
   1775 
   1776  /**
   1777   * Returns the EventMessage and nsAtom to be used for event listener
   1778   * registration.
   1779   */
   1780  static EventMessage GetEventMessageAndAtomForListener(const nsAString& aName,
   1781                                                        nsAtom** aOnName);
   1782 
   1783  /**
   1784   * Return the EventClassID for the event with the given name. The name is the
   1785   * event name *without* the 'on' prefix. Returns eBasicEventClass if the event
   1786   * is not known to be of any particular event class.
   1787   *
   1788   * @param aName the event name to look up
   1789   */
   1790  static mozilla::EventClassID GetEventClassID(const nsAString& aName);
   1791 
   1792  /**
   1793   * Return the event message and atom for the event with the given name.
   1794   * The name is the event name *without* the 'on' prefix.
   1795   * Returns eUnidentifiedEvent on the aEventID if the
   1796   * event doesn't match a known event name in the category.
   1797   *
   1798   * @param aName the event name to look up
   1799   * @param aEventClassID only return event id for aEventClassID
   1800   */
   1801  static nsAtom* GetEventMessageAndAtom(const nsAString& aName,
   1802                                        mozilla::EventClassID aEventClassID,
   1803                                        EventMessage* aEventMessage);
   1804 
   1805  /**
   1806   * Used only during traversal of the XPCOM graph by the cycle
   1807   * collector: push a pointer to the listener manager onto the
   1808   * children deque, if it exists. Do nothing if there is no listener
   1809   * manager.
   1810   *
   1811   * Crucially: does not perform any refcounting operations.
   1812   *
   1813   * @param aNode The node to traverse.
   1814   * @param children The buffer to push a listener manager pointer into.
   1815   */
   1816  static void TraverseListenerManager(nsINode* aNode,
   1817                                      nsCycleCollectionTraversalCallback& cb);
   1818 
   1819  /**
   1820   * Get the eventlistener manager for aNode, creating it if it does not
   1821   * already exist.
   1822   *
   1823   * @param aNode The node for which to get the eventlistener manager.
   1824   */
   1825  static mozilla::EventListenerManager* GetListenerManagerForNode(
   1826      nsINode* aNode);
   1827  /**
   1828   * Get the eventlistener manager for aNode, returning null if it does not
   1829   * already exist.
   1830   *
   1831   * @param aNode The node for which to get the eventlistener manager.
   1832   */
   1833  static mozilla::EventListenerManager* GetExistingListenerManagerForNode(
   1834      const nsINode* aNode);
   1835 
   1836  static void AddEntryToDOMArenaTable(nsINode* aNode,
   1837                                      mozilla::dom::DOMArena* aDOMArena);
   1838 
   1839  static already_AddRefed<mozilla::dom::DOMArena> TakeEntryFromDOMArenaTable(
   1840      const nsINode* aNode);
   1841 
   1842  static void UnmarkGrayJSListenersInCCGenerationDocuments();
   1843 
   1844  /**
   1845   * Remove the eventlistener manager for aNode.
   1846   *
   1847   * @param aNode The node for which to remove the eventlistener manager.
   1848   */
   1849  static void RemoveListenerManager(nsINode* aNode);
   1850 
   1851  static bool IsInitialized() { return sInitialized; }
   1852 
   1853  /**
   1854   * Checks if the localname/prefix/namespace triple is valid wrt prefix
   1855   * and namespace according to the Namespaces in XML and DOM Code
   1856   * specfications.
   1857   *
   1858   * @param aLocalname localname of the node
   1859   * @param aPrefix prefix of the node
   1860   * @param aNamespaceID namespace of the node
   1861   */
   1862  static bool IsValidNodeName(nsAtom* aLocalName, nsAtom* aPrefix,
   1863                              int32_t aNamespaceID);
   1864 
   1865  /**
   1866   * Creates a DocumentFragment from text using a context node to resolve
   1867   * namespaces.
   1868   *
   1869   * Please note that for safety reasons, if the node principal of
   1870   * aContextNode is the system principal, this function will automatically
   1871   * sanitize its input using nsTreeSanitizer.
   1872   *
   1873   * Note! In the HTML case with the HTML5 parser enabled, this is only called
   1874   * from Range.createContextualFragment() and the implementation here is
   1875   * quirky accordingly (html context node behaves like a body context node).
   1876   * If you don't want that quirky behavior, don't use this method as-is!
   1877   *
   1878   * @param aContextNode the node which is used to resolve namespaces
   1879   * @param aFragment the string which is parsed to a DocumentFragment
   1880   * @param aReturn the resulting fragment
   1881   * @param aPreventScriptExecution whether to mark scripts as already started
   1882   */
   1883  static already_AddRefed<mozilla::dom::DocumentFragment>
   1884  CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment,
   1885                           bool aPreventScriptExecution,
   1886                           mozilla::ErrorResult& aRv);
   1887 
   1888  static void SetHTML(mozilla::dom::FragmentOrElement* aTarget,
   1889                      Element* aContext, const nsAString& aHTML,
   1890                      const mozilla::dom::SetHTMLOptions& aOptions,
   1891                      mozilla::ErrorResult& aError);
   1892 
   1893  MOZ_CAN_RUN_SCRIPT
   1894  static void SetHTMLUnsafe(mozilla::dom::FragmentOrElement* aTarget,
   1895                            Element* aContext,
   1896                            const mozilla::dom::TrustedHTMLOrString& aSource,
   1897                            const mozilla::dom::SetHTMLUnsafeOptions& aOptions,
   1898                            bool aIsShadowRoot, nsIPrincipal* aSubjectPrincipal,
   1899                            mozilla::ErrorResult& aError);
   1900  /**
   1901   * Invoke the fragment parsing algorithm (innerHTML) using the HTML parser.
   1902   *
   1903   * Please note that for safety reasons, if the node principal of aTargetNode
   1904   * is the system principal, this function will automatically sanitize its
   1905   * input using nsTreeSanitizer.
   1906   *
   1907   * @param aSourceBuffer the string being set as innerHTML
   1908   * @param aTargetNode the target container
   1909   * @param aContextLocalName local name of context node
   1910   * @param aContextNamespace namespace of context node
   1911   * @param aQuirks true to make <table> not close <p>
   1912   * @param aPreventScriptExecution true to prevent scripts from executing;
   1913   *        don't set to false when parsing into a target node that has been
   1914   *        bound to tree.
   1915   * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
   1916   *         fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
   1917   *         long and NS_OK otherwise.
   1918   * @param aFlags defaults to -1 indicating that ParseFragmentHTML will do
   1919   *        default sanitization for system privileged calls to it. Only
   1920   *        ParserUtils::ParseFragment() should ever pass explicit aFlags
   1921   *        which will then used for sanitization of the fragment.
   1922   *        To pass explicit aFlags use any of the sanitization flags
   1923   *        listed in nsIParserUtils.idl.
   1924   */
   1925  static nsresult ParseFragmentHTML(const nsAString& aSourceBuffer,
   1926                                    nsIContent* aTargetNode,
   1927                                    nsAtom* aContextLocalName,
   1928                                    int32_t aContextNamespace, bool aQuirks,
   1929                                    bool aPreventScriptExecution,
   1930                                    int32_t aFlags = -1);
   1931 
   1932  /**
   1933   * Invoke the fragment parsing algorithm (innerHTML) using the XML parser.
   1934   *
   1935   * Please note that for safety reasons, if the node principal of aDocument
   1936   * is the system principal, this function will automatically sanitize its
   1937   * input using nsTreeSanitizer.
   1938   *
   1939   * @param aSourceBuffer the string being set as innerHTML
   1940   * @param aDocument the target document
   1941   * @param aTagStack the namespace mapping context
   1942   * @param aPreventExecution whether to mark scripts as already started
   1943   * @param aFlags, pass -1 and ParseFragmentXML will do default
   1944   *        sanitization for system privileged calls to it. Only
   1945   *        ParserUtils::ParseFragment() should ever pass explicit aFlags
   1946   *        which will then used for sanitization of the fragment.
   1947   *        To pass explicit aFlags use any of the sanitization flags
   1948   *        listed in nsIParserUtils.idl.
   1949   * @param aReturn the result fragment
   1950   * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
   1951   *         fragments is made, a return code from the XML parser.
   1952   */
   1953  static nsresult ParseFragmentXML(const nsAString& aSourceBuffer,
   1954                                   Document* aDocument,
   1955                                   nsTArray<nsString>& aTagStack,
   1956                                   bool aPreventScriptExecution, int32_t aFlags,
   1957                                   mozilla::dom::DocumentFragment** aReturn);
   1958 
   1959  /**
   1960   * Parse a string into a document using the HTML parser.
   1961   * Script elements are marked unexecutable.
   1962   *
   1963   * @param aSourceBuffer the string to parse as an HTML document
   1964   * @param aTargetDocument the document object to parse into. Must not have
   1965   *                        child nodes.
   1966   * @param aScriptingEnabledForNoscriptParsing whether <noscript> is parsed
   1967   *                                            as if scripting was enabled
   1968   * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
   1969   *         fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
   1970   *         long and NS_OK otherwise.
   1971   */
   1972  static nsresult ParseDocumentHTML(const nsAString& aSourceBuffer,
   1973                                    Document* aTargetDocument,
   1974                                    bool aScriptingEnabledForNoscriptParsing);
   1975 
   1976  /**
   1977   * Converts HTML source to plain text by parsing the source and using the
   1978   * plain text serializer on the resulting tree.
   1979   *
   1980   * @param aSourceBuffer the string to parse as an HTML document
   1981   * @param aResultBuffer the string where the plain text result appears;
   1982   *                      may be the same string as aSourceBuffer
   1983   * @param aFlags Flags from nsIDocumentEncoder.
   1984   * @param aWrapCol Number of columns after which to line wrap; 0 for no
   1985   *                 auto-wrapping
   1986   * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
   1987   *         fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
   1988   *         long and NS_OK otherwise.
   1989   */
   1990  static nsresult ConvertToPlainText(const nsAString& aSourceBuffer,
   1991                                     nsAString& aResultBuffer, uint32_t aFlags,
   1992                                     uint32_t aWrapCol);
   1993 
   1994  /**
   1995   * Creates a 'loaded-as-data' HTML document that takes that principal,
   1996   * script global, and URL from the argument, which may be null.
   1997   */
   1998  static already_AddRefed<Document> CreateInertHTMLDocument(
   1999      const Document* aTemplate);
   2000 
   2001  /**
   2002   * Creates a 'loaded-as-data' XML document that takes that principal,
   2003   * script global, and URL from the argument, which may be null.
   2004   */
   2005  static already_AddRefed<Document> CreateInertXMLDocument(
   2006      const Document* aTemplate);
   2007 
   2008 public:
   2009  /**
   2010   * Sets the text contents of a node by replacing all existing children
   2011   * with a single text child.
   2012   *
   2013   * The function always notifies.
   2014   *
   2015   * Will reuse the first text child if one is available. Will not reuse
   2016   * existing cdata children.
   2017   *
   2018   * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
   2019   *
   2020   * @param aContent Node to set contents of.
   2021   * @param aValue   Value to set contents to.
   2022   * @param aTryReuse When true, the function will try to reuse an existing
   2023   *                  textnodes rather than always creating a new one.
   2024   * @param aMutationEffectOnScript Whether to preserve trustworthiness of
   2025   *        script elements.
   2026   */
   2027  MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult SetNodeTextContent(
   2028      nsIContent* aContent, const nsAString& aValue, bool aTryReuse,
   2029      MutationEffectOnScript aMutationEffectOnScript =
   2030          MutationEffectOnScript::DropTrustWorthiness);
   2031 
   2032  /**
   2033   * Get the textual contents of a node. This is a concatenation of all
   2034   * textnodes that are direct or (depending on aDeep) indirect children
   2035   * of the node.
   2036   *
   2037   * NOTE! No serialization takes place and <br> elements
   2038   * are not converted into newlines. Only textnodes and cdata nodes are
   2039   * added to the result.
   2040   *
   2041   * @see nsLayoutUtils::GetFrameTextContent
   2042   *
   2043   * @param aNode Node to get textual contents of.
   2044   * @param aDeep If true child elements of aNode are recursivly descended
   2045   *              into to find text children.
   2046   * @param aResult the result. Out param.
   2047   * @return false on out of memory errors, true otherwise.
   2048   */
   2049  [[nodiscard]] static bool GetNodeTextContent(const nsINode* aNode, bool aDeep,
   2050                                               nsAString& aResult,
   2051                                               const mozilla::fallible_t&);
   2052 
   2053  static void GetNodeTextContent(const nsINode* aNode, bool aDeep,
   2054                                 nsAString& aResult);
   2055 
   2056  /**
   2057   * Same as GetNodeTextContents but appends the result rather than sets it.
   2058   */
   2059  static bool AppendNodeTextContent(const nsINode* aNode, bool aDeep,
   2060                                    nsAString& aResult,
   2061                                    const mozilla::fallible_t&);
   2062 
   2063  /**
   2064   * Utility method that checks if a given node has any non-empty children. This
   2065   * method does not descend recursively into children by default.
   2066   *
   2067   * @param aDiscoverMode Set to eRecurseIntoChildren to descend recursively
   2068   * into children.
   2069   */
   2070  enum TextContentDiscoverMode : uint8_t {
   2071    eRecurseIntoChildren,
   2072    eDontRecurseIntoChildren
   2073  };
   2074 
   2075  static bool HasNonEmptyTextContent(
   2076      nsINode* aNode,
   2077      TextContentDiscoverMode aDiscoverMode = eDontRecurseIntoChildren);
   2078 
   2079  /**
   2080   * Delete strings allocated for nsContentList matches
   2081   */
   2082  static void DestroyMatchString(void* aData);
   2083 
   2084  /*
   2085   * Notify when the first XUL menu is opened and when the all XUL menus are
   2086   * closed. At opening, aInstalling should be TRUE, otherwise, it should be
   2087   * FALSE.
   2088   */
   2089  MOZ_CAN_RUN_SCRIPT static void NotifyInstalledMenuKeyboardListener(
   2090      bool aInstalling);
   2091 
   2092  /**
   2093   * Check whether the nsIURI uses the given scheme.
   2094   *
   2095   * Note that this will check the innermost URI rather than that of
   2096   * the nsIURI itself.
   2097   */
   2098  static bool SchemeIs(nsIURI* aURI, const char* aScheme);
   2099 
   2100  /**
   2101   * Returns true if aPrincipal is an ExpandedPrincipal.
   2102   */
   2103  static bool IsExpandedPrincipal(nsIPrincipal* aPrincipal);
   2104 
   2105  /**
   2106   * Returns true if aPrincipal is the system or an ExpandedPrincipal.
   2107   */
   2108  static bool IsSystemOrExpandedPrincipal(nsIPrincipal* aPrincipal);
   2109 
   2110  /**
   2111   * Gets the system principal from the security manager.
   2112   */
   2113  static nsIPrincipal* GetSystemPrincipal();
   2114 
   2115  /**
   2116   * Gets the null subject principal singleton. This is only useful for
   2117   * assertions.
   2118   */
   2119  static nsIPrincipal* GetNullSubjectPrincipal() {
   2120    return sNullSubjectPrincipal;
   2121  }
   2122 
   2123  /**
   2124   * Gets the about:fingerprintingprotection principal.
   2125   */
   2126  static nsIPrincipal* GetFingerprintingProtectionPrincipal() {
   2127    return sFingerprintingProtectionPrincipal;
   2128  }
   2129 
   2130  /**
   2131   * *aResourcePrincipal is a principal describing who may access the contents
   2132   * of a resource. The resource can only be consumed by a principal that
   2133   * subsumes *aResourcePrincipal. MAKE SURE THAT NOTHING EVER ACTS WITH THE
   2134   * AUTHORITY OF *aResourcePrincipal.
   2135   * It may be null to indicate that the resource has no data from any origin
   2136   * in it yet and anything may access the resource.
   2137   * Additional data is being mixed into the resource from aExtraPrincipal
   2138   * (which may be null; if null, no data is being mixed in and this function
   2139   * will do nothing). Update *aResourcePrincipal to reflect the new data.
   2140   * If *aResourcePrincipal subsumes aExtraPrincipal, nothing needs to change,
   2141   * otherwise *aResourcePrincipal is replaced with the system principal.
   2142   * Returns true if *aResourcePrincipal changed.
   2143   */
   2144  static bool CombineResourcePrincipals(
   2145      nsCOMPtr<nsIPrincipal>* aResourcePrincipal,
   2146      nsIPrincipal* aExtraPrincipal);
   2147 
   2148  /**
   2149   * Trigger a link with uri aLinkURI. Triggers a load after doing a
   2150   * security check using aContent's principal.
   2151   *
   2152   * @param aContent the node on which a link was triggered.
   2153   * @param aLinkURI the URI of the link, must be non-null.
   2154   * @param aTargetSpec the target (like target=, may be empty).
   2155   * @param aUserInvolvement whether a user is involved when link was triggered.
   2156   */
   2157  MOZ_CAN_RUN_SCRIPT
   2158  static void TriggerLinkClick(
   2159      nsIContent* aContent, nsIURI* aLinkURI, const nsString& aTargetSpec,
   2160      mozilla::dom::UserNavigationInvolvement aUserInvolvement);
   2161 
   2162  /**
   2163   * Trigger a link with uri aLinkURI. If aClick is false, this triggers a
   2164   * mouseover on the link, otherwise it triggers a load after doing a
   2165   * security check using aContent's principal.
   2166   *
   2167   * @param aContent the node on which a link was triggered.
   2168   * @param aLinkURI the URI of the link, must be non-null.
   2169   * @param aTargetSpec the target (like target=, may be empty).
   2170   */
   2171  static void TriggerLinkMouseOver(nsIContent* aContent, nsIURI* aLinkURI,
   2172                                   const nsString& aTargetSpec);
   2173 
   2174  /**
   2175   * Get the link location.
   2176   */
   2177  static void GetLinkLocation(mozilla::dom::Element* aElement,
   2178                              nsString& aLocationString);
   2179 
   2180  /**
   2181   * Return top-level widget in the parent chain.
   2182   */
   2183  static nsIWidget* GetTopLevelWidget(nsIWidget* aWidget);
   2184 
   2185  /**
   2186   * Return the localized ellipsis for UI.
   2187   */
   2188  static const nsDependentString GetLocalizedEllipsis();
   2189 
   2190  /**
   2191   * Hide any XUL popups associated with aDocument, including any documents
   2192   * displayed in child frames. Does nothing if aDocument is null.
   2193   */
   2194  MOZ_CAN_RUN_SCRIPT_BOUNDARY static void HidePopupsInDocument(
   2195      Document* aDocument);
   2196 
   2197  /**
   2198   * Retrieve the current drag session, or null if no drag is currently occuring
   2199   */
   2200  static already_AddRefed<nsIDragSession> GetDragSession(nsIWidget* aWidget);
   2201 
   2202  static already_AddRefed<nsIDragSession> GetDragSession(nsPresContext* aPC);
   2203 
   2204  /*
   2205   * Initialize and set the dataTransfer field of an WidgetDragEvent.
   2206   */
   2207  static nsresult SetDataTransferInEvent(mozilla::WidgetDragEvent* aDragEvent);
   2208 
   2209  // filters the drag and drop action to fit within the effects allowed and
   2210  // returns it.
   2211  static uint32_t FilterDropEffect(uint32_t aAction, uint32_t aEffectAllowed);
   2212 
   2213  /*
   2214   * Return true if the target of a drop event is a content document that is
   2215   * an ancestor of the document for the source of the drag.
   2216   */
   2217  static bool CheckForSubFrameDrop(nsIDragSession* aDragSession,
   2218                                   mozilla::WidgetDragEvent* aDropEvent);
   2219 
   2220  /**
   2221   * Return true if aURI is a local file URI (i.e. file://).
   2222   */
   2223  static bool URIIsLocalFile(nsIURI* aURI);
   2224 
   2225  /**
   2226   * Get the application manifest URI for this document.  The manifest URI
   2227   * is specified in the manifest= attribute of the root element of the
   2228   * document.
   2229   *
   2230   * @param aDocument The document that lists the manifest.
   2231   * @param aURI The manifest URI.
   2232   */
   2233  static void GetOfflineAppManifest(Document* aDocument, nsIURI** aURI);
   2234 
   2235  /**
   2236   * Check whether an application should be allowed to use offline APIs.
   2237   */
   2238  static bool OfflineAppAllowed(nsIURI* aURI);
   2239 
   2240  /**
   2241   * Check whether an application should be allowed to use offline APIs.
   2242   */
   2243  static bool OfflineAppAllowed(nsIPrincipal* aPrincipal);
   2244 
   2245  /**
   2246   * Increases the count of blockers preventing scripts from running.
   2247   * NOTE: You might want to use nsAutoScriptBlocker rather than calling
   2248   * this directly
   2249   */
   2250  static void AddScriptBlocker();
   2251 
   2252  /**
   2253   * Decreases the count of blockers preventing scripts from running.
   2254   * NOTE: You might want to use nsAutoScriptBlocker rather than calling
   2255   * this directly
   2256   *
   2257   * WARNING! Calling this function could synchronously execute scripts.
   2258   */
   2259  static void RemoveScriptBlocker();
   2260 
   2261  /**
   2262   * Add a runnable that is to be executed as soon as it's safe to execute
   2263   * scripts.
   2264   * NOTE: If it's currently safe to execute scripts, aRunnable will be run
   2265   *       synchronously before the function returns.
   2266   *
   2267   * @param aRunnable  The nsIRunnable to run as soon as it's safe to execute
   2268   *                   scripts. Passing null is allowed and results in nothing
   2269   *                   happening. It is also allowed to pass an object that
   2270   *                   has not yet been AddRefed.
   2271   */
   2272  static void AddScriptRunner(already_AddRefed<nsIRunnable> aRunnable);
   2273  static void AddScriptRunner(nsIRunnable* aRunnable);
   2274 
   2275  /**
   2276   * Returns true if it's safe to execute content script and false otherwise.
   2277   *
   2278   * The only known case where this lies is mutation events. They run, and can
   2279   * run anything else, when this function returns false, but this is ok.
   2280   */
   2281  static bool IsSafeToRunScript();
   2282 
   2283  // Returns the browser window with the most recent time stamp that is
   2284  // not in private browsing mode.
   2285  static already_AddRefed<nsPIDOMWindowOuter> GetMostRecentNonPBWindow();
   2286 
   2287  // Returns the browser window with the most recent time stamp, filtered by the
   2288  // parameter.
   2289  static already_AddRefed<nsPIDOMWindowOuter> GetMostRecentWindowBy(
   2290      WindowMediatorFilter aFilter);
   2291 
   2292  /**
   2293   * Call this function if !IsSafeToRunScript() and we fail to run the script
   2294   * (rather than using AddScriptRunner as we usually do). |aDocument| is
   2295   * optional as it is only used for showing the URL in the console.
   2296   */
   2297  static void WarnScriptWasIgnored(Document* aDocument);
   2298 
   2299  /**
   2300   * Add a "synchronous section", in the form of an nsIRunnable run once the
   2301   * event loop has reached a "stable state". |aRunnable| must not cause any
   2302   * queued events to be processed (i.e. must not spin the event loop).
   2303   * We've reached a stable state when the currently executing task/event has
   2304   * finished, see
   2305   * http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#synchronous-section
   2306   * In practice this runs aRunnable once the currently executing event
   2307   * finishes. If called multiple times per task/event, all the runnables will
   2308   * be executed, in the order in which RunInStableState() was called.
   2309   */
   2310  static void RunInStableState(already_AddRefed<nsIRunnable> aRunnable);
   2311 
   2312  /* Add a pending IDBTransaction to be cleaned up at the end of performing a
   2313   * microtask checkpoint.
   2314   * See the step of "Cleanup Indexed Database Transactions" in
   2315   * https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
   2316   */
   2317  static void AddPendingIDBTransaction(
   2318      already_AddRefed<nsIRunnable> aTransaction);
   2319 
   2320  /**
   2321   * Returns true if we are doing StableState/MetastableState.
   2322   */
   2323  static bool IsInStableOrMetaStableState();
   2324 
   2325  static JSContext* GetCurrentJSContext();
   2326 
   2327  /**
   2328   * Case insensitive comparison between two atoms.
   2329   */
   2330  static bool EqualsIgnoreASCIICase(nsAtom* aAtom1, nsAtom* aAtom2);
   2331 
   2332  /**
   2333   * Case insensitive comparison between two strings. However it only ignores
   2334   * case for ASCII characters a-z.
   2335   */
   2336  static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
   2337                                    const nsAString& aStr2);
   2338 
   2339  /**
   2340   * Convert ASCII A-Z to a-z.
   2341   */
   2342  static void ASCIIToLower(nsAString& aStr);
   2343  static void ASCIIToLower(nsACString& aStr);
   2344  static void ASCIIToLower(const nsAString& aSource, nsAString& aDest);
   2345  static void ASCIIToLower(const nsACString& aSource, nsACString& aDest);
   2346 
   2347  /**
   2348   * Convert ASCII a-z to A-Z.
   2349   */
   2350  static void ASCIIToUpper(nsAString& aStr);
   2351  static void ASCIIToUpper(nsACString& aStr);
   2352  static void ASCIIToUpper(const nsAString& aSource, nsAString& aDest);
   2353  static void ASCIIToUpper(const nsACString& aSource, nsACString& aDest);
   2354 
   2355  /**
   2356   * Return whether aStr contains an ASCII uppercase character.
   2357   */
   2358  static bool StringContainsASCIIUpper(const nsAString& aStr);
   2359 
   2360  // Returns NS_OK for same origin, error (NS_ERROR_DOM_BAD_URI) if not.
   2361  static nsresult CheckSameOrigin(nsIChannel* aOldChannel,
   2362                                  nsIChannel* aNewChannel);
   2363  static nsIInterfaceRequestor* SameOriginChecker();
   2364 
   2365  /**
   2366   * Returns an ASCII compatible serialization of the nsIPrincipal or nsIURI's
   2367   * origin, as specified by the whatwg HTML specification.  If the principal
   2368   * does not have a host, the origin will be "null".
   2369   *
   2370   * https://html.spec.whatwg.org/multipage/browsers.html#ascii-serialisation-of-an-origin
   2371   *
   2372   * Note that this is different from nsIPrincipal::GetOrigin, does not contain
   2373   * gecko-specific metadata like origin attributes, and should not be used for
   2374   * permissions or security checks.
   2375   *
   2376   * See also `nsIPrincipal::GetWebExposedOriginSerialization`.
   2377   *
   2378   * These methods are thread-safe.
   2379   *
   2380   * @pre aPrincipal/aURI must not be null.
   2381   *
   2382   * @note this should be used for HTML5 origin determination.
   2383   */
   2384  static nsresult GetWebExposedOriginSerialization(nsIURI* aURI,
   2385                                                   nsACString& aOrigin);
   2386  static nsresult GetWebExposedOriginSerialization(nsIPrincipal* aPrincipal,
   2387                                                   nsAString& aOrigin);
   2388  static nsresult GetWebExposedOriginSerialization(nsIURI* aURI,
   2389                                                   nsAString& aOrigin);
   2390 
   2391  /**
   2392   * This method creates and dispatches "command" event, which implements
   2393   * XULCommandEvent.
   2394   * If aPresShell is not null, dispatching goes via
   2395   * PresShell::HandleDOMEventWithTarget().
   2396   */
   2397  MOZ_CAN_RUN_SCRIPT
   2398  static nsresult DispatchXULCommand(
   2399      nsIContent* aTarget, bool aTrusted,
   2400      mozilla::dom::Event* aSourceEvent = nullptr,
   2401      mozilla::PresShell* aPresShell = nullptr, bool aCtrl = false,
   2402      bool aAlt = false, bool aShift = false, bool aMeta = false,
   2403      // Including MouseEventBinding here leads
   2404      // to incude loops, unfortunately.
   2405      uint16_t inputSource = 0 /* MouseEvent_Binding::MOZ_SOURCE_UNKNOWN */,
   2406      int16_t aButton = 0);
   2407 
   2408  static bool CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel,
   2409                           bool aAllowIfInheritsPrincipal);
   2410 
   2411  /**
   2412   * The method checks whether the caller can access native anonymous content.
   2413   * If there is no JS in the stack or privileged JS is running, this
   2414   * method returns true, otherwise false.
   2415   */
   2416  static bool CanAccessNativeAnon();
   2417 
   2418  [[nodiscard]] static nsresult WrapNative(JSContext* cx, nsISupports* native,
   2419                                           const nsIID* aIID,
   2420                                           JS::MutableHandle<JS::Value> vp,
   2421                                           bool aAllowWrapping = true) {
   2422    return WrapNative(cx, native, nullptr, aIID, vp, aAllowWrapping);
   2423  }
   2424 
   2425  // Same as the WrapNative above, but use this one if aIID is nsISupports' IID.
   2426  [[nodiscard]] static nsresult WrapNative(JSContext* cx, nsISupports* native,
   2427                                           JS::MutableHandle<JS::Value> vp,
   2428                                           bool aAllowWrapping = true) {
   2429    return WrapNative(cx, native, nullptr, nullptr, vp, aAllowWrapping);
   2430  }
   2431 
   2432  [[nodiscard]] static nsresult WrapNative(JSContext* cx, nsISupports* native,
   2433                                           nsWrapperCache* cache,
   2434                                           JS::MutableHandle<JS::Value> vp,
   2435                                           bool aAllowWrapping = true) {
   2436    return WrapNative(cx, native, cache, nullptr, vp, aAllowWrapping);
   2437  }
   2438 
   2439  static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
   2440 
   2441  /**
   2442   * Strip all \n, \r and nulls from the given string
   2443   * @param aString the string to remove newlines from [in/out]
   2444   */
   2445  static void RemoveNewlines(nsString& aString);
   2446 
   2447  /**
   2448   * Convert Windows and Mac platform linebreaks to \n.
   2449   * @param aString the string to convert the newlines inside [in/out]
   2450   */
   2451  static void PlatformToDOMLineBreaks(nsString& aString);
   2452  [[nodiscard]] static bool PlatformToDOMLineBreaks(nsString& aString,
   2453                                                    const mozilla::fallible_t&);
   2454 
   2455  static bool IsHandlingKeyBoardEvent() { return sIsHandlingKeyBoardEvent; }
   2456 
   2457  static void SetIsHandlingKeyBoardEvent(bool aHandling) {
   2458    sIsHandlingKeyBoardEvent = aHandling;
   2459  }
   2460 
   2461  /**
   2462   * Utility method for getElementsByClassName.  aRootNode is the node (either
   2463   * document or element), which getElementsByClassName was called on.
   2464   */
   2465  static already_AddRefed<nsContentList> GetElementsByClassName(
   2466      nsINode* aRootNode, const nsAString& aClasses);
   2467 
   2468  /**
   2469   * Returns a presshell for this document, if there is one. This will be
   2470   * aDoc's direct presshell if there is one, otherwise we'll look at all
   2471   * ancestor documents to try to find a presshell, so for example this can
   2472   * still find a presshell for documents in display:none frames that have
   2473   * no presentation. So you have to be careful how you use this presshell ---
   2474   * getting generic data like a device context or widget from it is OK, but it
   2475   * might not be this document's actual presentation.
   2476   */
   2477  static mozilla::PresShell* FindPresShellForDocument(
   2478      const Document* aDocument);
   2479 
   2480  /**
   2481   * Like FindPresShellForDocument, but returns the shell's PresContext instead.
   2482   */
   2483  static nsPresContext* FindPresContextForDocument(const Document* aDocument);
   2484 
   2485  /**
   2486   * Returns the widget for this document if there is one. Looks at all ancestor
   2487   * documents to try to find a widget, so for example this can still find a
   2488   * widget for documents in display:none frames that have no presentation.
   2489   *
   2490   * You should probably use WidgetForContent() instead of this, unless you have
   2491   * a good reason to do otherwise.
   2492   */
   2493  static nsIWidget* WidgetForDocument(const Document* aDocument);
   2494 
   2495  /**
   2496   * Returns the appropriate widget for this element, if there is one. Unlike
   2497   * WidgetForDocument(), this returns the correct widget for content in popups.
   2498   *
   2499   * You should probably use this instead of WidgetForDocument().
   2500   */
   2501  static nsIWidget* WidgetForContent(const nsIContent* aContent);
   2502 
   2503  /**
   2504   * Returns a window renderer to use for the given document. Basically we
   2505   * look up the document hierarchy for the first document which has
   2506   * a presentation with an associated widget, and use that widget's
   2507   * window renderer.
   2508   *
   2509   * You should probably use WindowRendererForContent() instead of this, unless
   2510   * you have a good reason to do otherwise.
   2511   *
   2512   * @param aDoc the document for which to return a window renderer.
   2513   * @param aAllowRetaining an outparam that states whether the returned
   2514   * layer manager should be used for retained layers
   2515   */
   2516  static mozilla::WindowRenderer* WindowRendererForDocument(
   2517      const Document* aDoc);
   2518 
   2519  /**
   2520   * Returns a window renderer to use for the given content. Unlike
   2521   * WindowRendererForDocument(), this returns the correct window renderer for
   2522   * content in popups.
   2523   *
   2524   * You should probably use this instead of WindowRendererForDocument().
   2525   */
   2526  static mozilla::WindowRenderer* WindowRendererForContent(
   2527      const nsIContent* aContent);
   2528 
   2529  /**
   2530   * Returns true if calling execCommand with 'cut' or 'copy' arguments is
   2531   * allowed for the given subject principal. These are only allowed if the user
   2532   * initiated them (like with a mouse-click or key press).
   2533   */
   2534  static bool IsCutCopyAllowed(Document* aDocument,
   2535                               nsIPrincipal& aSubjectPrincipal);
   2536 
   2537  /**
   2538   * Returns true if CSSOM origin check should be skipped for WebDriver
   2539   * based crawl to be able to collect data from cross-origin CSS style
   2540   * sheets. This can be enabled by setting environment variable
   2541   * MOZ_BYPASS_CSSOM_ORIGIN_CHECK.
   2542   */
   2543  static bool BypassCSSOMOriginCheck() {
   2544 #ifdef RELEASE_OR_BETA
   2545    return false;
   2546 #else
   2547    return sBypassCSSOMOriginCheck;
   2548 #endif
   2549  }
   2550 
   2551  /**
   2552   * Returns the in-process subtree root document in a document hierarchy.
   2553   * This could be a chrome document.
   2554   */
   2555  static Document* GetInProcessSubtreeRootDocument(Document* aDoc) {
   2556    return const_cast<Document*>(
   2557        GetInProcessSubtreeRootDocument(const_cast<const Document*>(aDoc)));
   2558  }
   2559  static const Document* GetInProcessSubtreeRootDocument(const Document* aDoc);
   2560 
   2561  static void GetShiftText(nsAString& text);
   2562  static void GetControlText(nsAString& text);
   2563  static void GetCommandOrWinText(nsAString& text);
   2564  static void GetAltText(nsAString& text);
   2565  static void GetModifierSeparatorText(nsAString& text);
   2566 
   2567  /**
   2568   * Flushes the layout tree (recursively)
   2569   *
   2570   * @param aWindow the window the flush should start at
   2571   *
   2572   */
   2573  static void FlushLayoutForTree(nsPIDOMWindowOuter* aWindow);
   2574 
   2575  /**
   2576   * Returns true if content with the given principal is allowed to use XUL
   2577   * and XBL and false otherwise.
   2578   */
   2579  static bool AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal);
   2580 
   2581  /**
   2582   * Perform cleanup that's appropriate for XPCOM shutdown.
   2583   */
   2584  static void XPCOMShutdown();
   2585 
   2586  /**
   2587   * Checks if internal PDF viewer is enabled.
   2588   */
   2589  static bool IsPDFJSEnabled();
   2590 
   2591  /**
   2592   * Checks to see whether the given principal is the internal PDF
   2593   * viewer principal.
   2594   */
   2595  static bool IsPDFJS(nsIPrincipal* aPrincipal);
   2596  /**
   2597   * Same, but from WebIDL bindings. Checks whether the subject principal is for
   2598   * the internal PDF viewer or system JS.
   2599   */
   2600  static bool IsSystemOrPDFJS(JSContext*, JSObject*);
   2601 
   2602  /**
   2603   * Checks if the given JSContext is secure or if the subject principal is
   2604   * either an addon principal or an expanded principal, which contains at least
   2605   * one addon principal.
   2606   */
   2607  static bool IsSecureContextOrWebExtension(JSContext*, JSObject*);
   2608 
   2609  enum DocumentViewerType {
   2610    TYPE_UNSUPPORTED,
   2611    TYPE_CONTENT,
   2612    TYPE_FALLBACK,
   2613    TYPE_UNKNOWN
   2614  };
   2615 
   2616  static already_AddRefed<nsIDocumentLoaderFactory> FindInternalDocumentViewer(
   2617      const nsACString& aType, DocumentViewerType* aLoaderType = nullptr);
   2618 
   2619  /**
   2620   * This helper method returns true if the aPattern pattern matches aValue.
   2621   * aPattern should not contain leading and trailing slashes (/).
   2622   * The pattern has to match the entire value not just a subset.
   2623   * aDocument must be a valid pointer (not null).
   2624   *
   2625   * This is following the HTML5 specification:
   2626   * http://dev.w3.org/html5/spec/forms.html#attr-input-pattern
   2627   *
   2628   * WARNING: This method mutates aPattern!
   2629   *
   2630   * @param aValue       the string to check.
   2631   * @param aPattern     the string defining the pattern.
   2632   * @param aDocument    the owner document of the element.
   2633   * @param aHasMultiple whether or not there are multiple values.
   2634   * @param aFlags       the flags to use for creating the regexp object.
   2635   * @result             whether the given string is matches the pattern, or
   2636   *                     Nothing() if the pattern couldn't be evaluated.
   2637   */
   2638  static mozilla::Maybe<bool> IsPatternMatching(
   2639      const nsAString& aValue, nsString&& aPattern, const Document* aDocument,
   2640      bool aHasMultiple = false,
   2641      JS::RegExpFlags aFlags = JS::RegExpFlag::UnicodeSets);
   2642 
   2643  /**
   2644   * Calling this adds support for
   2645   * ontouch* event handler DOM attributes.
   2646   */
   2647  static void InitializeTouchEventTable();
   2648 
   2649  /**
   2650   * Test whether the given URI always inherits a security context
   2651   * from the document it comes from.
   2652   */
   2653  static nsresult URIInheritsSecurityContext(nsIURI* aURI, bool* aResult);
   2654 
   2655  /**
   2656   * Called before a channel is created to query whether the new
   2657   * channel should inherit the principal.
   2658   *
   2659   * The argument aLoadingPrincipal must not be null. The argument
   2660   * aURI must be the URI of the new channel. If aInheritForAboutBlank
   2661   * is true, then about:blank will be told to inherit the principal.
   2662   * If aForceInherit is true, the new channel will be told to inherit
   2663   * the principal no matter what.
   2664   *
   2665   * The return value is whether the new channel should inherit
   2666   * the principal.
   2667   */
   2668  static bool ChannelShouldInheritPrincipal(nsIPrincipal* aLoadingPrincipal,
   2669                                            nsIURI* aURI,
   2670                                            bool aInheritForAboutBlank,
   2671                                            bool aForceInherit);
   2672 
   2673  static nsresult Btoa(const nsAString& aBinaryData,
   2674                       nsAString& aAsciiBase64String);
   2675 
   2676  static nsresult Atob(const nsAString& aAsciiString, nsAString& aBinaryData);
   2677 
   2678  /**
   2679   * Returns whether the input element passed in parameter has the autocomplete
   2680   * functionality enabled. It is taking into account the form owner.
   2681   * NOTE: the caller has to make sure autocomplete makes sense for the
   2682   * element's type.
   2683   *
   2684   * @param aElement the input or textarea element to check. NOTE: aElement
   2685   * can't be null.
   2686   * @return whether the input element has autocomplete enabled.
   2687   */
   2688  static bool IsAutocompleteEnabled(mozilla::dom::Element* aElement);
   2689 
   2690  enum AutocompleteAttrState : uint8_t {
   2691    eAutocompleteAttrState_Unknown = 1,
   2692    eAutocompleteAttrState_Invalid,
   2693    eAutocompleteAttrState_Valid,
   2694  };
   2695  /**
   2696   * Parses the value of the autocomplete attribute into aResult, ensuring it's
   2697   * composed of valid tokens, otherwise the value "" is used.
   2698   * Note that this method is used for form fields, not on a <form> itself.
   2699   *
   2700   * @return whether aAttr was valid and can be cached.
   2701   */
   2702  static AutocompleteAttrState SerializeAutocompleteAttribute(
   2703      const nsAttrValue* aAttr, nsAString& aResult,
   2704      AutocompleteAttrState aCachedState = eAutocompleteAttrState_Unknown);
   2705 
   2706  /* Variation that is used to retrieve a dictionary of the parts of the
   2707   * autocomplete attribute.
   2708   *
   2709   * @return whether aAttr was valid and can be cached.
   2710   */
   2711  static AutocompleteAttrState SerializeAutocompleteAttribute(
   2712      const nsAttrValue* aAttr, mozilla::dom::AutocompleteInfo& aInfo,
   2713      AutocompleteAttrState aCachedState = eAutocompleteAttrState_Unknown,
   2714      bool aGrantAllValidValue = false);
   2715 
   2716  /**
   2717   * This will parse aSource, to extract the value of the pseudo attribute
   2718   * with the name specified in aName. See
   2719   * http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
   2720   * which is used to parse aSource.
   2721   *
   2722   * @param aSource the string to parse
   2723   * @param aName the name of the attribute to get the value for
   2724   * @param aValue [out] the value for the attribute with name specified in
   2725   *                     aAttribute. Empty if the attribute isn't present.
   2726   * @return true     if the attribute exists and was successfully parsed.
   2727   *         false if the attribute doesn't exist, or has a malformed
   2728   *                  value, such as an unknown or unterminated entity.
   2729   */
   2730  static bool GetPseudoAttributeValue(const nsString& aSource, nsAtom* aName,
   2731                                      nsAString& aValue);
   2732 
   2733  /**
   2734   * Returns true if the language name is a version of JavaScript and
   2735   * false otherwise
   2736   */
   2737  static bool IsJavaScriptLanguage(const nsString& aName);
   2738 
   2739  static bool IsJavascriptMIMEType(const nsAString& aMIMEType);
   2740  static bool IsJavascriptMIMEType(const nsACString& aMIMEType);
   2741 
   2742  /**
   2743   * Returns true if the given MIME type string is a valid JSON MIME type,
   2744   * otherwise false.
   2745   */
   2746  static bool IsJsonMimeType(const nsAString& aMimeType);
   2747 
   2748  /**
   2749   * Returns true if the given MIME type string has a CSS MIME type essence,
   2750   * otherwise false.
   2751   */
   2752  static bool HasCssMimeTypeEssence(const nsAString& aMimeType);
   2753 
   2754  /**
   2755   * Returns true if the given MIME type string has a wasm MIME type essence,
   2756   * otherwise false.
   2757   */
   2758  static bool HasWasmMimeTypeEssence(const nsAString& aMimeType);
   2759 
   2760  static void SplitMimeType(const nsAString& aValue, nsString& aType,
   2761                            nsString& aParams);
   2762 
   2763  /**
   2764   * Check whether aContent and aOffsetInContent points in a selection range of
   2765   * one of ranges in aSelection.  If aSelection is collapsed, this always
   2766   * return false even if aContent and aOffsetInContent is same as the collapsed
   2767   * position.
   2768   *
   2769   * @param aSelection  The selection you want to check whether point is in a
   2770   *                    range of it.
   2771   * @param aNode       The container node of the point which you want to check.
   2772   * @param aOffset     The offset in aNode of the point which you want to
   2773   *                    check.  aNode and aOffset can be computed with
   2774   *                    UIEvent::GetRangeParentContentAndOffset() if you want to
   2775   *                    check the click point.
   2776   * @param aAllowCrossShadowBoundary If true, this method allows the selection
   2777   *                                  to have boundaries that cross shadow
   2778   *                                  boundaries.
   2779   */
   2780  static bool IsPointInSelection(const mozilla::dom::Selection& aSelection,
   2781                                 const nsINode& aNode, const uint32_t aOffset,
   2782                                 const bool aAllowCrossShadowBoundary = false);
   2783 
   2784  /**
   2785   * Takes a selection, and a text control element (<input> or <textarea>), and
   2786   * returns the offsets in the text content corresponding to the selection.
   2787   * The selection's anchor and focus must both be in the root node passed or a
   2788   * descendant.
   2789   *
   2790   * @param aSelection      Selection to check
   2791   * @param aRoot           Root <input> or <textarea> element
   2792   * @param aOutStartOffset Output start offset
   2793   * @param aOutEndOffset   Output end offset
   2794   */
   2795  static void GetSelectionInTextControl(mozilla::dom::Selection* aSelection,
   2796                                        Element* aRoot,
   2797                                        uint32_t& aOutStartOffset,
   2798                                        uint32_t& aOutEndOffset);
   2799 
   2800  /**
   2801   * Takes a frame for anonymous content within a text control (<input> or
   2802   * <textarea>), and returns an offset in the text content, adjusted for a
   2803   * trailing <br> frame.
   2804   *
   2805   * @param aOffsetFrame      Frame for the text content in which the offset
   2806   *                          lies
   2807   * @param aOffset           Offset as calculated by GetContentOffsetsFromPoint
   2808   * @param aOutOffset        Output adjusted offset
   2809   *
   2810   * @see GetSelectionInTextControl for the original basis of this function.
   2811   */
   2812  static int32_t GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame,
   2813                                                int32_t aOffset);
   2814 
   2815  /**
   2816   * Returns pointer to HTML editor instance for the aPresContext when there is.
   2817   * The HTML editor is shared by contenteditable elements or used in
   2818   * designMode.  When there are no contenteditable elements and the document
   2819   * is not in designMode, this returns nullptr.
   2820   */
   2821  static mozilla::HTMLEditor* GetHTMLEditor(nsPresContext* aPresContext);
   2822  static mozilla::HTMLEditor* GetHTMLEditor(nsDocShell* aDocShell);
   2823 
   2824  /**
   2825   * Returns pointer to a text editor if <input> or <textarea> element is
   2826   * active element in the document for aPresContext, or pointer to HTML
   2827   * editor if there is (i.e., even if non-editable element has focus or
   2828   * nobody has focus).  The reason is, HTML editor may handle some input
   2829   * even if there is no active editing host.
   2830   * Note that this does not return editor in descendant documents.
   2831   */
   2832  static mozilla::EditorBase* GetActiveEditor(nsPresContext* aPresContext);
   2833  static mozilla::EditorBase* GetActiveEditor(nsPIDOMWindowOuter* aWindow);
   2834 
   2835  /**
   2836   * Returns `TextEditor` which manages `aAnonymousContent` if there is.
   2837   * Note that this method returns `nullptr` if `TextEditor` for the
   2838   * `aAnonymousContent` hasn't been created yet.
   2839   */
   2840  static mozilla::TextEditor* GetExtantTextEditorFromAnonymousNode(
   2841      const nsIContent* aAnonymousContent);
   2842 
   2843  /**
   2844   * Returns whether a node has an editable ancestor.
   2845   *
   2846   * @param aNode The node to test.
   2847   */
   2848  static bool IsNodeInEditableRegion(nsINode* aNode);
   2849 
   2850  /**
   2851   * Returns a LogModule that logs debugging info from RFP functions.
   2852   */
   2853  static mozilla::LogModule* ResistFingerprintingLog();
   2854 
   2855  /**
   2856   * Returns a LogModule that dump calls from content script are logged to.
   2857   * This can be enabled with the 'Dump' module, and is useful for synchronizing
   2858   * content JS to other logging modules.
   2859   */
   2860  static mozilla::LogModule* DOMDumpLog();
   2861 
   2862  /**
   2863   * Returns whether a given header is forbidden for an XHR or fetch
   2864   * request.
   2865   */
   2866  static bool IsForbiddenRequestHeader(const nsACString& aHeader,
   2867                                       const nsACString& aValue);
   2868 
   2869  /**
   2870   * Returns whether a given header is forbidden for a system XHR
   2871   * request.
   2872   */
   2873  static bool IsForbiddenSystemRequestHeader(const nsACString& aHeader);
   2874 
   2875  /**
   2876   * Checks whether the header overrides any http methods
   2877   */
   2878  static bool IsOverrideMethodHeader(const nsACString& headerName);
   2879  /**
   2880   * Checks whether the  header value contains any forbidden method
   2881   */
   2882  static bool ContainsForbiddenMethod(const nsACString& headerValue);
   2883 
   2884  class ParsedRange {
   2885   public:
   2886    explicit ParsedRange(mozilla::Maybe<uint64_t> aStart,
   2887                         mozilla::Maybe<uint64_t> aEnd)
   2888        : mStart(aStart), mEnd(aEnd) {}
   2889 
   2890    mozilla::Maybe<uint64_t> Start() const { return mStart; }
   2891    mozilla::Maybe<uint64_t> End() const { return mEnd; }
   2892 
   2893    bool operator==(const ParsedRange& aOther) const {
   2894      return Start() == aOther.Start() && End() == aOther.End();
   2895    }
   2896 
   2897   private:
   2898    mozilla::Maybe<uint64_t> mStart;
   2899    mozilla::Maybe<uint64_t> mEnd;
   2900  };
   2901 
   2902  /**
   2903   * Parse a single range request and return a pair containing the resulting
   2904   * start and end of the range.
   2905   *
   2906   * See https://fetch.spec.whatwg.org/#simple-range-header-value
   2907   */
   2908  static mozilla::Maybe<ParsedRange> ParseSingleRangeRequest(
   2909      const nsACString& aHeaderValue, bool aAllowWhitespace);
   2910 
   2911  /**
   2912   * Returns whether a given header has characters that aren't permitted
   2913   */
   2914  static bool IsCorsUnsafeRequestHeaderValue(const nsACString& aHeaderValue);
   2915 
   2916  /**
   2917   * Returns whether a given Accept header value is allowed
   2918   * for a non-CORS XHR or fetch request.
   2919   */
   2920  static bool IsAllowedNonCorsAccept(const nsACString& aHeaderValue);
   2921 
   2922  /**
   2923   * Returns whether a given Content-Type header value is allowed
   2924   * for a non-CORS XHR or fetch request.
   2925   */
   2926  static bool IsAllowedNonCorsContentType(const nsACString& aHeaderValue);
   2927 
   2928  /**
   2929   * Returns whether a given Content-Language or accept-language header value is
   2930   * allowed for a non-CORS XHR or fetch request.
   2931   */
   2932  static bool IsAllowedNonCorsLanguage(const nsACString& aHeaderValue);
   2933 
   2934  /**
   2935   * Returns whether a given Range header value is allowed for a non-CORS XHR or
   2936   * fetch request.
   2937   */
   2938  static bool IsAllowedNonCorsRange(const nsACString& aHeaderValue);
   2939 
   2940  /**
   2941   * Returns whether a given header and value is a CORS-safelisted request
   2942   * header per https://fetch.spec.whatwg.org/#cors-safelisted-request-header
   2943   */
   2944  static bool IsCORSSafelistedRequestHeader(const nsACString& aName,
   2945                                            const nsACString& aValue);
   2946 
   2947  /**
   2948   * Returns whether a given header is forbidden for an XHR or fetch
   2949   * response.
   2950   */
   2951  static bool IsForbiddenResponseHeader(const nsACString& aHeader);
   2952 
   2953  /**
   2954   * Returns the inner window ID for the window associated with a request.
   2955   */
   2956  static uint64_t GetInnerWindowID(nsIRequest* aRequest);
   2957 
   2958  /**
   2959   * Returns the inner window ID for the window associated with a load group.
   2960   */
   2961  static uint64_t GetInnerWindowID(nsILoadGroup* aLoadGroup);
   2962 
   2963  /**
   2964   * Encloses aHost in brackets if it is an IPv6 address.
   2965   */
   2966  static void MaybeFixIPv6Host(nsACString& aHost);
   2967 
   2968  /**
   2969   * If the hostname for aURI is an IPv6 it encloses it in brackets,
   2970   * otherwise it just outputs the hostname in aHost.
   2971   */
   2972  static nsresult GetHostOrIPv6WithBrackets(nsIURI* aURI, nsAString& aHost);
   2973  static nsresult GetHostOrIPv6WithBrackets(nsIURI* aURI, nsACString& aHost);
   2974  static nsresult GetHostOrIPv6WithBrackets(nsIPrincipal* aPrincipal,
   2975                                            nsACString& aHost);
   2976 
   2977  /*
   2978   * Call the given callback on all remote children of the given top-level
   2979   * window. Return Callstate::Stop from the callback to stop calling further
   2980   * children.
   2981   */
   2982  static void CallOnAllRemoteChildren(
   2983      nsPIDOMWindowOuter* aWindow,
   2984      const std::function<mozilla::CallState(mozilla::dom::BrowserParent*)>&
   2985          aCallback);
   2986 
   2987  /**
   2988   * Given a flavor obtained from an IPCDataTransferItem or nsITransferable,
   2989   * returns true if we should treat the data as an image.
   2990   */
   2991  static bool IsFlavorImage(const nsACString& aFlavor);
   2992 
   2993  static bool IPCTransferableDataItemHasKnownFlavor(
   2994      const mozilla::dom::IPCTransferableDataItem& aItem);
   2995 
   2996  static nsresult IPCTransferableDataToTransferable(
   2997      const mozilla::dom::IPCTransferableData& aTransferableData,
   2998      bool aAddDataFlavor, nsITransferable* aTransferable,
   2999      const bool aFilterUnknownFlavors);
   3000 
   3001  static nsresult IPCTransferableToTransferable(
   3002      const mozilla::dom::IPCTransferable& aIPCTransferable,
   3003      bool aAddDataFlavor, nsITransferable* aTransferable,
   3004      const bool aFilterUnknownFlavors);
   3005 
   3006  static nsresult IPCTransferableDataItemToVariant(
   3007      const mozilla::dom::IPCTransferableDataItem& aItem,
   3008      nsIWritableVariant* aVariant);
   3009 
   3010  static void TransferablesToIPCTransferableDatas(
   3011      nsIArray* aTransferables,
   3012      nsTArray<mozilla::dom::IPCTransferableData>& aIPC, bool aInSyncMessage,
   3013      mozilla::dom::ContentParent* aParent);
   3014 
   3015  static void TransferableToIPCTransferableData(
   3016      nsITransferable* aTransferable,
   3017      mozilla::dom::IPCTransferableData* aTransferableData, bool aInSyncMessage,
   3018      mozilla::dom::ContentParent* aParent);
   3019 
   3020  static void TransferableToIPCTransferable(
   3021      nsITransferable* aTransferable,
   3022      mozilla::dom::IPCTransferable* aIPCTransferable, bool aInSyncMessage,
   3023      mozilla::dom::ContentParent* aParent);
   3024 
   3025  /*
   3026   * Get the pixel data from the given source surface and return it as a
   3027   * BigBuffer. The length and stride will be assigned from the surface.
   3028   */
   3029  static mozilla::Maybe<mozilla::ipc::BigBuffer> GetSurfaceData(
   3030      mozilla::gfx::DataSourceSurface&, size_t* aLength, int32_t* aStride);
   3031 
   3032  static mozilla::Maybe<mozilla::dom::IPCImage> SurfaceToIPCImage(
   3033      mozilla::gfx::DataSourceSurface&);
   3034  static already_AddRefed<mozilla::gfx::DataSourceSurface> IPCImageToSurface(
   3035      const mozilla::dom::IPCImage&);
   3036  static already_AddRefed<imgIContainer> IPCImageToImage(
   3037      const mozilla::dom::IPCImage&);
   3038 
   3039  // Helpers shared by the implementations of nsContentUtils methods and
   3040  // nsIDOMWindowUtils methods.
   3041  static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers);
   3042  static nsIWidget* GetWidget(mozilla::PresShell* aPresShell, nsPoint* aOffset);
   3043  static int16_t GetButtonsFlagForButton(int32_t aButton);
   3044  static mozilla::LayoutDeviceIntPoint ToWidgetPoint(
   3045      const mozilla::CSSPoint& aPoint, const nsPoint& aOffset,
   3046      nsPresContext* aPresContext);
   3047 
   3048  /**
   3049   * Synthesize a mouse event to the given widget
   3050   * (See synthesizeMouseEvent in Window.webidl).
   3051   *
   3052   * @return A boolean indicating whether the default action was prevented
   3053   *         by any event listener.
   3054   */
   3055  MOZ_CAN_RUN_SCRIPT
   3056  static mozilla::Result<bool, nsresult> SynthesizeMouseEvent(
   3057      mozilla::PresShell* aPresShell, nsIWidget* aWidget,
   3058      const nsAString& aType, mozilla::LayoutDeviceIntPoint& aRefPoint,
   3059      const mozilla::dom::SynthesizeMouseEventData& aMouseEventData,
   3060      const mozilla::dom::SynthesizeMouseEventOptions& aOptions,
   3061      const mozilla::dom::Optional<
   3062          mozilla::OwningNonNull<mozilla::dom::VoidFunction>>& aCallback);
   3063 
   3064  static void FirePageShowEventForFrameLoaderSwap(
   3065      nsIDocShellTreeItem* aItem,
   3066      mozilla::dom::EventTarget* aChromeEventHandler, bool aFireIfShowing,
   3067      bool aOnlySystemGroup = false);
   3068 
   3069  static void FirePageHideEventForFrameLoaderSwap(
   3070      nsIDocShellTreeItem* aItem,
   3071      mozilla::dom::EventTarget* aChromeEventHandler,
   3072      bool aOnlySystemGroup = false);
   3073 
   3074  static already_AddRefed<nsPIWindowRoot> GetWindowRoot(Document* aDoc);
   3075 
   3076  /*
   3077   * If there is a Referrer-Policy response header in |aChannel|, parse a
   3078   * referrer policy from the header.
   3079   *
   3080   * @param the channel from which to get the Referrer-Policy header
   3081   * @return referrer policy from the response header in aChannel
   3082   */
   3083  static mozilla::dom::ReferrerPolicy GetReferrerPolicyFromChannel(
   3084      nsIChannel* aChannel);
   3085 
   3086  static bool IsNonSubresourceRequest(nsIChannel* aChannel);
   3087 
   3088  static bool IsNonSubresourceInternalPolicyType(nsContentPolicyType aType);
   3089 
   3090 public:
   3091  /*
   3092   * Returns true if this window's channel has been marked as a third-party
   3093   * tracking resource.
   3094   */
   3095  static bool IsThirdPartyTrackingResourceWindow(nsPIDOMWindowInner* aWindow);
   3096 
   3097  /*
   3098   * Returns true if this window's channel has been marked as a first-party
   3099   * tracking resource.
   3100   */
   3101  static bool IsFirstPartyTrackingResourceWindow(nsPIDOMWindowInner* aWindow);
   3102 
   3103  /*
   3104   * Serializes a HTML nsINode into its markup representation.
   3105   */
   3106  template <SerializeShadowRoots ShouldSerializeShadowRoots =
   3107                SerializeShadowRoots::No>
   3108  static bool SerializeNodeToMarkup(
   3109      nsINode* aRoot, bool aDescendantsOnly, nsAString& aOut,
   3110      bool aSerializableShadowRoots,
   3111      const mozilla::dom::Sequence<
   3112          mozilla::OwningNonNull<mozilla::dom::ShadowRoot>>& aShadowRoots);
   3113 
   3114  /*
   3115   * Returns true iff the provided JSObject is a global, and its URI matches
   3116   * the provided about: URI.
   3117   * @param aGlobal the JSObject whose URI to check, if it is a global.
   3118   * @param aUri the URI to match, e.g. "about:feeds"
   3119   */
   3120  static bool IsSpecificAboutPage(JSObject* aGlobal, const char* aUri);
   3121 
   3122  static void SetScrollbarsVisibility(nsIDocShell* aDocShell, bool aVisible);
   3123 
   3124  /*
   3125   * Try to find the docshell corresponding to the given event target.
   3126   */
   3127  static nsIDocShell* GetDocShellForEventTarget(
   3128      mozilla::dom::EventTarget* aTarget);
   3129 
   3130  /**
   3131   * Returns true if the "HTTPS state" of the document should be "modern". See:
   3132   *
   3133   * https://html.spec.whatwg.org/#concept-document-https-state
   3134   * https://fetch.spec.whatwg.org/#concept-response-https-state
   3135   */
   3136  static bool HttpsStateIsModern(Document* aDocument);
   3137 
   3138  /**
   3139   * Returns true of the document's URI is a .onion
   3140   */
   3141  static bool DocumentHasOnionURI(Document* aDocument);
   3142 
   3143  /**
   3144   * Returns true if the channel is for top-level window and is over secure
   3145   * context.
   3146   * https://github.com/whatwg/html/issues/4930 tracks the spec side of this.
   3147   */
   3148  static bool ComputeIsSecureContext(nsIChannel* aChannel);
   3149 
   3150  /**
   3151   * Try to upgrade an element.
   3152   * https://html.spec.whatwg.org/multipage/custom-elements.html#concept-try-upgrade
   3153   */
   3154  static void TryToUpgradeElement(Element* aElement);
   3155 
   3156  /**
   3157   * Creates a new XUL or XHTML element applying any appropriate custom element
   3158   * definition.
   3159   *
   3160   * If aFromParser != FROM_PARSER_FRAGMENT, a nested event loop permits
   3161   * arbitrary changes to the world before this function returns.  This should
   3162   * probably just be MOZ_CAN_RUN_SCRIPT - bug 1543259.
   3163   */
   3164  MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult NewXULOrHTMLElement(
   3165      Element** aResult, mozilla::dom::NodeInfo* aNodeInfo,
   3166      mozilla::dom::FromParser aFromParser, nsAtom* aIsAtom,
   3167      mozilla::dom::CustomElementDefinition* aDefinition);
   3168 
   3169  static mozilla::dom::CustomElementRegistry* GetCustomElementRegistry(
   3170      Document*);
   3171 
   3172  /**
   3173   * Looking up a custom element definition.
   3174   * https://html.spec.whatwg.org/#look-up-a-custom-element-definition
   3175   */
   3176  static mozilla::dom::CustomElementDefinition* LookupCustomElementDefinition(
   3177      Document* aDoc, nsAtom* aNameAtom, uint32_t aNameSpaceID,
   3178      nsAtom* aTypeAtom);
   3179 
   3180  static void RegisterCallbackUpgradeElement(Element* aElement,
   3181                                             nsAtom* aTypeName);
   3182 
   3183  static void RegisterUnresolvedElement(Element* aElement, nsAtom* aTypeName);
   3184  static void UnregisterUnresolvedElement(Element* aElement);
   3185 
   3186  static void EnqueueUpgradeReaction(
   3187      Element* aElement, mozilla::dom::CustomElementDefinition* aDefinition);
   3188 
   3189  static void EnqueueLifecycleCallback(
   3190      mozilla::dom::ElementCallbackType aType, Element* aCustomElement,
   3191      const mozilla::dom::LifecycleCallbackArgs& aArgs,
   3192      mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
   3193 
   3194  static mozilla::dom::CustomElementFormValue ConvertToCustomElementFormValue(
   3195      const mozilla::dom::Nullable<
   3196          mozilla::dom::OwningFileOrUSVStringOrFormData>& aState);
   3197 
   3198  static mozilla::dom::Nullable<mozilla::dom::OwningFileOrUSVStringOrFormData>
   3199  ExtractFormAssociatedCustomElementValue(
   3200      nsIGlobalObject* aGlobal,
   3201      const mozilla::dom::CustomElementFormValue& aCEValue);
   3202 
   3203  /**
   3204   * Appends all "document level" native anonymous content subtree roots for
   3205   * aDocument to aElements.  Document level NAC subtrees are those created
   3206   * by ancestor frames of the document element's primary frame, such as
   3207   * the scrollbar elements created by the root scroll frame.
   3208   */
   3209  static void AppendDocumentLevelNativeAnonymousContentTo(
   3210      Document* aDocument, nsTArray<nsIContent*>& aElements);
   3211 
   3212  /**
   3213   * Appends all native anonymous content subtree roots generated by `aContent`
   3214   * to `aKids`.
   3215   *
   3216   * See `AllChildrenIterator` for the description of the `aFlags` parameter.
   3217   */
   3218  static void AppendNativeAnonymousChildren(const nsIContent* aContent,
   3219                                            nsTArray<nsIContent*>& aKids,
   3220                                            uint32_t aFlags);
   3221 
   3222  /**
   3223   * Query triggeringPrincipal if there's a 'triggeringprincipal' attribute on
   3224   * aLoadingNode, if no such attribute is specified, aDefaultPrincipal is
   3225   * returned if it is provided, otherwise the NodePrincipal of aLoadingNode is
   3226   * returned.
   3227   *
   3228   * Return true if aLoadingNode has a 'triggeringprincipal' attribute, and
   3229   * the value 'triggeringprincipal' is also successfully deserialized,
   3230   * otherwise return false.
   3231   */
   3232  static bool QueryTriggeringPrincipal(nsIContent* aLoadingNode,
   3233                                       nsIPrincipal* aDefaultPrincipal,
   3234                                       nsIPrincipal** aTriggeringPrincipal);
   3235 
   3236  static bool QueryTriggeringPrincipal(nsIContent* aLoadingNode,
   3237                                       nsIPrincipal** aTriggeringPrincipal) {
   3238    return QueryTriggeringPrincipal(aLoadingNode, nullptr,
   3239                                    aTriggeringPrincipal);
   3240  }
   3241 
   3242  // Returns whether the image for the given URI and triggering principal is
   3243  // already available. Ideally this should exactly match the "list of available
   3244  // images" in the HTML spec, but our implementation of that at best only
   3245  // resembles it.
   3246  static bool IsImageAvailable(nsIContent*, nsIURI*,
   3247                               nsIPrincipal* aDefaultTriggeringPrincipal,
   3248                               mozilla::CORSMode);
   3249  static bool IsImageAvailable(nsIURI*, nsIPrincipal* aTriggeringPrincipal,
   3250                               mozilla::CORSMode, Document*);
   3251 
   3252  /**
   3253   * Returns the content policy type that should be used for loading images
   3254   * for displaying in the UI.  The sources of such images can be <xul:image>,
   3255   * <xul:menuitem> on OSX where we load the image through nsMenuItemIconX, etc.
   3256   */
   3257  static void GetContentPolicyTypeForUIImageLoading(
   3258      nsIContent* aLoadingNode, nsIPrincipal** aTriggeringPrincipal,
   3259      nsContentPolicyType& aContentPolicyType, uint64_t* aRequestContextID);
   3260 
   3261  static nsresult CreateJSValueFromSequenceOfObject(
   3262      JSContext* aCx, const mozilla::dom::Sequence<JSObject*>& aTransfer,
   3263      JS::MutableHandle<JS::Value> aValue);
   3264 
   3265  /**
   3266   * This implements the structured cloning algorithm as described by
   3267   * https://html.spec.whatwg.org/#structured-cloning.
   3268   */
   3269  static void StructuredClone(
   3270      JSContext* aCx, nsIGlobalObject* aGlobal, JS::Handle<JS::Value> aValue,
   3271      const mozilla::dom::StructuredSerializeOptions& aOptions,
   3272      JS::MutableHandle<JS::Value> aRetval, mozilla::ErrorResult& aError);
   3273 
   3274  /**
   3275   * Returns true if reserved key events should be prevented from being sent
   3276   * to their target. Instead, the key event should be handled by chrome only.
   3277   */
   3278  static bool ShouldBlockReservedKeys(mozilla::WidgetKeyboardEvent* aKeyEvent);
   3279 
   3280  /**
   3281   * Returns one of the nsIObjectLoadingContent::TYPE_ values describing the
   3282   * content type which will be used for the given MIME type when loaded within
   3283   * an nsObjectLoadingContent.
   3284   *
   3285   * NOTE: This method doesn't take capabilities into account. The caller must
   3286   * take that into account.
   3287   *
   3288   * @param aMIMEType  The MIME type of the document being loaded.
   3289   * @param aIsSandboxed  If the document is loaded in an iframe sandbox.
   3290   */
   3291  static uint32_t HtmlObjectContentTypeForMIMEType(const nsCString& aMIMEType,
   3292                                                   bool aIsSandboxed);
   3293 
   3294  /**
   3295   * Detect whether a string is a local-url.
   3296   * https://drafts.csswg.org/css-values/#local-urls
   3297   */
   3298  static bool IsLocalRefURL(const nsAString& aString);
   3299 
   3300  /**
   3301   * Compose a tab id with process id and a serial number.
   3302   */
   3303  static uint64_t GenerateTabId();
   3304 
   3305  /**
   3306   * Compose a browser id with process id and a serial number.
   3307   */
   3308  static uint64_t GenerateBrowserId();
   3309 
   3310  /**
   3311   * Generate an id for a BrowsingContext using a range of serial
   3312   * numbers reserved for the current process.
   3313   */
   3314  static uint64_t GenerateBrowsingContextId();
   3315 
   3316  /**
   3317   * Generate an id using a range of serial numbers reserved for the current
   3318   * process. aId should be a counter that's incremented every time
   3319   * GenerateProcessSpecificId is called.
   3320   */
   3321  static uint64_t GenerateProcessSpecificId(uint64_t aId);
   3322 
   3323  static std::tuple<uint64_t, uint64_t> SplitProcessSpecificId(uint64_t aId);
   3324 
   3325  /**
   3326   * Generate a window ID which is unique across processes and will never be
   3327   * recycled.
   3328   */
   3329  static uint64_t GenerateWindowId();
   3330 
   3331  /**
   3332   * Generate an ID for a load which is unique across processes and will never
   3333   * be recycled.
   3334   */
   3335  static uint64_t GenerateLoadIdentifier();
   3336 
   3337  /**
   3338   * Determine whether or not the user is currently interacting with the web
   3339   * browser. This method is safe to call from off of the main thread.
   3340   */
   3341  static bool GetUserIsInteracting();
   3342 
   3343  // Alternate data MIME type used by the ScriptLoader to register and read
   3344  // bytecode out of the nsCacheInfoChannel.
   3345  [[nodiscard]] static bool InitJSBytecodeMimeType();
   3346  static nsCString& JSScriptBytecodeMimeType() {
   3347    MOZ_ASSERT(sJSScriptBytecodeMimeType);
   3348    return *sJSScriptBytecodeMimeType;
   3349  }
   3350  static nsCString& JSModuleBytecodeMimeType() {
   3351    MOZ_ASSERT(sJSModuleBytecodeMimeType);
   3352    return *sJSModuleBytecodeMimeType;
   3353  }
   3354 
   3355  /**
   3356   * Checks if the passed-in name is one of the special names: "_blank", "_top",
   3357   * "_parent" or "_self".
   3358   */
   3359  static bool IsSpecialName(const nsAString& aName);
   3360 
   3361  /**
   3362   * Checks if the passed-in name should override an existing name on the
   3363   * window. Values which should not override include: "", "_blank", "_top",
   3364   * "_parent" and "_self".
   3365   */
   3366  static bool IsOverridingWindowName(const nsAString& aName);
   3367 
   3368  /**
   3369   * If there is a SourceMap (higher precedence) or X-SourceMap (lower
   3370   * precedence) response header in |aChannel|, set |aResult| to the
   3371   * header's value and return true.  Otherwise, return false.
   3372   *
   3373   * @param aChannel The HTTP channel
   3374   * @param aResult The string result.
   3375   */
   3376  static bool GetSourceMapURL(nsIHttpChannel* aChannel, nsACString& aResult);
   3377 
   3378  /**
   3379   * Returns true if the passed-in mesasge is a pending InputEvent.
   3380   *
   3381   * @param aMsg  The message to check
   3382   */
   3383  static bool IsMessageInputEvent(const IPC::Message& aMsg);
   3384 
   3385  /**
   3386   * Returns true if the passed-in message is a critical InputEvent.
   3387   *
   3388   * @param aMsg  The message to check
   3389   */
   3390  static bool IsMessageCriticalInputEvent(const IPC::Message& aMsg);
   3391 
   3392  static void AsyncPrecreateStringBundles();
   3393 
   3394  static bool ContentIsLink(nsIContent* aContent);
   3395 
   3396  static already_AddRefed<mozilla::dom::ContentFrameMessageManager>
   3397  TryGetBrowserChildGlobal(nsISupports* aFrom);
   3398 
   3399  // Get a serial number for a newly created inner or outer window.
   3400  static uint32_t InnerOrOuterWindowCreated();
   3401  // Record that an inner or outer window has been destroyed.
   3402  static void InnerOrOuterWindowDestroyed();
   3403  // Get the current number of inner or outer windows.
   3404  static int32_t GetCurrentInnerOrOuterWindowCount() {
   3405    return sInnerOrOuterWindowCount;
   3406  }
   3407 
   3408  // Return an anonymized URI so that it can be safely exposed publicly.
   3409  static nsresult AnonymizeURI(nsIURI* aURI, nsCString& aAnonymizedURI);
   3410 
   3411  /**
   3412   * Serializes a JSON-like JS::Value into a string.
   3413   * Cases where JSON.stringify would return undefined are handled according to
   3414   * the |aBehavior| argument:
   3415   *
   3416   * - If it is |UndefinedIsNullStringLiteral|, the string "null" is returned.
   3417   * - If it is |UndefinedIsVoidString|, the void string is returned.
   3418   *
   3419   * The |UndefinedIsNullStringLiteral| case is likely not desirable, but is
   3420   * retained for now for historical reasons.
   3421   * Usage:
   3422   *   nsAutoString serializedValue;
   3423   *   nsContentUtils::StringifyJSON(cx, value, serializedValue, behavior);
   3424   */
   3425  static bool StringifyJSON(JSContext* aCx, JS::Handle<JS::Value> aValue,
   3426                            nsAString& aOutStr, JSONBehavior aBehavior);
   3427 
   3428  /**
   3429   * Returns true if the top level ancestor content document of aDocument hasn't
   3430   * yet had the first contentful paint and there is a high priority event
   3431   * pending in the main thread.
   3432   */
   3433  static bool HighPriorityEventPendingForTopLevelDocumentBeforeContentfulPaint(
   3434      Document* aDocument);
   3435 
   3436  /**
   3437   * Get the inner window corresponding to the incumbent global, including
   3438   * mapping extension content script globals to the attached window.
   3439   *
   3440   * Returns null if the incumbent global doesn't correspond to an inner window.
   3441   */
   3442  static nsGlobalWindowInner* IncumbentInnerWindow();
   3443 
   3444  /**
   3445   * Get the inner window corresponding to the entry global, including mapping
   3446   * extension content script globals to the attached window.
   3447   *
   3448   * Returns null if the entry global doesn't correspond to an inner window.
   3449   */
   3450  static nsGlobalWindowInner* EntryInnerWindow();
   3451 
   3452  /*
   3453   * Return safe area insets of window that defines as
   3454   * https://drafts.csswg.org/css-env-1/#safe-area-insets.
   3455   */
   3456  static mozilla::LayoutDeviceIntMargin GetWindowSafeAreaInsets(
   3457      nsIScreen* aScreen, const mozilla::LayoutDeviceIntMargin& aSafeareaInsets,
   3458      const mozilla::LayoutDeviceIntRect& aWindowRect);
   3459 
   3460  struct SubresourceCacheValidationInfo {
   3461    // The expiration time, in seconds, if known.
   3462    mozilla::Maybe<CacheExpirationTime> mExpirationTime;
   3463    bool mMustRevalidate = false;
   3464  };
   3465 
   3466  /**
   3467   * Gets cache validation info for subresources such as images, CSS
   3468   * stylesheets, or JS.
   3469   */
   3470  static SubresourceCacheValidationInfo GetSubresourceCacheValidationInfo(
   3471      nsIRequest*, nsIURI*);
   3472 
   3473  /**
   3474   * Gets cache expiration time for subresources such as images, CSS
   3475   * stylesheets, or JS.
   3476   */
   3477  static CacheExpirationTime GetSubresourceCacheExpirationTime(nsIRequest*,
   3478                                                               nsIURI*);
   3479 
   3480  /**
   3481   * Returns true if the request associated with the document should bypass the
   3482   * shared sub resource cache.
   3483   */
   3484  static bool ShouldBypassSubResourceCache(Document* aDoc);
   3485 
   3486  static uint32_t SecondsFromPRTime(PRTime aTime) {
   3487    return uint32_t(int64_t(aTime) / int64_t(PR_USEC_PER_SEC));
   3488  }
   3489 
   3490  /**
   3491   * Converts the given URL to a string and truncates it to the given length.
   3492   *
   3493   * Returns an empty string if aURL is null.
   3494   */
   3495  static nsCString TruncatedURLForDisplay(nsIURI* aURL, size_t aMaxLen = 128);
   3496 
   3497  /**
   3498   * Anonymize the given id by hashing it with the provided origin. The
   3499   * resulting id will have the same length as the one that was passed in.
   3500   */
   3501  enum class OriginFormat {
   3502    Base64,
   3503    Plain,
   3504  };
   3505 
   3506  static nsresult AnonymizeId(nsAString& aId, const nsACString& aOriginKey,
   3507                              OriginFormat aFormat = OriginFormat::Base64);
   3508 
   3509  /**
   3510   * Create and load the string bundle for the 'aFile'.
   3511   * This API is used to preload the string bundle on the main thread so later
   3512   * other thread could access it.
   3513   */
   3514  static nsresult EnsureAndLoadStringBundle(PropertiesFile aFile);
   3515 
   3516  /**
   3517   * The method asks nsIAppShell to prioritize Gecko's internal tasks over
   3518   * the OS level tasks for a short period of time.
   3519   */
   3520  static void RequestGeckoTaskBurst();
   3521 
   3522  static void SetMayHaveFormCheckboxStateChangeListeners() {
   3523    sMayHaveFormCheckboxStateChangeListeners = true;
   3524  }
   3525 
   3526  static bool MayHaveFormCheckboxStateChangeListeners() {
   3527    return sMayHaveFormCheckboxStateChangeListeners;
   3528  }
   3529 
   3530  static void SetMayHaveFormRadioStateChangeListeners() {
   3531    sMayHaveFormRadioStateChangeListeners = true;
   3532  }
   3533 
   3534  static bool MayHaveFormRadioStateChangeListeners() {
   3535    return sMayHaveFormRadioStateChangeListeners;
   3536  }
   3537 
   3538  /**
   3539   * Returns the closest link element in the flat tree of aContent if there's
   3540   * one, otherwise returns nullptr.
   3541   */
   3542  static nsIContent* GetClosestLinkInFlatTree(nsIContent* aContent);
   3543 
   3544  static bool IsExternalProtocol(nsIURI* aURI);
   3545 
   3546  /**
   3547   * Compares the position of aNode1 and aNode2 in the document
   3548   * @param aNode1 First content to compare.
   3549   * @param aNode2 Second content to compare.
   3550   * @param aCommonAncestor Potential ancestor of the contents, if one exists.
   3551   *                        This is only a hint; if it's not an ancestor of
   3552   *                        aNode1 or aNode2, this function will still
   3553   *                        work, but it will be slower.
   3554   * @return < 0 if aNode1 is before aNode2,
   3555   *         > 0 if aNode1 is after aNode2,
   3556   *         0 otherwise
   3557   */
   3558  template <TreeKind aKind>
   3559  static int32_t CompareTreePosition(const nsINode* aNode1,
   3560                                     const nsINode* aNode2,
   3561                                     const nsINode* aCommonAncestor,
   3562                                     NodeIndexCache* = nullptr);
   3563 
   3564  // Get the index of a kid in its parent, including anonymous content, in
   3565  // either the flat tree or the dom tree.
   3566  //
   3567  // The order goes as follows:
   3568  //   ::marker (-3)
   3569  //   ::before (-2)
   3570  //   ShadowRoot (-1, only if TreeKind is not Flat)
   3571  //   non-anonymous kids (0..n)
   3572  //   anonymous content (n..m)
   3573  //   ::after (m + 1)
   3574  template <TreeKind>
   3575  static mozilla::Maybe<int32_t> GetIndexInParent(const nsINode* aParent,
   3576                                                  const nsINode* aNode);
   3577 
   3578  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   3579  static nsIContent* AttachDeclarativeShadowRoot(
   3580      nsIContent* aHost, mozilla::dom::ShadowRootMode aMode, bool aIsClonable,
   3581      bool aIsSerializable, bool aDelegatesFocus, const nsAString&);
   3582 
   3583  static bool NavigationMustBeAReplace(nsIURI& aURI, const Document& aDocument);
   3584 
   3585 private:
   3586  static bool InitializeEventTable();
   3587 
   3588  static nsresult EnsureStringBundle(PropertiesFile aFile);
   3589 
   3590  static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
   3591                              nsIPrincipal* aPrincipal);
   3592 
   3593  static nsresult WrapNative(JSContext* cx, nsISupports* native,
   3594                             nsWrapperCache* cache, const nsIID* aIID,
   3595                             JS::MutableHandle<JS::Value> vp,
   3596                             bool aAllowWrapping);
   3597 
   3598  // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
   3599  MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult DispatchEvent(
   3600      Document* aDoc, mozilla::dom::EventTarget* aTarget,
   3601      const nsAString& aEventName, CanBubble, Cancelable, Composed, Trusted,
   3602      bool* aDefaultAction = nullptr,
   3603      ChromeOnlyDispatch = ChromeOnlyDispatch::eNo,
   3604      SystemGroupOnly = SystemGroupOnly::eNo);
   3605 
   3606  // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
   3607  MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult DispatchEvent(
   3608      Document* aDoc, mozilla::dom::EventTarget* aTarget,
   3609      mozilla::WidgetEvent& aWidgetEvent, EventMessage aEventMessage, CanBubble,
   3610      Cancelable, Trusted, bool* aDefaultAction = nullptr,
   3611      ChromeOnlyDispatch = ChromeOnlyDispatch::eNo);
   3612 
   3613  static void InitializeModifierStrings();
   3614 
   3615  static void DropFragmentParsers();
   3616 
   3617  static bool MatchClassNames(mozilla::dom::Element* aElement,
   3618                              int32_t aNamespaceID, nsAtom* aAtom, void* aData);
   3619  static void DestroyClassNameArray(void* aData);
   3620  static void* AllocClassMatchingInfo(nsINode* aRootNode,
   3621                                      const nsString* aClasses);
   3622 
   3623  static mozilla::EventClassID GetEventClassIDFromMessage(
   3624      EventMessage aEventMessage);
   3625 
   3626  // Fills in aInfo with the tokens from the supplied autocomplete attribute.
   3627  static AutocompleteAttrState InternalSerializeAutocompleteAttribute(
   3628      const nsAttrValue* aAttrVal, mozilla::dom::AutocompleteInfo& aInfo,
   3629      bool aGrantAllValidValue = false);
   3630 
   3631  static mozilla::CallState CallOnAllRemoteChildren(
   3632      mozilla::dom::MessageBroadcaster* aManager,
   3633      const std::function<mozilla::CallState(mozilla::dom::BrowserParent*)>&
   3634          aCallback);
   3635 
   3636  static nsINode* GetCommonAncestorHelper(nsINode* aNode1, nsINode* aNode2);
   3637  static nsIContent* GetCommonFlattenedTreeAncestorHelper(
   3638      nsIContent* aContent1, nsIContent* aContent2);
   3639 
   3640  /**
   3641   * Return 0 if aChild1 is same as aChild2.
   3642   * Return -1 if aChild1 is a preceding sibling of aChild2.
   3643   * Return 1 if aChild1 is a following sibling of aChild2.
   3644   * If aChild1 and/or aChild2 is nullptr, it's treated as end of the parent
   3645   * node.
   3646   * Return Nothing if aChild1 is a root of the native anonymous subtree.
   3647   */
   3648  template <TreeKind aKind,
   3649            typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM ||
   3650                                        aKind == TreeKind::Flat>>
   3651  static mozilla::Maybe<int32_t> CompareChildNodes(
   3652      const nsINode* aChild1, const nsINode* aChild2,
   3653      NodeIndexCache* aIndexCache = nullptr);
   3654 
   3655  /**
   3656   * Return 0 if aChild2 is at aOffset1.
   3657   * Return -1 if aChild2 is a following sibling of a child at aOffset1
   3658   * Return 1 if aChild2 is a preceding sibling of a child at aOffset1.
   3659   * Return Nothing if aChild2 is a root of the native anonymous subtree.
   3660   */
   3661  template <TreeKind aKind,
   3662            typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM ||
   3663                                        aKind == TreeKind::Flat>>
   3664  static mozilla::Maybe<int32_t> CompareChildOffsetAndChildNode(
   3665      uint32_t aOffset1, const nsINode& aChild2,
   3666      NodeIndexCache* aIndexCache = nullptr);
   3667 
   3668  /**
   3669   * Return 0 if aChild1 is at aOffset2.
   3670   * Return -1 if aChild1 is a preceding sibling of a child at aOffset2.
   3671   * Return 1 if aChild1 is a following sibling of a child at aOffset2.
   3672   * Return Nothing if aChild1 is a root of the native anonymous subtree.
   3673   */
   3674  template <TreeKind aKind,
   3675            typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM ||
   3676                                        aKind == TreeKind::Flat>>
   3677  static mozilla::Maybe<int32_t> CompareChildNodeAndChildOffset(
   3678      const nsINode& aChild1, uint32_t aOffset2,
   3679      NodeIndexCache* aIndexCache = nullptr);
   3680 
   3681  /**
   3682   * Helper method for ComparePoints() and ComparePointsWithIndices(). This
   3683   * includes odd traditional behavior. Therefore, do not use this method as a
   3684   * utility method.
   3685   */
   3686  template <TreeKind aKind = TreeKind::ShadowIncludingDOM,
   3687            typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM ||
   3688                                        aKind == TreeKind::Flat>>
   3689  static mozilla::Maybe<int32_t> CompareClosestCommonAncestorChildren(
   3690      const nsINode&, const nsINode*, const nsINode*,
   3691      NodeIndexCache* = nullptr);
   3692 
   3693  static nsIXPConnect* sXPConnect;
   3694 
   3695  static nsIScriptSecurityManager* sSecurityManager;
   3696  static nsIPrincipal* sSystemPrincipal;
   3697  static nsIPrincipal* sNullSubjectPrincipal;
   3698  static nsIPrincipal* sFingerprintingProtectionPrincipal;
   3699 
   3700  static nsIConsoleService* sConsoleService;
   3701 
   3702  static nsIStringBundleService* sStringBundleService;
   3703  class nsContentUtilsReporter;
   3704 
   3705  static nsIContentPolicy* sContentPolicyService;
   3706  static bool sTriedToGetContentPolicy;
   3707 
   3708  static mozilla::StaticRefPtr<nsIBidiKeyboard> sBidiKeyboard;
   3709 
   3710  static bool sInitialized;
   3711  static uint32_t sScriptBlockerCount;
   3712  static uint32_t sDOMNodeRemovedSuppressCount;
   3713 
   3714  // Not an nsCOMArray because removing elements from those is slower
   3715  static AutoTArray<nsCOMPtr<nsIRunnable>, 8>* sBlockedScriptRunners;
   3716  static uint32_t sRunnersCountAtFirstBlocker;
   3717  static uint32_t sScriptBlockerCountWhereRunnersPrevented;
   3718 
   3719  static nsIInterfaceRequestor* sSameOriginChecker;
   3720 
   3721  static bool sIsHandlingKeyBoardEvent;
   3722 #ifndef RELEASE_OR_BETA
   3723  static bool sBypassCSSOMOriginCheck;
   3724 #endif
   3725 
   3726  class UserInteractionObserver;
   3727  static UserInteractionObserver* sUserInteractionObserver;
   3728 
   3729  static nsHtml5StringParser* sHTMLFragmentParser;
   3730  static nsParser* sXMLFragmentParser;
   3731  static nsIFragmentContentSink* sXMLFragmentSink;
   3732 
   3733  /**
   3734   * True if there's a fragment parser activation on the stack.
   3735   */
   3736  static bool sFragmentParsingActive;
   3737 
   3738  static nsString* sShiftText;
   3739  static nsString* sControlText;
   3740  static nsString* sCommandOrWinText;
   3741  static nsString* sAltText;
   3742  static nsString* sModifierSeparator;
   3743 
   3744  // Alternate data mime types, used by the ScriptLoader to register and read
   3745  // the bytecode out of the nsCacheInfoChannel.
   3746  static nsCString* sJSScriptBytecodeMimeType;
   3747  static nsCString* sJSModuleBytecodeMimeType;
   3748 
   3749  static mozilla::LazyLogModule gResistFingerprintingLog;
   3750  static mozilla::LazyLogModule sDOMDumpLog;
   3751 
   3752  static int32_t sInnerOrOuterWindowCount;
   3753  static uint32_t sInnerOrOuterWindowSerialCounter;
   3754 
   3755  static bool sMayHaveFormCheckboxStateChangeListeners;
   3756  static bool sMayHaveFormRadioStateChangeListeners;
   3757 };
   3758 
   3759 /* static */ inline ExtContentPolicyType
   3760 nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType) {
   3761  switch (aType) {
   3762    case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
   3763    case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
   3764    case nsIContentPolicy::TYPE_INTERNAL_MODULE:
   3765    case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
   3766    case nsIContentPolicy::TYPE_INTERNAL_WORKER:
   3767    case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
   3768    case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
   3769    case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
   3770    case nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE:
   3771    case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
   3772    case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
   3773    case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
   3774    case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
   3775      return ExtContentPolicy::TYPE_SCRIPT;
   3776 
   3777    case nsIContentPolicy::TYPE_INTERNAL_EMBED:
   3778    case nsIContentPolicy::TYPE_INTERNAL_OBJECT:
   3779      return ExtContentPolicy::TYPE_OBJECT;
   3780 
   3781    case nsIContentPolicy::TYPE_INTERNAL_FRAME:
   3782    case nsIContentPolicy::TYPE_INTERNAL_IFRAME:
   3783      return ExtContentPolicy::TYPE_SUBDOCUMENT;
   3784 
   3785    case nsIContentPolicy::TYPE_INTERNAL_AUDIO:
   3786    case nsIContentPolicy::TYPE_INTERNAL_VIDEO:
   3787    case nsIContentPolicy::TYPE_INTERNAL_TRACK:
   3788      return ExtContentPolicy::TYPE_MEDIA;
   3789 
   3790    case nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST_ASYNC:
   3791    case nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST_SYNC:
   3792    case nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE:
   3793      return ExtContentPolicy::TYPE_XMLHTTPREQUEST;
   3794 
   3795    case nsIContentPolicy::TYPE_INTERNAL_IMAGE:
   3796    case nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD:
   3797    case nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON:
   3798      return ExtContentPolicy::TYPE_IMAGE;
   3799 
   3800    case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET:
   3801    case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD:
   3802      return ExtContentPolicy::TYPE_STYLESHEET;
   3803 
   3804    case nsIContentPolicy::TYPE_INTERNAL_DTD:
   3805    case nsIContentPolicy::TYPE_INTERNAL_FORCE_ALLOWED_DTD:
   3806      return ExtContentPolicy::TYPE_DTD;
   3807 
   3808    case nsIContentPolicy::TYPE_INTERNAL_FONT_PRELOAD:
   3809      return ExtContentPolicy::TYPE_FONT;
   3810 
   3811    case nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD:
   3812      return ExtContentPolicy::TYPE_FETCH;
   3813 
   3814    case nsIContentPolicy::TYPE_INTERNAL_EXTERNAL_RESOURCE:
   3815      return ExtContentPolicy::TYPE_OTHER;
   3816 
   3817    case nsIContentPolicy::TYPE_INTERNAL_JSON_PRELOAD:
   3818      return ExtContentPolicy::TYPE_JSON;
   3819 
   3820    case nsIContentPolicy::TYPE_INVALID:
   3821    case nsIContentPolicy::TYPE_OTHER:
   3822    case nsIContentPolicy::TYPE_SCRIPT:
   3823    case nsIContentPolicy::TYPE_IMAGE:
   3824    case nsIContentPolicy::TYPE_STYLESHEET:
   3825    case nsIContentPolicy::TYPE_OBJECT:
   3826    case nsIContentPolicy::TYPE_DOCUMENT:
   3827    case nsIContentPolicy::TYPE_SUBDOCUMENT:
   3828    case nsIContentPolicy::TYPE_PING:
   3829    case nsIContentPolicy::TYPE_XMLHTTPREQUEST:
   3830    case nsIContentPolicy::TYPE_DTD:
   3831    case nsIContentPolicy::TYPE_FONT:
   3832    case nsIContentPolicy::TYPE_MEDIA:
   3833    case nsIContentPolicy::TYPE_WEBSOCKET:
   3834    case nsIContentPolicy::TYPE_CSP_REPORT:
   3835    case nsIContentPolicy::TYPE_XSLT:
   3836    case nsIContentPolicy::TYPE_BEACON:
   3837    case nsIContentPolicy::TYPE_FETCH:
   3838    case nsIContentPolicy::TYPE_IMAGESET:
   3839    case nsIContentPolicy::TYPE_WEB_MANIFEST:
   3840    case nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD:
   3841    case nsIContentPolicy::TYPE_SPECULATIVE:
   3842    case nsIContentPolicy::TYPE_UA_FONT:
   3843    case nsIContentPolicy::TYPE_PROXIED_WEBRTC_MEDIA:
   3844    case nsIContentPolicy::TYPE_WEB_IDENTITY:
   3845    case nsIContentPolicy::TYPE_WEB_TRANSPORT:
   3846    case nsIContentPolicy::TYPE_JSON:
   3847      // NOTE: When adding something here make sure the enumerator is defined!
   3848      return static_cast<ExtContentPolicyType>(aType);
   3849 
   3850    case nsIContentPolicy::TYPE_END:
   3851      break;
   3852      // Do not add default: so that compilers can catch the missing case.
   3853  }
   3854 
   3855  MOZ_ASSERT(false, "Unhandled nsContentPolicyType value");
   3856  return ExtContentPolicy::TYPE_INVALID;
   3857 }
   3858 
   3859 class MOZ_RAII nsAutoScriptBlocker {
   3860 public:
   3861  explicit nsAutoScriptBlocker() { nsContentUtils::AddScriptBlocker(); }
   3862  ~nsAutoScriptBlocker() { nsContentUtils::RemoveScriptBlocker(); }
   3863 
   3864 private:
   3865 };
   3866 
   3867 class MOZ_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved
   3868    : public nsAutoScriptBlocker {
   3869 public:
   3870  nsAutoScriptBlockerSuppressNodeRemoved() {
   3871    ++nsContentUtils::sDOMNodeRemovedSuppressCount;
   3872  }
   3873  ~nsAutoScriptBlockerSuppressNodeRemoved() {
   3874    --nsContentUtils::sDOMNodeRemovedSuppressCount;
   3875  }
   3876 };
   3877 
   3878 namespace mozilla::dom {
   3879 
   3880 class TreeOrderComparator {
   3881 public:
   3882  bool Equals(nsINode* aElem1, nsINode* aElem2) const {
   3883    return aElem1 == aElem2;
   3884  }
   3885  bool LessThan(nsINode* aElem1, nsINode* aElem2) const {
   3886    return nsContentUtils::PositionIsBefore(aElem1, aElem2);
   3887  }
   3888 };
   3889 
   3890 }  // namespace mozilla::dom
   3891 
   3892 #define NS_INTERFACE_MAP_ENTRY_TEAROFF(_interface, _allocator) \
   3893  NS_INTERFACE_MAP_ENTRY_TEAROFF_AMBIGUOUS(_interface, _interface, _allocator)
   3894 
   3895 #define NS_INTERFACE_MAP_ENTRY_TEAROFF_AMBIGUOUS(_interface, _implClass, \
   3896                                                 _allocator)             \
   3897  if (aIID.Equals(NS_GET_IID(_interface))) {                             \
   3898    foundInterface = static_cast<_implClass*>(_allocator);               \
   3899    if (!foundInterface) {                                               \
   3900      *aInstancePtr = nullptr;                                           \
   3901      return NS_ERROR_OUT_OF_MEMORY;                                     \
   3902    }                                                                    \
   3903  } else
   3904 
   3905 /*
   3906 * In the following helper macros we exploit the fact that the result of a
   3907 * series of additions will not be finite if any one of the operands in the
   3908 * series is not finite.
   3909 */
   3910 #define NS_ENSURE_FINITE(f, rv) \
   3911  if (!std::isfinite(f)) {      \
   3912    return (rv);                \
   3913  }
   3914 
   3915 #define NS_ENSURE_FINITE2(f1, f2, rv) \
   3916  if (!std::isfinite((f1) + (f2))) {  \
   3917    return (rv);                      \
   3918  }
   3919 
   3920 #define NS_ENSURE_FINITE4(f1, f2, f3, f4, rv)      \
   3921  if (!std::isfinite((f1) + (f2) + (f3) + (f4))) { \
   3922    return (rv);                                   \
   3923  }
   3924 
   3925 #define NS_ENSURE_FINITE5(f1, f2, f3, f4, f5, rv)         \
   3926  if (!std::isfinite((f1) + (f2) + (f3) + (f4) + (f5))) { \
   3927    return (rv);                                          \
   3928  }
   3929 
   3930 #define NS_ENSURE_FINITE6(f1, f2, f3, f4, f5, f6, rv)            \
   3931  if (!std::isfinite((f1) + (f2) + (f3) + (f4) + (f5) + (f6))) { \
   3932    return (rv);                                                 \
   3933  }
   3934 
   3935 // Deletes a linked list iteratively to avoid blowing up the stack (bug 460444).
   3936 #define NS_CONTENT_DELETE_LIST_MEMBER(type_, ptr_, member_) \
   3937  {                                                         \
   3938    type_* cur = (ptr_)->member_;                           \
   3939    (ptr_)->member_ = nullptr;                              \
   3940    while (cur) {                                           \
   3941      type_* next = cur->member_;                           \
   3942      cur->member_ = nullptr;                               \
   3943      delete cur;                                           \
   3944      cur = next;                                           \
   3945    }                                                       \
   3946  }
   3947 
   3948 #endif /* nsContentUtils_h___ */