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