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