Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/dom/base/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 147 kB image not shown  

Quelle  nsContentUtils.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


/* A namespace class for static content utilities. */

#ifndef nsContentUtils_h___
#define nsContentUtils_h___

#if defined(XP_WIN)
#  include <float.h>
#endif

#if defined(SOLARIS)
#  include <ieeefp.h>
#endif

#include <cstddef>
#include <cstdint>
#include <functional>
#include <tuple>
#include <utility>
#include "ErrorList.h"
#include "Units.h"
#include "js/Id.h"
#include "js/RegExpFlags.h"
#include "js/RootingAPI.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/SourceLocation.h"
#include "mozilla/CORSMode.h"
#include "mozilla/CallState.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/CacheExpirationTime.h"
#include "mozilla/dom/FromParser.h"
#include "mozilla/dom/FetchPriority.h"
#include "mozilla/fallible.h"
#include "mozilla/gfx/Point.h"
#include "nsCOMPtr.h"
#include "nsIContentPolicy.h"
#include "nsINode.h"
#include "nsIScriptError.h"
#include "nsIThread.h"
#include "nsLiteralString.h"
#include "nsMargin.h"
#include "nsPIDOMWindow.h"
#include "nsRFPService.h"
#include "nsStringFwd.h"
#include "nsTArray.h"
#include "nsTLiteralString.h"
#include "prtime.h"

#if defined(XP_WIN)
// Undefine LoadImage to prevent naming conflict with Windows.
#  undef LoadImage
#endif

class JSObject;
class imgICache;
class imgIContainer;
class imgINotificationObserver;
class imgIRequest;
class imgLoader;
class imgRequestProxy;
class nsAtom;
class nsAttrValue;
class nsAutoScriptBlockerSuppressNodeRemoved;
class nsContentList;
class nsCycleCollectionTraversalCallback;
class nsDocShell;
class nsGlobalWindowInner;
class nsHtml5StringParser;
class nsIArray;
class nsIBidiKeyboard;
class nsIChannel;
class nsIConsoleService;
class nsIContent;
class nsIDocShell;
class nsIDocShellTreeItem;
class nsIDocumentLoaderFactory;
class nsIDragSession;
class nsIFile;
class nsIFragmentContentSink;
class nsIFrame;
class nsIHttpChannel;
class nsIIOService;
class nsIImageLoadingContent;
class nsIInterfaceRequestor;
class nsILoadGroup;
class nsILoadInfo;
class nsIObserver;
class nsIPrincipal;
class nsIReferrerInfo;
class nsIRequest;
class nsIRunnable;
class nsIScreen;
class nsIScriptContext;
class nsIScriptSecurityManager;
class nsISerialEventTarget;
class nsIStringBundle;
class nsIStringBundleService;
class nsISupports;
class nsITransferable;
class nsIURI;
class nsIWidget;
class nsIWritableVariant;
class nsIXPConnect;
class nsNodeInfoManager;
class nsParser;
class nsPIWindowRoot;
class nsPresContext;
class nsTextFragment;
class nsView;
class nsWrapperCache;

struct JSContext;
struct nsPoint;

namespace IPC {
class Message;
class MessageReader;
class MessageWriter;
}  // namespace IPC

namespace JS {
class Value;
class PropertyDescriptor;
}  // namespace JS

namespace mozilla {
class Dispatcher;
class EditorBase;
class ErrorResult;
class EventListenerManager;
class HTMLEditor;
class LazyLogModule;
class LogModule;
class PresShell;
class StringBuffer;
class TextEditor;
class WidgetDragEvent;
class WidgetKeyboardEvent;

struct InputEventOptions;

template <typename ParentType, typename RefType>
class RangeBoundaryBase;

template <typename T>
class NotNull;
template <class T>
class StaticRefPtr;

namespace dom {
class IPCImage;
struct AutocompleteInfo;
class BrowserChild;
class BrowserParent;
class BrowsingContext;
class BrowsingContextGroup;
class ContentChild;
class ContentFrameMessageManager;
class ContentParent;
struct CustomElementDefinition;
class CustomElementFormValue;
class CustomElementRegistry;
class DataTransfer;
class Document;
class DocumentFragment;
class DOMArena;
class Element;
class Event;
class EventTarget;
class FragmentOrElement;
class HTMLElement;
class HTMLInputElement;
class IPCTransferable;
class IPCTransferableData;
class IPCTransferableDataImageContainer;
class IPCTransferableDataItem;
struct LifecycleCallbackArgs;
class MessageBroadcaster;
class NodeInfo;
class OwningFileOrUSVStringOrFormData;
class Selection;
enum class ShadowRootMode : uint8_t;
class ShadowRoot;
struct StructuredSerializeOptions;
class TrustedHTMLOrString;
class WorkerPrivate;
enum class ElementCallbackType;
enum class ReferrerPolicy : uint8_t;
}  // namespace dom

namespace ipc {
class BigBuffer;
class IProtocol;
}  // namespace ipc

namespace gfx {
class DataSourceSurface;
enum class SurfaceFormat : int8_t;
}  // namespace gfx

class WindowRenderer;

}  // namespace mozilla

extern const char kLoadAsData[];

// Stolen from nsReadableUtils, but that's OK, since we can declare the same
// name multiple times.
const nsString& EmptyString();
const nsCString& EmptyCString();

enum EventNameType {
  EventNameType_None = 0x0000,
  EventNameType_HTML = 0x0001,
  EventNameType_XUL = 0x0002,
  EventNameType_SVGGraphic = 0x0004,  // svg graphic elements
  EventNameType_SVGSVG = 0x0008,      // the svg element
  EventNameType_SMIL = 0x0010,        // smil elements
  EventNameType_HTMLBodyOrFramesetOnly = 0x0020,
  EventNameType_HTMLMedia = 0x0040,

  EventNameType_HTMLXUL = 0x0003,
  EventNameType_All = 0xFFFF
};

enum class TreeKind : uint8_t { DOM, Flat };

enum class SerializeShadowRoots : uint8_t { Yes, No };

struct EventNameMapping {
  // This holds pointers to nsGkAtoms members, and is therefore safe as a
  // non-owning reference.
  nsAtom* MOZ_NON_OWNING_REF mAtom;
  int32_t mType;
  mozilla::EventMessage mMessage;
  mozilla::EventClassID mEventClassID;
};

namespace mozilla::dom {
enum JSONBehavior { UndefinedIsNullStringLiteral, UndefinedIsVoidString };
}  // namespace mozilla::dom

class nsContentUtils {
  friend class nsAutoScriptBlockerSuppressNodeRemoved;
  using Element = mozilla::dom::Element;
  using Document = mozilla::dom::Document;
  using Cancelable = mozilla::Cancelable;
  using CanBubble = mozilla::CanBubble;
  using Composed = mozilla::Composed;
  using ChromeOnlyDispatch = mozilla::ChromeOnlyDispatch;
  using EventMessage = mozilla::EventMessage;
  using TimeDuration = mozilla::TimeDuration;
  using Trusted = mozilla::Trusted;
  using JSONBehavior = mozilla::dom::JSONBehavior;
  using RFPTarget = mozilla::RFPTarget;

 public:
  static nsresult Init();

  static bool IsCallerChrome();
  static bool ThreadsafeIsCallerChrome();
  static bool IsCallerUAWidget();
  static bool IsFuzzingEnabled()
#ifndef FUZZING
  {
    return false;
  }
#else
      ;
#endif
  static bool IsErrorPage(nsIURI* aURI);

  static bool IsCallerChromeOrFuzzingEnabled(JSContext* aCx, JSObject*) {
    return ThreadsafeIsSystemCaller(aCx) || IsFuzzingEnabled();
  }

  static bool IsCallerChromeOrElementTransformGettersEnabled(JSContext* aCx,
                                                             JSObject*);

