michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* A namespace class for static content utilities. */ michael@0: michael@0: #ifndef nsContentUtils_h___ michael@0: #define nsContentUtils_h___ michael@0: michael@0: #if defined(XP_WIN) michael@0: #include michael@0: #endif michael@0: michael@0: #if defined(SOLARIS) michael@0: #include michael@0: #endif michael@0: michael@0: #include "js/TypeDecls.h" michael@0: #include "js/Value.h" michael@0: #include "js/RootingAPI.h" michael@0: #include "mozilla/EventForwards.h" michael@0: #include "mozilla/GuardObjects.h" michael@0: #include "mozilla/TimeStamp.h" michael@0: #include "nsContentListDeclarations.h" michael@0: #include "nsMathUtils.h" michael@0: #include "nsTArrayForwardDeclare.h" michael@0: #include "Units.h" michael@0: michael@0: #if defined(XP_WIN) michael@0: // Undefine LoadImage to prevent naming conflict with Windows. michael@0: #undef LoadImage michael@0: #endif michael@0: michael@0: class imgICache; michael@0: class imgIContainer; michael@0: class imgINotificationObserver; michael@0: class imgIRequest; michael@0: class imgLoader; michael@0: class imgRequestProxy; michael@0: class nsAutoScriptBlockerSuppressNodeRemoved; michael@0: class nsHtml5StringParser; michael@0: class nsIChannel; michael@0: class nsIConsoleService; michael@0: class nsIContent; michael@0: class nsIContentPolicy; michael@0: class nsIContentSecurityPolicy; michael@0: class nsIDocShell; michael@0: class nsIDocument; michael@0: class nsIDocumentLoaderFactory; michael@0: class nsIDocumentObserver; michael@0: class nsIDOMDocument; michael@0: class nsIDOMDocumentFragment; michael@0: class nsIDOMEvent; michael@0: class nsIDOMHTMLFormElement; michael@0: class nsIDOMHTMLInputElement; michael@0: class nsIDOMKeyEvent; michael@0: class nsIDOMNode; michael@0: class nsIDOMScriptObjectFactory; michael@0: class nsIDOMWindow; michael@0: class nsIDragSession; michael@0: class nsIEditor; michael@0: class nsIFragmentContentSink; michael@0: class nsIFrame; michael@0: class nsIImageLoadingContent; michael@0: class nsIInterfaceRequestor; michael@0: class nsIIOService; michael@0: class nsIJSRuntimeService; michael@0: class nsILineBreaker; michael@0: class nsNameSpaceManager; michael@0: class nsINodeInfo; michael@0: class nsIObserver; michael@0: class nsIParser; michael@0: class nsIParserService; michael@0: class nsIPresShell; michael@0: class nsIPrincipal; michael@0: class nsIRunnable; michael@0: class nsIScriptContext; michael@0: class nsIScriptGlobalObject; michael@0: class nsIScriptSecurityManager; michael@0: class nsIStringBundle; michael@0: class nsIStringBundleService; michael@0: class nsISupportsHashKey; michael@0: class nsIURI; michael@0: class nsIWidget; michael@0: class nsIWordBreaker; michael@0: class nsIXPConnect; michael@0: class nsNodeInfoManager; michael@0: class nsPIDOMWindow; michael@0: class nsPresContext; michael@0: class nsScriptObjectTracer; michael@0: class nsStringBuffer; michael@0: class nsStringHashKey; michael@0: class nsTextFragment; michael@0: class nsViewportInfo; michael@0: class nsWrapperCache; michael@0: class nsAttrValue; michael@0: michael@0: struct JSPropertyDescriptor; michael@0: struct JSRuntime; michael@0: struct nsIntMargin; michael@0: michael@0: template class nsCOMArray; michael@0: template class nsDataHashtable; michael@0: template class nsRefPtrHashtable; michael@0: template class nsReadingIterator; michael@0: michael@0: namespace mozilla { michael@0: class ErrorResult; michael@0: class EventListenerManager; michael@0: michael@0: namespace dom { michael@0: class DocumentFragment; michael@0: class Element; michael@0: class EventTarget; michael@0: class Selection; michael@0: } // namespace dom michael@0: michael@0: namespace layers { michael@0: class LayerManager; michael@0: } // namespace layers michael@0: michael@0: // Called back from DeferredFinalize. Should add 'thing' to the array of smart michael@0: // pointers in 'pointers', creating the array if 'pointers' is null, and return michael@0: // the array. michael@0: typedef void* (*DeferredFinalizeAppendFunction)(void* pointers, void* thing); michael@0: michael@0: // Called to finalize a number of objects. Slice is the number of objects michael@0: // to finalize, or if it's UINT32_MAX, all objects should be finalized. michael@0: // Return value indicates whether it finalized all objects in the buffer. michael@0: typedef bool (*DeferredFinalizeFunction)(uint32_t slice, void* data); michael@0: michael@0: } // namespace mozilla michael@0: michael@0: class nsIBidiKeyboard; michael@0: michael@0: extern const char kLoadAsData[]; michael@0: michael@0: // Stolen from nsReadableUtils, but that's OK, since we can declare the same michael@0: // name multiple times. michael@0: const nsAFlatString& EmptyString(); michael@0: const nsAFlatCString& EmptyCString(); michael@0: michael@0: enum EventNameType { michael@0: EventNameType_None = 0x0000, michael@0: EventNameType_HTML = 0x0001, michael@0: EventNameType_XUL = 0x0002, michael@0: EventNameType_SVGGraphic = 0x0004, // svg graphic elements michael@0: EventNameType_SVGSVG = 0x0008, // the svg element michael@0: EventNameType_SMIL = 0x0010, // smil elements michael@0: EventNameType_HTMLBodyOrFramesetOnly = 0x0020, michael@0: michael@0: EventNameType_HTMLXUL = 0x0003, michael@0: EventNameType_All = 0xFFFF michael@0: }; michael@0: michael@0: struct EventNameMapping michael@0: { michael@0: nsIAtom* mAtom; michael@0: uint32_t mId; michael@0: int32_t mType; michael@0: uint32_t mStructType; michael@0: }; michael@0: michael@0: struct nsShortcutCandidate { michael@0: nsShortcutCandidate(uint32_t aCharCode, bool aIgnoreShift) : michael@0: mCharCode(aCharCode), mIgnoreShift(aIgnoreShift) michael@0: { michael@0: } michael@0: uint32_t mCharCode; michael@0: bool mIgnoreShift; michael@0: }; michael@0: michael@0: class nsContentUtils michael@0: { michael@0: friend class nsAutoScriptBlockerSuppressNodeRemoved; michael@0: typedef mozilla::dom::Element Element; michael@0: typedef mozilla::TimeDuration TimeDuration; michael@0: michael@0: public: michael@0: static nsresult Init(); michael@0: michael@0: /** michael@0: * Get a JSContext from the document's scope object. michael@0: */ michael@0: static JSContext* GetContextFromDocument(nsIDocument *aDocument); michael@0: michael@0: static bool IsCallerChrome(); michael@0: static bool ThreadsafeIsCallerChrome(); michael@0: static bool IsCallerXBL(); michael@0: michael@0: static bool IsImageSrcSetDisabled(); michael@0: michael@0: static bool LookupBindingMember(JSContext* aCx, nsIContent *aContent, michael@0: JS::Handle aId, michael@0: JS::MutableHandle aDesc); michael@0: michael@0: /** michael@0: * Returns the parent node of aChild crossing document boundaries. michael@0: */ michael@0: static nsINode* GetCrossDocParentNode(nsINode* aChild); michael@0: michael@0: /** michael@0: * Do not ever pass null pointers to this method. If one of your michael@0: * nsIContents is null, you have to decide for yourself what michael@0: * "IsDescendantOf" really means. michael@0: * michael@0: * @param aPossibleDescendant node to test for being a descendant of michael@0: * aPossibleAncestor michael@0: * @param aPossibleAncestor node to test for being an ancestor of michael@0: * aPossibleDescendant michael@0: * @return true if aPossibleDescendant is a descendant of michael@0: * aPossibleAncestor (or is aPossibleAncestor). false michael@0: * otherwise. michael@0: */ michael@0: static bool ContentIsDescendantOf(const nsINode* aPossibleDescendant, michael@0: const nsINode* aPossibleAncestor); michael@0: michael@0: /** michael@0: * Similar to ContentIsDescendantOf, except will treat an HTMLTemplateElement michael@0: * or ShadowRoot as an ancestor of things in the corresponding DocumentFragment. michael@0: * See the concept of "host-including inclusive ancestor" in the DOM michael@0: * specification. michael@0: */ michael@0: static bool ContentIsHostIncludingDescendantOf( michael@0: const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor); michael@0: michael@0: /** michael@0: * Similar to ContentIsDescendantOf except it crosses document boundaries. michael@0: */ michael@0: static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant, michael@0: nsINode* aPossibleAncestor); michael@0: michael@0: /* michael@0: * This method fills the |aArray| with all ancestor nodes of |aNode| michael@0: * including |aNode| at the zero index. michael@0: */ michael@0: static nsresult GetAncestors(nsINode* aNode, michael@0: nsTArray& aArray); michael@0: michael@0: /* michael@0: * This method fills |aAncestorNodes| with all ancestor nodes of |aNode| michael@0: * including |aNode| (QI'd to nsIContent) at the zero index. michael@0: * For each ancestor, there is a corresponding element in |aAncestorOffsets| michael@0: * which is the IndexOf the child in relation to its parent. michael@0: * michael@0: * This method just sucks. michael@0: */ michael@0: static nsresult GetAncestorsAndOffsets(nsIDOMNode* aNode, michael@0: int32_t aOffset, michael@0: nsTArray* aAncestorNodes, michael@0: nsTArray* aAncestorOffsets); michael@0: michael@0: /* michael@0: * The out parameter, |aCommonAncestor| will be the closest node, if any, michael@0: * to both |aNode| and |aOther| which is also an ancestor of each. michael@0: * Returns an error if the two nodes are disconnected and don't have michael@0: * a common ancestor. michael@0: */ michael@0: static nsresult GetCommonAncestor(nsIDOMNode *aNode, michael@0: nsIDOMNode *aOther, michael@0: nsIDOMNode** aCommonAncestor); michael@0: michael@0: /** michael@0: * Returns the common ancestor, if any, for two nodes. Returns null if the michael@0: * nodes are disconnected. michael@0: */ michael@0: static nsINode* GetCommonAncestor(nsINode* aNode1, michael@0: nsINode* aNode2); michael@0: michael@0: /** michael@0: * Returns true if aNode1 is before aNode2 in the same connected michael@0: * tree. michael@0: */ michael@0: static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2); michael@0: michael@0: /** michael@0: * Utility routine to compare two "points", where a point is a michael@0: * node/offset pair michael@0: * Returns -1 if point1 < point2, 1, if point1 > point2, michael@0: * 0 if error or if point1 == point2. michael@0: * NOTE! If the two nodes aren't in the same connected subtree, michael@0: * the result is 1, and the optional aDisconnected parameter michael@0: * is set to true. michael@0: */ michael@0: static int32_t ComparePoints(nsINode* aParent1, int32_t aOffset1, michael@0: nsINode* aParent2, int32_t aOffset2, michael@0: bool* aDisconnected = nullptr); michael@0: static int32_t ComparePoints(nsIDOMNode* aParent1, int32_t aOffset1, michael@0: nsIDOMNode* aParent2, int32_t aOffset2, michael@0: bool* aDisconnected = nullptr); michael@0: michael@0: /** michael@0: * Brute-force search of the element subtree rooted at aContent for michael@0: * an element with the given id. aId must be nonempty, otherwise michael@0: * this method may return nodes even if they have no id! michael@0: */ michael@0: static Element* MatchElementId(nsIContent *aContent, const nsAString& aId); michael@0: michael@0: /** michael@0: * Similar to above, but to be used if one already has an atom for the ID michael@0: */ michael@0: static Element* MatchElementId(nsIContent *aContent, const nsIAtom* aId); michael@0: michael@0: /** michael@0: * Reverses the document position flags passed in. michael@0: * michael@0: * @param aDocumentPosition The document position flags to be reversed. michael@0: * michael@0: * @return The reversed document position flags. michael@0: * michael@0: * @see nsIDOMNode michael@0: */ michael@0: static uint16_t ReverseDocumentPosition(uint16_t aDocumentPosition); michael@0: michael@0: static uint32_t CopyNewlineNormalizedUnicodeTo(const nsAString& aSource, michael@0: uint32_t aSrcOffset, michael@0: char16_t* aDest, michael@0: uint32_t aLength, michael@0: bool& aLastCharCR); michael@0: michael@0: static uint32_t CopyNewlineNormalizedUnicodeTo(nsReadingIterator& aSrcStart, const nsReadingIterator& aSrcEnd, nsAString& aDest); michael@0: michael@0: static const nsDependentSubstring TrimCharsInSet(const char* aSet, michael@0: const nsAString& aValue); michael@0: michael@0: template michael@0: static const nsDependentSubstring TrimWhitespace(const nsAString& aStr, michael@0: bool aTrimTrailing = true); michael@0: michael@0: /** michael@0: * Returns true if aChar is of class Ps, Pi, Po, Pf, or Pe. michael@0: */ michael@0: static bool IsFirstLetterPunctuation(uint32_t aChar); michael@0: static bool IsFirstLetterPunctuationAt(const nsTextFragment* aFrag, uint32_t aOffset); michael@0: michael@0: /** michael@0: * Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No michael@0: */ michael@0: static bool IsAlphanumeric(uint32_t aChar); michael@0: static bool IsAlphanumericAt(const nsTextFragment* aFrag, uint32_t aOffset); michael@0: michael@0: /* michael@0: * Is the character an HTML whitespace character? michael@0: * michael@0: * We define whitespace using the list in HTML5 and css3-selectors: michael@0: * U+0009, U+000A, U+000C, U+000D, U+0020 michael@0: * michael@0: * HTML 4.01 also lists U+200B (zero-width space). michael@0: */ michael@0: static bool IsHTMLWhitespace(char16_t aChar); michael@0: michael@0: /* michael@0: * Returns whether the character is an HTML whitespace (see IsHTMLWhitespace) michael@0: * or a nbsp character (U+00A0). michael@0: */ michael@0: static bool IsHTMLWhitespaceOrNBSP(char16_t aChar); michael@0: michael@0: /** michael@0: * Is the HTML local name a block element? michael@0: */ michael@0: static bool IsHTMLBlock(nsIAtom* aLocalName); michael@0: michael@0: /** michael@0: * Is the HTML local name a void element? michael@0: */ michael@0: static bool IsHTMLVoid(nsIAtom* aLocalName); michael@0: michael@0: /** michael@0: * Parse a margin string of format 'top, right, bottom, left' into michael@0: * an nsIntMargin. michael@0: * michael@0: * @param aString the string to parse michael@0: * @param aResult the resulting integer michael@0: * @return whether the value could be parsed michael@0: */ michael@0: static bool ParseIntMarginValue(const nsAString& aString, nsIntMargin& aResult); michael@0: michael@0: /** michael@0: * Parse the value of the attribute according to the HTML5 michael@0: * spec as of April 16, 2012. michael@0: * michael@0: * @param aValue the value to parse michael@0: * @return 1 to 7, or 0 if the value couldn't be parsed michael@0: */ michael@0: static int32_t ParseLegacyFontSize(const nsAString& aValue); michael@0: michael@0: static void Shutdown(); michael@0: michael@0: /** michael@0: * Checks whether two nodes come from the same origin. michael@0: */ michael@0: static nsresult CheckSameOrigin(const nsINode* aTrustedNode, michael@0: nsIDOMNode* aUnTrustedNode); michael@0: static nsresult CheckSameOrigin(const nsINode* aTrustedNode, michael@0: const nsINode* unTrustedNode); michael@0: michael@0: // Check if the (JS) caller can access aNode. michael@0: static bool CanCallerAccess(nsIDOMNode *aNode); michael@0: static bool CanCallerAccess(nsINode* aNode); michael@0: michael@0: // Check if the (JS) caller can access aWindow. michael@0: // aWindow can be either outer or inner window. michael@0: static bool CanCallerAccess(nsPIDOMWindow* aWindow); michael@0: michael@0: /** michael@0: * Get the window through the JS context that's currently on the stack. michael@0: * If there's no JS context currently on the stack, returns null. michael@0: */ michael@0: static nsPIDOMWindow *GetWindowFromCaller(); michael@0: michael@0: /** michael@0: * The two GetDocumentFrom* functions below allow a caller to get at a michael@0: * document that is relevant to the currently executing script. michael@0: * michael@0: * GetDocumentFromCaller gets its document by looking at the last called michael@0: * function and finding the document that the function itself relates to. michael@0: * For example, consider two windows A and B in the same origin. B has a michael@0: * function which does something that ends up needing the current document. michael@0: * If a script in window A were to call B's function, GetDocumentFromCaller michael@0: * would find that function (in B) and return B's document. michael@0: * michael@0: * GetDocumentFromContext gets its document by looking at the currently michael@0: * executing context's global object and returning its document. Thus, michael@0: * given the example above, GetDocumentFromCaller would see that the michael@0: * currently executing script was in window A, and return A's document. michael@0: */ michael@0: /** michael@0: * Get the document from the currently executing function. This will return michael@0: * the document that the currently executing function is in/from. michael@0: * michael@0: * @return The document or null if no JS Context. michael@0: */ michael@0: static nsIDocument* GetDocumentFromCaller(); michael@0: michael@0: /** michael@0: * Get the document through the JS context that's currently on the stack. michael@0: * If there's no JS context currently on the stack it will return null. michael@0: * This will return the document of the calling script. michael@0: * michael@0: * @return The document or null if no JS context michael@0: */ michael@0: static nsIDocument* GetDocumentFromContext(); michael@0: michael@0: // Check if a node is in the document prolog, i.e. before the document michael@0: // element. michael@0: static bool InProlog(nsINode *aNode); michael@0: michael@0: static nsIParserService* GetParserService(); michael@0: michael@0: static nsNameSpaceManager* NameSpaceManager() michael@0: { michael@0: return sNameSpaceManager; michael@0: } michael@0: michael@0: static nsIIOService* GetIOService() michael@0: { michael@0: return sIOService; michael@0: } michael@0: michael@0: static nsIBidiKeyboard* GetBidiKeyboard(); michael@0: michael@0: /** michael@0: * Get the cache security manager service. Can return null if the layout michael@0: * module has been shut down. michael@0: */ michael@0: static nsIScriptSecurityManager* GetSecurityManager() michael@0: { michael@0: return sSecurityManager; michael@0: } michael@0: michael@0: /** michael@0: * Get the ContentSecurityPolicy for a JS context. michael@0: **/ michael@0: static bool GetContentSecurityPolicy(JSContext* aCx, michael@0: nsIContentSecurityPolicy** aCSP); michael@0: michael@0: // Returns the subject principal. Guaranteed to return non-null. May only michael@0: // be called when nsContentUtils is initialized. michael@0: static nsIPrincipal* GetSubjectPrincipal(); michael@0: michael@0: // Returns the principal of the given JS object. This should never be null michael@0: // for any object in the XPConnect runtime. michael@0: // michael@0: // In general, being interested in the principal of an object is enough to michael@0: // guarantee that the return value is non-null. michael@0: static nsIPrincipal* GetObjectPrincipal(JSObject* aObj); michael@0: michael@0: static nsresult GenerateStateKey(nsIContent* aContent, michael@0: const nsIDocument* aDocument, michael@0: nsACString& aKey); michael@0: michael@0: /** michael@0: * Create a new nsIURI from aSpec, using aBaseURI as the base. The michael@0: * origin charset of the new nsIURI will be the document charset of michael@0: * aDocument. michael@0: */ michael@0: static nsresult NewURIWithDocumentCharset(nsIURI** aResult, michael@0: const nsAString& aSpec, michael@0: nsIDocument* aDocument, michael@0: nsIURI* aBaseURI); michael@0: michael@0: /** michael@0: * Convert aInput (in encoding aEncoding) to UTF16 in aOutput. michael@0: * michael@0: * @param aEncoding the Gecko-canonical name of the encoding or the empty michael@0: * string (meaning UTF-8) michael@0: */ michael@0: static nsresult ConvertStringFromEncoding(const nsACString& aEncoding, michael@0: const nsACString& aInput, michael@0: nsAString& aOutput); michael@0: michael@0: /** michael@0: * Determine whether a buffer begins with a BOM for UTF-8, UTF-16LE, michael@0: * UTF-16BE michael@0: * michael@0: * @param aBuffer the buffer to check michael@0: * @param aLength the length of the buffer michael@0: * @param aCharset empty if not found michael@0: * @return boolean indicating whether a BOM was detected. michael@0: */ michael@0: static bool CheckForBOM(const unsigned char* aBuffer, uint32_t aLength, michael@0: nsACString& aCharset); michael@0: michael@0: /** michael@0: * Returns true if |aName| is a valid name to be registered via michael@0: * document.registerElement. michael@0: */ michael@0: static bool IsCustomElementName(nsIAtom* aName); michael@0: michael@0: static nsresult CheckQName(const nsAString& aQualifiedName, michael@0: bool aNamespaceAware = true, michael@0: const char16_t** aColon = nullptr); michael@0: michael@0: static nsresult SplitQName(const nsIContent* aNamespaceResolver, michael@0: const nsAFlatString& aQName, michael@0: int32_t *aNamespace, nsIAtom **aLocalName); michael@0: michael@0: static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI, michael@0: const nsAString& aQualifiedName, michael@0: nsNodeInfoManager* aNodeInfoManager, michael@0: uint16_t aNodeType, michael@0: nsINodeInfo** aNodeInfo); michael@0: michael@0: static void SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix, michael@0: nsIAtom **aTagName, int32_t *aNameSpaceID); michael@0: michael@0: // Get a permission-manager setting for the given principal and type. michael@0: // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is michael@0: // returned, otherwise true is returned. Always returns true for the michael@0: // system principal, and false for a null principal. michael@0: static bool IsSitePermAllow(nsIPrincipal* aPrincipal, const char* aType); michael@0: michael@0: // Get a permission-manager setting for the given principal and type. michael@0: // If the pref doesn't exist or if it isn't DENY_ACTION, false is michael@0: // returned, otherwise true is returned. Always returns false for the michael@0: // system principal, and true for a null principal. michael@0: static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const char* aType); michael@0: michael@0: // Get a permission-manager setting for the given principal and type. michael@0: // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is michael@0: // returned, otherwise true is returned. Always returns true for the michael@0: // system principal, and false for a null principal. michael@0: // This version checks the permission for an exact host match on michael@0: // the principal michael@0: static bool IsExactSitePermAllow(nsIPrincipal* aPrincipal, const char* aType); michael@0: michael@0: // Get a permission-manager setting for the given principal and type. michael@0: // If the pref doesn't exist or if it isn't DENY_ACTION, false is michael@0: // returned, otherwise true is returned. Always returns false for the michael@0: // system principal, and true for a null principal. michael@0: // This version checks the permission for an exact host match on michael@0: // the principal michael@0: static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal, const char* aType); michael@0: michael@0: // Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s. michael@0: static bool HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2); michael@0: michael@0: static nsILineBreaker* LineBreaker() michael@0: { michael@0: return sLineBreaker; michael@0: } michael@0: michael@0: static nsIWordBreaker* WordBreaker() michael@0: { michael@0: return sWordBreaker; michael@0: } michael@0: michael@0: /** michael@0: * Regster aObserver as a shutdown observer. A strong reference is held michael@0: * to aObserver until UnregisterShutdownObserver is called. michael@0: */ michael@0: static void RegisterShutdownObserver(nsIObserver* aObserver); michael@0: static void UnregisterShutdownObserver(nsIObserver* aObserver); michael@0: michael@0: /** michael@0: * @return true if aContent has an attribute aName in namespace aNameSpaceID, michael@0: * and the attribute value is non-empty. michael@0: */ michael@0: static bool HasNonEmptyAttr(const nsIContent* aContent, int32_t aNameSpaceID, michael@0: nsIAtom* aName); michael@0: michael@0: /** michael@0: * Method that gets the primary presContext for the node. michael@0: * michael@0: * @param aContent The content node. michael@0: * @return the presContext, or nullptr if the content is not in a document michael@0: * (if GetCurrentDoc returns nullptr) michael@0: */ michael@0: static nsPresContext* GetContextForContent(const nsIContent* aContent); michael@0: michael@0: /** michael@0: * Method to do security and content policy checks on the image URI michael@0: * michael@0: * @param aURI uri of the image to be loaded michael@0: * @param aContext the context the image is loaded in (eg an element) michael@0: * @param aLoadingDocument the document we belong to michael@0: * @param aLoadingPrincipal the principal doing the load michael@0: * @param aImageBlockingStatus the nsIContentPolicy blocking status for this michael@0: * image. This will be set even if a security check fails for the michael@0: * image, to some reasonable REJECT_* value. This out param will only michael@0: * be set if it's non-null. michael@0: * @return true if the load can proceed, or false if it is blocked. michael@0: * Note that aImageBlockingStatus, if set will always be an ACCEPT michael@0: * status if true is returned and always be a REJECT_* status if michael@0: * false is returned. michael@0: */ michael@0: static bool CanLoadImage(nsIURI* aURI, michael@0: nsISupports* aContext, michael@0: nsIDocument* aLoadingDocument, michael@0: nsIPrincipal* aLoadingPrincipal, michael@0: int16_t* aImageBlockingStatus = nullptr); michael@0: /** michael@0: * Method to start an image load. This does not do any security checks. michael@0: * This method will attempt to make aURI immutable; a caller that wants to michael@0: * keep a mutable version around should pass in a clone. michael@0: * michael@0: * @param aURI uri of the image to be loaded michael@0: * @param aLoadingDocument the document we belong to michael@0: * @param aLoadingPrincipal the principal doing the load michael@0: * @param aReferrer the referrer URI michael@0: * @param aObserver the observer for the image load michael@0: * @param aLoadFlags the load flags to use. See nsIRequest michael@0: * @return the imgIRequest for the image load michael@0: */ michael@0: static nsresult LoadImage(nsIURI* aURI, michael@0: nsIDocument* aLoadingDocument, michael@0: nsIPrincipal* aLoadingPrincipal, michael@0: nsIURI* aReferrer, michael@0: imgINotificationObserver* aObserver, michael@0: int32_t aLoadFlags, michael@0: const nsAString& initiatorType, michael@0: imgRequestProxy** aRequest); michael@0: michael@0: /** michael@0: * Obtain an image loader that respects the given document/channel's privacy status. michael@0: * Null document/channel arguments return the public image loader. michael@0: */ michael@0: static imgLoader* GetImgLoaderForDocument(nsIDocument* aDoc); michael@0: static imgLoader* GetImgLoaderForChannel(nsIChannel* aChannel); michael@0: michael@0: /** michael@0: * Returns whether the given URI is in the image cache. michael@0: */ michael@0: static bool IsImageInCache(nsIURI* aURI, nsIDocument* aDocument); michael@0: michael@0: /** michael@0: * Method to get an imgIContainer from an image loading content michael@0: * michael@0: * @param aContent The image loading content. Must not be null. michael@0: * @param aRequest The image request [out] michael@0: * @return the imgIContainer corresponding to the first frame of the image michael@0: */ michael@0: static already_AddRefed GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nullptr); michael@0: michael@0: /** michael@0: * Helper method to call imgIRequest::GetStaticRequest. michael@0: */ michael@0: static already_AddRefed GetStaticRequest(imgRequestProxy* aRequest); michael@0: michael@0: /** michael@0: * Method that decides whether a content node is draggable michael@0: * michael@0: * @param aContent The content node to test. michael@0: * @return whether it's draggable michael@0: */ michael@0: static bool ContentIsDraggable(nsIContent* aContent); michael@0: michael@0: /** michael@0: * Method that decides whether a content node is a draggable image michael@0: * michael@0: * @param aContent The content node to test. michael@0: * @return whether it's a draggable image michael@0: */ michael@0: static bool IsDraggableImage(nsIContent* aContent); michael@0: michael@0: /** michael@0: * Method that decides whether a content node is a draggable link michael@0: * michael@0: * @param aContent The content node to test. michael@0: * @return whether it's a draggable link michael@0: */ michael@0: static bool IsDraggableLink(const nsIContent* aContent); michael@0: michael@0: /** michael@0: * Convenience method to create a new nodeinfo that differs only by name michael@0: * from aNodeInfo. michael@0: */ michael@0: static nsresult NameChanged(nsINodeInfo* aNodeInfo, nsIAtom* aName, michael@0: nsINodeInfo** aResult); michael@0: michael@0: /** michael@0: * Returns the appropriate event argument names for the specified michael@0: * namespace and event name. Added because we need to switch between michael@0: * SVG's "evt" and the rest of the world's "event", and because onerror michael@0: * takes 3 args. michael@0: */ michael@0: static void GetEventArgNames(int32_t aNameSpaceID, nsIAtom *aEventName, michael@0: uint32_t *aArgCount, const char*** aArgNames); michael@0: michael@0: /** michael@0: * If aNode is not an element, return true exactly when aContent's binding michael@0: * parent is null. michael@0: * michael@0: * If aNode is an element, return true exactly when aContent's binding parent michael@0: * is the same as aNode's. michael@0: * michael@0: * This method is particularly useful for callers who are trying to ensure michael@0: * that they are working with a non-anonymous descendant of a given node. If michael@0: * aContent is a descendant of aNode, a return value of false from this michael@0: * method means that it's an anonymous descendant from aNode's point of view. michael@0: * michael@0: * Both arguments to this method must be non-null. michael@0: */ michael@0: static bool IsInSameAnonymousTree(const nsINode* aNode, const nsIContent* aContent); michael@0: michael@0: /** michael@0: * Return the nsIXPConnect service. michael@0: */ michael@0: static nsIXPConnect *XPConnect() michael@0: { michael@0: return sXPConnect; michael@0: } michael@0: michael@0: /** michael@0: * Report simple error message to the browser console michael@0: * @param aErrorText the error message michael@0: * @param classification Name of the module reporting error michael@0: */ michael@0: static void LogSimpleConsoleError(const nsAString& aErrorText, michael@0: const char * classification); michael@0: michael@0: /** michael@0: * Report a non-localized error message to the error console. michael@0: * @param aErrorText the error message michael@0: * @param aErrorFlags See nsIScriptError. michael@0: * @param aCategory Name of module reporting error. michael@0: * @param aDocument Reference to the document which triggered the message. michael@0: * @param [aURI=nullptr] (Optional) URI of resource containing error. michael@0: * @param [aSourceLine=EmptyString()] (Optional) The text of the line that michael@0: contains the error (may be empty). michael@0: * @param [aLineNumber=0] (Optional) Line number within resource michael@0: containing error. michael@0: * @param [aColumnNumber=0] (Optional) Column number within resource michael@0: containing error. michael@0: If aURI is null, then aDocument->GetDocumentURI() is used. michael@0: */ michael@0: static nsresult ReportToConsoleNonLocalized(const nsAString& aErrorText, michael@0: uint32_t aErrorFlags, michael@0: const nsACString& aCategory, michael@0: nsIDocument* aDocument, michael@0: nsIURI* aURI = nullptr, michael@0: const nsAFlatString& aSourceLine michael@0: = EmptyString(), michael@0: uint32_t aLineNumber = 0, michael@0: uint32_t aColumnNumber = 0); michael@0: michael@0: /** michael@0: * Report a localized error message to the error console. michael@0: * @param aErrorFlags See nsIScriptError. michael@0: * @param aCategory Name of module reporting error. michael@0: * @param aDocument Reference to the document which triggered the message. michael@0: * @param aFile Properties file containing localized message. michael@0: * @param aMessageName Name of localized message. michael@0: * @param [aParams=nullptr] (Optional) Parameters to be substituted into michael@0: localized message. michael@0: * @param [aParamsLength=0] (Optional) Length of aParams. michael@0: * @param [aURI=nullptr] (Optional) URI of resource containing error. michael@0: * @param [aSourceLine=EmptyString()] (Optional) The text of the line that michael@0: contains the error (may be empty). michael@0: * @param [aLineNumber=0] (Optional) Line number within resource michael@0: containing error. michael@0: * @param [aColumnNumber=0] (Optional) Column number within resource michael@0: containing error. michael@0: If aURI is null, then aDocument->GetDocumentURI() is used. michael@0: */ michael@0: enum PropertiesFile { michael@0: eCSS_PROPERTIES, michael@0: eXBL_PROPERTIES, michael@0: eXUL_PROPERTIES, michael@0: eLAYOUT_PROPERTIES, michael@0: eFORMS_PROPERTIES, michael@0: ePRINTING_PROPERTIES, michael@0: eDOM_PROPERTIES, michael@0: eHTMLPARSER_PROPERTIES, michael@0: eSVG_PROPERTIES, michael@0: eBRAND_PROPERTIES, michael@0: eCOMMON_DIALOG_PROPERTIES, michael@0: eMATHML_PROPERTIES, michael@0: eSECURITY_PROPERTIES, michael@0: PropertiesFile_COUNT michael@0: }; michael@0: static nsresult ReportToConsole(uint32_t aErrorFlags, michael@0: const nsACString& aCategory, michael@0: nsIDocument* aDocument, michael@0: PropertiesFile aFile, michael@0: const char *aMessageName, michael@0: const char16_t **aParams = nullptr, michael@0: uint32_t aParamsLength = 0, michael@0: nsIURI* aURI = nullptr, michael@0: const nsAFlatString& aSourceLine michael@0: = EmptyString(), michael@0: uint32_t aLineNumber = 0, michael@0: uint32_t aColumnNumber = 0); michael@0: michael@0: static void LogMessageToConsole(const char* aMsg, ...); michael@0: michael@0: /** michael@0: * Get the localized string named |aKey| in properties file |aFile|. michael@0: */ michael@0: static nsresult GetLocalizedString(PropertiesFile aFile, michael@0: const char* aKey, michael@0: nsXPIDLString& aResult); michael@0: michael@0: /** michael@0: * A helper function that parses a sandbox attribute (of an