From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- dom/base/nsContentUtils.h | 2963 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2963 insertions(+) create mode 100644 dom/base/nsContentUtils.h (limited to 'dom/base/nsContentUtils.h') diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h new file mode 100644 index 000000000..278fbd008 --- /dev/null +++ b/dom/base/nsContentUtils.h @@ -0,0 +1,2963 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A namespace class for static content utilities. */ + +#ifndef nsContentUtils_h___ +#define nsContentUtils_h___ + +#if defined(XP_WIN) +#include +#endif + +#if defined(SOLARIS) +#include +#endif + +#include "js/TypeDecls.h" +#include "js/Value.h" +#include "js/RootingAPI.h" +#include "mozilla/EventForwards.h" +#include "mozilla/GuardObjects.h" +#include "mozilla/TimeStamp.h" +#include "nsContentListDeclarations.h" +#include "nsMathUtils.h" +#include "nsTArrayForwardDeclare.h" +#include "Units.h" +#include "mozilla/dom/AutocompleteInfoBinding.h" +#include "mozilla/dom/BindingDeclarations.h" // For CallerType +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/FloatingPoint.h" +#include "mozilla/net/ReferrerPolicy.h" +#include "mozilla/Logging.h" +#include "mozilla/NotNull.h" +#include "nsIContentPolicy.h" +#include "nsIDocument.h" +#include "nsPIDOMWindow.h" + +#if defined(XP_WIN) +// Undefine LoadImage to prevent naming conflict with Windows. +#undef LoadImage +#endif + +class imgICache; +class imgIContainer; +class imgINotificationObserver; +class imgIRequest; +class imgLoader; +class imgRequestProxy; +class nsAutoScriptBlockerSuppressNodeRemoved; +class nsHtml5StringParser; +class nsIChannel; +class nsIConsoleService; +class nsIContent; +class nsIContentPolicy; +class nsIContentSecurityPolicy; +class nsIDocShellTreeItem; +class nsIDocumentLoaderFactory; +class nsIDOMDocument; +class nsIDOMDocumentFragment; +class nsIDOMEvent; +class nsIDOMHTMLInputElement; +class nsIDOMKeyEvent; +class nsIDOMNode; +class nsIDragSession; +class nsIEditor; +class nsIFragmentContentSink; +class nsIFrame; +class nsIImageLoadingContent; +class nsIInterfaceRequestor; +class nsIIOService; +class nsILineBreaker; +class nsILoadGroup; +class nsIMessageBroadcaster; +class nsNameSpaceManager; +class nsIObserver; +class nsIParser; +class nsIParserService; +class nsIPresShell; +class nsIPrincipal; +class nsIRequest; +class nsIRunnable; +class nsIScriptContext; +class nsIScriptSecurityManager; +class nsIStringBundle; +class nsIStringBundleService; +class nsISupportsHashKey; +class nsIURI; +class nsIUUIDGenerator; +class nsIWidget; +class nsIWordBreaker; +class nsIXPConnect; +class nsNodeInfoManager; +class nsPIDOMWindowInner; +class nsPIDOMWindowOuter; +class nsPresContext; +class nsStringBuffer; +class nsStringHashKey; +class nsTextFragment; +class nsView; +class nsViewportInfo; +class nsWrapperCache; +class nsAttrValue; +class nsITransferable; +class nsPIWindowRoot; +class nsIWindowProvider; + +struct JSRuntime; + +template class nsCOMArray; +template class nsDataHashtable; +template class nsRefPtrHashtable; +template class nsReadingIterator; + +namespace mozilla { +class ErrorResult; +class EventListenerManager; + +namespace dom { +struct CustomElementDefinition; +class DocumentFragment; +class Element; +class EventTarget; +class IPCDataTransfer; +class IPCDataTransferItem; +struct LifecycleCallbackArgs; +class NodeInfo; +class nsIContentChild; +class nsIContentParent; +class TabChild; +class Selection; +class TabParent; +} // namespace dom + +namespace ipc { +class Shmem; +class IShmemAllocator; +} + +namespace gfx { +class DataSourceSurface; +} // namespace gfx + +namespace layers { +class LayerManager; +} // namespace layers + +} // namespace mozilla + +class nsIBidiKeyboard; + +extern const char kLoadAsData[]; + +// Stolen from nsReadableUtils, but that's OK, since we can declare the same +// name multiple times. +const nsAFlatString& EmptyString(); +const nsAFlatCString& EmptyCString(); + +enum EventNameType { + EventNameType_None = 0x0000, + EventNameType_HTML = 0x0001, + EventNameType_XUL = 0x0002, + EventNameType_SVGGraphic = 0x0004, // svg graphic elements + EventNameType_SVGSVG = 0x0008, // the svg element + EventNameType_SMIL = 0x0010, // smil elements + EventNameType_HTMLBodyOrFramesetOnly = 0x0020, + + EventNameType_HTMLXUL = 0x0003, + EventNameType_All = 0xFFFF +}; + +struct EventNameMapping +{ + // This holds pointers to nsGkAtoms members, and is therefore safe as a + // non-owning reference. + nsIAtom* MOZ_NON_OWNING_REF mAtom; + int32_t mType; + mozilla::EventMessage mMessage; + mozilla::EventClassID mEventClassID; + // True if mAtom is possibly used by special SVG/SMIL events, but + // mMessage is eUnidentifiedEvent. See EventNameList.h + bool mMaybeSpecialSVGorSMILEvent; +}; + +typedef bool (*CallOnRemoteChildFunction) (mozilla::dom::TabParent* aTabParent, + void* aArg); + +class nsContentUtils +{ + friend class nsAutoScriptBlockerSuppressNodeRemoved; + typedef mozilla::dom::Element Element; + typedef mozilla::TimeDuration TimeDuration; + +public: + static nsresult Init(); + + static bool IsCallerChrome(); + static bool ThreadsafeIsCallerChrome(); + static bool IsCallerContentXBL(); + + // In the traditional Gecko architecture, both C++ code and untrusted JS code + // needed to rely on the same XPCOM method/getter/setter to get work done. + // This required lots of security checks in the various exposed methods, which + // in turn created difficulty in determining whether the caller was script + // (whose access needed to be checked) and internal C++ platform code (whose + // access did not need to be checked). To address this problem, Gecko had a + // convention whereby the absence of script on the stack was interpretted as + // "System Caller" and always granted unfettered access. + // + // Unfortunately, this created a bunch of footguns. For example, when the + // implementation of a DOM method wanted to perform a privileged + // sub-operation, it needed to "hide" the presence of script on the stack in + // order for that sub-operation to be allowed. Additionally, if script could + // trigger an API entry point to be invoked in some asynchronous way without + // script on the stack, it could potentially perform privilege escalation. + // + // In the modern world, untrusted script should interact with the platform + // exclusively over WebIDL APIs, and platform code has a lot more flexibility + // in deciding whether or not to use XPCOM. This gives us the flexibility to + // do something better. + // + // Going forward, APIs should be designed such that any security checks that + // ask the question "is my caller allowed to do this?" should live in WebIDL + // API entry points, with a separate method provided for internal callers + // that just want to get the job done. + // + // To enforce this and catch bugs, nsContentUtils::SubjectPrincipal will crash + // if it is invoked without script on the stack. To land that transition, it + // was necessary to go through and whitelist a bunch of callers that were + // depending on the old behavior. Those callers should be fixed up, and these + // methods should not be used by new code without review from bholley or bz. + static bool LegacyIsCallerNativeCode() { return !GetCurrentJSContext(); } + static bool LegacyIsCallerChromeOrNativeCode() { return LegacyIsCallerNativeCode() || IsCallerChrome(); } + static nsIPrincipal* SubjectPrincipalOrSystemIfNativeCaller() + { + if (!GetCurrentJSContext()) { + return GetSystemPrincipal(); + } + return SubjectPrincipal(); + } + + static bool LookupBindingMember(JSContext* aCx, nsIContent *aContent, + JS::Handle aId, + JS::MutableHandle aDesc); + + // Check whether we should avoid leaking distinguishing information to JS/CSS. + static bool ShouldResistFingerprinting(nsIDocShell* aDocShell); + + /** + * Returns the parent node of aChild crossing document boundaries. + * Uses the parent node in the composed document. + */ + static nsINode* GetCrossDocParentNode(nsINode* aChild); + + /** + * Do not ever pass null pointers to this method. If one of your + * nsIContents is null, you have to decide for yourself what + * "IsDescendantOf" really means. + * + * @param aPossibleDescendant node to test for being a descendant of + * aPossibleAncestor + * @param aPossibleAncestor node to test for being an ancestor of + * aPossibleDescendant + * @return true if aPossibleDescendant is a descendant of + * aPossibleAncestor (or is aPossibleAncestor). false + * otherwise. + */ + static bool ContentIsDescendantOf(const nsINode* aPossibleDescendant, + const nsINode* aPossibleAncestor); + + /** + * Similar to ContentIsDescendantOf, except will treat an HTMLTemplateElement + * or ShadowRoot as an ancestor of things in the corresponding DocumentFragment. + * See the concept of "host-including inclusive ancestor" in the DOM + * specification. + */ + static bool ContentIsHostIncludingDescendantOf( + const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor); + + /** + * Similar to ContentIsDescendantOf except it crosses document boundaries, + * this function uses ancestor/descendant relations in the composed document + * (see shadow DOM spec). + */ + static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant, + nsINode* aPossibleAncestor); + + /* + * This method fills the |aArray| with all ancestor nodes of |aNode| + * including |aNode| at the zero index. + */ + static nsresult GetAncestors(nsINode* aNode, + nsTArray& aArray); + + /* + * This method fills |aAncestorNodes| with all ancestor nodes of |aNode| + * including |aNode| (QI'd to nsIContent) at the zero index. + * For each ancestor, there is a corresponding element in |aAncestorOffsets| + * which is the IndexOf the child in relation to its parent. + * + * This method just sucks. + */ + static nsresult GetAncestorsAndOffsets(nsIDOMNode* aNode, + int32_t aOffset, + nsTArray* aAncestorNodes, + nsTArray* aAncestorOffsets); + + /* + * The out parameter, |aCommonAncestor| will be the closest node, if any, + * to both |aNode| and |aOther| which is also an ancestor of each. + * Returns an error if the two nodes are disconnected and don't have + * a common ancestor. + */ + static nsresult GetCommonAncestor(nsIDOMNode *aNode, + nsIDOMNode *aOther, + nsIDOMNode** aCommonAncestor); + + /** + * Returns the common ancestor, if any, for two nodes. Returns null if the + * nodes are disconnected. + */ + static nsINode* GetCommonAncestor(nsINode* aNode1, + nsINode* aNode2); + + /** + * Returns true if aNode1 is before aNode2 in the same connected + * tree. + */ + static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2); + + /** + * Utility routine to compare two "points", where a point is a + * node/offset pair + * Returns -1 if point1 < point2, 1, if point1 > point2, + * 0 if error or if point1 == point2. + * NOTE! If the two nodes aren't in the same connected subtree, + * the result is 1, and the optional aDisconnected parameter + * is set to true. + */ + static int32_t ComparePoints(nsINode* aParent1, int32_t aOffset1, + nsINode* aParent2, int32_t aOffset2, + bool* aDisconnected = nullptr); + static int32_t ComparePoints(nsIDOMNode* aParent1, int32_t aOffset1, + nsIDOMNode* aParent2, int32_t aOffset2, + bool* aDisconnected = nullptr); + + /** + * Brute-force search of the element subtree rooted at aContent for + * an element with the given id. aId must be nonempty, otherwise + * this method may return nodes even if they have no id! + */ + static Element* MatchElementId(nsIContent *aContent, const nsAString& aId); + + /** + * Similar to above, but to be used if one already has an atom for the ID + */ + static Element* MatchElementId(nsIContent *aContent, const nsIAtom* aId); + + /** + * Reverses the document position flags passed in. + * + * @param aDocumentPosition The document position flags to be reversed. + * + * @return The reversed document position flags. + * + * @see nsIDOMNode + */ + static uint16_t ReverseDocumentPosition(uint16_t aDocumentPosition); + + /** + * Returns a subdocument for aDocument with a particular outer window ID. + * + * @param aDocument + * The document whose subdocuments will be searched. + * @param aOuterWindowID + * The outer window ID for the subdocument to be found. This must + * be a value greater than 0. + * @return nsIDocument* + * A pointer to the found nsIDocument. nullptr if the subdocument + * cannot be found, or if either aDocument or aOuterWindowId were + * invalid. If the outer window ID belongs to aDocument itself, this + * will return a pointer to aDocument. + */ + static nsIDocument* GetSubdocumentWithOuterWindowId(nsIDocument *aDocument, + uint64_t aOuterWindowId); + + static uint32_t CopyNewlineNormalizedUnicodeTo(const nsAString& aSource, + uint32_t aSrcOffset, + char16_t* aDest, + uint32_t aLength, + bool& aLastCharCR); + + static uint32_t CopyNewlineNormalizedUnicodeTo(nsReadingIterator& aSrcStart, const nsReadingIterator& aSrcEnd, nsAString& aDest); + + static const nsDependentSubstring TrimCharsInSet(const char* aSet, + const nsAString& aValue); + + template + static const nsDependentSubstring TrimWhitespace(const nsAString& aStr, + bool aTrimTrailing = true); + + /** + * Returns true if aChar is of class Ps, Pi, Po, Pf, or Pe. + */ + static bool IsFirstLetterPunctuation(uint32_t aChar); + static bool IsFirstLetterPunctuationAt(const nsTextFragment* aFrag, uint32_t aOffset); + + /** + * Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No + */ + static bool IsAlphanumeric(uint32_t aChar); + static bool IsAlphanumericAt(const nsTextFragment* aFrag, uint32_t aOffset); + + /* + * Is the character an HTML whitespace character? + * + * We define whitespace using the list in HTML5 and css3-selectors: + * U+0009, U+000A, U+000C, U+000D, U+0020 + * + * HTML 4.01 also lists U+200B (zero-width space). + */ + static bool IsHTMLWhitespace(char16_t aChar); + + /* + * Returns whether the character is an HTML whitespace (see IsHTMLWhitespace) + * or a nbsp character (U+00A0). + */ + static bool IsHTMLWhitespaceOrNBSP(char16_t aChar); + + /** + * Is the HTML local name a block element? + */ + static bool IsHTMLBlock(nsIContent* aContent); + + enum ParseHTMLIntegerResultFlags { + eParseHTMLInteger_NoFlags = 0, + eParseHTMLInteger_IsPercent = 1 << 0, + // eParseHTMLInteger_NonStandard is set if the string representation of the + // integer was not the canonical one (e.g. had extra leading '+' or '0'). + eParseHTMLInteger_NonStandard = 1 << 1, + eParseHTMLInteger_DidNotConsumeAllInput = 1 << 2, + // Set if one or more error flags were set. + eParseHTMLInteger_Error = 1 << 3, + eParseHTMLInteger_ErrorNoValue = 1 << 4, + eParseHTMLInteger_ErrorOverflow = 1 << 5 + }; + static int32_t ParseHTMLInteger(const nsAString& aValue, + ParseHTMLIntegerResultFlags *aResult); + + /** + * Parse a margin string of format 'top, right, bottom, left' into + * an nsIntMargin. + * + * @param aString the string to parse + * @param aResult the resulting integer + * @return whether the value could be parsed + */ + static bool ParseIntMarginValue(const nsAString& aString, nsIntMargin& aResult); + + /** + * Parse the value of the attribute according to the HTML5 + * spec as of April 16, 2012. + * + * @param aValue the value to parse + * @return 1 to 7, or 0 if the value couldn't be parsed + */ + static int32_t ParseLegacyFontSize(const nsAString& aValue); + + static void Shutdown(); + + /** + * Checks whether two nodes come from the same origin. + */ + static nsresult CheckSameOrigin(const nsINode* aTrustedNode, + nsIDOMNode* aUnTrustedNode); + static nsresult CheckSameOrigin(const nsINode* aTrustedNode, + const nsINode* unTrustedNode); + + // Check if the (JS) caller can access aNode. + static bool CanCallerAccess(nsIDOMNode *aNode); + static bool CanCallerAccess(nsINode* aNode); + + // Check if the (JS) caller can access aWindow. + // aWindow can be either outer or inner window. + static bool CanCallerAccess(nsPIDOMWindowInner* aWindow); + + /** + * GetDocumentFromCaller gets its document by looking at the last called + * function and finding the document that the function itself relates to. + * For example, consider two windows A and B in the same origin. B has a + * function which does something that ends up needing the current document. + * If a script in window A were to call B's function, GetDocumentFromCaller + * would find that function (in B) and return B's document. + * + * @return The document or null if no JS Context. + */ + static nsIDocument* GetDocumentFromCaller(); + + // Check if a node is in the document prolog, i.e. before the document + // element. + static bool InProlog(nsINode *aNode); + + static nsIParserService* GetParserService(); + + static nsNameSpaceManager* NameSpaceManager() + { + return sNameSpaceManager; + } + + static nsIIOService* GetIOService() + { + return sIOService; + } + + static nsIBidiKeyboard* GetBidiKeyboard(); + + /** + * Get the cache security manager service. Can return null if the layout + * module has been shut down. + */ + static nsIScriptSecurityManager* GetSecurityManager() + { + return sSecurityManager; + } + + // Returns the subject principal. Guaranteed to return non-null. May only + // be called when nsContentUtils is initialized. + static nsIPrincipal* SubjectPrincipal(); + + // Returns the prinipal of the given JS object. This may only be called on + // the main thread for objects from the main thread's JSRuntime. + static nsIPrincipal* ObjectPrincipal(JSObject* aObj); + + static nsresult GenerateStateKey(nsIContent* aContent, + const nsIDocument* aDocument, + nsACString& aKey); + + /** + * Create a new nsIURI from aSpec, using aBaseURI as the base. The + * origin charset of the new nsIURI will be the document charset of + * aDocument. + */ + static nsresult NewURIWithDocumentCharset(nsIURI** aResult, + const nsAString& aSpec, + nsIDocument* aDocument, + nsIURI* aBaseURI); + + /** + * Convert aInput (in encoding aEncoding) to UTF16 in aOutput. + * + * @param aEncoding the Gecko-canonical name of the encoding or the empty + * string (meaning UTF-8) + */ + static nsresult ConvertStringFromEncoding(const nsACString& aEncoding, + const nsACString& aInput, + nsAString& aOutput); + + /** + * Determine whether a buffer begins with a BOM for UTF-8, UTF-16LE, + * UTF-16BE + * + * @param aBuffer the buffer to check + * @param aLength the length of the buffer + * @param aCharset empty if not found + * @return boolean indicating whether a BOM was detected. + */ + static bool CheckForBOM(const unsigned char* aBuffer, uint32_t aLength, + nsACString& aCharset); + + /** + * Returns true if |aName| is a valid name to be registered via + * document.registerElement. + */ + static bool IsCustomElementName(nsIAtom* aName); + + static nsresult CheckQName(const nsAString& aQualifiedName, + bool aNamespaceAware = true, + const char16_t** aColon = nullptr); + + static nsresult SplitQName(const nsIContent* aNamespaceResolver, + const nsAFlatString& aQName, + int32_t *aNamespace, nsIAtom **aLocalName); + + static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI, + const nsAString& aQualifiedName, + nsNodeInfoManager* aNodeInfoManager, + uint16_t aNodeType, + mozilla::dom::NodeInfo** aNodeInfo); + + static void SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix, + nsIAtom **aTagName, int32_t *aNameSpaceID); + + // Get a permission-manager setting for the given principal and type. + // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is + // returned, otherwise true is returned. Always returns true for the + // system principal, and false for a null principal. + static bool IsSitePermAllow(nsIPrincipal* aPrincipal, const char* aType); + + // Get a permission-manager setting for the given principal and type. + // If the pref doesn't exist or if it isn't DENY_ACTION, false is + // returned, otherwise true is returned. Always returns false for the + // system principal, and true for a null principal. + static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const char* aType); + + // Get a permission-manager setting for the given principal and type. + // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is + // returned, otherwise true is returned. Always returns true for the + // system principal, and false for a null principal. + // This version checks the permission for an exact host match on + // the principal + static bool IsExactSitePermAllow(nsIPrincipal* aPrincipal, const char* aType); + + // Get a permission-manager setting for the given principal and type. + // If the pref doesn't exist or if it isn't DENY_ACTION, false is + // returned, otherwise true is returned. Always returns false for the + // system principal, and true for a null principal. + // This version checks the permission for an exact host match on + // the principal + static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal, const char* aType); + + // Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s. + static bool HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2); + + static nsILineBreaker* LineBreaker() + { + return sLineBreaker; + } + + static nsIWordBreaker* WordBreaker() + { + return sWordBreaker; + } + + /** + * Regster aObserver as a shutdown observer. A strong reference is held + * to aObserver until UnregisterShutdownObserver is called. + */ + static void RegisterShutdownObserver(nsIObserver* aObserver); + static void UnregisterShutdownObserver(nsIObserver* aObserver); + + /** + * @return true if aContent has an attribute aName in namespace aNameSpaceID, + * and the attribute value is non-empty. + */ + static bool HasNonEmptyAttr(const nsIContent* aContent, int32_t aNameSpaceID, + nsIAtom* aName); + + /** + * Method that gets the primary presContext for the node. + * + * @param aContent The content node. + * @return the presContext, or nullptr if the content is not in a document + * (if GetCurrentDoc returns nullptr) + */ + static nsPresContext* GetContextForContent(const nsIContent* aContent); + + /** + * Method to do security and content policy checks on the image URI + * + * @param aURI uri of the image to be loaded + * @param aContext the context the image is loaded in (eg an element) + * @param aLoadingDocument the document we belong to + * @param aLoadingPrincipal the principal doing the load + * @param [aContentPolicyType=nsIContentPolicy::TYPE_INTERNAL_IMAGE] (Optional) + * The CP content type to use + * @param aImageBlockingStatus the nsIContentPolicy blocking status for this + * image. This will be set even if a security check fails for the + * image, to some reasonable REJECT_* value. This out param will only + * be set if it's non-null. + * @return true if the load can proceed, or false if it is blocked. + * Note that aImageBlockingStatus, if set will always be an ACCEPT + * status if true is returned and always be a REJECT_* status if + * false is returned. + */ + static bool CanLoadImage(nsIURI* aURI, + nsISupports* aContext, + nsIDocument* aLoadingDocument, + nsIPrincipal* aLoadingPrincipal, + int16_t* aImageBlockingStatus = nullptr, + uint32_t aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE); + + /** + * Returns true if objects in aDocument shouldn't initiate image loads. + */ + static bool DocumentInactiveForImageLoads(nsIDocument* aDocument); + + /** + * Method to start an image load. This does not do any security checks. + * This method will attempt to make aURI immutable; a caller that wants to + * keep a mutable version around should pass in a clone. + * + * @param aURI uri of the image to be loaded + * @param aContext element of document where the result of this request + * will be used. + * @param aLoadingDocument the document we belong to + * @param aLoadingPrincipal the principal doing the load + * @param aReferrer the referrer URI + * @param aReferrerPolicy the referrer-sending policy to use on channel + * creation + * @param aObserver the observer for the image load + * @param aLoadFlags the load flags to use. See nsIRequest + * @param [aContentPolicyType=nsIContentPolicy::TYPE_INTERNAL_IMAGE] (Optional) + * The CP content type to use + * @return the imgIRequest for the image load + */ + static nsresult LoadImage(nsIURI* aURI, + nsINode* aContext, + nsIDocument* aLoadingDocument, + nsIPrincipal* aLoadingPrincipal, + nsIURI* aReferrer, + mozilla::net::ReferrerPolicy aReferrerPolicy, + imgINotificationObserver* aObserver, + int32_t aLoadFlags, + const nsAString& initiatorType, + imgRequestProxy** aRequest, + uint32_t aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE); + + /** + * Obtain an image loader that respects the given document/channel's privacy status. + * Null document/channel arguments return the public image loader. + */ + static imgLoader* GetImgLoaderForDocument(nsIDocument* aDoc); + static imgLoader* GetImgLoaderForChannel(nsIChannel* aChannel, + nsIDocument* aContext); + + /** + * Returns whether the given URI is in the image cache. + */ + static bool IsImageInCache(nsIURI* aURI, nsIDocument* aDocument); + + /** + * Method to get an imgIContainer from an image loading content + * + * @param aContent The image loading content. Must not be null. + * @param aRequest The image request [out] + * @return the imgIContainer corresponding to the first frame of the image + */ + static already_AddRefed GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nullptr); + + /** + * Helper method to call imgIRequest::GetStaticRequest. + */ + static already_AddRefed GetStaticRequest(imgRequestProxy* aRequest); + + /** + * Method that decides whether a content node is draggable + * + * @param aContent The content node to test. + * @return whether it's draggable + */ + static bool ContentIsDraggable(nsIContent* aContent); + + /** + * Method that decides whether a content node is a draggable image + * + * @param aContent The content node to test. + * @return whether it's a draggable image + */ + static bool IsDraggableImage(nsIContent* aContent); + + /** + * Method that decides whether a content node is a draggable link + * + * @param aContent The content node to test. + * @return whether it's a draggable link + */ + static bool IsDraggableLink(const nsIContent* aContent); + + /** + * Convenience method to create a new nodeinfo that differs only by name + * from aNodeInfo. + */ + static nsresult NameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsIAtom* aName, + mozilla::dom::NodeInfo** aResult); + + /** + * Returns the appropriate event argument names for the specified + * namespace and event name. Added because we need to switch between + * SVG's "evt" and the rest of the world's "event", and because onerror + * on window takes 5 args. + */ + static void GetEventArgNames(int32_t aNameSpaceID, nsIAtom *aEventName, + bool aIsForWindow, + uint32_t *aArgCount, const char*** aArgNames); + + /** + * Returns origin attributes of the document. + **/ + static mozilla::PrincipalOriginAttributes + GetOriginAttributes(nsIDocument* aDoc); + + /** + * Returns origin attributes of the load group. + **/ + static mozilla::PrincipalOriginAttributes + GetOriginAttributes(nsILoadGroup* aLoadGroup); + + /** + * Returns true if this document is in a Private Browsing window. + */ + static bool IsInPrivateBrowsing(nsIDocument* aDoc); + + /** + * Returns true if this loadGroup uses Private Browsing. + */ + static bool IsInPrivateBrowsing(nsILoadGroup* aLoadGroup); + + /** + * If aNode is not an element, return true exactly when aContent's binding + * parent is null. + * + * If aNode is an element, return true exactly when aContent's binding parent + * is the same as aNode's. + * + * This method is particularly useful for callers who are trying to ensure + * that they are working with a non-anonymous descendant of a given node. If + * aContent is a descendant of aNode, a return value of false from this + * method means that it's an anonymous descendant from aNode's point of view. + * + * Both arguments to this method must be non-null. + */ + static bool IsInSameAnonymousTree(const nsINode* aNode, const nsIContent* aContent); + + /** + * Return the nsIXPConnect service. + */ + static nsIXPConnect *XPConnect() + { + return sXPConnect; + } + + /** + * Report simple error message to the browser console + * @param aErrorText the error message + * @param classification Name of the module reporting error + */ + static void LogSimpleConsoleError(const nsAString& aErrorText, + const char * classification); + + /** + * Report a non-localized error message to the error console. + * @param aErrorText the error message + * @param aErrorFlags See nsIScriptError. + * @param aCategory Name of module reporting error. + * @param aDocument Reference to the document which triggered the message. + * @param [aURI=nullptr] (Optional) URI of resource containing error. + * @param [aSourceLine=EmptyString()] (Optional) The text of the line that + contains the error (may be empty). + * @param [aLineNumber=0] (Optional) Line number within resource + containing error. + * @param [aColumnNumber=0] (Optional) Column number within resource + containing error. + If aURI is null, then aDocument->GetDocumentURI() is used. + * @param [aLocationMode] (Optional) Specifies the behavior if + error location information is omitted. + */ + enum MissingErrorLocationMode { + // Don't show location information in the error console. + eOMIT_LOCATION, + // Get location information from the currently executing script. + eUSE_CALLING_LOCATION + }; + static nsresult ReportToConsoleNonLocalized(const nsAString& aErrorText, + uint32_t aErrorFlags, + const nsACString& aCategory, + const nsIDocument* aDocument, + nsIURI* aURI = nullptr, + const nsAFlatString& aSourceLine + = EmptyString(), + uint32_t aLineNumber = 0, + uint32_t aColumnNumber = 0, + MissingErrorLocationMode aLocationMode + = eUSE_CALLING_LOCATION); + + /** + * Report a localized error message to the error console. + * @param aErrorFlags See nsIScriptError. + * @param aCategory Name of module reporting error. + * @param aDocument Reference to the document which triggered the message. + * @param aFile Properties file containing localized message. + * @param aMessageName Name of localized message. + * @param [aParams=nullptr] (Optional) Parameters to be substituted into + localized message. + * @param [aParamsLength=0] (Optional) Length of aParams. + * @param [aURI=nullptr] (Optional) URI of resource containing error. + * @param [aSourceLine=EmptyString()] (Optional) The text of the line that + contains the error (may be empty). + * @param [aLineNumber=0] (Optional) Line number within resource + containing error. + * @param [aColumnNumber=0] (Optional) Column number within resource + containing error. + If aURI is null, then aDocument->GetDocumentURI() is used. + */ + enum PropertiesFile { + eCSS_PROPERTIES, + eXBL_PROPERTIES, + eXUL_PROPERTIES, + eLAYOUT_PROPERTIES, + eFORMS_PROPERTIES, + ePRINTING_PROPERTIES, + eDOM_PROPERTIES, + eHTMLPARSER_PROPERTIES, + eSVG_PROPERTIES, + eBRAND_PROPERTIES, + eCOMMON_DIALOG_PROPERTIES, + eMATHML_PROPERTIES, + eSECURITY_PROPERTIES, + eNECKO_PROPERTIES, + PropertiesFile_COUNT + }; + static nsresult ReportToConsole(uint32_t aErrorFlags, + const nsACString& aCategory, + const nsIDocument* aDocument, + PropertiesFile aFile, + const char *aMessageName, + const char16_t **aParams = nullptr, + uint32_t aParamsLength = 0, + nsIURI* aURI = nullptr, + const nsAFlatString& aSourceLine + = EmptyString(), + uint32_t aLineNumber = 0, + uint32_t aColumnNumber = 0); + + static void LogMessageToConsole(const char* aMsg); + + /** + * Get the localized string named |aKey| in properties file |aFile|. + */ + static nsresult GetLocalizedString(PropertiesFile aFile, + const char* aKey, + nsXPIDLString& aResult); + + /** + * A helper function that parses a sandbox attribute (of an