  // The APIs for checking whether the caller is system (in the sense of system
  // principal) should only be used when the JSContext is known to accurately
  // represent the caller.  In practice, that means you should only use them in
  // two situations at the moment:
  //
  // 1) Functions used in WebIDL Func annotations.
  // 2) Bindings code or other code called directly from the JS engine.
  //
  // Use pretty much anywhere else is almost certainly wrong and should be
  // replaced with [NeedsCallerType] annotations in bindings.

  // Check whether the caller is system if you know you're on the main thread.
  static bool IsSystemCaller(JSContext* aCx);

  // Check whether the caller is system if you might be on a worker or worklet
  // thread.
  static bool ThreadsafeIsSystemCaller(JSContext* aCx);

  // In the traditional Gecko architecture, both C++ code and untrusted JS code
  // needed to rely on the same XPCOM method/getter/setter to get work done.
  // This required lots of security checks in the various exposed methods, which
  // in turn created difficulty in determining whether the caller was script
  // (whose access needed to be checked) and internal C++ platform code (whose
  // access did not need to be checked). To address this problem, Gecko had a
  // convention whereby the absence of script on the stack was interpretted as
  // "System Caller" and always granted unfettered access.
  //
  // Unfortunately, this created a bunch of footguns. For example, when the
  // implementation of a DOM method wanted to perform a privileged
  // sub-operation, it needed to "hide" the presence of script on the stack in
  // order for that sub-operation to be allowed. Additionally, if script could
  // trigger an API entry point to be invoked in some asynchronous way without
  // script on the stack, it could potentially perform privilege escalation.
  //
  // In the modern world, untrusted script should interact with the platform
  // exclusively over WebIDL APIs, and platform code has a lot more flexibility
  // in deciding whether or not to use XPCOM. This gives us the flexibility to
  // do something better.
  //
  // Going forward, APIs should be designed such that any security checks that
  // ask the question "is my caller allowed to do this?" should live in WebIDL
  // API entry points, with a separate method provided for internal callers
  // that just want to get the job done.
  //
  // To enforce this and catch bugs, nsContentUtils::SubjectPrincipal will crash
  // if it is invoked without script on the stack. To land that transition, it
  // was necessary to go through and whitelist a bunch of callers that were
  // depending on the old behavior. Those callers should be fixed up, and these
  // methods should not be used by new code without review from bholley or bz.
  static bool LegacyIsCallerNativeCode() { return !GetCurrentJSContext(); }
  static bool LegacyIsCallerChromeOrNativeCode() {
    return LegacyIsCallerNativeCode() || IsCallerChrome();
  }
  static nsIPrincipal* SubjectPrincipalOrSystemIfNativeCaller() {
    if (!GetCurrentJSContext()) {
      return GetSystemPrincipal();
    }
    return SubjectPrincipal();
  }

  static bool LookupBindingMember(
      JSContext* aCx, nsIContent* aContent, JS::Handle<jsid> aId,
      JS::MutableHandle<JS::PropertyDescriptor> aDesc);

  // Check whether we should avoid leaking distinguishing information to JS/CSS.
  // This function can be called both in the main thread and worker threads.
  static bool ShouldResistFingerprinting(bool aIsPrivateMode,
                                         RFPTarget aTarget);
  static bool ShouldResistFingerprinting(nsIGlobalObject* aGlobalObject,
                                         RFPTarget aTarget);
  // Similar to the function above, but always allows CallerType::System
  // callers.
  static bool ShouldResistFingerprinting(mozilla::dom::CallerType aCallerType,
                                         nsIGlobalObject* aGlobalObject,
                                         RFPTarget aTarget);
  static bool ShouldResistFingerprinting(nsIDocShell* aDocShell,
                                         RFPTarget aTarget);
  // These functions are the new, nuanced functions
  static bool ShouldResistFingerprinting(nsIChannel* aChannel,
                                         RFPTarget aTarget);
  // These functions are labeled as dangerous because they will do the wrong
  // thing in _most_ cases. They should only be used if you don't have a fully
  // constructed LoadInfo or Document.
  // A constant string used as justification is required when calling them,
  // it should explain why a Document, Channel, LoadInfo, or CookieJarSettings
  // does not exist in this context.
  // (see below for more on justification strings.)
  static bool ShouldResistFingerprinting_dangerous(
      nsIURI* aURI, const mozilla::OriginAttributes& aOriginAttributes,
      const char* aJustification, RFPTarget aTarget);
  static bool ShouldResistFingerprinting_dangerous(nsIPrincipal* aPrincipal,
                                                   const char* aJustification,
                                                   RFPTarget aTarget);

  /**
   * Implement a RFP function that only checks the pref, and does not take
   * into account any additional context such as PBM mode or Web Extensions.
   *
   * It requires an explanation for why the coarse check is being used instead
   * of the nuanced check. While there is a gradual cut over of
   * ShouldResistFingerprinting calls to a nuanced API, some features still
   * require a legacy function. (Additionally, we sometimes use the coarse
   * check first, to avoid running additional code to support a nuanced check.)
   */

  static bool ShouldResistFingerprinting(const char* aJustification,
                                         RFPTarget aTarget);

  static bool ETPSaysShouldNotResistFingerprinting(
      nsICookieJarSettings* aCookieJarSettings, bool aIsPBM);

  static bool ETPSaysShouldNotResistFingerprinting(nsIChannel* aChannel,
                                                   nsILoadInfo* aLoadInfo);

  // A helper function to calculate the rounded window size for fingerprinting
  // resistance. The rounded size is based on the chrome UI size and available
  // screen size. If the inputWidth/Height is greater than the available content
  // size, this will report the available content size. Otherwise, it will
  // round the size to the nearest upper 200x100.
  static void CalcRoundedWindowSizeForResistingFingerprinting(
      int32_t aChromeWidth, int32_t aChromeHeight, int32_t aScreenWidth,
      int32_t aScreenHeight, int32_t aInputWidth, int32_t aInputHeight,
      bool aSetOuterWidth, bool aSetOuterHeight, int32_t* aOutputWidth,
      int32_t* aOutputHeight);

  /**
   * Returns the parent node of aChild crossing document boundaries, but skips
   * any cross-process parent frames and continues with the nearest in-process
   * frame in the hierarchy.
   *
   * Uses the parent node in the composed document.
   */

  static nsINode* GetNearestInProcessCrossDocParentNode(nsINode* aChild);

  /**
   * Similar to nsINode::IsInclusiveDescendantOf, except will treat an
   * HTMLTemplateElement or ShadowRoot as an ancestor of things in the
   * corresponding DocumentFragment. See the concept of "host-including
   * inclusive ancestor" in the DOM specification.
   */

  static bool ContentIsHostIncludingDescendantOf(
      const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);

  /**
   * Similar to nsINode::IsInclusiveDescendantOf except it crosses document
   * boundaries, this function uses ancestor/descendant relations in the
   * composed document (see shadow DOM spec).
   */

