Thu, 15 Jan 2015 15:55:04 +0100
Back out 97036ab72558 which inappropriately compared turds to third parties.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
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/. */
7 /* A namespace class for static content utilities. */
9 #ifndef nsContentUtils_h___
10 #define nsContentUtils_h___
12 #if defined(XP_WIN)
13 #include <float.h>
14 #endif
16 #if defined(SOLARIS)
17 #include <ieeefp.h>
18 #endif
20 #include "js/TypeDecls.h"
21 #include "js/Value.h"
22 #include "js/RootingAPI.h"
23 #include "mozilla/EventForwards.h"
24 #include "mozilla/GuardObjects.h"
25 #include "mozilla/TimeStamp.h"
26 #include "nsContentListDeclarations.h"
27 #include "nsMathUtils.h"
28 #include "nsTArrayForwardDeclare.h"
29 #include "Units.h"
31 #if defined(XP_WIN)
32 // Undefine LoadImage to prevent naming conflict with Windows.
33 #undef LoadImage
34 #endif
36 class imgICache;
37 class imgIContainer;
38 class imgINotificationObserver;
39 class imgIRequest;
40 class imgLoader;
41 class imgRequestProxy;
42 class nsAutoScriptBlockerSuppressNodeRemoved;
43 class nsHtml5StringParser;
44 class nsIChannel;
45 class nsIConsoleService;
46 class nsIContent;
47 class nsIContentPolicy;
48 class nsIContentSecurityPolicy;
49 class nsIDocShell;
50 class nsIDocument;
51 class nsIDocumentLoaderFactory;
52 class nsIDocumentObserver;
53 class nsIDOMDocument;
54 class nsIDOMDocumentFragment;
55 class nsIDOMEvent;
56 class nsIDOMHTMLFormElement;
57 class nsIDOMHTMLInputElement;
58 class nsIDOMKeyEvent;
59 class nsIDOMNode;
60 class nsIDOMScriptObjectFactory;
61 class nsIDOMWindow;
62 class nsIDragSession;
63 class nsIEditor;
64 class nsIFragmentContentSink;
65 class nsIFrame;
66 class nsIImageLoadingContent;
67 class nsIInterfaceRequestor;
68 class nsIIOService;
69 class nsIJSRuntimeService;
70 class nsILineBreaker;
71 class nsNameSpaceManager;
72 class nsINodeInfo;
73 class nsIObserver;
74 class nsIParser;
75 class nsIParserService;
76 class nsIPresShell;
77 class nsIPrincipal;
78 class nsIRunnable;
79 class nsIScriptContext;
80 class nsIScriptGlobalObject;
81 class nsIScriptSecurityManager;
82 class nsIStringBundle;
83 class nsIStringBundleService;
84 class nsISupportsHashKey;
85 class nsIURI;
86 class nsIWidget;
87 class nsIWordBreaker;
88 class nsIXPConnect;
89 class nsNodeInfoManager;
90 class nsPIDOMWindow;
91 class nsPresContext;
92 class nsScriptObjectTracer;
93 class nsStringBuffer;
94 class nsStringHashKey;
95 class nsTextFragment;
96 class nsViewportInfo;
97 class nsWrapperCache;
98 class nsAttrValue;
100 struct JSPropertyDescriptor;
101 struct JSRuntime;
102 struct nsIntMargin;
104 template<class E> class nsCOMArray;
105 template<class K, class V> class nsDataHashtable;
106 template<class K, class V> class nsRefPtrHashtable;
107 template<class T> class nsReadingIterator;
109 namespace mozilla {
110 class ErrorResult;
111 class EventListenerManager;
113 namespace dom {
114 class DocumentFragment;
115 class Element;
116 class EventTarget;
117 class Selection;
118 } // namespace dom
120 namespace layers {
121 class LayerManager;
122 } // namespace layers
124 // Called back from DeferredFinalize. Should add 'thing' to the array of smart
125 // pointers in 'pointers', creating the array if 'pointers' is null, and return
126 // the array.
127 typedef void* (*DeferredFinalizeAppendFunction)(void* pointers, void* thing);
129 // Called to finalize a number of objects. Slice is the number of objects
130 // to finalize, or if it's UINT32_MAX, all objects should be finalized.
131 // Return value indicates whether it finalized all objects in the buffer.
132 typedef bool (*DeferredFinalizeFunction)(uint32_t slice, void* data);
134 } // namespace mozilla
136 class nsIBidiKeyboard;
138 extern const char kLoadAsData[];
140 // Stolen from nsReadableUtils, but that's OK, since we can declare the same
141 // name multiple times.
142 const nsAFlatString& EmptyString();
143 const nsAFlatCString& EmptyCString();
145 enum EventNameType {
146 EventNameType_None = 0x0000,
147 EventNameType_HTML = 0x0001,
148 EventNameType_XUL = 0x0002,
149 EventNameType_SVGGraphic = 0x0004, // svg graphic elements
150 EventNameType_SVGSVG = 0x0008, // the svg element
151 EventNameType_SMIL = 0x0010, // smil elements
152 EventNameType_HTMLBodyOrFramesetOnly = 0x0020,
154 EventNameType_HTMLXUL = 0x0003,
155 EventNameType_All = 0xFFFF
156 };
158 struct EventNameMapping
159 {
160 nsIAtom* mAtom;
161 uint32_t mId;
162 int32_t mType;
163 uint32_t mStructType;
164 };
166 struct nsShortcutCandidate {
167 nsShortcutCandidate(uint32_t aCharCode, bool aIgnoreShift) :
168 mCharCode(aCharCode), mIgnoreShift(aIgnoreShift)
169 {
170 }
171 uint32_t mCharCode;
172 bool mIgnoreShift;
173 };
175 class nsContentUtils
176 {
177 friend class nsAutoScriptBlockerSuppressNodeRemoved;
178 typedef mozilla::dom::Element Element;
179 typedef mozilla::TimeDuration TimeDuration;
181 public:
182 static nsresult Init();
184 /**
185 * Get a JSContext from the document's scope object.
186 */
187 static JSContext* GetContextFromDocument(nsIDocument *aDocument);
189 static bool IsCallerChrome();
190 static bool ThreadsafeIsCallerChrome();
191 static bool IsCallerXBL();
193 static bool IsImageSrcSetDisabled();
195 static bool LookupBindingMember(JSContext* aCx, nsIContent *aContent,
196 JS::Handle<jsid> aId,
197 JS::MutableHandle<JSPropertyDescriptor> aDesc);
199 /**
200 * Returns the parent node of aChild crossing document boundaries.
201 */
202 static nsINode* GetCrossDocParentNode(nsINode* aChild);
204 /**
205 * Do not ever pass null pointers to this method. If one of your
206 * nsIContents is null, you have to decide for yourself what
207 * "IsDescendantOf" really means.
208 *
209 * @param aPossibleDescendant node to test for being a descendant of
210 * aPossibleAncestor
211 * @param aPossibleAncestor node to test for being an ancestor of
212 * aPossibleDescendant
213 * @return true if aPossibleDescendant is a descendant of
214 * aPossibleAncestor (or is aPossibleAncestor). false
215 * otherwise.
216 */
217 static bool ContentIsDescendantOf(const nsINode* aPossibleDescendant,
218 const nsINode* aPossibleAncestor);
220 /**
221 * Similar to ContentIsDescendantOf, except will treat an HTMLTemplateElement
222 * or ShadowRoot as an ancestor of things in the corresponding DocumentFragment.
223 * See the concept of "host-including inclusive ancestor" in the DOM
224 * specification.
225 */
226 static bool ContentIsHostIncludingDescendantOf(
227 const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
229 /**
230 * Similar to ContentIsDescendantOf except it crosses document boundaries.
231 */
232 static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
233 nsINode* aPossibleAncestor);
235 /*
236 * This method fills the |aArray| with all ancestor nodes of |aNode|
237 * including |aNode| at the zero index.
238 */
239 static nsresult GetAncestors(nsINode* aNode,
240 nsTArray<nsINode*>& aArray);
242 /*
243 * This method fills |aAncestorNodes| with all ancestor nodes of |aNode|
244 * including |aNode| (QI'd to nsIContent) at the zero index.
245 * For each ancestor, there is a corresponding element in |aAncestorOffsets|
246 * which is the IndexOf the child in relation to its parent.
247 *
248 * This method just sucks.
249 */
250 static nsresult GetAncestorsAndOffsets(nsIDOMNode* aNode,
251 int32_t aOffset,
252 nsTArray<nsIContent*>* aAncestorNodes,
253 nsTArray<int32_t>* aAncestorOffsets);
255 /*
256 * The out parameter, |aCommonAncestor| will be the closest node, if any,
257 * to both |aNode| and |aOther| which is also an ancestor of each.
258 * Returns an error if the two nodes are disconnected and don't have
259 * a common ancestor.
260 */
261 static nsresult GetCommonAncestor(nsIDOMNode *aNode,
262 nsIDOMNode *aOther,
263 nsIDOMNode** aCommonAncestor);
265 /**
266 * Returns the common ancestor, if any, for two nodes. Returns null if the
267 * nodes are disconnected.
268 */
269 static nsINode* GetCommonAncestor(nsINode* aNode1,
270 nsINode* aNode2);
272 /**
273 * Returns true if aNode1 is before aNode2 in the same connected
274 * tree.
275 */
276 static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2);
278 /**
279 * Utility routine to compare two "points", where a point is a
280 * node/offset pair
281 * Returns -1 if point1 < point2, 1, if point1 > point2,
282 * 0 if error or if point1 == point2.
283 * NOTE! If the two nodes aren't in the same connected subtree,
284 * the result is 1, and the optional aDisconnected parameter
285 * is set to true.
286 */
287 static int32_t ComparePoints(nsINode* aParent1, int32_t aOffset1,
288 nsINode* aParent2, int32_t aOffset2,
289 bool* aDisconnected = nullptr);
290 static int32_t ComparePoints(nsIDOMNode* aParent1, int32_t aOffset1,
291 nsIDOMNode* aParent2, int32_t aOffset2,
292 bool* aDisconnected = nullptr);
294 /**
295 * Brute-force search of the element subtree rooted at aContent for
296 * an element with the given id. aId must be nonempty, otherwise
297 * this method may return nodes even if they have no id!
298 */
299 static Element* MatchElementId(nsIContent *aContent, const nsAString& aId);
301 /**
302 * Similar to above, but to be used if one already has an atom for the ID
303 */
304 static Element* MatchElementId(nsIContent *aContent, const nsIAtom* aId);
306 /**
307 * Reverses the document position flags passed in.
308 *
309 * @param aDocumentPosition The document position flags to be reversed.
310 *
311 * @return The reversed document position flags.
312 *
313 * @see nsIDOMNode
314 */
315 static uint16_t ReverseDocumentPosition(uint16_t aDocumentPosition);
317 static uint32_t CopyNewlineNormalizedUnicodeTo(const nsAString& aSource,
318 uint32_t aSrcOffset,
319 char16_t* aDest,
320 uint32_t aLength,
321 bool& aLastCharCR);
323 static uint32_t CopyNewlineNormalizedUnicodeTo(nsReadingIterator<char16_t>& aSrcStart, const nsReadingIterator<char16_t>& aSrcEnd, nsAString& aDest);
325 static const nsDependentSubstring TrimCharsInSet(const char* aSet,
326 const nsAString& aValue);
328 template<bool IsWhitespace(char16_t)>
329 static const nsDependentSubstring TrimWhitespace(const nsAString& aStr,
330 bool aTrimTrailing = true);
332 /**
333 * Returns true if aChar is of class Ps, Pi, Po, Pf, or Pe.
334 */
335 static bool IsFirstLetterPunctuation(uint32_t aChar);
336 static bool IsFirstLetterPunctuationAt(const nsTextFragment* aFrag, uint32_t aOffset);
338 /**
339 * Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No
340 */
341 static bool IsAlphanumeric(uint32_t aChar);
342 static bool IsAlphanumericAt(const nsTextFragment* aFrag, uint32_t aOffset);
344 /*
345 * Is the character an HTML whitespace character?
346 *
347 * We define whitespace using the list in HTML5 and css3-selectors:
348 * U+0009, U+000A, U+000C, U+000D, U+0020
349 *
350 * HTML 4.01 also lists U+200B (zero-width space).
351 */
352 static bool IsHTMLWhitespace(char16_t aChar);
354 /*
355 * Returns whether the character is an HTML whitespace (see IsHTMLWhitespace)
356 * or a nbsp character (U+00A0).
357 */
358 static bool IsHTMLWhitespaceOrNBSP(char16_t aChar);
360 /**
361 * Is the HTML local name a block element?
362 */
363 static bool IsHTMLBlock(nsIAtom* aLocalName);
365 /**
366 * Is the HTML local name a void element?
367 */
368 static bool IsHTMLVoid(nsIAtom* aLocalName);
370 /**
371 * Parse a margin string of format 'top, right, bottom, left' into
372 * an nsIntMargin.
373 *
374 * @param aString the string to parse
375 * @param aResult the resulting integer
376 * @return whether the value could be parsed
377 */
378 static bool ParseIntMarginValue(const nsAString& aString, nsIntMargin& aResult);
380 /**
381 * Parse the value of the <font size=""> attribute according to the HTML5
382 * spec as of April 16, 2012.
383 *
384 * @param aValue the value to parse
385 * @return 1 to 7, or 0 if the value couldn't be parsed
386 */
387 static int32_t ParseLegacyFontSize(const nsAString& aValue);
389 static void Shutdown();
391 /**
392 * Checks whether two nodes come from the same origin.
393 */
394 static nsresult CheckSameOrigin(const nsINode* aTrustedNode,
395 nsIDOMNode* aUnTrustedNode);
396 static nsresult CheckSameOrigin(const nsINode* aTrustedNode,
397 const nsINode* unTrustedNode);
399 // Check if the (JS) caller can access aNode.
400 static bool CanCallerAccess(nsIDOMNode *aNode);
401 static bool CanCallerAccess(nsINode* aNode);
403 // Check if the (JS) caller can access aWindow.
404 // aWindow can be either outer or inner window.
405 static bool CanCallerAccess(nsPIDOMWindow* aWindow);
407 /**
408 * Get the window through the JS context that's currently on the stack.
409 * If there's no JS context currently on the stack, returns null.
410 */
411 static nsPIDOMWindow *GetWindowFromCaller();
413 /**
414 * The two GetDocumentFrom* functions below allow a caller to get at a
415 * document that is relevant to the currently executing script.
416 *
417 * GetDocumentFromCaller gets its document by looking at the last called
418 * function and finding the document that the function itself relates to.
419 * For example, consider two windows A and B in the same origin. B has a
420 * function which does something that ends up needing the current document.
421 * If a script in window A were to call B's function, GetDocumentFromCaller
422 * would find that function (in B) and return B's document.
423 *
424 * GetDocumentFromContext gets its document by looking at the currently
425 * executing context's global object and returning its document. Thus,
426 * given the example above, GetDocumentFromCaller would see that the
427 * currently executing script was in window A, and return A's document.
428 */
429 /**
430 * Get the document from the currently executing function. This will return
431 * the document that the currently executing function is in/from.
432 *
433 * @return The document or null if no JS Context.
434 */
435 static nsIDocument* GetDocumentFromCaller();
437 /**
438 * Get the document through the JS context that's currently on the stack.
439 * If there's no JS context currently on the stack it will return null.
440 * This will return the document of the calling script.
441 *
442 * @return The document or null if no JS context
443 */
444 static nsIDocument* GetDocumentFromContext();
446 // Check if a node is in the document prolog, i.e. before the document
447 // element.
448 static bool InProlog(nsINode *aNode);
450 static nsIParserService* GetParserService();
452 static nsNameSpaceManager* NameSpaceManager()
453 {
454 return sNameSpaceManager;
455 }
457 static nsIIOService* GetIOService()
458 {
459 return sIOService;
460 }
462 static nsIBidiKeyboard* GetBidiKeyboard();
464 /**
465 * Get the cache security manager service. Can return null if the layout
466 * module has been shut down.
467 */
468 static nsIScriptSecurityManager* GetSecurityManager()
469 {
470 return sSecurityManager;
471 }
473 /**
474 * Get the ContentSecurityPolicy for a JS context.
475 **/
476 static bool GetContentSecurityPolicy(JSContext* aCx,
477 nsIContentSecurityPolicy** aCSP);
479 // Returns the subject principal. Guaranteed to return non-null. May only
480 // be called when nsContentUtils is initialized.
481 static nsIPrincipal* GetSubjectPrincipal();
483 // Returns the principal of the given JS object. This should never be null
484 // for any object in the XPConnect runtime.
485 //
486 // In general, being interested in the principal of an object is enough to
487 // guarantee that the return value is non-null.
488 static nsIPrincipal* GetObjectPrincipal(JSObject* aObj);
490 static nsresult GenerateStateKey(nsIContent* aContent,
491 const nsIDocument* aDocument,
492 nsACString& aKey);
494 /**
495 * Create a new nsIURI from aSpec, using aBaseURI as the base. The
496 * origin charset of the new nsIURI will be the document charset of
497 * aDocument.
498 */
499 static nsresult NewURIWithDocumentCharset(nsIURI** aResult,
500 const nsAString& aSpec,
501 nsIDocument* aDocument,
502 nsIURI* aBaseURI);
504 /**
505 * Convert aInput (in encoding aEncoding) to UTF16 in aOutput.
506 *
507 * @param aEncoding the Gecko-canonical name of the encoding or the empty
508 * string (meaning UTF-8)
509 */
510 static nsresult ConvertStringFromEncoding(const nsACString& aEncoding,
511 const nsACString& aInput,
512 nsAString& aOutput);
514 /**
515 * Determine whether a buffer begins with a BOM for UTF-8, UTF-16LE,
516 * UTF-16BE
517 *
518 * @param aBuffer the buffer to check
519 * @param aLength the length of the buffer
520 * @param aCharset empty if not found
521 * @return boolean indicating whether a BOM was detected.
522 */
523 static bool CheckForBOM(const unsigned char* aBuffer, uint32_t aLength,
524 nsACString& aCharset);
526 /**
527 * Returns true if |aName| is a valid name to be registered via
528 * document.registerElement.
529 */
530 static bool IsCustomElementName(nsIAtom* aName);
532 static nsresult CheckQName(const nsAString& aQualifiedName,
533 bool aNamespaceAware = true,
534 const char16_t** aColon = nullptr);
536 static nsresult SplitQName(const nsIContent* aNamespaceResolver,
537 const nsAFlatString& aQName,
538 int32_t *aNamespace, nsIAtom **aLocalName);
540 static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
541 const nsAString& aQualifiedName,
542 nsNodeInfoManager* aNodeInfoManager,
543 uint16_t aNodeType,
544 nsINodeInfo** aNodeInfo);
546 static void SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix,
547 nsIAtom **aTagName, int32_t *aNameSpaceID);
549 // Get a permission-manager setting for the given principal and type.
550 // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
551 // returned, otherwise true is returned. Always returns true for the
552 // system principal, and false for a null principal.
553 static bool IsSitePermAllow(nsIPrincipal* aPrincipal, const char* aType);
555 // Get a permission-manager setting for the given principal and type.
556 // If the pref doesn't exist or if it isn't DENY_ACTION, false is
557 // returned, otherwise true is returned. Always returns false for the
558 // system principal, and true for a null principal.
559 static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const char* aType);
561 // Get a permission-manager setting for the given principal and type.
562 // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
563 // returned, otherwise true is returned. Always returns true for the
564 // system principal, and false for a null principal.
565 // This version checks the permission for an exact host match on
566 // the principal
567 static bool IsExactSitePermAllow(nsIPrincipal* aPrincipal, const char* aType);
569 // Get a permission-manager setting for the given principal and type.
570 // If the pref doesn't exist or if it isn't DENY_ACTION, false is
571 // returned, otherwise true is returned. Always returns false for the
572 // system principal, and true for a null principal.
573 // This version checks the permission for an exact host match on
574 // the principal
575 static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal, const char* aType);
577 // Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s.
578 static bool HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2);
580 static nsILineBreaker* LineBreaker()
581 {
582 return sLineBreaker;
583 }
585 static nsIWordBreaker* WordBreaker()
586 {
587 return sWordBreaker;
588 }
590 /**
591 * Regster aObserver as a shutdown observer. A strong reference is held
592 * to aObserver until UnregisterShutdownObserver is called.
593 */
594 static void RegisterShutdownObserver(nsIObserver* aObserver);
595 static void UnregisterShutdownObserver(nsIObserver* aObserver);
597 /**
598 * @return true if aContent has an attribute aName in namespace aNameSpaceID,
599 * and the attribute value is non-empty.
600 */
601 static bool HasNonEmptyAttr(const nsIContent* aContent, int32_t aNameSpaceID,
602 nsIAtom* aName);
604 /**
605 * Method that gets the primary presContext for the node.
606 *
607 * @param aContent The content node.
608 * @return the presContext, or nullptr if the content is not in a document
609 * (if GetCurrentDoc returns nullptr)
610 */
611 static nsPresContext* GetContextForContent(const nsIContent* aContent);
613 /**
614 * Method to do security and content policy checks on the image URI
615 *
616 * @param aURI uri of the image to be loaded
617 * @param aContext the context the image is loaded in (eg an element)
618 * @param aLoadingDocument the document we belong to
619 * @param aLoadingPrincipal the principal doing the load
620 * @param aImageBlockingStatus the nsIContentPolicy blocking status for this
621 * image. This will be set even if a security check fails for the
622 * image, to some reasonable REJECT_* value. This out param will only
623 * be set if it's non-null.
624 * @return true if the load can proceed, or false if it is blocked.
625 * Note that aImageBlockingStatus, if set will always be an ACCEPT
626 * status if true is returned and always be a REJECT_* status if
627 * false is returned.
628 */
629 static bool CanLoadImage(nsIURI* aURI,
630 nsISupports* aContext,
631 nsIDocument* aLoadingDocument,
632 nsIPrincipal* aLoadingPrincipal,
633 int16_t* aImageBlockingStatus = nullptr);
634 /**
635 * Method to start an image load. This does not do any security checks.
636 * This method will attempt to make aURI immutable; a caller that wants to
637 * keep a mutable version around should pass in a clone.
638 *
639 * @param aURI uri of the image to be loaded
640 * @param aLoadingDocument the document we belong to
641 * @param aLoadingPrincipal the principal doing the load
642 * @param aReferrer the referrer URI
643 * @param aObserver the observer for the image load
644 * @param aLoadFlags the load flags to use. See nsIRequest
645 * @return the imgIRequest for the image load
646 */
647 static nsresult LoadImage(nsIURI* aURI,
648 nsIDocument* aLoadingDocument,
649 nsIPrincipal* aLoadingPrincipal,
650 nsIURI* aReferrer,
651 imgINotificationObserver* aObserver,
652 int32_t aLoadFlags,
653 const nsAString& initiatorType,
654 imgRequestProxy** aRequest);
656 /**
657 * Obtain an image loader that respects the given document/channel's privacy status.
658 * Null document/channel arguments return the public image loader.
659 */
660 static imgLoader* GetImgLoaderForDocument(nsIDocument* aDoc);
661 static imgLoader* GetImgLoaderForChannel(nsIChannel* aChannel);
663 /**
664 * Returns whether the given URI is in the image cache.
665 */
666 static bool IsImageInCache(nsIURI* aURI, nsIDocument* aDocument);
668 /**
669 * Method to get an imgIContainer from an image loading content
670 *
671 * @param aContent The image loading content. Must not be null.
672 * @param aRequest The image request [out]
673 * @return the imgIContainer corresponding to the first frame of the image
674 */
675 static already_AddRefed<imgIContainer> GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nullptr);
677 /**
678 * Helper method to call imgIRequest::GetStaticRequest.
679 */
680 static already_AddRefed<imgRequestProxy> GetStaticRequest(imgRequestProxy* aRequest);
682 /**
683 * Method that decides whether a content node is draggable
684 *
685 * @param aContent The content node to test.
686 * @return whether it's draggable
687 */
688 static bool ContentIsDraggable(nsIContent* aContent);
690 /**
691 * Method that decides whether a content node is a draggable image
692 *
693 * @param aContent The content node to test.
694 * @return whether it's a draggable image
695 */
696 static bool IsDraggableImage(nsIContent* aContent);
698 /**
699 * Method that decides whether a content node is a draggable link
700 *
701 * @param aContent The content node to test.
702 * @return whether it's a draggable link
703 */
704 static bool IsDraggableLink(const nsIContent* aContent);
706 /**
707 * Convenience method to create a new nodeinfo that differs only by name
708 * from aNodeInfo.
709 */
710 static nsresult NameChanged(nsINodeInfo* aNodeInfo, nsIAtom* aName,
711 nsINodeInfo** aResult);
713 /**
714 * Returns the appropriate event argument names for the specified
715 * namespace and event name. Added because we need to switch between
716 * SVG's "evt" and the rest of the world's "event", and because onerror
717 * takes 3 args.
718 */
719 static void GetEventArgNames(int32_t aNameSpaceID, nsIAtom *aEventName,
720 uint32_t *aArgCount, const char*** aArgNames);
722 /**
723 * If aNode is not an element, return true exactly when aContent's binding
724 * parent is null.
725 *
726 * If aNode is an element, return true exactly when aContent's binding parent
727 * is the same as aNode's.
728 *
729 * This method is particularly useful for callers who are trying to ensure
730 * that they are working with a non-anonymous descendant of a given node. If
731 * aContent is a descendant of aNode, a return value of false from this
732 * method means that it's an anonymous descendant from aNode's point of view.
733 *
734 * Both arguments to this method must be non-null.
735 */
736 static bool IsInSameAnonymousTree(const nsINode* aNode, const nsIContent* aContent);
738 /**
739 * Return the nsIXPConnect service.
740 */
741 static nsIXPConnect *XPConnect()
742 {
743 return sXPConnect;
744 }
746 /**
747 * Report simple error message to the browser console
748 * @param aErrorText the error message
749 * @param classification Name of the module reporting error
750 */
751 static void LogSimpleConsoleError(const nsAString& aErrorText,
752 const char * classification);
754 /**
755 * Report a non-localized error message to the error console.
756 * @param aErrorText the error message
757 * @param aErrorFlags See nsIScriptError.
758 * @param aCategory Name of module reporting error.
759 * @param aDocument Reference to the document which triggered the message.
760 * @param [aURI=nullptr] (Optional) URI of resource containing error.
761 * @param [aSourceLine=EmptyString()] (Optional) The text of the line that
762 contains the error (may be empty).
763 * @param [aLineNumber=0] (Optional) Line number within resource
764 containing error.
765 * @param [aColumnNumber=0] (Optional) Column number within resource
766 containing error.
767 If aURI is null, then aDocument->GetDocumentURI() is used.
768 */
769 static nsresult ReportToConsoleNonLocalized(const nsAString& aErrorText,
770 uint32_t aErrorFlags,
771 const nsACString& aCategory,
772 nsIDocument* aDocument,
773 nsIURI* aURI = nullptr,
774 const nsAFlatString& aSourceLine
775 = EmptyString(),
776 uint32_t aLineNumber = 0,
777 uint32_t aColumnNumber = 0);
779 /**
780 * Report a localized error message to the error console.
781 * @param aErrorFlags See nsIScriptError.
782 * @param aCategory Name of module reporting error.
783 * @param aDocument Reference to the document which triggered the message.
784 * @param aFile Properties file containing localized message.
785 * @param aMessageName Name of localized message.
786 * @param [aParams=nullptr] (Optional) Parameters to be substituted into
787 localized message.
788 * @param [aParamsLength=0] (Optional) Length of aParams.
789 * @param [aURI=nullptr] (Optional) URI of resource containing error.
790 * @param [aSourceLine=EmptyString()] (Optional) The text of the line that
791 contains the error (may be empty).
792 * @param [aLineNumber=0] (Optional) Line number within resource
793 containing error.
794 * @param [aColumnNumber=0] (Optional) Column number within resource
795 containing error.
796 If aURI is null, then aDocument->GetDocumentURI() is used.
797 */
798 enum PropertiesFile {
799 eCSS_PROPERTIES,
800 eXBL_PROPERTIES,
801 eXUL_PROPERTIES,
802 eLAYOUT_PROPERTIES,
803 eFORMS_PROPERTIES,
804 ePRINTING_PROPERTIES,
805 eDOM_PROPERTIES,
806 eHTMLPARSER_PROPERTIES,
807 eSVG_PROPERTIES,
808 eBRAND_PROPERTIES,
809 eCOMMON_DIALOG_PROPERTIES,
810 eMATHML_PROPERTIES,
811 eSECURITY_PROPERTIES,
812 PropertiesFile_COUNT
813 };
814 static nsresult ReportToConsole(uint32_t aErrorFlags,
815 const nsACString& aCategory,
816 nsIDocument* aDocument,
817 PropertiesFile aFile,
818 const char *aMessageName,
819 const char16_t **aParams = nullptr,
820 uint32_t aParamsLength = 0,
821 nsIURI* aURI = nullptr,
822 const nsAFlatString& aSourceLine
823 = EmptyString(),
824 uint32_t aLineNumber = 0,
825 uint32_t aColumnNumber = 0);
827 static void LogMessageToConsole(const char* aMsg, ...);
829 /**
830 * Get the localized string named |aKey| in properties file |aFile|.
831 */
832 static nsresult GetLocalizedString(PropertiesFile aFile,
833 const char* aKey,
834 nsXPIDLString& aResult);
836 /**
837 * A helper function that parses a sandbox attribute (of an <iframe> or
838 * a CSP directive) and converts it to the set of flags used internally.
839 *
840 * @param sandboxAttr the sandbox attribute
841 * @return the set of flags (0 if sandboxAttr is null)
842 */
843 static uint32_t ParseSandboxAttributeToFlags(const nsAttrValue* sandboxAttr);
846 /**
847 * Fill (with the parameters given) the localized string named |aKey| in
848 * properties file |aFile|.
849 */
850 private:
851 static nsresult FormatLocalizedString(PropertiesFile aFile,
852 const char* aKey,
853 const char16_t** aParams,
854 uint32_t aParamsLength,
855 nsXPIDLString& aResult);
857 public:
858 template<uint32_t N>
859 static nsresult FormatLocalizedString(PropertiesFile aFile,
860 const char* aKey,
861 const char16_t* (&aParams)[N],
862 nsXPIDLString& aResult)
863 {
864 return FormatLocalizedString(aFile, aKey, aParams, N, aResult);
865 }
867 /**
868 * Returns true if aDocument is a chrome document
869 */
870 static bool IsChromeDoc(nsIDocument *aDocument);
872 /**
873 * Returns true if aDocument is in a docshell whose parent is the same type
874 */
875 static bool IsChildOfSameType(nsIDocument* aDoc);
877 /**
878 '* Returns true if the content-type will be rendered as plain-text.
879 */
880 static bool IsPlainTextType(const nsACString& aContentType);
882 /**
883 * Get the script file name to use when compiling the script
884 * referenced by aURI. In cases where there's no need for any extra
885 * security wrapper automation the script file name that's returned
886 * will be the spec in aURI, else it will be the spec in aDocument's
887 * URI followed by aURI's spec, separated by " -> ". Returns true
888 * if the script file name was modified, false if it's aURI's
889 * spec.
890 */
891 static bool GetWrapperSafeScriptFilename(nsIDocument *aDocument,
892 nsIURI *aURI,
893 nsACString& aScriptURI);
896 /**
897 * Returns true if aDocument belongs to a chrome docshell for
898 * display purposes. Returns false for null documents or documents
899 * which do not belong to a docshell.
900 */
901 static bool IsInChromeDocshell(nsIDocument *aDocument);
903 /**
904 * Return the content policy service
905 */
906 static nsIContentPolicy *GetContentPolicy();
908 /**
909 * Quick helper to determine whether there are any mutation listeners
910 * of a given type that apply to this content or any of its ancestors.
911 * The method has the side effect to call document's MayDispatchMutationEvent
912 * using aTargetForSubtreeModified as the parameter.
913 *
914 * @param aNode The node to search for listeners
915 * @param aType The type of listener (NS_EVENT_BITS_MUTATION_*)
916 * @param aTargetForSubtreeModified The node which is the target of the
917 * possible DOMSubtreeModified event.
918 *
919 * @return true if there are mutation listeners of the specified type
920 */
921 static bool HasMutationListeners(nsINode* aNode,
922 uint32_t aType,
923 nsINode* aTargetForSubtreeModified);
925 /**
926 * Quick helper to determine whether there are any mutation listeners
927 * of a given type that apply to any content in this document. It is valid
928 * to pass null for aDocument here, in which case this function always
929 * returns true.
930 *
931 * @param aDocument The document to search for listeners
932 * @param aType The type of listener (NS_EVENT_BITS_MUTATION_*)
933 *
934 * @return true if there are mutation listeners of the specified type
935 */
936 static bool HasMutationListeners(nsIDocument* aDocument,
937 uint32_t aType);
938 /**
939 * Synchronously fire DOMNodeRemoved on aChild. Only fires the event if
940 * there really are listeners by checking using the HasMutationListeners
941 * function above. The function makes sure to hold the relevant objects alive
942 * for the duration of the event firing. However there are no guarantees
943 * that any of the objects are alive by the time the function returns.
944 * If you depend on that you need to hold references yourself.
945 *
946 * @param aChild The node to fire DOMNodeRemoved at.
947 * @param aParent The parent of aChild.
948 * @param aOwnerDoc The ownerDocument of aChild.
949 */
950 static void MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
951 nsIDocument* aOwnerDoc);
953 /**
954 * This method creates and dispatches a trusted event.
955 * Works only with events which can be created by calling
956 * nsIDOMDocument::CreateEvent() with parameter "Events".
957 * @param aDoc The document which will be used to create the event.
958 * @param aTarget The target of the event, should be QIable to
959 * nsIDOMEventTarget.
960 * @param aEventName The name of the event.
961 * @param aCanBubble Whether the event can bubble.
962 * @param aCancelable Is the event cancelable.
963 * @param aDefaultAction Set to true if default action should be taken,
964 * see nsIDOMEventTarget::DispatchEvent.
965 */
966 static nsresult DispatchTrustedEvent(nsIDocument* aDoc,
967 nsISupports* aTarget,
968 const nsAString& aEventName,
969 bool aCanBubble,
970 bool aCancelable,
971 bool *aDefaultAction = nullptr);
973 /**
974 * This method creates and dispatches a untrusted event.
975 * Works only with events which can be created by calling
976 * nsIDOMDocument::CreateEvent() with parameter "Events".
977 * @param aDoc The document which will be used to create the event.
978 * @param aTarget The target of the event, should be QIable to
979 * nsIDOMEventTarget.
980 * @param aEventName The name of the event.
981 * @param aCanBubble Whether the event can bubble.
982 * @param aCancelable Is the event cancelable.
983 * @param aDefaultAction Set to true if default action should be taken,
984 * see nsIDOMEventTarget::DispatchEvent.
985 */
986 static nsresult DispatchUntrustedEvent(nsIDocument* aDoc,
987 nsISupports* aTarget,
988 const nsAString& aEventName,
989 bool aCanBubble,
990 bool aCancelable,
991 bool *aDefaultAction = nullptr);
993 /**
994 * This method creates and dispatches a trusted event to the chrome
995 * event handler.
996 * Works only with events which can be created by calling
997 * nsIDOMDocument::CreateEvent() with parameter "Events".
998 * @param aDocument The document which will be used to create the event,
999 * and whose window's chrome handler will be used to
1000 * dispatch the event.
1001 * @param aTarget The target of the event, used for event->SetTarget()
1002 * @param aEventName The name of the event.
1003 * @param aCanBubble Whether the event can bubble.
1004 * @param aCancelable Is the event cancelable.
1005 * @param aDefaultAction Set to true if default action should be taken,
1006 * see nsIDOMEventTarget::DispatchEvent.
1007 */
1008 static nsresult DispatchChromeEvent(nsIDocument* aDoc,
1009 nsISupports* aTarget,
1010 const nsAString& aEventName,
1011 bool aCanBubble,
1012 bool aCancelable,
1013 bool *aDefaultAction = nullptr);
1015 /**
1016 * Determines if an event attribute name (such as onclick) is valid for
1017 * a given element type. Types are from the EventNameType enumeration
1018 * defined above.
1019 *
1020 * @param aName the event name to look up
1021 * @param aType the type of content
1022 */
1023 static bool IsEventAttributeName(nsIAtom* aName, int32_t aType);
1025 /**
1026 * Return the event id for the event with the given name. The name is the
1027 * event name with the 'on' prefix. Returns NS_USER_DEFINED_EVENT if the
1028 * event doesn't match a known event name.
1029 *
1030 * @param aName the event name to look up
1031 */
1032 static uint32_t GetEventId(nsIAtom* aName);
1034 /**
1035 * Return the category for the event with the given name. The name is the
1036 * event name *without* the 'on' prefix. Returns NS_EVENT if the event
1037 * is not known to be in any particular category.
1038 *
1039 * @param aName the event name to look up
1040 */
1041 static uint32_t GetEventCategory(const nsAString& aName);
1043 /**
1044 * Return the event id and atom for the event with the given name.
1045 * The name is the event name *without* the 'on' prefix.
1046 * Returns NS_USER_DEFINED_EVENT on the aEventID if the
1047 * event doesn't match a known event name in the category.
1048 *
1049 * @param aName the event name to look up
1050 * @param aEventStruct only return event id in aEventStruct category
1051 */
1052 static nsIAtom* GetEventIdAndAtom(const nsAString& aName,
1053 uint32_t aEventStruct,
1054 uint32_t* aEventID);
1056 /**
1057 * Used only during traversal of the XPCOM graph by the cycle
1058 * collector: push a pointer to the listener manager onto the
1059 * children deque, if it exists. Do nothing if there is no listener
1060 * manager.
1061 *
1062 * Crucially: does not perform any refcounting operations.
1063 *
1064 * @param aNode The node to traverse.
1065 * @param children The buffer to push a listener manager pointer into.
1066 */
1067 static void TraverseListenerManager(nsINode *aNode,
1068 nsCycleCollectionTraversalCallback &cb);
1070 /**
1071 * Get the eventlistener manager for aNode, creating it if it does not
1072 * already exist.
1073 *
1074 * @param aNode The node for which to get the eventlistener manager.
1075 */
1076 static mozilla::EventListenerManager*
1077 GetListenerManagerForNode(nsINode* aNode);
1078 /**
1079 * Get the eventlistener manager for aNode, returning null if it does not
1080 * already exist.
1081 *
1082 * @param aNode The node for which to get the eventlistener manager.
1083 */
1084 static mozilla::EventListenerManager*
1085 GetExistingListenerManagerForNode(const nsINode* aNode);
1087 static void UnmarkGrayJSListenersInCCGenerationDocuments(uint32_t aGeneration);
1089 /**
1090 * Remove the eventlistener manager for aNode.
1091 *
1092 * @param aNode The node for which to remove the eventlistener manager.
1093 */
1094 static void RemoveListenerManager(nsINode *aNode);
1096 static bool IsInitialized()
1097 {
1098 return sInitialized;
1099 }
1101 /**
1102 * Checks if the localname/prefix/namespace triple is valid wrt prefix
1103 * and namespace according to the Namespaces in XML and DOM Code
1104 * specfications.
1105 *
1106 * @param aLocalname localname of the node
1107 * @param aPrefix prefix of the node
1108 * @param aNamespaceID namespace of the node
1109 */
1110 static bool IsValidNodeName(nsIAtom *aLocalName, nsIAtom *aPrefix,
1111 int32_t aNamespaceID);
1113 /**
1114 * Creates a DocumentFragment from text using a context node to resolve
1115 * namespaces.
1116 *
1117 * Note! In the HTML case with the HTML5 parser enabled, this is only called
1118 * from Range.createContextualFragment() and the implementation here is
1119 * quirky accordingly (html context node behaves like a body context node).
1120 * If you don't want that quirky behavior, don't use this method as-is!
1121 *
1122 * @param aContextNode the node which is used to resolve namespaces
1123 * @param aFragment the string which is parsed to a DocumentFragment
1124 * @param aReturn the resulting fragment
1125 * @param aPreventScriptExecution whether to mark scripts as already started
1126 */
1127 static nsresult CreateContextualFragment(nsINode* aContextNode,
1128 const nsAString& aFragment,
1129 bool aPreventScriptExecution,
1130 nsIDOMDocumentFragment** aReturn);
1131 static already_AddRefed<mozilla::dom::DocumentFragment>
1132 CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment,
1133 bool aPreventScriptExecution,
1134 mozilla::ErrorResult& aRv);
1136 /**
1137 * Invoke the fragment parsing algorithm (innerHTML) using the HTML parser.
1138 *
1139 * @param aSourceBuffer the string being set as innerHTML
1140 * @param aTargetNode the target container
1141 * @param aContextLocalName local name of context node
1142 * @param aContextNamespace namespace of context node
1143 * @param aQuirks true to make <table> not close <p>
1144 * @param aPreventScriptExecution true to prevent scripts from executing;
1145 * don't set to false when parsing into a target node that has been
1146 * bound to tree.
1147 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1148 * fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
1149 * long and NS_OK otherwise.
1150 */
1151 static nsresult ParseFragmentHTML(const nsAString& aSourceBuffer,
1152 nsIContent* aTargetNode,
1153 nsIAtom* aContextLocalName,
1154 int32_t aContextNamespace,
1155 bool aQuirks,
1156 bool aPreventScriptExecution);
1158 /**
1159 * Invoke the fragment parsing algorithm (innerHTML) using the XML parser.
1160 *
1161 * @param aSourceBuffer the string being set as innerHTML
1162 * @param aTargetNode the target container
1163 * @param aTagStack the namespace mapping context
1164 * @param aPreventExecution whether to mark scripts as already started
1165 * @param aReturn the result fragment
1166 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1167 * fragments is made, a return code from the XML parser.
1168 */
1169 static nsresult ParseFragmentXML(const nsAString& aSourceBuffer,
1170 nsIDocument* aDocument,
1171 nsTArray<nsString>& aTagStack,
1172 bool aPreventScriptExecution,
1173 nsIDOMDocumentFragment** aReturn);
1175 /**
1176 * Parse a string into a document using the HTML parser.
1177 * Script elements are marked unexecutable.
1178 *
1179 * @param aSourceBuffer the string to parse as an HTML document
1180 * @param aTargetDocument the document object to parse into. Must not have
1181 * child nodes.
1182 * @param aScriptingEnabledForNoscriptParsing whether <noscript> is parsed
1183 * as if scripting was enabled
1184 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1185 * fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
1186 * long and NS_OK otherwise.
1187 */
1188 static nsresult ParseDocumentHTML(const nsAString& aSourceBuffer,
1189 nsIDocument* aTargetDocument,
1190 bool aScriptingEnabledForNoscriptParsing);
1192 /**
1193 * Converts HTML source to plain text by parsing the source and using the
1194 * plain text serializer on the resulting tree.
1195 *
1196 * @param aSourceBuffer the string to parse as an HTML document
1197 * @param aResultBuffer the string where the plain text result appears;
1198 * may be the same string as aSourceBuffer
1199 * @param aFlags Flags from nsIDocumentEncoder.
1200 * @param aWrapCol Number of columns after which to line wrap; 0 for no
1201 * auto-wrapping
1202 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1203 * fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
1204 * long and NS_OK otherwise.
1205 */
1206 static nsresult ConvertToPlainText(const nsAString& aSourceBuffer,
1207 nsAString& aResultBuffer,
1208 uint32_t aFlags,
1209 uint32_t aWrapCol);
1211 /**
1212 * Sets the text contents of a node by replacing all existing children
1213 * with a single text child.
1214 *
1215 * The function always notifies.
1216 *
1217 * Will reuse the first text child if one is available. Will not reuse
1218 * existing cdata children.
1219 *
1220 * @param aContent Node to set contents of.
1221 * @param aValue Value to set contents to.
1222 * @param aTryReuse When true, the function will try to reuse an existing
1223 * textnodes rather than always creating a new one.
1224 */
1225 static nsresult SetNodeTextContent(nsIContent* aContent,
1226 const nsAString& aValue,
1227 bool aTryReuse);
1229 /**
1230 * Get the textual contents of a node. This is a concatenation of all
1231 * textnodes that are direct or (depending on aDeep) indirect children
1232 * of the node.
1233 *
1234 * NOTE! No serialization takes place and <br> elements
1235 * are not converted into newlines. Only textnodes and cdata nodes are
1236 * added to the result.
1237 *
1238 * @param aNode Node to get textual contents of.
1239 * @param aDeep If true child elements of aNode are recursivly descended
1240 * into to find text children.
1241 * @param aResult the result. Out param.
1242 * @return false on out of memory errors, true otherwise.
1243 */
1244 static bool GetNodeTextContent(nsINode* aNode, bool aDeep,
1245 nsAString& aResult) NS_WARN_UNUSED_RESULT;
1247 /**
1248 * Same as GetNodeTextContents but appends the result rather than sets it.
1249 */
1250 static bool AppendNodeTextContent(nsINode* aNode, bool aDeep,
1251 nsAString& aResult, const mozilla::fallible_t&);
1253 /**
1254 * Utility method that checks if a given node has any non-empty
1255 * children.
1256 * NOTE! This method does not descend recursivly into elements.
1257 * Though it would be easy to make it so if needed
1258 */
1259 static bool HasNonEmptyTextContent(nsINode* aNode);
1261 /**
1262 * Delete strings allocated for nsContentList matches
1263 */
1264 static void DestroyMatchString(void* aData);
1266 /**
1267 * Unbinds the content from the tree and nulls it out if it's not null.
1268 */
1269 static void DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent);
1270 static void DestroyAnonymousContent(nsCOMPtr<Element>* aElement);
1272 static void DeferredFinalize(nsISupports* aSupports);
1273 static void DeferredFinalize(mozilla::DeferredFinalizeAppendFunction aAppendFunc,
1274 mozilla::DeferredFinalizeFunction aFunc,
1275 void* aThing);
1277 /*
1278 * Notify when the first XUL menu is opened and when the all XUL menus are
1279 * closed. At opening, aInstalling should be TRUE, otherwise, it should be
1280 * FALSE.
1281 */
1282 static void NotifyInstalledMenuKeyboardListener(bool aInstalling);
1284 /**
1285 * Do security checks before loading a resource. Does the following checks:
1286 * nsIScriptSecurityManager::CheckLoadURIWithPrincipal
1287 * NS_CheckContentLoadPolicy
1288 * nsIScriptSecurityManager::CheckSameOriginURI
1289 *
1290 * You will still need to do at least SameOrigin checks before on redirects.
1291 *
1292 * @param aURIToLoad URI that is getting loaded.
1293 * @param aLoadingPrincipal Principal of the resource that is initiating
1294 * the load
1295 * @param aCheckLoadFlags Flags to be passed to
1296 * nsIScriptSecurityManager::CheckLoadURIWithPrincipal
1297 * NOTE: If this contains ALLOW_CHROME the
1298 * CheckSameOriginURI check will be skipped if
1299 * aURIToLoad is a chrome uri.
1300 * @param aAllowData Set to true to skip CheckSameOriginURI check when
1301 aURIToLoad is a data uri.
1302 * @param aContentPolicyType Type \
1303 * @param aContext Context |- to be passed to
1304 * @param aMimeGuess Mimetype | NS_CheckContentLoadPolicy
1305 * @param aExtra Extra /
1306 */
1307 static nsresult CheckSecurityBeforeLoad(nsIURI* aURIToLoad,
1308 nsIPrincipal* aLoadingPrincipal,
1309 uint32_t aCheckLoadFlags,
1310 bool aAllowData,
1311 uint32_t aContentPolicyType,
1312 nsISupports* aContext,
1313 const nsAFlatCString& aMimeGuess = EmptyCString(),
1314 nsISupports* aExtra = nullptr);
1316 /**
1317 * Returns true if aPrincipal is the system principal.
1318 */
1319 static bool IsSystemPrincipal(nsIPrincipal* aPrincipal);
1321 /**
1322 * Returns true if aPrincipal is an nsExpandedPrincipal.
1323 */
1324 static bool IsExpandedPrincipal(nsIPrincipal* aPrincipal);
1326 /**
1327 * Returns true if aPrincipal is the system or an nsExpandedPrincipal.
1328 */
1329 static bool IsSystemOrExpandedPrincipal(nsIPrincipal* aPrincipal)
1330 {
1331 return IsSystemPrincipal(aPrincipal) || IsExpandedPrincipal(aPrincipal);
1332 }
1334 /**
1335 * Gets the system principal from the security manager.
1336 */
1337 static nsIPrincipal* GetSystemPrincipal();
1339 /**
1340 * *aResourcePrincipal is a principal describing who may access the contents
1341 * of a resource. The resource can only be consumed by a principal that
1342 * subsumes *aResourcePrincipal. MAKE SURE THAT NOTHING EVER ACTS WITH THE
1343 * AUTHORITY OF *aResourcePrincipal.
1344 * It may be null to indicate that the resource has no data from any origin
1345 * in it yet and anything may access the resource.
1346 * Additional data is being mixed into the resource from aExtraPrincipal
1347 * (which may be null; if null, no data is being mixed in and this function
1348 * will do nothing). Update *aResourcePrincipal to reflect the new data.
1349 * If *aResourcePrincipal subsumes aExtraPrincipal, nothing needs to change,
1350 * otherwise *aResourcePrincipal is replaced with the system principal.
1351 * Returns true if *aResourcePrincipal changed.
1352 */
1353 static bool CombineResourcePrincipals(nsCOMPtr<nsIPrincipal>* aResourcePrincipal,
1354 nsIPrincipal* aExtraPrincipal);
1356 /**
1357 * Trigger a link with uri aLinkURI. If aClick is false, this triggers a
1358 * mouseover on the link, otherwise it triggers a load after doing a
1359 * security check using aContent's principal.
1360 *
1361 * @param aContent the node on which a link was triggered.
1362 * @param aPresContext the pres context, must be non-null.
1363 * @param aLinkURI the URI of the link, must be non-null.
1364 * @param aTargetSpec the target (like target=, may be empty).
1365 * @param aClick whether this was a click or not (if false, this method
1366 * assumes you just hovered over the link).
1367 * @param aIsUserTriggered whether the user triggered the link. This would be
1368 * false for loads from auto XLinks or from the
1369 * click() method if we ever implement it.
1370 * @param aIsTrusted If false, JS Context will be pushed to stack
1371 * when the link is triggered.
1372 */
1373 static void TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
1374 nsIURI *aLinkURI, const nsString& aTargetSpec,
1375 bool aClick, bool aIsUserTriggered,
1376 bool aIsTrusted);
1378 /**
1379 * Get the link location.
1380 */
1381 static void GetLinkLocation(mozilla::dom::Element* aElement,
1382 nsString& aLocationString);
1384 /**
1385 * Return top-level widget in the parent chain.
1386 */
1387 static nsIWidget* GetTopLevelWidget(nsIWidget* aWidget);
1389 /**
1390 * Return the localized ellipsis for UI.
1391 */
1392 static const nsDependentString GetLocalizedEllipsis();
1394 /**
1395 * Get the candidates for accelkeys for aDOMKeyEvent.
1396 *
1397 * @param aDOMKeyEvent [in] the key event for accelkey handling.
1398 * @param aCandidates [out] the candidate shortcut key combination list.
1399 * the first item is most preferred.
1400 */
1401 static void GetAccelKeyCandidates(nsIDOMKeyEvent* aDOMKeyEvent,
1402 nsTArray<nsShortcutCandidate>& aCandidates);
1404 /**
1405 * Get the candidates for accesskeys for aNativeKeyEvent.
1406 *
1407 * @param aNativeKeyEvent [in] the key event for accesskey handling.
1408 * @param aCandidates [out] the candidate access key list.
1409 * the first item is most preferred.
1410 */
1411 static void GetAccessKeyCandidates(
1412 mozilla::WidgetKeyboardEvent* aNativeKeyEvent,
1413 nsTArray<uint32_t>& aCandidates);
1415 /**
1416 * Hide any XUL popups associated with aDocument, including any documents
1417 * displayed in child frames. Does nothing if aDocument is null.
1418 */
1419 static void HidePopupsInDocument(nsIDocument* aDocument);
1421 /**
1422 * Retrieve the current drag session, or null if no drag is currently occuring
1423 */
1424 static already_AddRefed<nsIDragSession> GetDragSession();
1426 /*
1427 * Initialize and set the dataTransfer field of an WidgetDragEvent.
1428 */
1429 static nsresult SetDataTransferInEvent(mozilla::WidgetDragEvent* aDragEvent);
1431 // filters the drag and drop action to fit within the effects allowed and
1432 // returns it.
1433 static uint32_t FilterDropEffect(uint32_t aAction, uint32_t aEffectAllowed);
1435 /*
1436 * Return true if the target of a drop event is a content document that is
1437 * an ancestor of the document for the source of the drag.
1438 */
1439 static bool CheckForSubFrameDrop(nsIDragSession* aDragSession,
1440 mozilla::WidgetDragEvent* aDropEvent);
1442 /**
1443 * Return true if aURI is a local file URI (i.e. file://).
1444 */
1445 static bool URIIsLocalFile(nsIURI *aURI);
1447 /**
1448 * Given a URI, return set beforeHash to the part before the '#', and
1449 * afterHash to the remainder of the URI, including the '#'.
1450 */
1451 static nsresult SplitURIAtHash(nsIURI *aURI,
1452 nsACString &aBeforeHash,
1453 nsACString &aAfterHash);
1455 /**
1456 * Get the application manifest URI for this document. The manifest URI
1457 * is specified in the manifest= attribute of the root element of the
1458 * document.
1459 *
1460 * @param aDocument The document that lists the manifest.
1461 * @param aURI The manifest URI.
1462 */
1463 static void GetOfflineAppManifest(nsIDocument *aDocument, nsIURI **aURI);
1465 /**
1466 * Check whether an application should be allowed to use offline APIs.
1467 */
1468 static bool OfflineAppAllowed(nsIURI *aURI);
1470 /**
1471 * Check whether an application should be allowed to use offline APIs.
1472 */
1473 static bool OfflineAppAllowed(nsIPrincipal *aPrincipal);
1475 /**
1476 * If offline-apps.allow_by_default is true, we set offline-app permission
1477 * for the principal and return true. Otherwise false.
1478 */
1479 static bool MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal, nsIDOMWindow *aWindow);
1481 /**
1482 * Increases the count of blockers preventing scripts from running.
1483 * NOTE: You might want to use nsAutoScriptBlocker rather than calling
1484 * this directly
1485 */
1486 static void AddScriptBlocker();
1488 /**
1489 * Decreases the count of blockers preventing scripts from running.
1490 * NOTE: You might want to use nsAutoScriptBlocker rather than calling
1491 * this directly
1492 *
1493 * WARNING! Calling this function could synchronously execute scripts.
1494 */
1495 static void RemoveScriptBlocker();
1497 /**
1498 * Add a runnable that is to be executed as soon as it's safe to execute
1499 * scripts.
1500 * NOTE: If it's currently safe to execute scripts, aRunnable will be run
1501 * synchronously before the function returns.
1502 *
1503 * @param aRunnable The nsIRunnable to run as soon as it's safe to execute
1504 * scripts. Passing null is allowed and results in nothing
1505 * happening. It is also allowed to pass an object that
1506 * has not yet been AddRefed.
1507 * @return false on out of memory, true otherwise.
1508 */
1509 static bool AddScriptRunner(nsIRunnable* aRunnable);
1511 /**
1512 * Returns true if it's safe to execute content script and false otherwise.
1513 *
1514 * The only known case where this lies is mutation events. They run, and can
1515 * run anything else, when this function returns false, but this is ok.
1516 */
1517 static bool IsSafeToRunScript() {
1518 return sScriptBlockerCount == 0;
1519 }
1521 /**
1522 * Retrieve information about the viewport as a data structure.
1523 * This will return information in the viewport META data section
1524 * of the document. This can be used in lieu of ProcessViewportInfo(),
1525 * which places the viewport information in the document header instead
1526 * of returning it directly.
1527 *
1528 * @param aDisplayWidth width of the on-screen display area for this
1529 * document, in device pixels.
1530 * @param aDisplayHeight height of the on-screen display area for this
1531 * document, in device pixels.
1532 *
1533 * NOTE: If the site is optimized for mobile (via the doctype), this
1534 * will return viewport information that specifies default information.
1535 */
1536 static nsViewportInfo GetViewportInfo(nsIDocument* aDocument,
1537 const mozilla::ScreenIntSize& aDisplaySize);
1539 // Call EnterMicroTask when you're entering JS execution.
1540 // Usually the best way to do this is to use nsAutoMicroTask.
1541 static void EnterMicroTask();
1542 static void LeaveMicroTask();
1544 static bool IsInMicroTask();
1545 static uint32_t MicroTaskLevel();
1546 static void SetMicroTaskLevel(uint32_t aLevel);
1548 /* Process viewport META data. This gives us information for the scale
1549 * and zoom of a page on mobile devices. We stick the information in
1550 * the document header and use it later on after rendering.
1551 *
1552 * See Bug #436083
1553 */
1554 static nsresult ProcessViewportInfo(nsIDocument *aDocument,
1555 const nsAString &viewportInfo);
1557 static nsIScriptContext* GetContextForEventHandlers(nsINode* aNode,
1558 nsresult* aRv);
1560 static JSContext *GetCurrentJSContext();
1561 static JSContext *GetSafeJSContext();
1562 static JSContext *GetCurrentJSContextForThread();
1563 static JSContext *GetDefaultJSContextForThread();
1565 /**
1566 * Case insensitive comparison between two strings. However it only ignores
1567 * case for ASCII characters a-z.
1568 */
1569 static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
1570 const nsAString& aStr2);
1572 /**
1573 * Convert ASCII A-Z to a-z.
1574 * @return NS_OK on success, or NS_ERROR_OUT_OF_MEMORY if making the string
1575 * writable needs to allocate memory and that allocation fails.
1576 */
1577 static nsresult ASCIIToLower(nsAString& aStr);
1578 static nsresult ASCIIToLower(const nsAString& aSource, nsAString& aDest);
1580 /**
1581 * Convert ASCII a-z to A-Z.
1582 * @return NS_OK on success, or NS_ERROR_OUT_OF_MEMORY if making the string
1583 * writable needs to allocate memory and that allocation fails.
1584 */
1585 static nsresult ASCIIToUpper(nsAString& aStr);
1586 static nsresult ASCIIToUpper(const nsAString& aSource, nsAString& aDest);
1588 /**
1589 * Return whether aStr contains an ASCII uppercase character.
1590 */
1591 static bool StringContainsASCIIUpper(const nsAString& aStr);
1593 // Returns NS_OK for same origin, error (NS_ERROR_DOM_BAD_URI) if not.
1594 static nsresult CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel);
1595 static nsIInterfaceRequestor* GetSameOriginChecker();
1597 // Trace the safe JS context.
1598 static void TraceSafeJSContext(JSTracer* aTrc);
1601 /**
1602 * Get the Origin of the passed in nsIPrincipal or nsIURI. If the passed in
1603 * nsIURI or the URI of the passed in nsIPrincipal does not have a host, the
1604 * origin is set to 'null'.
1605 *
1606 * The ASCII versions return a ASCII strings that are puny-code encoded,
1607 * suitable for, for example, header values. The UTF versions return strings
1608 * containing international characters.
1609 *
1610 * @pre aPrincipal/aOrigin must not be null.
1611 *
1612 * @note this should be used for HTML5 origin determination.
1613 */
1614 static nsresult GetASCIIOrigin(nsIPrincipal* aPrincipal,
1615 nsCString& aOrigin);
1616 static nsresult GetASCIIOrigin(nsIURI* aURI, nsCString& aOrigin);
1617 static nsresult GetUTFOrigin(nsIPrincipal* aPrincipal,
1618 nsString& aOrigin);
1619 static nsresult GetUTFOrigin(nsIURI* aURI, nsString& aOrigin);
1620 static void GetUTFNonNullOrigin(nsIURI* aURI, nsString& aOrigin);
1622 /**
1623 * This method creates and dispatches "command" event, which implements
1624 * nsIDOMXULCommandEvent.
1625 * If aShell is not null, dispatching goes via
1626 * nsIPresShell::HandleDOMEventWithTarget.
1627 */
1628 static nsresult DispatchXULCommand(nsIContent* aTarget,
1629 bool aTrusted,
1630 nsIDOMEvent* aSourceEvent = nullptr,
1631 nsIPresShell* aShell = nullptr,
1632 bool aCtrl = false,
1633 bool aAlt = false,
1634 bool aShift = false,
1635 bool aMeta = false);
1637 /**
1638 * Gets the nsIDocument given the script context. Will return nullptr on failure.
1639 *
1640 * @param aScriptContext the script context to get the document for; can be null
1641 *
1642 * @return the document associated with the script context
1643 */
1644 static nsIDocument*
1645 GetDocumentFromScriptContext(nsIScriptContext* aScriptContext);
1647 static bool CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel, bool aAllowIfInheritsPrincipal);
1649 /**
1650 * The method checks whether the caller can access native anonymous content.
1651 * If there is no JS in the stack or privileged JS is running, this
1652 * method returns true, otherwise false.
1653 */
1654 static bool CanAccessNativeAnon();
1656 MOZ_WARN_UNUSED_RESULT
1657 static nsresult WrapNative(JSContext *cx, nsISupports *native,
1658 const nsIID* aIID, JS::MutableHandle<JS::Value> vp,
1659 bool aAllowWrapping = true)
1660 {
1661 return WrapNative(cx, native, nullptr, aIID, vp, aAllowWrapping);
1662 }
1664 // Same as the WrapNative above, but use this one if aIID is nsISupports' IID.
1665 MOZ_WARN_UNUSED_RESULT
1666 static nsresult WrapNative(JSContext *cx, nsISupports *native,
1667 JS::MutableHandle<JS::Value> vp,
1668 bool aAllowWrapping = true)
1669 {
1670 return WrapNative(cx, native, nullptr, nullptr, vp, aAllowWrapping);
1671 }
1673 MOZ_WARN_UNUSED_RESULT
1674 static nsresult WrapNative(JSContext *cx, nsISupports *native,
1675 nsWrapperCache *cache,
1676 JS::MutableHandle<JS::Value> vp,
1677 bool aAllowWrapping = true)
1678 {
1679 return WrapNative(cx, native, cache, nullptr, vp, aAllowWrapping);
1680 }
1682 /**
1683 * Creates an arraybuffer from a binary string.
1684 */
1685 static nsresult CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
1686 JSObject** aResult);
1688 static nsresult CreateBlobBuffer(JSContext* aCx,
1689 const nsACString& aData,
1690 JS::MutableHandle<JS::Value> aBlob);
1692 static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
1694 /**
1695 * Strip all \n, \r and nulls from the given string
1696 * @param aString the string to remove newlines from [in/out]
1697 */
1698 static void RemoveNewlines(nsString &aString);
1700 /**
1701 * Convert Windows and Mac platform linebreaks to \n.
1702 * @param aString the string to convert the newlines inside [in/out]
1703 */
1704 static void PlatformToDOMLineBreaks(nsString &aString);
1706 /**
1707 * Populates aResultString with the contents of the string-buffer aBuf, up
1708 * to aBuf's null-terminator. aBuf must not be null. Ownership of the string
1709 * is not transferred.
1710 */
1711 static void PopulateStringFromStringBuffer(nsStringBuffer* aBuf,
1712 nsAString& aResultString);
1714 static bool IsHandlingKeyBoardEvent()
1715 {
1716 return sIsHandlingKeyBoardEvent;
1717 }
1719 static void SetIsHandlingKeyBoardEvent(bool aHandling)
1720 {
1721 sIsHandlingKeyBoardEvent = aHandling;
1722 }
1724 /**
1725 * Utility method for getElementsByClassName. aRootNode is the node (either
1726 * document or element), which getElementsByClassName was called on.
1727 */
1728 static already_AddRefed<nsContentList>
1729 GetElementsByClassName(nsINode* aRootNode, const nsAString& aClasses)
1730 {
1731 NS_PRECONDITION(aRootNode, "Must have root node");
1733 return NS_GetFuncStringHTMLCollection(aRootNode, MatchClassNames,
1734 DestroyClassNameArray,
1735 AllocClassMatchingInfo,
1736 aClasses);
1737 }
1739 /**
1740 * Returns a presshell for this document, if there is one. This will be
1741 * aDoc's direct presshell if there is one, otherwise we'll look at all
1742 * ancestor documents to try to find a presshell, so for example this can
1743 * still find a presshell for documents in display:none frames that have
1744 * no presentation. So you have to be careful how you use this presshell ---
1745 * getting generic data like a device context or widget from it is OK, but it
1746 * might not be this document's actual presentation.
1747 */
1748 static nsIPresShell* FindPresShellForDocument(const nsIDocument* aDoc);
1750 /**
1751 * Returns the widget for this document if there is one. Looks at all ancestor
1752 * documents to try to find a widget, so for example this can still find a
1753 * widget for documents in display:none frames that have no presentation.
1754 */
1755 static nsIWidget* WidgetForDocument(const nsIDocument* aDoc);
1757 /**
1758 * Returns a layer manager to use for the given document. Basically we
1759 * look up the document hierarchy for the first document which has
1760 * a presentation with an associated widget, and use that widget's
1761 * layer manager.
1762 *
1763 * @param aDoc the document for which to return a layer manager.
1764 * @param aAllowRetaining an outparam that states whether the returned
1765 * layer manager should be used for retained layers
1766 */
1767 static already_AddRefed<mozilla::layers::LayerManager>
1768 LayerManagerForDocument(const nsIDocument *aDoc, bool *aAllowRetaining = nullptr);
1770 /**
1771 * Returns a layer manager to use for the given document. Basically we
1772 * look up the document hierarchy for the first document which has
1773 * a presentation with an associated widget, and use that widget's
1774 * layer manager. In addition to the normal layer manager lookup this will
1775 * specifically request a persistent layer manager. This means that the layer
1776 * manager is expected to remain the layer manager for the document in the
1777 * forseeable future. This function should be used carefully as it may change
1778 * the document's layer manager.
1779 *
1780 * @param aDoc the document for which to return a layer manager.
1781 * @param aAllowRetaining an outparam that states whether the returned
1782 * layer manager should be used for retained layers
1783 */
1784 static already_AddRefed<mozilla::layers::LayerManager>
1785 PersistentLayerManagerForDocument(nsIDocument *aDoc, bool *aAllowRetaining = nullptr);
1787 /**
1788 * Determine whether a content node is focused or not,
1789 *
1790 * @param aContent the content node to check
1791 * @return true if the content node is focused, false otherwise.
1792 */
1793 static bool IsFocusedContent(const nsIContent *aContent);
1795 /**
1796 * Returns true if the DOM full-screen API is enabled.
1797 */
1798 static bool IsFullScreenApiEnabled();
1800 /**
1801 * Returns true if requests for full-screen are allowed in the current
1802 * context. Requests are only allowed if the user initiated them (like with
1803 * a mouse-click or key press), unless this check has been disabled by
1804 * setting the pref "full-screen-api.allow-trusted-requests-only" to false.
1805 */
1806 static bool IsRequestFullScreenAllowed();
1808 /**
1809 * Returns true if the DOM fullscreen API is restricted to content only.
1810 * This mirrors the pref "full-screen-api.content-only". If this is true,
1811 * fullscreen requests in chrome are denied, and fullscreen requests in
1812 * content stop percolating upwards before they reach chrome documents.
1813 * That is, when an element in content requests fullscreen, only its
1814 * containing frames that are in content are also made fullscreen, not
1815 * the containing frame in the chrome document.
1816 *
1817 * Note if the fullscreen API is running in content only mode then multiple
1818 * branches of a doctree can be fullscreen at the same time, but no fullscreen
1819 * document will have a common ancestor with another fullscreen document
1820 * that is also fullscreen (since the only common ancestor they can have
1821 * is the chrome document, and that can't be fullscreen). i.e. multiple
1822 * child documents of the chrome document can be fullscreen, but the chrome
1823 * document won't be fullscreen.
1824 *
1825 * Making the fullscreen API content only is useful on platforms where we
1826 * still want chrome to be visible or accessible while content is
1827 * fullscreen, like on Windows 8 in Metro mode.
1828 *
1829 * Note that if the fullscreen API is content only, chrome can still go
1830 * fullscreen by setting the "fullScreen" attribute on its XUL window.
1831 */
1832 static bool IsFullscreenApiContentOnly();
1834 /**
1835 * Returns true if the idle observers API is enabled.
1836 */
1837 static bool IsIdleObserverAPIEnabled() { return sIsIdleObserverAPIEnabled; }
1839 /*
1840 * Returns true if the performance timing APIs are enabled.
1841 */
1842 static bool IsPerformanceTimingEnabled()
1843 {
1844 return sIsPerformanceTimingEnabled;
1845 }
1847 /*
1848 * Returns true if the performance timing APIs are enabled.
1849 */
1850 static bool IsResourceTimingEnabled()
1851 {
1852 return sIsResourceTimingEnabled;
1853 }
1855 /**
1856 * Returns true if the doc tree branch which contains aDoc contains any
1857 * plugins which we don't control event dispatch for, i.e. do any plugins
1858 * in the same tab as this document receive key events outside of our
1859 * control? This always returns false on MacOSX.
1860 */
1861 static bool HasPluginWithUncontrolledEventDispatch(nsIDocument* aDoc);
1863 /**
1864 * Fire mutation events for changes caused by parsing directly into a
1865 * context node.
1866 *
1867 * @param aDoc the document of the node
1868 * @param aDest the destination node that got stuff appended to it
1869 * @param aOldChildCount the number of children the node had before parsing
1870 */
1871 static void FireMutationEventsForDirectParsing(nsIDocument* aDoc,
1872 nsIContent* aDest,
1873 int32_t aOldChildCount);
1875 /**
1876 * Returns true if the content is in a document and contains a plugin
1877 * which we don't control event dispatch for, i.e. do any plugins in this
1878 * doc tree receive key events outside of our control? This always returns
1879 * false on MacOSX.
1880 */
1881 static bool HasPluginWithUncontrolledEventDispatch(nsIContent* aContent);
1883 /**
1884 * Returns the document that is the closest ancestor to aDoc that is
1885 * fullscreen. If aDoc is fullscreen this returns aDoc. If aDoc is not
1886 * fullscreen and none of aDoc's ancestors are fullscreen this returns
1887 * nullptr.
1888 */
1889 static nsIDocument* GetFullscreenAncestor(nsIDocument* aDoc);
1891 /**
1892 * Returns true if aWin and the current pointer lock document
1893 * have common scriptable top window.
1894 */
1895 static bool IsInPointerLockContext(nsIDOMWindow* aWin);
1897 /**
1898 * Returns the time limit on handling user input before
1899 * EventStateManager::IsHandlingUserInput() stops returning true.
1900 * This enables us to detect long running user-generated event handlers.
1901 */
1902 static TimeDuration HandlingUserInputTimeout();
1904 static void GetShiftText(nsAString& text);
1905 static void GetControlText(nsAString& text);
1906 static void GetMetaText(nsAString& text);
1907 static void GetOSText(nsAString& text);
1908 static void GetAltText(nsAString& text);
1909 static void GetModifierSeparatorText(nsAString& text);
1911 /**
1912 * Returns if aContent has a tabbable subdocument.
1913 * A sub document isn't tabbable when it's a zombie document.
1914 *
1915 * @param aElement element to test.
1916 *
1917 * @return Whether the subdocument is tabbable.
1918 */
1919 static bool IsSubDocumentTabbable(nsIContent* aContent);
1921 /**
1922 * Returns if aNode ignores user focus.
1923 *
1924 * @param aNode node to test
1925 *
1926 * @return Whether the node ignores user focus.
1927 */
1928 static bool IsUserFocusIgnored(nsINode* aNode);
1930 /**
1931 * Returns if aContent has the 'scrollgrab' property.
1932 * aContent may be null (in this case false is returned).
1933 */
1934 static bool HasScrollgrab(nsIContent* aContent);
1936 /**
1937 * Flushes the layout tree (recursively)
1938 *
1939 * @param aWindow the window the flush should start at
1940 *
1941 */
1942 static void FlushLayoutForTree(nsIDOMWindow* aWindow);
1944 /**
1945 * Returns true if content with the given principal is allowed to use XUL
1946 * and XBL and false otherwise.
1947 */
1948 static bool AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal);
1950 /**
1951 * Perform cleanup that's appropriate for XPCOM shutdown.
1952 */
1953 static void XPCOMShutdown();
1955 enum ContentViewerType
1956 {
1957 TYPE_UNSUPPORTED,
1958 TYPE_CONTENT,
1959 TYPE_PLUGIN,
1960 TYPE_UNKNOWN
1961 };
1963 static already_AddRefed<nsIDocumentLoaderFactory>
1964 FindInternalContentViewer(const char* aType,
1965 ContentViewerType* aLoaderType = nullptr);
1967 /**
1968 * This helper method returns true if the aPattern pattern matches aValue.
1969 * aPattern should not contain leading and trailing slashes (/).
1970 * The pattern has to match the entire value not just a subset.
1971 * aDocument must be a valid pointer (not null).
1972 *
1973 * This is following the HTML5 specification:
1974 * http://dev.w3.org/html5/spec/forms.html#attr-input-pattern
1975 *
1976 * WARNING: This method mutates aPattern and aValue!
1977 *
1978 * @param aValue the string to check.
1979 * @param aPattern the string defining the pattern.
1980 * @param aDocument the owner document of the element.
1981 * @result whether the given string is matches the pattern.
1982 */
1983 static bool IsPatternMatching(nsAString& aValue, nsAString& aPattern,
1984 nsIDocument* aDocument);
1986 /**
1987 * Calling this adds support for
1988 * ontouch* event handler DOM attributes.
1989 */
1990 static void InitializeTouchEventTable();
1992 /**
1993 * Test whether the given URI always inherits a security context
1994 * from the document it comes from.
1995 */
1996 static nsresult URIInheritsSecurityContext(nsIURI *aURI, bool *aResult);
1998 /**
1999 * Set the given principal as the owner of the given channel, if
2000 * needed. aURI must be the URI of aChannel. aPrincipal may be
2001 * null. If aSetUpForAboutBlank is true, then about:blank will get
2002 * the principal set up on it. If aForceOwner is true, the owner
2003 * will be set on the channel, even if the principal can be determined
2004 * from the channel.
2005 * The return value is whether the principal was set up as the owner
2006 * of the channel.
2007 */
2008 static bool SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
2009 nsIChannel* aChannel,
2010 nsIURI* aURI,
2011 bool aSetUpForAboutBlank,
2012 bool aForceOwner = false);
2014 static nsresult Btoa(const nsAString& aBinaryData,
2015 nsAString& aAsciiBase64String);
2017 static nsresult Atob(const nsAString& aAsciiString,
2018 nsAString& aBinaryData);
2020 /**
2021 * Returns whether the input element passed in parameter has the autocomplete
2022 * functionality enabled. It is taking into account the form owner.
2023 * NOTE: the caller has to make sure autocomplete makes sense for the
2024 * element's type.
2025 *
2026 * @param aInput the input element to check. NOTE: aInput can't be null.
2027 * @return whether the input element has autocomplete enabled.
2028 */
2029 static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput);
2031 /**
2032 * This will parse aSource, to extract the value of the pseudo attribute
2033 * with the name specified in aName. See
2034 * http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
2035 * which is used to parse aSource.
2036 *
2037 * @param aSource the string to parse
2038 * @param aName the name of the attribute to get the value for
2039 * @param aValue [out] the value for the attribute with name specified in
2040 * aAttribute. Empty if the attribute isn't present.
2041 * @return true if the attribute exists and was successfully parsed.
2042 * false if the attribute doesn't exist, or has a malformed
2043 * value, such as an unknown or unterminated entity.
2044 */
2045 static bool GetPseudoAttributeValue(const nsString& aSource, nsIAtom *aName,
2046 nsAString& aValue);
2048 /**
2049 * Returns true if the language name is a version of JavaScript and
2050 * false otherwise
2051 */
2052 static bool IsJavaScriptLanguage(const nsString& aName);
2054 /**
2055 * Returns the JSVersion for a string of the form '1.n', n = 0, ..., 8, and
2056 * JSVERSION_UNKNOWN for other strings.
2057 */
2058 static JSVersion ParseJavascriptVersion(const nsAString& aVersionStr);
2060 static bool IsJavascriptMIMEType(const nsAString& aMIMEType);
2062 static void SplitMimeType(const nsAString& aValue, nsString& aType,
2063 nsString& aParams);
2065 /**
2066 * Function checks if the user is idle.
2067 *
2068 * @param aRequestedIdleTimeInMS The idle observer's requested idle time.
2069 * @param aUserIsIdle boolean indicating if the user
2070 * is currently idle or not. *
2071 * @return NS_OK NS_OK returned if the requested idle service and
2072 * the current idle time were successfully obtained.
2073 * NS_ERROR_FAILURE returned if the the requested
2074 * idle service or the current idle were not obtained.
2075 */
2076 static nsresult IsUserIdle(uint32_t aRequestedIdleTimeInMS, bool* aUserIsIdle);
2078 /**
2079 * Takes a selection, and a text control element (<input> or <textarea>), and
2080 * returns the offsets in the text content corresponding to the selection.
2081 * The selection's anchor and focus must both be in the root node passed or a
2082 * descendant.
2083 *
2084 * @param aSelection Selection to check
2085 * @param aRoot Root <input> or <textarea> element
2086 * @param aOutStartOffset Output start offset
2087 * @param aOutEndOffset Output end offset
2088 */
2089 static void GetSelectionInTextControl(mozilla::dom::Selection* aSelection,
2090 Element* aRoot,
2091 int32_t& aOutStartOffset,
2092 int32_t& aOutEndOffset);
2094 /**
2095 * Takes a frame for anonymous content within a text control (<input> or
2096 * <textarea>), and returns an offset in the text content, adjusted for a
2097 * trailing <br> frame.
2098 *
2099 * @param aOffsetFrame Frame for the text content in which the offset
2100 * lies
2101 * @param aOffset Offset as calculated by GetContentOffsetsFromPoint
2102 * @param aOutOffset Output adjusted offset
2103 *
2104 * @see GetSelectionInTextControl for the original basis of this function.
2105 */
2106 static int32_t GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame,
2107 int32_t aOffset);
2109 static nsIEditor* GetHTMLEditor(nsPresContext* aPresContext);
2111 /**
2112 * Check whether a spec feature/version is supported.
2113 * @param aObject the object, which should support the feature,
2114 * for example nsIDOMNode or nsIDOMDOMImplementation
2115 * @param aFeature the feature ("Views", "Core", "HTML", "Range" ...)
2116 * @param aVersion the version ("1.0", "2.0", ...)
2117 * @return whether the feature is supported or not
2118 */
2119 static bool InternalIsSupported(nsISupports* aObject,
2120 const nsAString& aFeature,
2121 const nsAString& aVersion);
2123 /**
2124 * Return true if the browser.dom.window.dump.enabled pref is set.
2125 */
2126 static bool DOMWindowDumpEnabled();
2128 /**
2129 * Returns whether a content is an insertion point for XBL
2130 * bindings or web components ShadowRoot. In web components,
2131 * this corresponds to a <content> element that participates
2132 * in node distribution. In XBL this corresponds to an
2133 * <xbl:children> element in anonymous content.
2134 *
2135 * @param aContent The content to test for being an insertion point.
2136 */
2137 static bool IsContentInsertionPoint(const nsIContent* aContent);
2139 private:
2140 static bool InitializeEventTable();
2142 static nsresult EnsureStringBundle(PropertiesFile aFile);
2144 static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
2145 nsIPrincipal* aPrincipal);
2147 static nsresult WrapNative(JSContext *cx, nsISupports *native,
2148 nsWrapperCache *cache, const nsIID* aIID,
2149 JS::MutableHandle<JS::Value> vp,
2150 bool aAllowWrapping);
2152 static nsresult DispatchEvent(nsIDocument* aDoc,
2153 nsISupports* aTarget,
2154 const nsAString& aEventName,
2155 bool aCanBubble,
2156 bool aCancelable,
2157 bool aTrusted,
2158 bool *aDefaultAction = nullptr);
2160 static void InitializeModifierStrings();
2162 static void DropFragmentParsers();
2164 static bool MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
2165 nsIAtom* aAtom, void* aData);
2166 static void DestroyClassNameArray(void* aData);
2167 static void* AllocClassMatchingInfo(nsINode* aRootNode,
2168 const nsString* aClasses);
2170 static nsIXPConnect *sXPConnect;
2172 static nsIScriptSecurityManager *sSecurityManager;
2174 static nsIParserService *sParserService;
2176 static nsNameSpaceManager *sNameSpaceManager;
2178 static nsIIOService *sIOService;
2180 static bool sImgLoaderInitialized;
2181 static void InitImgLoader();
2183 // The following four members are initialized lazily
2184 static imgLoader* sImgLoader;
2185 static imgLoader* sPrivateImgLoader;
2186 static imgICache* sImgCache;
2187 static imgICache* sPrivateImgCache;
2189 static nsIConsoleService* sConsoleService;
2191 static nsDataHashtable<nsISupportsHashKey, EventNameMapping>* sAtomEventTable;
2192 static nsDataHashtable<nsStringHashKey, EventNameMapping>* sStringEventTable;
2193 static nsCOMArray<nsIAtom>* sUserDefinedEvents;
2195 static nsIStringBundleService* sStringBundleService;
2196 static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
2198 static nsIContentPolicy* sContentPolicyService;
2199 static bool sTriedToGetContentPolicy;
2201 static nsILineBreaker* sLineBreaker;
2202 static nsIWordBreaker* sWordBreaker;
2204 static nsIBidiKeyboard* sBidiKeyboard;
2206 static bool sInitialized;
2207 static uint32_t sScriptBlockerCount;
2208 #ifdef DEBUG
2209 static uint32_t sDOMNodeRemovedSuppressCount;
2210 #endif
2211 static uint32_t sMicroTaskLevel;
2212 // Not an nsCOMArray because removing elements from those is slower
2213 static nsTArray< nsCOMPtr<nsIRunnable> >* sBlockedScriptRunners;
2214 static uint32_t sRunnersCountAtFirstBlocker;
2215 static uint32_t sScriptBlockerCountWhereRunnersPrevented;
2217 static nsIInterfaceRequestor* sSameOriginChecker;
2219 static bool sIsHandlingKeyBoardEvent;
2220 static bool sAllowXULXBL_for_file;
2221 static bool sIsFullScreenApiEnabled;
2222 static bool sTrustedFullScreenOnly;
2223 static bool sFullscreenApiIsContentOnly;
2224 static uint32_t sHandlingInputTimeout;
2225 static bool sIsIdleObserverAPIEnabled;
2226 static bool sIsPerformanceTimingEnabled;
2227 static bool sIsResourceTimingEnabled;
2229 static nsHtml5StringParser* sHTMLFragmentParser;
2230 static nsIParser* sXMLFragmentParser;
2231 static nsIFragmentContentSink* sXMLFragmentSink;
2233 /**
2234 * True if there's a fragment parser activation on the stack.
2235 */
2236 static bool sFragmentParsingActive;
2238 static nsString* sShiftText;
2239 static nsString* sControlText;
2240 static nsString* sMetaText;
2241 static nsString* sOSText;
2242 static nsString* sAltText;
2243 static nsString* sModifierSeparator;
2245 #if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
2246 static bool sDOMWindowDumpEnabled;
2247 #endif
2248 };
2250 class MOZ_STACK_CLASS nsAutoScriptBlocker {
2251 public:
2252 nsAutoScriptBlocker(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
2253 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
2254 nsContentUtils::AddScriptBlocker();
2255 }
2256 ~nsAutoScriptBlocker() {
2257 nsContentUtils::RemoveScriptBlocker();
2258 }
2259 private:
2260 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
2261 };
2263 class MOZ_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved :
2264 public nsAutoScriptBlocker {
2265 public:
2266 nsAutoScriptBlockerSuppressNodeRemoved() {
2267 #ifdef DEBUG
2268 ++nsContentUtils::sDOMNodeRemovedSuppressCount;
2269 #endif
2270 }
2271 ~nsAutoScriptBlockerSuppressNodeRemoved() {
2272 #ifdef DEBUG
2273 --nsContentUtils::sDOMNodeRemovedSuppressCount;
2274 #endif
2275 }
2276 };
2278 class MOZ_STACK_CLASS nsAutoMicroTask
2279 {
2280 public:
2281 nsAutoMicroTask()
2282 {
2283 nsContentUtils::EnterMicroTask();
2284 }
2285 ~nsAutoMicroTask()
2286 {
2287 nsContentUtils::LeaveMicroTask();
2288 }
2289 };
2291 namespace mozilla {
2292 namespace dom {
2294 class TreeOrderComparator {
2295 public:
2296 bool Equals(nsINode* aElem1, nsINode* aElem2) const {
2297 return aElem1 == aElem2;
2298 }
2299 bool LessThan(nsINode* aElem1, nsINode* aElem2) const {
2300 return nsContentUtils::PositionIsBefore(aElem1, aElem2);
2301 }
2302 };
2304 } // namespace dom
2305 } // namespace mozilla
2307 #define NS_INTERFACE_MAP_ENTRY_TEAROFF(_interface, _allocator) \
2308 if (aIID.Equals(NS_GET_IID(_interface))) { \
2309 foundInterface = static_cast<_interface *>(_allocator); \
2310 if (!foundInterface) { \
2311 *aInstancePtr = nullptr; \
2312 return NS_ERROR_OUT_OF_MEMORY; \
2313 } \
2314 } else
2316 /*
2317 * In the following helper macros we exploit the fact that the result of a
2318 * series of additions will not be finite if any one of the operands in the
2319 * series is not finite.
2320 */
2321 #define NS_ENSURE_FINITE(f, rv) \
2322 if (!NS_finite(f)) { \
2323 return (rv); \
2324 }
2326 #define NS_ENSURE_FINITE2(f1, f2, rv) \
2327 if (!NS_finite((f1)+(f2))) { \
2328 return (rv); \
2329 }
2331 #define NS_ENSURE_FINITE4(f1, f2, f3, f4, rv) \
2332 if (!NS_finite((f1)+(f2)+(f3)+(f4))) { \
2333 return (rv); \
2334 }
2336 #define NS_ENSURE_FINITE5(f1, f2, f3, f4, f5, rv) \
2337 if (!NS_finite((f1)+(f2)+(f3)+(f4)+(f5))) { \
2338 return (rv); \
2339 }
2341 #define NS_ENSURE_FINITE6(f1, f2, f3, f4, f5, f6, rv) \
2342 if (!NS_finite((f1)+(f2)+(f3)+(f4)+(f5)+(f6))) { \
2343 return (rv); \
2344 }
2346 // Deletes a linked list iteratively to avoid blowing up the stack (bug 460444).
2347 #define NS_CONTENT_DELETE_LIST_MEMBER(type_, ptr_, member_) \
2348 { \
2349 type_ *cur = (ptr_)->member_; \
2350 (ptr_)->member_ = nullptr; \
2351 while (cur) { \
2352 type_ *next = cur->member_; \
2353 cur->member_ = nullptr; \
2354 delete cur; \
2355 cur = next; \
2356 } \
2357 }
2359 #endif /* nsContentUtils_h___ */