  static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
                                            nsINode* aPossibleAncestor);

  /**
   * As with ContentIsCrossDocDescendantOf but crosses shadow boundaries but not
   * cross document boundaries.
   *
   * @see nsINode::GetFlattenedTreeParentNode()
   */

  static bool ContentIsFlattenedTreeDescendantOf(
      const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);

  /**
   * Same as `ContentIsFlattenedTreeDescendantOf`, but from the flattened tree
   * point of view of the style system
   *
   * @see nsINode::GetFlattenedTreeParentNodeForStyle()
   */

  static bool ContentIsFlattenedTreeDescendantOfForStyle(
      const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);

  /**
   * Retarget an object A against an object B
   * @see https://dom.spec.whatwg.org/#retarget
   */

  static nsINode* Retarget(nsINode* aTargetA, nsINode* aTargetB);

  /**
   * @see https://wicg.github.io/element-timing/#get-an-element
   */

  static Element* GetAnElementForTiming(Element* aTarget,
                                        const Document* aDocument,
                                        nsIGlobalObject* aGlobal);

  /*
   * https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor.
   *
   * This method fills the |aArray| with all ancestor nodes of |aNode|
   * including |aNode| at the zero index.
   *
   */

  static nsresult GetInclusiveAncestors(nsINode* aNode,
                                        nsTArray<nsINode*>& aArray);

  /*
   * https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor.
   *
   * This method fills |aAncestorNodes| with all ancestor nodes of |aNode|
   * including |aNode| (QI'd to nsIContent) at the zero index.
   * For each ancestor, there is a corresponding element in |aAncestorOffsets|
   * which is the ComputeIndexOf the child in relation to its parent.
   *
   * This method just sucks.
   */

  static nsresult GetInclusiveAncestorsAndOffsets(
      nsINode* aNode, uint32_t aOffset, nsTArray<nsIContent*>& aAncestorNodes,
      nsTArray<mozilla::Maybe<uint32_t>>& aAncestorOffsets);

  /*
   * https://dom.spec.whatwg.org/#concept-shadow-including-ancestor.
   *
   * Similar as the GetInclusiveAncestorsAndOffsets method, except this
   * will use host elements as the parent for shadow roots.
   *
   * When the current content is a ShadowRoot, the offset of it from
   * its ancestor (the host element) will be Nothing().
   */

  static nsresult GetShadowIncludingAncestorsAndOffsets(
      nsINode* aNode, uint32_t aOffset, nsTArray<nsIContent*>& aAncestorNodes,
      nsTArray<mozilla::Maybe<uint32_t>>& aAncestorOffsets);

  /**
   * Returns the closest common inclusive ancestor
   * (https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor) , if any,
   * for two nodes.
   *
   * Returns null if the nodes are disconnected.
   */

  static nsINode* GetClosestCommonInclusiveAncestor(nsINode* aNode1,
                                                    nsINode* aNode2) {
    if (aNode1 == aNode2) {
      return aNode1;
    }

    return GetCommonAncestorHelper(aNode1, aNode2);
  }

  static nsINode* GetClosestCommonShadowIncludingInclusiveAncestor(
      nsINode* aNode1, nsINode* aNode2);

  /**
   * Returns the common flattened tree ancestor, if any, for two given content
   * nodes.
   */

  static nsIContent* GetCommonFlattenedTreeAncestor(nsIContent* aContent1,
                                                    nsIContent* aContent2) {
    if (aContent1 == aContent2) {
      return aContent1;
    }

    return GetCommonFlattenedTreeAncestorHelper(aContent1, aContent2);
  }

  /**
   * Returns the common flattened tree ancestor from the point of view of
   * the selection system, if any, for two given content nodes.
   */

  static nsIContent* GetCommonFlattenedTreeAncestorForSelection(
      nsIContent* aContent1, nsIContent* aContent2);

  /**
   * Returns the common flattened tree ancestor from the point of view of the
   * style system, if any, for two given content nodes.
   */

  static Element* GetCommonFlattenedTreeAncestorForStyle(Element* aElement1,
                                                         Element* aElement2);

  /**
   * Returns the common BrowserParent ancestor, if any, for two given
   * BrowserParent.
   */

  static mozilla::dom::BrowserParent* GetCommonBrowserParentAncestor(
      mozilla::dom::BrowserParent* aBrowserParent1,
      mozilla::dom::BrowserParent* aBrowserParent2);

  // https://html.spec.whatwg.org/#target-element
  // https://html.spec.whatwg.org/#find-a-potential-indicated-element
  static Element* GetTargetElement(Document* aDocument,
                                   const nsAString& aAnchorName);
  /**
   * Returns true if aNode1 is before aNode2 in the same connected
   * tree.
   * aNode1Index and aNode2Index are in/out arguments. If non-null, and value is
   * Some, that value is used instead of calling slow ComputeIndexOf on the
   * parent node. If value is Nothing, the value will be set to the return value
   * of ComputeIndexOf.
   */

  static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2,
                               mozilla::Maybe<uint32_t>* aNode1Index = nullptr,
                               mozilla::Maybe<uint32_t>* aNode2Index = nullptr);

  /**
   * Cache implementation for ComparePoints().
   *
   * This cache keeps the last cache_size child/index combinations
   * in a stack-allocated array for fast lookup.
   * If the cache is full, the entries are overridden,
   * starting from the oldest entry.
   *
   * Note: This cache does not observe invalidation. As soon as script has
   * run, this cache must not be used anymore.
   * Also, this cache uses raw pointers. Beware!
   */

  template <size_t cache_size>
  struct ResizableNodeIndexCache {
    /**
     * Looks up or computes two indices in one loop.
     */

    void ComputeIndicesOf(const nsINode* aParent, const nsINode* aChild1,
                          const nsINode* aChild2,
                          mozilla::Maybe<uint32_t>& aChild1Index,
                          mozilla::Maybe<uint32_t>& aChild2Index) {
      bool foundChild1 = false;
      bool foundChild2 = false;
      for (size_t cacheIndex = 0; cacheIndex < cache_size; ++cacheIndex) {
        if (foundChild1 && foundChild2) {
          return;
        }
        const nsINode* node = mNodes[cacheIndex];
        if (!node) {
          // reached the end of not-fully-populated cache.
          break;
        }
        if (!foundChild1 && node == aChild1) {
          aChild1Index = mIndices[cacheIndex];
          foundChild1 = true;
          continue;
        }
        if (!foundChild2 && node == aChild2) {
          aChild2Index = mIndices[cacheIndex];
          foundChild2 = true;
          continue;
        }
      }
      if (!foundChild1) {
        aChild1Index = ComputeAndInsertIndexIntoCache(aParent, aChild1);
      }
      if (!foundChild2) {
        aChild2Index = ComputeAndInsertIndexIntoCache(aParent, aChild2);
      }
    }
    /**
     * Looks up or computes child index.
     */

    mozilla::Maybe<uint32_t> ComputeIndexOf(const nsINode* aParent,
                                            const nsINode* aChild) {
      for (size_t cacheIndex = 0; cacheIndex < cache_size; ++cacheIndex) {
        const nsINode* node = mNodes[cacheIndex];
        if (!node) {
          break;
        }
        if (node == aChild) {
          return mIndices[cacheIndex];
        }
      }
      return ComputeAndInsertIndexIntoCache(aParent, aChild);
    }

   private:
    /**
     * Computes the index of aChild in aParent, inserts the index into the
     * cache, and returns the index.
     */

    mozilla::Maybe<uint32_t> ComputeAndInsertIndexIntoCache(
        const nsINode* aParent, const nsINode* aChild) {
      mozilla::Maybe<uint32_t> childIndex = aParent->ComputeIndexOf(aChild);

      mNodes[mNext] = aChild;
      mIndices[mNext] = childIndex;

      ++mNext;
      if (mNext == cache_size) {
        // the last element of the cache has been reached.
        // set mNext to 0 to start overriding the oldest cache entries.
        mNext = 0;
      }
      return childIndex;
    }

    /// Node storage. The array is initialized to null
    /// by the empty initializer list.
    const nsINode* mNodes[cache_size]{};

    mozilla::Maybe<uint32_t> mIndices[cache_size];

    /// The next element in the cache that will be written to.
    /// If the cache is full (mNext == cache_size),
    /// the oldest entries in the cache will be overridden,
    /// ie. mNext will be set to 0.
    size_t mNext{0};
  };

  /**
   * Typedef with a reasonable default cache size.
   * If Caches of different sizes are needed,
   * ComparePoints would need to become templated.
   */

  using NodeIndexCache = ResizableNodeIndexCache<100>;

  /**
   *  Utility routine to compare two "points", where a point is a node/offset
   *  pair.
   *  Pass a cache object as aParent1Cache if you expect to repeatedly
   *  call this function with the same value as aParent1.
   *
   *  @return -1 if point1 < point2,
   *          1 if point1 > point2,
   *          0 if point1 == point2.
   *          `Nothing` if the two nodes aren't in the same connected subtree.
   */

  static mozilla::Maybe<int32_t> ComparePoints(
      const nsINode* aParent1, uint32_t aOffset1, const nsINode* aParent2,
      uint32_t aOffset2, NodeIndexCache* aIndexCache = nullptr);
  template <typename FPT, typename FRT, typename SPT, typename SRT>
  static mozilla::Maybe<int32_t> ComparePoints(
      const mozilla::RangeBoundaryBase<FPT, FRT>& aFirstBoundary,
      const mozilla::RangeBoundaryBase<SPT, SRT>& aSecondBoundary);

  /**
   *  Utility routine to compare two "points", where a point is a
   *  node/offset pair
   *  Returns -1 if point1 < point2, 1, if point1 > point2,
   *  0 if error or if point1 == point2.
   *  NOTE! If the two nodes aren't in the same connected subtree,
   *  the result is 1, and the optional aDisconnected parameter
   *  is set to true.
   *
   *  Pass a cache object as aIndexCache if you expect to repeatedly
   *  call this function.
   * ComparePointsCache will store the last X (currently 100) node/index
   * combinations in a stack-allocated array and does a lookup there
   * before going into the expensive ComputeIndexOf() method.
   */

  static int32_t ComparePoints_Deprecated(
      const nsINode* aParent1, uint32_t aOffset1, const nsINode* aParent2,
      uint32_t aOffset2, bool* aDisconnected = nullptr,
      NodeIndexCache* aIndexCache = nullptr);
  template <typename FPT, typename FRT, typename SPT, typename SRT>
  static int32_t ComparePoints_Deprecated(
      const mozilla::RangeBoundaryBase<FPT, FRT>& aFirstBoundary,
      const mozilla::RangeBoundaryBase<SPT, SRT>& aSecondBoundary,
      bool* aDisconnected = nullptr);

  /**
   * DO NOT USE this method for comparing the points in new code.  this method
   * emulates same result as `ComparePoints` before bug 1741148.
   * When the old `ComparePoints` was called with offset value over `INT32_MAX`
   * or `-1` which is used as "not found" by some API, they were treated as-is
   * without checking whether the negative value or valid value.  Thus, this
   * handles the negative offset cases in the special paths to keep the
   * traditional behavior. If you want to use this in new code, it means that
   * you **should** check the offset values and call `ComparePoints` instead.
   */

  static mozilla::Maybe<int32_t> ComparePoints_AllowNegativeOffsets(
      const nsINode* aParent1, int64_t aOffset1, const nsINode* aParent2,
      int64_t aOffset2) {
    if (MOZ_UNLIKELY(aOffset1 < 0 || aOffset2 < 0)) {
      // If in same container, just the offset is compared.
      if (aParent1 == aParent2) {
        const int32_t compOffsets =
            aOffset1 == aOffset2 ? 0 : (aOffset1 < aOffset2 ? -1 : 1);
        return mozilla::Some(compOffsets);
      }
      // Otherwise, aOffset1 is referred only when aParent2 is a descendant of
      // aParent1.
      if (aOffset1 < 0 && aParent2->IsInclusiveDescendantOf(aParent1)) {
        return mozilla::Some(-1);
      }
      // And also aOffset2 is referred only when aParent1 is a descendant of
      // aParent2.
      if (aOffset2 < 0 && aParent1->IsInclusiveDescendantOf(aParent2)) {
        return mozilla::Some(1);
      }
      // Otherwise, aOffset1 nor aOffset2 is referred so that any value is fine
      // if negative.
      return ComparePoints(
          aParent1, aOffset1 < 0 ? UINT32_MAX : static_cast<uint32_t>(aOffset1),
          aParent2,
          aOffset2 < 0 ? UINT32_MAX : static_cast<uint32_t>(aOffset2));
    }
    return ComparePoints(aParent1, aOffset1, aParent2, aOffset2);
  }

  /**
   * Brute-force search of the element subtree rooted at aContent for
   * an element with the given id.  aId must be nonempty, otherwise
   * this method may return nodes even if they have no id!
   */

  static Element* MatchElementId(nsIContent* aContent, const nsAString& aId);

  /**
   * Similar to above, but to be used if one already has an atom for the ID
   */

  static Element* MatchElementId(nsIContent* aContent, const nsAtom* aId);

  /**
   * Reverses the document position flags passed in.
   *
   * @param   aDocumentPosition   The document position flags to be reversed.
   *
   * @return  The reversed document position flags.
   *
   * @see Node
   */

  static uint16_t ReverseDocumentPosition(uint16_t aDocumentPosition);

  static const nsDependentSubstring TrimCharsInSet(const char* aSet,
                                                   const nsAString& aValue);

  template <bool IsWhitespace(char16_t)>
  static const nsDependentSubstring TrimWhitespace(const nsAString& aStr,
                                                   bool aTrimTrailing = true);

  /**
   * Returns true if aChar is of class Ps, Pi, Po, Pf, or Pe.
   */

  static bool IsFirstLetterPunctuation(uint32_t aChar);

  /**
   * Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No
   */

  static bool IsAlphanumeric(uint32_t aChar);
  /**
   * Returns true if aChar is of class L*, N* or S* (for first-letter).
   */

  static bool IsAlphanumericOrSymbol(uint32_t aChar);
  /**
   * Returns true if aChar is a kind of hyphen.
   */

  static bool IsHyphen(uint32_t aChar);

  /*
   * Is the character an HTML whitespace character?
   *
   * We define whitespace using the list in HTML5 and css3-selectors:
   * U+0009, U+000A, U+000C, U+000D, U+0020
   *
   * HTML 4.01 also lists U+200B (zero-width space).
   */

  static bool IsHTMLWhitespace(char16_t aChar);

  /*
   * Returns whether the character is an HTML whitespace (see IsHTMLWhitespace)
   * or a nbsp character (U+00A0).
   */

  static bool IsHTMLWhitespaceOrNBSP(char16_t aChar);

  /**
   * https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
   */

  static bool IsHTMLBlockLevelElement(nsIContent* aContent);

  enum ParseHTMLIntegerResultFlags {
    eParseHTMLInteger_NoFlags = 0,
    // eParseHTMLInteger_NonStandard is set if the string representation of the
    // integer was not the canonical one, but matches at least one of the
    // following:
    //   * had leading whitespaces
    //   * had '+' sign
    //   * had leading '0'
    //   * was '-0'
    eParseHTMLInteger_NonStandard = 1 << 0,
    eParseHTMLInteger_DidNotConsumeAllInput = 1 << 1,
    // Set if one or more error flags were set.
    eParseHTMLInteger_Error = 1 << 2,
    eParseHTMLInteger_ErrorNoValue = 1 << 3,
    eParseHTMLInteger_ErrorOverflow = 1 << 4,
    // Use this flag to detect the difference between overflow and underflow
    eParseHTMLInteger_Negative = 1 << 5,
  };
  static int32_t ParseHTMLInteger(const nsAString& aValue,
                                  ParseHTMLIntegerResultFlags* aResult) {
    return ParseHTMLInteger(aValue.BeginReading(), aValue.EndReading(),
                            aResult);
  }
  static int32_t ParseHTMLInteger(const char16_t* aStart, const char16_t* aEnd,
                                  ParseHTMLIntegerResultFlags* aResult);
  static int32_t ParseHTMLInteger(const nsACString& aValue,
                                  ParseHTMLIntegerResultFlags* aResult) {
    return ParseHTMLInteger(aValue.BeginReading(), aValue.EndReading(),
                            aResult);
  }
  static int32_t ParseHTMLInteger(const char* aStart, const char* aEnd,
                                  ParseHTMLIntegerResultFlags* aResult);

 private:
  template <class CharT>
  static int32_t ParseHTMLIntegerImpl(const CharT* aStart, const CharT* aEnd,
                                      ParseHTMLIntegerResultFlags* aResult);

 public:
  /**
   * Parse the value of the <font size=""> attribute according to the HTML5
   * spec as of April 16, 2012.
   *
   * @param aValue the value to parse
   * @return 1 to 7, or 0 if the value couldn't be parsed
   */

  static int32_t ParseLegacyFontSize(const nsAString& aValue);

  static void Shutdown();

  /**
   * Checks whether two nodes come from the same origin.
   */

  static nsresult CheckSameOrigin(const nsINode* aTrustedNode,
                                  const nsINode* unTrustedNode);

  // Check if the (JS) caller can access aNode.
  static bool CanCallerAccess(const nsINode* aNode);

  // Check if the (JS) caller can access aWindow.
  // aWindow can be either outer or inner window.
  static bool CanCallerAccess(nsPIDOMWindowInner* aWindow);

  // Check if the principal is chrome or an addon with the permission.
  static bool PrincipalHasPermission(nsIPrincipal& aPrincipal,
                                     const nsAtom* aPerm);

  // Check if the JS caller is chrome or an addon with the permission.
  static bool CallerHasPermission(JSContext* aCx, const nsAtom* aPerm);

  /**
   * Returns the triggering principal which should be used for the given URL
   * attribute value with the given subject principal.
   *
   * If the attribute value is not an absolute URL, the subject principal will
   * be ignored, and the node principal of aContent will be used instead.
   * If aContent is non-null, this function will always return a principal.
   * Otherewise, it may return null if aSubjectPrincipal is null or is rejected
   * based on the attribute value.
   *
   * @param aContent The content on which the attribute is being set.
   * @param aAttrValue The URL value of the attribute. For parsed attribute
   *        values, such as `srcset`, this function should be called separately
   *        for each URL value it contains.
   * @param aSubjectPrincipal The subject principal of the scripted caller
   *        responsible for setting the attribute, or null if no scripted caller
   *        can be determined.
   */

  static nsIPrincipal* GetAttrTriggeringPrincipal(
      nsIContent* aContent, const nsAString& aAttrValue,
      nsIPrincipal* aSubjectPrincipal);

  /**
   * Returns true if the given string is guaranteed to be treated as an absolute
   * URL, rather than a relative URL. In practice, this means any complete URL
   * as supported by nsStandardURL, or any string beginning with a valid scheme
   * which is known to the IO service, and has the URI_NORELATIVE flag.
   *
   * If the URL may be treated as absolute in some cases, but relative in others
   * (for instance, "http:foo", which can be either an absolute or relative URL,
   * depending on the context), this function returns false.
   */

  static bool IsAbsoluteURL(const nsACString& aURL);

  // Check if a node is in the document prolog, i.e. before the document
  // element.
  static bool InProlog(nsINode* aNode);

  static nsIBidiKeyboard* GetBidiKeyboard();

  /**
   * Get the cache security manager service. Can return null if the layout
   * module has been shut down.
   */

  static nsIScriptSecurityManager* GetSecurityManager() {
    return sSecurityManager;
  }

  // Returns the subject principal from the JSContext. May only be called
  // from the main thread and assumes an existing compartment.
  static nsIPrincipal* SubjectPrincipal(JSContext* aCx);

  // Returns the subject principal. Guaranteed to return non-null. May only
  // be called when nsContentUtils is initialized.
  static nsIPrincipal* SubjectPrincipal();

  // Returns the prinipal of the given JS object. This may only be called on
  // the main thread for objects from the main thread's JSRuntime. The object
  // must not be a cross-compartment wrapper, because CCWs are not associated
  // with a single realm.
  static nsIPrincipal* ObjectPrincipal(JSObject* aObj);

  static void GenerateStateKey(nsIContent* aContent, Document* aDocument,
                               nsACString& aKey);

  /**
   * Create a new nsIURI from aSpec, using aBaseURI as the base.  The
   * origin charset of the new nsIURI will be the document charset of
   * aDocument.
   */

  static nsresult NewURIWithDocumentCharset(nsIURI** aResult,
                                            const nsAString& aSpec,
                                            Document* aDocument,
                                            nsIURI* aBaseURI);

  /**
   * Returns true if |aAtom| contains at least one |aChar|.
   */

  static bool ContainsChar(nsAtom* aAtom, char aChar);

  /**
   * Returns true if |aName| is a name with dashes.
   */

  static bool IsNameWithDash(nsAtom* aName);

  /**
   * Returns true if |aName| is a valid name to be registered via
   * customElements.define.
   */

  static bool IsCustomElementName(nsAtom* aName, uint32_t aNameSpaceID);

  static nsresult CheckQName(const nsAString& aQualifiedName,
                             bool aNamespaceAware = true,
                             const char16_t** aColon = nullptr);

  static nsresult SplitQName(const nsIContent* aNamespaceResolver,
                             const nsString& aQName, int32_t* aNamespace,
                             nsAtom** aLocalName);

  static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                       const nsAString& aQualifiedName,
                                       nsNodeInfoManager* aNodeInfoManager,
                                       uint16_t aNodeType,
                                       mozilla::dom::NodeInfo** aNodeInfo);

  static void SplitExpatName(const char16_t* aExpatName, nsAtom** aPrefix,
                             nsAtom** aTagName, int32_t* aNameSpaceID);

  // Get a permission-manager setting for the given principal and type.
  // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
  // returned, otherwise true is returned. Always returns true for the
  // system principal, and false for a null principal.
  static bool IsSitePermAllow(nsIPrincipal* aPrincipal,
                              const nsACString& aType);

  // Get a permission-manager setting for the given principal and type.
  // If the pref doesn't exist or if it isn't DENY_ACTION, false is
  // returned, otherwise true is returned. Always returns false for the
  // system principal, and true for a null principal.
  static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const nsACString& aType);

  // Get a permission-manager setting for the given principal and type.
  // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
  // returned, otherwise true is returned. Always returns true for the
  // system principal, and false for a null principal.
  // This version checks the permission for an exact host match on
  // the principal
  static bool IsExactSitePermAllow(nsIPrincipal* aPrincipal,
                                   const nsACString& aType);

  // Get a permission-manager setting for the given principal and type.
  // If the pref doesn't exist or if it isn't DENY_ACTION, false is
  // returned, otherwise true is returned. Always returns false for the
  // system principal, and true for a null principal.
  // This version checks the permission for an exact host match on
  // the principal
  static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal,
                                  const nsACString& aType);

  // Returns true if the pref exists and is not UNKNOWN_ACTION.
  static bool HasSitePerm(nsIPrincipal* aPrincipal, const nsACString& aType);

  // Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s.
  static bool HaveEqualPrincipals(Document* aDoc1, Document* aDoc2);

  /**
   * Regster aObserver as a shutdown observer. A strong reference is held
   * to aObserver until UnregisterShutdownObserver is called.
   */

  static void RegisterShutdownObserver(nsIObserver* aObserver);
  static void UnregisterShutdownObserver(nsIObserver* aObserver);

  /**
   * @return true if aContent has an attribute aName in namespace aNameSpaceID,
   * and the attribute value is non-empty.
   */

  static bool HasNonEmptyAttr(const nsIContent* aContent, int32_t aNameSpaceID,
                              nsAtom* aName);

  /**
   * Method that gets the primary presContext for the node.
   *
   * @param aContent The content node.
   * @return the presContext, or nullptr if the content is not in a document
   *         (if GetComposedDoc returns nullptr)
   */

  static nsPresContext* GetContextForContent(const nsIContent* aContent);

  /**
   * Method that gets the pres shell for the node.
   *
   * @param aContent The content node.
   * @return the pres shell, or nullptr if the content is not in a document
   *         (if GetComposedDoc returns nullptr)
   */

  static mozilla::PresShell* GetPresShellForContent(const nsIContent* aContent);

  /**
   * Returns true if objects in aDocument shouldn't initiate image loads.
   */

  static bool DocumentInactiveForImageLoads(Document* aDocument);

  /**
   * Convert a CORSMode into the corresponding imgILoader flags for
   * passing to LoadImage.
   * @param aMode CORS mode to convert
   * @return a bitfield suitable to bitwise OR with other nsIRequest flags
   */

  static int32_t CORSModeToLoadImageFlags(mozilla::CORSMode aMode);

  /**
   * Method to start an image load.  This does not do any security checks.
   * This method will attempt to make aURI immutable; a caller that wants to
   * keep a mutable version around should pass in a clone.
   *
   * @param aURI uri of the image to be loaded
   * @param aContext element of document where the result of this request
   *                 will be used.
   * @param aLoadingDocument the document we belong to
   * @param aLoadingPrincipal the principal doing the load
   * @param aReferrerInfo the referrerInfo use on channel creation
   * @param aObserver the observer for the image load
   * @param aLoadFlags the load flags to use.  See nsIRequest
   * @param [aContentPolicyType=nsIContentPolicy::TYPE_INTERNAL_IMAGE]
   * (Optional) The CP content type to use
   * @param aUseUrgentStartForChannel,(Optional) a flag to mark on channel if it
   *        is triggered by user input events.
   * @return the imgIRequest for the image load
   */

  static nsresult LoadImage(
      nsIURI* aURI, nsINode* aContext, Document* aLoadingDocument,
      nsIPrincipal* aLoadingPrincipal, uint64_t aRequestContextID,
      nsIReferrerInfo* aReferrerInfo, imgINotificationObserver* aObserver,
      int32_t aLoadFlags, const nsAString& initiatorType,
      imgRequestProxy** aRequest,
      nsContentPolicyType aContentPolicyType =
          nsIContentPolicy::TYPE_INTERNAL_IMAGE,
      bool aUseUrgentStartForChannel = falsebool aLinkPreload = false,
      uint64_t aEarlyHintPreloaderId = 0,
      mozilla::dom::FetchPriority aFetchPriority =
          mozilla::dom::FetchPriority::Auto);

  /**
   * Obtain an image loader that respects the given document/channel's privacy
   * status. Null document/channel arguments return the public image loader.
   */

  static imgLoader* GetImgLoaderForDocument(Document* aDoc);
  static imgLoader* GetImgLoaderForChannel(nsIChannel* aChannel,
                                           Document* aContext);

  /**
   * Method to get an imgIContainer from an image loading content
   *
   * @param aContent The image loading content.  Must not be null.
   * @param aRequest The image request [out]
   * @return the imgIContainer corresponding to the first frame of the image
   */

  static already_AddRefed<imgIContainer> GetImageFromContent(
      nsIImageLoadingContent* aContent, imgIRequest** aRequest = nullptr);

  /**
   * Method that decides whether a content node is draggable
   *
   * @param aContent The content node to test.
   * @return whether it's draggable
   */

  static bool ContentIsDraggable(nsIContent* aContent);

  /**
   * Method that decides whether a content node is a draggable image
   *
   * @param aContent The content node to test.
   * @return whether it's a draggable image
   */

  static bool IsDraggableImage(nsIContent* aContent);

  /**
   * Method that decides whether a content node is a draggable link
   *
   * @param aContent The content node to test.
   * @return whether it's a draggable link
   */

  static bool IsDraggableLink(const nsIContent* aContent);

  /**
   * Convenience method to create a new nodeinfo that differs only by prefix and
   * name from aNodeInfo. The new nodeinfo's name is set to aName, and prefix is
   * set to null.
   */

  static nsresult QNameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsAtom* aName,
                               mozilla::dom::NodeInfo** aResult);

  /**
   * Returns the appropriate event argument names for the specified
   * namespace and event name.  Added because we need to switch between
   * SVG's "evt" and the rest of the world's "event", and because onerror
   * on window takes 5 args.
   */

  static void GetEventArgNames(int32_t aNameSpaceID, nsAtom* aEventName,
                               bool aIsForWindow, uint32_t* aArgCount,
                               const char*** aArgNames);

  /**
   * Returns true if this loadGroup uses Private Browsing.
   */

  static bool IsInPrivateBrowsing(nsILoadGroup* aLoadGroup);

  /**
   * Returns whether a node is in the same tree as another one, accounting for
   * anonymous roots.
   *
   * This method is particularly useful for callers who are trying to ensure
   * that they are working with a non-anonymous descendant of a given node.  If
   * aContent is a descendant of aNode, a return value of false from this
   * method means that it's an anonymous descendant from aNode's point of view.
   *
   * Both arguments to this method must be non-null.
   */

  static bool IsInSameAnonymousTree(const nsINode* aNode,
                                    const nsINode* aOtherNode);

  /*
   * Traverse the parent chain from aElement up to aStop, and return true if
   * there's an interactive html content; false otherwise.
   *
   * Note: This crosses shadow boundaries but not document boundaries.
   */

  static bool IsInInteractiveHTMLContent(const Element* aElement,
                                         const Element* aStop);

  /**
   * Return the nsIXPConnect service.
   */

  static nsIXPConnect* XPConnect() { return sXPConnect; }

  /**
   * Report simple error message to the browser console
   *   @param aErrorText the error message
   *   @param aCategory Name of the module reporting error
   *   @param aFromPrivateWindow Whether from private window or not
   *   @param aFromChromeContext Whether from chrome context or not
   *   @param [aErrorFlags] See nsIScriptError.
   */

  static void LogSimpleConsoleError(
      const nsAString& aErrorText, const nsACString& aCategory,
      bool aFromPrivateWindow, bool aFromChromeContext,
      uint32_t aErrorFlags = nsIScriptError::errorFlag);

  /**
   * Report a non-localized error message to the error console.
   *   @param aErrorText the error message
   *   @param aErrorFlags See nsIScriptError.
   *   @param aCategory Name of module reporting error.
   *   @param aDocument Reference to the document which triggered the message.
   *   @param aLocation message location. Pass the empty location to omit it.
   */

  static nsresult ReportToConsoleNonLocalized(
      const nsAString& aErrorText, uint32_t aErrorFlags,
      const nsACString& aCategory, const Document* aDocument,
      const mozilla::SourceLocation& aLocation =
          mozilla::JSCallingLocation::Get());

  /**
   * Report a non-localized error message to the error console base on the
   * innerWindowID.
   *   @param aErrorText the error message
   *   @param aErrorFlags See nsIScriptError.
   *   @param aCategory Name of module reporting error.
   *   @param [aInnerWindowID] Inner window ID for document which triggered the
   *          message.
   *   @param aLocation message location. Pass the empty location to omit it.
   */

  static nsresult ReportToConsoleByWindowID(
      const nsAString& aErrorText, uint32_t aErrorFlags,
      const nsACString& aCategory, uint64_t aInnerWindowID,
      const mozilla::SourceLocation& aLocation =
          mozilla::JSCallingLocation::Get());

  /**
   * Report a localized error message to the error console.
   *   @param aErrorFlags See nsIScriptError.
   *   @param aCategory Name of module reporting error.
   *   @param aDocument Reference to the document which triggered the message.
   *   @param aFile Properties file containing localized message.
   *   @param aMessageName Name of localized message.
   *   @param [aParams=empty-array] (Optional) Parameters to be substituted into
              localized message.
   *   @param aLocation message location. Pass the empty location to omit it.
   */

  enum PropertiesFile {
    eCSS_PROPERTIES,
    eXUL_PROPERTIES,
    eLAYOUT_PROPERTIES,
    eFORMS_PROPERTIES,
    ePRINTING_PROPERTIES,
    eDOM_PROPERTIES,
    eHTMLPARSER_PROPERTIES,
    eSVG_PROPERTIES,
    eBRAND_PROPERTIES,
    eCOMMON_DIALOG_PROPERTIES,
    eMATHML_PROPERTIES,
    eSECURITY_PROPERTIES,
    eNECKO_PROPERTIES,
    eFORMS_PROPERTIES_en_US,
    eDOM_PROPERTIES_en_US,
    PropertiesFile_COUNT
  };
  static nsresult ReportToConsole(
      uint32_t aErrorFlags, const nsACString& aCategory,
      const Document* aDocument, PropertiesFile aFile, const char* aMessageName,
      const nsTArray<nsString>& aParams = nsTArray<nsString>(),
      const mozilla::SourceLocation& aLocation =
          mozilla::JSCallingLocation::Get());

  static void ReportEmptyGetElementByIdArg(const Document* aDoc);

  static void LogMessageToConsole(const char* aMsg);

  static bool SpoofLocaleEnglish();
  static bool SpoofLocaleEnglish(const Document* aDocument);

  /**
   * Get the localized string named |aKey| in properties file |aFile|.
   */

  static nsresult GetLocalizedString(PropertiesFile aFile, const char* aKey,
                                     nsAString& aResult);

  /**
   * Same as GetLocalizedString, except that it might use en-US locale depending
   * on SpoofLocaleEnglish() and whether the document is a built-in browser
   * page.
   */

  static nsresult GetMaybeLocalizedString(PropertiesFile aFile,
                                          const char* aKey, Document* aDocument,
                                          nsAString& aResult);

  /**
   * A helper function that parses a sandbox attribute (of an <iframe> or a CSP
   * directive) and converts it to the set of flags used internally.
   *
   * @param aSandboxAttr  the sandbox attribute
   * @return              the set of flags (SANDBOXED_NONE if aSandboxAttr is
   *                      null)
   */

  static uint32_t ParseSandboxAttributeToFlags(const nsAttrValue* aSandboxAttr);

  /**
   * A helper function that checks if a string matches a valid sandbox flag.
   *
   * @param aFlag   the potential sandbox flag.
   * @return        true if the flag is a sandbox flag.
   */

  static bool IsValidSandboxFlag(const nsAString& aFlag);

  /**
   * A helper function that returns a string attribute corresponding to the
   * sandbox flags.
   *
   * @param aFlags    the sandbox flags
   * @param aString   the attribute corresponding to the flags (null if aFlags
   *                  is zero)
   */

  static void SandboxFlagsToString(uint32_t aFlags, nsAString& aString);

  static bool PrefetchPreloadEnabled(nsIDocShell* aDocShell);

  static void ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,
                                 nsACString& aSourceSpecOut, uint32_t* aLineOut,
                                 uint32_t* aColumnOut, nsString& aMessageOut);

  static nsresult CalculateBufferSizeForImage(
      const uint32_t& aStride, const mozilla::gfx::IntSize& aImageSize,
      const mozilla::gfx::SurfaceFormat& aFormat, size_t* aMaxBufferSize,
      size_t* aUsedBufferSize);

  // Returns true if the URI's host is contained in a list which is a comma
  // separated domain list.  Each item may start with "*.".  If starts with
  // "*.", it matches any sub-domains.
  // The aList argument must be a lower-case string.
  static bool IsURIInList(nsIURI* aURI, const nsCString& aList);

  // Returns true if the URI's host is contained in a pref list which is a comma
  // separated domain list.  Each item may start with "*.".  If starts with
  // "*.", it matches any sub-domains.
  static bool IsURIInPrefList(nsIURI* aURI, const char* aPrefName);

  /*&
   * A convenience version of FormatLocalizedString that can be used if all the
   * params are in same-typed strings.  The variadic template args need to come
   * at the end, so we put aResult at the beginning to make sure it's clear
   * which is the output and which are the inputs.
   */

  template <typename... T>
  static nsresult FormatLocalizedString(nsAString& aResult,
                                        PropertiesFile aFile, const char* aKey,
                                        const T&... aParams) {
    static_assert(sizeof...(aParams) != 0, "Use GetLocalizedString()");
    AutoTArray<nsString, sizeof...(aParams)> params = {
        aParams...,
    };
    return FormatLocalizedString(aFile, aKey, params, aResult);
  }

  /**
   * Same as FormatLocalizedString template version, except that it might use
   * en-US locale depending on SpoofLocaleEnglish() and whether the document is
   * a built-in browser page.
   */

  template <typename... T>
  static nsresult FormatMaybeLocalizedString(nsAString& aResult,
                                             PropertiesFile aFile,
                                             const char* aKey,
                                             Document* aDocument,
                                             const T&... aParams) {
    static_assert(sizeof...(aParams) != 0, "Use GetMaybeLocalizedString()");
    AutoTArray<nsString, sizeof...(aParams)> params = {
        aParams...,
    };
    return FormatMaybeLocalizedString(aFile, aKey, aDocument, params, aResult);
  }

  /**
   * Fill (with the parameters given) the localized string named |aKey| in
   * properties file |aFile| consuming an nsTArray of nsString parameters rather
   * than a char16_t** for the sake of avoiding use-after-free errors involving
   * temporaries.
   */

  static nsresult FormatLocalizedString(PropertiesFile aFile, const char* aKey,
                                        const nsTArray<nsString>& aParamArray,
                                        nsAString& aResult);

  /**
   * Same as FormatLocalizedString, except that it might use en-US locale
   * depending on SpoofLocaleEnglish() and whether the document is a built-in
   * browser page.
   */

  static nsresult FormatMaybeLocalizedString(
      PropertiesFile aFile, const char* aKey, Document* aDocument,
      const nsTArray<nsString>& aParamArray, nsAString& aResult);

  /**
   * Returns true if aDocument is a chrome document
   */

  static bool IsChromeDoc(const Document* aDocument);

  /**
   * Returns true if aDocument is an addon document
   */

  static bool IsAddonDoc(const Document* aDocument);

  /**
   * Returns true if aDocument is in a docshell whose parent is the same type
   */

  static bool IsChildOfSameType(Document* aDoc);

  /**
   * Returns true if the content-type will be rendered as plain-text.
   */

  static bool IsPlainTextType(const nsACString& aContentType);

  /**
   * Returns true iff the type is rendered as plain text and doesn't support
   * non-UTF-8 encodings.
   */

  static bool IsUtf8OnlyPlainTextType(const nsACString& aContentType);

  /**
   * Returns true if aDocument belongs to a chrome docshell for
   * display purposes.  Returns false for null documents or documents
   * which do not belong to a docshell.
   */

  static bool IsInChromeDocshell(const Document* aDocument);

  /**
   * Return the content policy service
   */

  static nsIContentPolicy* GetContentPolicy();

  /**
   * Map internal content policy types to external ones.
   */

  static inline ExtContentPolicyType InternalContentPolicyTypeToExternal(
      nsContentPolicyType aType);

  /**
   * check whether the Link header field applies to the context resource
   * see <http://tools.ietf.org/html/rfc5988#section-5.2>
   */

  static bool LinkContextIsURI(const nsAString& aAnchor, nsIURI* aDocURI);

  /**
   * Returns true if the content policy type is any of:
   *   * TYPE_INTERNAL_SCRIPT_PRELOAD
   *   * TYPE_INTERNAL_IMAGE_PRELOAD
   *   * TYPE_INTERNAL_STYLESHEET_PRELOAD
   */

  static bool IsPreloadType(nsContentPolicyType aType);

  /**
   * Quick helper to determine whether mutation events are enabled and there are
   * any mutation listeners of a given type that apply to this content or any of
   * its ancestors.
   * The method has the side effect to call document's MayDispatchMutationEvent
   * using aTargetForSubtreeModified as the parameter.
   *
   * @param aNode  The node to search for listeners
   * @param aType  The type of listener (NS_EVENT_BITS_MUTATION_*)
   * @param aTargetForSubtreeModified The node which is the target of the
   *                                  possible DOMSubtreeModified event.
   *
   * @return true if there are mutation listeners of the specified type
   */

  static bool WantMutationEvents(nsINode* aNode, uint32_t aType,
                                 nsINode* aTargetForSubtreeModified);

  /**
   * Quick helper to determine whether there are any mutation listeners
   * of a given type that apply to any content in this document. It is valid
   * to pass null for aDocument here, in which case this function always
   * returns true.
   *
   * @param aDocument The document to search for listeners
   * @param aType     The type of listener (NS_EVENT_BITS_MUTATION_*)
   *
   * @return true if there are mutation listeners of the specified type
   */

  static bool HasMutationListeners(Document* aDocument, uint32_t aType);
  /**
   * Synchronously fire DOMNodeRemoved on aChild. Only fires the event if
   * there really are listeners by checking using the HasMutationListeners
   * function above. The function makes sure to hold the relevant objects alive
   * for the duration of the event firing. However there are no guarantees
   * that any of the objects are alive by the time the function returns.
   * If you depend on that you need to hold references yourself.
   *
   * @param aChild    The node to fire DOMNodeRemoved at.
   * @param aParent   The parent of aChild.
   */

  MOZ_CAN_RUN_SCRIPT static void MaybeFireNodeRemoved(nsINode* aChild,
                                                      nsINode* aParent);

  /**
   * These methods create and dispatch a trusted event.
   * Works only with events which can be created by calling
   * Document::CreateEvent() with parameter "Events".
   * Note that don't use these methods for "input" event.  Use
   * DispatchInputEvent() instead.
   *
   * @param aDoc           The document which will be used to create the event.
   * @param aTarget        The target of the event.
   * @param aEventName     The name of the event.
   * @param aCanBubble     Whether the event can bubble.
   * @param aCancelable    Is the event cancelable.
   * @param aCopmosed      Is the event composed.
   * @param aDefaultAction Set to true if default action should be taken,
   *                       see EventTarget::DispatchEvent.
   */

  // TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
  // (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
  static nsresult DispatchTrustedEvent(Document* aDoc,
                                       mozilla::dom::EventTarget* aTarget,
                                       const nsAString& aEventName, CanBubble,
                                       Cancelable,
                                       Composed aComposed = Composed::eDefault,
                                       bool* aDefaultAction = nullptr);

  // TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
  // (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
  static nsresult DispatchTrustedEvent(Document* aDoc,
                                       mozilla::dom::EventTarget* aTarget,
                                       const nsAString& aEventName,
                                       CanBubble aCanBubble,
                                       Cancelable aCancelable,
                                       bool* aDefaultAction) {
    return DispatchTrustedEvent(aDoc, aTarget, aEventName, aCanBubble,
                                aCancelable, Composed::eDefault,
                                aDefaultAction);
  }

  /**
   * This method creates and dispatches a trusted event using an event message.
   * @param aDoc           The document which will be used to create the event.
   * @param aTarget        The target of the event.
   * @param aEventMessage  The event message.
   * @param aCanBubble     Whether the event can bubble.
   * @param aCancelable    Is the event cancelable.
   * @param aDefaultAction Set to true if default action should be taken,
   *                       see EventTarget::DispatchEvent.
   */

  template <class WidgetEventType>
  static nsresult DispatchTrustedEvent(
      Document* aDoc, mozilla::dom::EventTarget* aTarget,
      EventMessage aEventMessage, CanBubble aCanBubble, Cancelable aCancelable,
      bool* aDefaultAction = nullptr,
      ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo) {
    WidgetEventType event(true, aEventMessage);
    MOZ_ASSERT(GetEventClassIDFromMessage(aEventMessage) == event.mClass);
    return DispatchEvent(aDoc, aTarget, event, aEventMessage, aCanBubble,
                         aCancelable, Trusted::eYes, aDefaultAction,
                         aOnlyChromeDispatch);
  }

  /**
   * This method dispatches "beforeinput" event with EditorInputEvent or
   * "input" event with proper event class.  If it's unsafe to dispatch,
   * this put the event into the script runner queue.  In such case, the
   * event becomes not cancelable even if it's defined as cancelable by
   * the spec.
   * Input Events spec defines as:
   *   Input events are dispatched on elements that act as editing hosts,
   *   including elements with the contenteditable attribute set, textarea
   *   elements, and input elements that permit text input.
   *
   * @param aEventTarget        The event target element of the "beforeinput"
   *                            or "input" event.  Must not be nullptr.
   * @param aEventMessage       Muse be eEditorBeforeInput or eEditorInput.
   * @param aEditorInputType    The inputType value of InputEvent.
   *                            If aEventTarget won't dispatch "input" event
   *                            with InputEvent, set EditorInputType::eUnknown.
   * @param aEditorBase         Optional.  If this is called by editor,
   *                            editor should set this.  Otherwise, leave
   *                            nullptr.
   * @param aOptions            Optional.  If aEditorInputType value requires
   *                            some additional data, they should be properly
   *                            set with this argument.
   * @param aEventStatus        Returns nsEventStatus_eConsumeNoDefault if
   *                            the dispatching event is cancelable and the
   *                            event was canceled by script (including
   *                            chrome script).  Otherwise, returns given
   *                            value.  Note that this can be nullptr only
   *                            when the dispatching event is not cancelable.
   */

  MOZ_CAN_RUN_SCRIPT static nsresult DispatchInputEvent(Element* aEventTarget);
  MOZ_CAN_RUN_SCRIPT static nsresult DispatchInputEvent(
      Element* aEventTarget, mozilla::EventMessage aEventMessage,
      mozilla::EditorInputType aEditorInputType,
      mozilla::EditorBase* aEditorBase, mozilla::InputEventOptions&& aOptions,
      nsEventStatus* aEventStatus = nullptr);

  /**
   * This method creates and dispatches a untrusted event.
   * Works only with events which can be created by calling
   * Document::CreateEvent() with parameter "Events".
   * @param aDoc           The document which will be used to create the event.
   * @param aTarget        The target of the event.
   * @param aEventName     The name of the event.
   * @param aCanBubble     Whether the event can bubble.
   * @param aCancelable    Is the event cancelable.
   * @param aDefaultAction Set to true if default action should be taken,
   *                       see EventTarget::DispatchEvent.
   */

  static nsresult DispatchUntrustedEvent(Document* aDoc,
                                         mozilla::dom::EventTarget* aTarget,
                                         const nsAString& aEventName, CanBubble,
                                         Cancelable,
                                         bool* aDefaultAction = nullptr);

  /**
   * This method creates and dispatches a untrusted event using an event
   * message.
   * @param aDoc           The document which will be used to create the event.
   * @param aTarget        The target of the event.
   * @param aEventMessage  The event message.
   * @param aCanBubble     Whether the event can bubble.
   * @param aCancelable    Is the event cancelable.
   * @param aDefaultAction Set to true if default action should be taken,
   *                       see EventTarget::DispatchEvent.
   */

  template <class WidgetEventType>
  static nsresult DispatchUntrustedEvent(
      Document* aDoc, mozilla::dom::EventTarget* aTarget,
      EventMessage aEventMessage, CanBubble aCanBubble, Cancelable aCancelable,
      bool* aDefaultAction = nullptr,
      ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo) {
--> --------------------

--> maximum size reached

--> --------------------

100%


¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.