michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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: #ifndef nsIDocument_h___ michael@0: #define nsIDocument_h___ michael@0: michael@0: #include "mozFlushType.h" // for enum michael@0: #include "nsAutoPtr.h" // for member michael@0: #include "nsCOMArray.h" // for member michael@0: #include "nsCRT.h" // for NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW michael@0: #include "nsCompatibility.h" // for member michael@0: #include "nsCOMPtr.h" // for member michael@0: #include "nsGkAtoms.h" // for static class members michael@0: #include "nsIDocumentObserver.h" // for typedef (nsUpdateType) michael@0: #include "nsILoadGroup.h" // for member (in nsCOMPtr) michael@0: #include "nsINode.h" // for base class michael@0: #include "nsIScriptGlobalObject.h" // for member (in nsCOMPtr) michael@0: #include "nsPIDOMWindow.h" // for use in inline functions michael@0: #include "nsPropertyTable.h" // for member michael@0: #include "nsTHashtable.h" // for member michael@0: #include "nsWeakReference.h" michael@0: #include "mozilla/dom/DocumentBinding.h" michael@0: #include "mozilla/WeakPtr.h" michael@0: #include "Units.h" michael@0: #include "nsExpirationTracker.h" michael@0: #include "nsClassHashtable.h" michael@0: michael@0: class imgIRequest; michael@0: class nsAString; michael@0: class nsBindingManager; michael@0: class nsCSSStyleSheet; michael@0: class nsIDocShell; michael@0: class nsDocShell; michael@0: class nsDOMNavigationTiming; michael@0: class nsFrameLoader; michael@0: class nsHTMLCSSStyleSheet; michael@0: class nsHTMLDocument; michael@0: class nsHTMLStyleSheet; michael@0: class nsIAtom; michael@0: class nsIBFCacheEntry; michael@0: class nsIBoxObject; michael@0: class nsIChannel; michael@0: class nsIContent; michael@0: class nsIContentSink; michael@0: class nsIDocShell; michael@0: class nsIDocumentEncoder; michael@0: class nsIDocumentObserver; michael@0: class nsIDOMDocument; michael@0: class nsIDOMDocumentFragment; michael@0: class nsIDOMDocumentType; michael@0: class nsIDOMElement; michael@0: class nsIDOMNodeFilter; michael@0: class nsIDOMNodeList; michael@0: class nsIDOMXPathExpression; michael@0: class nsIDOMXPathNSResolver; michael@0: class nsIHTMLCollection; michael@0: class nsILayoutHistoryState; michael@0: class nsILoadContext; michael@0: class nsIObjectLoadingContent; michael@0: class nsIObserver; michael@0: class nsIPresShell; michael@0: class nsIPrincipal; michael@0: class nsIRequest; michael@0: class nsIStreamListener; michael@0: class nsIStructuredCloneContainer; michael@0: class nsIStyleRule; michael@0: class nsIStyleSheet; michael@0: class nsIURI; michael@0: class nsIVariant; michael@0: class nsViewManager; michael@0: class nsPresContext; michael@0: class nsRange; michael@0: class nsScriptLoader; michael@0: class nsSMILAnimationController; michael@0: class nsStyleSet; michael@0: class nsTextNode; michael@0: class nsWindowSizes; michael@0: class nsSmallVoidArray; michael@0: class nsDOMCaretPosition; michael@0: class nsViewportInfo; michael@0: class nsIGlobalObject; michael@0: class nsCSSSelectorList; michael@0: michael@0: namespace mozilla { michael@0: class ErrorResult; michael@0: class EventStates; michael@0: michael@0: namespace css { michael@0: class Loader; michael@0: class ImageLoader; michael@0: } // namespace css michael@0: michael@0: namespace dom { michael@0: class Attr; michael@0: class CDATASection; michael@0: class Comment; michael@0: struct CustomElementDefinition; michael@0: class DocumentFragment; michael@0: class DocumentType; michael@0: class DOMImplementation; michael@0: class DOMStringList; michael@0: class Element; michael@0: struct ElementRegistrationOptions; michael@0: class Event; michael@0: class EventTarget; michael@0: class FrameRequestCallback; michael@0: class HTMLBodyElement; michael@0: struct LifecycleCallbackArgs; michael@0: class Link; michael@0: class GlobalObject; michael@0: class NodeFilter; michael@0: class NodeIterator; michael@0: class ProcessingInstruction; michael@0: class StyleSheetList; michael@0: class Touch; michael@0: class TouchList; michael@0: class TreeWalker; michael@0: class UndoManager; michael@0: class XPathEvaluator; michael@0: template class OwningNonNull; michael@0: template class Sequence; michael@0: michael@0: template class CallbackObjectHolder; michael@0: typedef CallbackObjectHolder NodeFilterHolder; michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: #define NS_IDOCUMENT_IID \ michael@0: { 0x906d05e7, 0x39af, 0x4ff0, \ michael@0: { 0xbc, 0xcd, 0x30, 0x0c, 0x7f, 0xeb, 0x86, 0x21 } } michael@0: michael@0: // Flag for AddStyleSheet(). michael@0: #define NS_STYLESHEET_FROM_CATALOG (1 << 0) michael@0: michael@0: // Enum for requesting a particular type of document when creating a doc michael@0: enum DocumentFlavor { michael@0: DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant michael@0: DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true michael@0: DocumentFlavorSVG // SVGDocument michael@0: }; michael@0: michael@0: // Document states michael@0: michael@0: // RTL locale: specific to the XUL localedir attribute michael@0: #define NS_DOCUMENT_STATE_RTL_LOCALE NS_DEFINE_EVENT_STATE_MACRO(0) michael@0: // Window activation status michael@0: #define NS_DOCUMENT_STATE_WINDOW_INACTIVE NS_DEFINE_EVENT_STATE_MACRO(1) michael@0: michael@0: // Some function forward-declarations michael@0: class nsContentList; michael@0: michael@0: already_AddRefed michael@0: NS_GetContentList(nsINode* aRootNode, michael@0: int32_t aMatchNameSpaceId, michael@0: const nsAString& aTagname); michael@0: //---------------------------------------------------------------------- michael@0: michael@0: // Document interface. This is implemented by all document objects in michael@0: // Gecko. michael@0: class nsIDocument : public nsINode michael@0: { michael@0: typedef mozilla::dom::GlobalObject GlobalObject; michael@0: public: michael@0: typedef mozilla::dom::Element Element; michael@0: michael@0: NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID) michael@0: NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW michael@0: michael@0: #ifdef MOZILLA_INTERNAL_API michael@0: nsIDocument(); michael@0: #endif michael@0: michael@0: /** michael@0: * Let the document know that we're starting to load data into it. michael@0: * @param aCommand The parser command. Must not be null. michael@0: * XXXbz It's odd to have that here. michael@0: * @param aChannel The channel the data will come from. The channel must be michael@0: * able to report its Content-Type. michael@0: * @param aLoadGroup The loadgroup this document should use from now on. michael@0: * Note that the document might not be the only thing using michael@0: * this loadgroup. michael@0: * @param aContainer The container this document is in. This may be null. michael@0: * XXXbz maybe we should make it more explicit (eg make the michael@0: * container an nsIWebNavigation or nsIDocShell or michael@0: * something)? michael@0: * @param [out] aDocListener the listener to pump data from the channel into. michael@0: * Generally this will be the parser this document michael@0: * sets up, or some sort of data-handler for media michael@0: * documents. michael@0: * @param aReset whether the document should call Reset() on itself. If this michael@0: * is false, the document will NOT set its principal to the michael@0: * channel's owner, will not clear any event listeners that are michael@0: * already set on it, etc. michael@0: * @param aSink The content sink to use for the data. If this is null and michael@0: * the document needs a content sink, it will create one based michael@0: * on whatever it knows about the data it's going to load. michael@0: * This MUST be null if the underlying document is an HTML michael@0: * document. Even in the XML case, please don't add new calls michael@0: * with non-null sink. michael@0: * michael@0: * Once this has been called, the document will return false for michael@0: * MayStartLayout() until SetMayStartLayout(true) is called on it. Making michael@0: * sure this happens is the responsibility of the caller of michael@0: * StartDocumentLoad(). michael@0: */ michael@0: virtual nsresult StartDocumentLoad(const char* aCommand, michael@0: nsIChannel* aChannel, michael@0: nsILoadGroup* aLoadGroup, michael@0: nsISupports* aContainer, michael@0: nsIStreamListener **aDocListener, michael@0: bool aReset, michael@0: nsIContentSink* aSink = nullptr) = 0; michael@0: virtual void StopDocumentLoad() = 0; michael@0: michael@0: /** michael@0: * Signal that the document title may have changed michael@0: * (see nsDocument::GetTitle). michael@0: * @param aBoundTitleElement true if an HTML or SVG element michael@0: * has just been bound to the document. michael@0: */ michael@0: virtual void NotifyPossibleTitleChange(bool aBoundTitleElement) = 0; michael@0: michael@0: /** michael@0: * Return the URI for the document. May return null. michael@0: * michael@0: * The value returned corresponds to the "document's current address" in michael@0: * HTML5. As such, it may change over the lifetime of the document, for michael@0: * instance as a result of a call to pushState() or replaceState(). michael@0: */ michael@0: nsIURI* GetDocumentURI() const michael@0: { michael@0: return mDocumentURI; michael@0: } michael@0: michael@0: /** michael@0: * Return the original URI of the document. This is the same as the michael@0: * document's URI unless history.pushState() or replaceState() is invoked on michael@0: * the document. michael@0: * michael@0: * This method corresponds to the "document's address" in HTML5 and, once michael@0: * set, doesn't change over the lifetime of the document. michael@0: */ michael@0: nsIURI* GetOriginalURI() const michael@0: { michael@0: return mOriginalURI; michael@0: } michael@0: michael@0: /** michael@0: * Set the URI for the document. This also sets the document's original URI, michael@0: * if it's null. michael@0: */ michael@0: virtual void SetDocumentURI(nsIURI* aURI) = 0; michael@0: michael@0: /** michael@0: * Set the URI for the document loaded via XHR, when accessed from michael@0: * chrome privileged script. michael@0: */ michael@0: virtual void SetChromeXHRDocURI(nsIURI* aURI) = 0; michael@0: michael@0: /** michael@0: * Set the base URI for the document loaded via XHR, when accessed from michael@0: * chrome privileged script. michael@0: */ michael@0: virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) = 0; michael@0: michael@0: /** michael@0: * Set the principal responsible for this document. michael@0: */ michael@0: virtual void SetPrincipal(nsIPrincipal *aPrincipal) = 0; michael@0: michael@0: /** michael@0: * Return the LoadGroup for the document. May return null. michael@0: */ michael@0: already_AddRefed<nsILoadGroup> GetDocumentLoadGroup() const michael@0: { michael@0: nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup); michael@0: return group.forget(); michael@0: } michael@0: michael@0: /** michael@0: * Return the base URI for relative URIs in the document (the document uri michael@0: * unless it's overridden by SetBaseURI, HTML <base> tags, etc.). The michael@0: * returned URI could be null if there is no document URI. If the document michael@0: * is a srcdoc document, return the parent document's base URL. michael@0: */ michael@0: nsIURI* GetDocBaseURI() const michael@0: { michael@0: if (mIsSrcdocDocument && mParentDocument) { michael@0: return mParentDocument->GetDocBaseURI(); michael@0: } michael@0: return mDocumentBaseURI ? mDocumentBaseURI : mDocumentURI; michael@0: } michael@0: virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult SetBaseURI(nsIURI* aURI) = 0; michael@0: michael@0: /** michael@0: * Get/Set the base target of a link in a document. michael@0: */ michael@0: virtual void GetBaseTarget(nsAString &aBaseTarget) = 0; michael@0: void SetBaseTarget(const nsString& aBaseTarget) { michael@0: mBaseTarget = aBaseTarget; michael@0: } michael@0: michael@0: /** michael@0: * Return a standard name for the document's character set. michael@0: */ michael@0: const nsCString& GetDocumentCharacterSet() const michael@0: { michael@0: return mCharacterSet; michael@0: } michael@0: michael@0: /** michael@0: * Set the document's character encoding. |aCharSetID| should be canonical. michael@0: * That is, callers are responsible for the charset alias resolution. michael@0: */ michael@0: virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) = 0; michael@0: michael@0: int32_t GetDocumentCharacterSetSource() const michael@0: { michael@0: return mCharacterSetSource; michael@0: } michael@0: michael@0: // This method MUST be called before SetDocumentCharacterSet if michael@0: // you're planning to call both. michael@0: void SetDocumentCharacterSetSource(int32_t aCharsetSource) michael@0: { michael@0: mCharacterSetSource = aCharsetSource; michael@0: } michael@0: michael@0: /** michael@0: * Add an observer that gets notified whenever the charset changes. michael@0: */ michael@0: virtual nsresult AddCharSetObserver(nsIObserver* aObserver) = 0; michael@0: michael@0: /** michael@0: * Remove a charset observer. michael@0: */ michael@0: virtual void RemoveCharSetObserver(nsIObserver* aObserver) = 0; michael@0: michael@0: /** michael@0: * This gets fired when the element that an id refers to changes. michael@0: * This fires at difficult times. It is generally not safe to do anything michael@0: * which could modify the DOM in any way. Use michael@0: * nsContentUtils::AddScriptRunner. michael@0: * @return true to keep the callback in the callback set, false michael@0: * to remove it. michael@0: */ michael@0: typedef bool (* IDTargetObserver)(Element* aOldElement, michael@0: Element* aNewelement, void* aData); michael@0: michael@0: /** michael@0: * Add an IDTargetObserver for a specific ID. The IDTargetObserver michael@0: * will be fired whenever the content associated with the ID changes michael@0: * in the future. If aForImage is true, mozSetImageElement can override michael@0: * what content is associated with the ID. In that case the IDTargetObserver michael@0: * will be notified at those times when the result of LookupImageElement michael@0: * changes. michael@0: * At most one (aObserver, aData, aForImage) triple can be michael@0: * registered for each ID. michael@0: * @return the content currently associated with the ID. michael@0: */ michael@0: virtual Element* AddIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver, michael@0: void* aData, bool aForImage) = 0; michael@0: /** michael@0: * Remove the (aObserver, aData, aForImage) triple for a specific ID, if michael@0: * registered. michael@0: */ michael@0: virtual void RemoveIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver, michael@0: void* aData, bool aForImage) = 0; michael@0: michael@0: /** michael@0: * Get the Content-Type of this document. michael@0: * (This will always return NS_OK, but has this signature to be compatible michael@0: * with nsIDOMDocument::GetContentType()) michael@0: */ michael@0: NS_IMETHOD GetContentType(nsAString& aContentType) = 0; michael@0: michael@0: /** michael@0: * Set the Content-Type of this document. michael@0: */ michael@0: virtual void SetContentType(const nsAString& aContentType) = 0; michael@0: michael@0: /** michael@0: * Return the language of this document. michael@0: */ michael@0: void GetContentLanguage(nsAString& aContentLanguage) const michael@0: { michael@0: CopyASCIItoUTF16(mContentLanguage, aContentLanguage); michael@0: } michael@0: michael@0: // The states BidiEnabled and MathMLEnabled should persist across multiple views michael@0: // (screen, print) of the same document. michael@0: michael@0: /** michael@0: * Check if the document contains bidi data. michael@0: * If so, we have to apply the Unicode Bidi Algorithm. michael@0: */ michael@0: bool GetBidiEnabled() const michael@0: { michael@0: return mBidiEnabled; michael@0: } michael@0: michael@0: /** michael@0: * Indicate the document contains bidi data. michael@0: * Currently, we cannot disable bidi, because once bidi is enabled, michael@0: * it affects a frame model irreversibly, and plays even though michael@0: * the document no longer contains bidi data. michael@0: */ michael@0: void SetBidiEnabled() michael@0: { michael@0: mBidiEnabled = true; michael@0: } michael@0: michael@0: /** michael@0: * Check if the document contains (or has contained) any MathML elements. michael@0: */ michael@0: bool GetMathMLEnabled() const michael@0: { michael@0: return mMathMLEnabled; michael@0: } michael@0: michael@0: void SetMathMLEnabled() michael@0: { michael@0: mMathMLEnabled = true; michael@0: } michael@0: michael@0: /** michael@0: * Ask this document whether it's the initial document in its window. michael@0: */ michael@0: bool IsInitialDocument() const michael@0: { michael@0: return mIsInitialDocumentInWindow; michael@0: } michael@0: michael@0: /** michael@0: * Tell this document that it's the initial document in its window. See michael@0: * comments on mIsInitialDocumentInWindow for when this should be called. michael@0: */ michael@0: void SetIsInitialDocument(bool aIsInitialDocument) michael@0: { michael@0: mIsInitialDocumentInWindow = aIsInitialDocument; michael@0: } michael@0: michael@0: michael@0: /** michael@0: * Get the bidi options for this document. michael@0: * @see nsBidiUtils.h michael@0: */ michael@0: uint32_t GetBidiOptions() const michael@0: { michael@0: return mBidiOptions; michael@0: } michael@0: michael@0: /** michael@0: * Set the bidi options for this document. This just sets the bits; michael@0: * callers are expected to take action as needed if they want this michael@0: * change to actually change anything immediately. michael@0: * @see nsBidiUtils.h michael@0: */ michael@0: void SetBidiOptions(uint32_t aBidiOptions) michael@0: { michael@0: mBidiOptions = aBidiOptions; michael@0: } michael@0: michael@0: /** michael@0: * Get the has mixed active content loaded flag for this document. michael@0: */ michael@0: bool GetHasMixedActiveContentLoaded() michael@0: { michael@0: return mHasMixedActiveContentLoaded; michael@0: } michael@0: michael@0: /** michael@0: * Set the has mixed active content loaded flag for this document. michael@0: */ michael@0: void SetHasMixedActiveContentLoaded(bool aHasMixedActiveContentLoaded) michael@0: { michael@0: mHasMixedActiveContentLoaded = aHasMixedActiveContentLoaded; michael@0: } michael@0: michael@0: /** michael@0: * Get mixed active content blocked flag for this document. michael@0: */ michael@0: bool GetHasMixedActiveContentBlocked() michael@0: { michael@0: return mHasMixedActiveContentBlocked; michael@0: } michael@0: michael@0: /** michael@0: * Set the mixed active content blocked flag for this document. michael@0: */ michael@0: void SetHasMixedActiveContentBlocked(bool aHasMixedActiveContentBlocked) michael@0: { michael@0: mHasMixedActiveContentBlocked = aHasMixedActiveContentBlocked; michael@0: } michael@0: michael@0: /** michael@0: * Get the has mixed display content loaded flag for this document. michael@0: */ michael@0: bool GetHasMixedDisplayContentLoaded() michael@0: { michael@0: return mHasMixedDisplayContentLoaded; michael@0: } michael@0: michael@0: /** michael@0: * Set the has mixed display content loaded flag for this document. michael@0: */ michael@0: void SetHasMixedDisplayContentLoaded(bool aHasMixedDisplayContentLoaded) michael@0: { michael@0: mHasMixedDisplayContentLoaded = aHasMixedDisplayContentLoaded; michael@0: } michael@0: michael@0: /** michael@0: * Get mixed display content blocked flag for this document. michael@0: */ michael@0: bool GetHasMixedDisplayContentBlocked() michael@0: { michael@0: return mHasMixedDisplayContentBlocked; michael@0: } michael@0: michael@0: /** michael@0: * Set the mixed display content blocked flag for this document. michael@0: */ michael@0: void SetHasMixedDisplayContentBlocked(bool aHasMixedDisplayContentBlocked) michael@0: { michael@0: mHasMixedDisplayContentBlocked = aHasMixedDisplayContentBlocked; michael@0: } michael@0: michael@0: /** michael@0: * Get the sandbox flags for this document. michael@0: * @see nsSandboxFlags.h for the possible flags michael@0: */ michael@0: uint32_t GetSandboxFlags() const michael@0: { michael@0: return mSandboxFlags; michael@0: } michael@0: michael@0: /** michael@0: * Set the sandbox flags for this document. michael@0: * @see nsSandboxFlags.h for the possible flags michael@0: */ michael@0: void SetSandboxFlags(uint32_t sandboxFlags) michael@0: { michael@0: mSandboxFlags = sandboxFlags; michael@0: } michael@0: michael@0: /** michael@0: * Access HTTP header data (this may also get set from other michael@0: * sources, like HTML META tags). michael@0: */ michael@0: virtual void GetHeaderData(nsIAtom* aHeaderField, nsAString& aData) const = 0; michael@0: virtual void SetHeaderData(nsIAtom* aheaderField, const nsAString& aData) = 0; michael@0: michael@0: /** michael@0: * Create a new presentation shell that will use aContext for its michael@0: * presentation context (presentation contexts <b>must not</b> be michael@0: * shared among multiple presentation shells). The caller of this michael@0: * method is responsible for calling BeginObservingDocument() on the michael@0: * presshell if the presshell should observe document mutations. michael@0: */ michael@0: virtual already_AddRefed<nsIPresShell> CreateShell(nsPresContext* aContext, michael@0: nsViewManager* aViewManager, michael@0: nsStyleSet* aStyleSet) = 0; michael@0: virtual void DeleteShell() = 0; michael@0: michael@0: nsIPresShell* GetShell() const michael@0: { michael@0: return GetBFCacheEntry() ? nullptr : mPresShell; michael@0: } michael@0: michael@0: void DisallowBFCaching() michael@0: { michael@0: NS_ASSERTION(!mBFCacheEntry, "We're already in the bfcache!"); michael@0: mBFCacheDisallowed = true; michael@0: } michael@0: michael@0: bool IsBFCachingAllowed() const michael@0: { michael@0: return !mBFCacheDisallowed; michael@0: } michael@0: michael@0: void SetBFCacheEntry(nsIBFCacheEntry* aEntry) michael@0: { michael@0: NS_ASSERTION(IsBFCachingAllowed() || !aEntry, michael@0: "You should have checked!"); michael@0: michael@0: mBFCacheEntry = aEntry; michael@0: } michael@0: michael@0: nsIBFCacheEntry* GetBFCacheEntry() const michael@0: { michael@0: return mBFCacheEntry; michael@0: } michael@0: michael@0: /** michael@0: * Return the parent document of this document. Will return null michael@0: * unless this document is within a compound document and has a michael@0: * parent. Note that this parent chain may cross chrome boundaries. michael@0: */ michael@0: nsIDocument *GetParentDocument() const michael@0: { michael@0: return mParentDocument; michael@0: } michael@0: michael@0: /** michael@0: * Set the parent document of this document. michael@0: */ michael@0: void SetParentDocument(nsIDocument* aParent) michael@0: { michael@0: mParentDocument = aParent; michael@0: } michael@0: michael@0: /** michael@0: * Are plugins allowed in this document ? michael@0: */ michael@0: virtual nsresult GetAllowPlugins (bool* aAllowPlugins) = 0; michael@0: michael@0: /** michael@0: * Set the sub document for aContent to aSubDoc. michael@0: */ michael@0: virtual nsresult SetSubDocumentFor(Element* aContent, michael@0: nsIDocument* aSubDoc) = 0; michael@0: michael@0: /** michael@0: * Get the sub document for aContent michael@0: */ michael@0: virtual nsIDocument *GetSubDocumentFor(nsIContent *aContent) const = 0; michael@0: michael@0: /** michael@0: * Find the content node for which aDocument is a sub document. michael@0: */ michael@0: virtual Element* FindContentForSubDocument(nsIDocument* aDocument) const = 0; michael@0: michael@0: /** michael@0: * Return the doctype for this document. michael@0: */ michael@0: mozilla::dom::DocumentType* GetDoctype() const; michael@0: michael@0: /** michael@0: * Return the root element for this document. michael@0: */ michael@0: Element* GetRootElement() const; michael@0: michael@0: virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) = 0; michael@0: michael@0: /** michael@0: * True iff this doc will ignore manual character encoding overrides. michael@0: */ michael@0: virtual bool WillIgnoreCharsetOverride() { michael@0: return true; michael@0: } michael@0: michael@0: /** michael@0: * Return whether the document was created by a srcdoc iframe. michael@0: */ michael@0: bool IsSrcdocDocument() const { michael@0: return mIsSrcdocDocument; michael@0: } michael@0: michael@0: /** michael@0: * Sets whether the document was created by a srcdoc iframe. michael@0: */ michael@0: void SetIsSrcdocDocument(bool aIsSrcdocDocument) { michael@0: mIsSrcdocDocument = aIsSrcdocDocument; michael@0: } michael@0: michael@0: /* michael@0: * Gets the srcdoc string from within the channel (assuming both exist). michael@0: * Returns a void string if this isn't a srcdoc document or if michael@0: * the channel has not been set. michael@0: */ michael@0: nsresult GetSrcdocData(nsAString& aSrcdocData); michael@0: michael@0: bool DidDocumentOpen() { michael@0: return mDidDocumentOpen; michael@0: } michael@0: michael@0: protected: michael@0: virtual Element *GetRootElementInternal() const = 0; michael@0: michael@0: private: michael@0: class SelectorCacheKey michael@0: { michael@0: public: michael@0: SelectorCacheKey(const nsAString& aString) : mKey(aString) michael@0: { michael@0: MOZ_COUNT_CTOR(SelectorCacheKey); michael@0: } michael@0: michael@0: nsString mKey; michael@0: nsExpirationState mState; michael@0: michael@0: nsExpirationState* GetExpirationState() { return &mState; } michael@0: michael@0: ~SelectorCacheKey() michael@0: { michael@0: MOZ_COUNT_DTOR(SelectorCacheKey); michael@0: } michael@0: }; michael@0: michael@0: class SelectorCacheKeyDeleter; michael@0: michael@0: public: michael@0: class SelectorCache MOZ_FINAL michael@0: : public nsExpirationTracker<SelectorCacheKey, 4> michael@0: { michael@0: public: michael@0: SelectorCache(); michael@0: michael@0: // CacheList takes ownership of aSelectorList. michael@0: void CacheList(const nsAString& aSelector, nsCSSSelectorList* aSelectorList); michael@0: michael@0: virtual void NotifyExpired(SelectorCacheKey* aSelector) MOZ_OVERRIDE; michael@0: michael@0: // We do not call MarkUsed because it would just slow down lookups and michael@0: // because we're OK expiring things after a few seconds even if they're michael@0: // being used. Returns whether we actually had an entry for aSelector. michael@0: // If we have an entry and *aList is null, that indicates that aSelector michael@0: // has already been parsed and is not a syntactically valid selector. michael@0: bool GetList(const nsAString& aSelector, nsCSSSelectorList** aList) michael@0: { michael@0: return mTable.Get(aSelector, aList); michael@0: } michael@0: michael@0: ~SelectorCache() michael@0: { michael@0: AgeAllGenerations(); michael@0: } michael@0: michael@0: private: michael@0: nsClassHashtable<nsStringHashKey, nsCSSSelectorList> mTable; michael@0: }; michael@0: michael@0: SelectorCache& GetSelectorCache() michael@0: { michael@0: return mSelectorCache; michael@0: } michael@0: // Get the root <html> element, or return null if there isn't one (e.g. michael@0: // if the root isn't <html>) michael@0: Element* GetHtmlElement() const; michael@0: // Returns the first child of GetHtmlContent which has the given tag, michael@0: // or nullptr if that doesn't exist. michael@0: Element* GetHtmlChildElement(nsIAtom* aTag); michael@0: // Get the canonical <body> element, or return null if there isn't one (e.g. michael@0: // if the root isn't <html> or if the <body> isn't there) michael@0: mozilla::dom::HTMLBodyElement* GetBodyElement(); michael@0: // Get the canonical <head> element, or return null if there isn't one (e.g. michael@0: // if the root isn't <html> or if the <head> isn't there) michael@0: Element* GetHeadElement() { michael@0: return GetHtmlChildElement(nsGkAtoms::head); michael@0: } michael@0: michael@0: /** michael@0: * Accessors to the collection of stylesheets owned by this document. michael@0: * Style sheets are ordered, most significant last. michael@0: */ michael@0: michael@0: /** michael@0: * Get the number of stylesheets michael@0: * michael@0: * @return the number of stylesheets michael@0: * @throws no exceptions michael@0: */ michael@0: virtual int32_t GetNumberOfStyleSheets() const = 0; michael@0: michael@0: /** michael@0: * Get a particular stylesheet michael@0: * @param aIndex the index the stylesheet lives at. This is zero-based michael@0: * @return the stylesheet at aIndex. Null if aIndex is out of range. michael@0: * @throws no exceptions michael@0: */ michael@0: virtual nsIStyleSheet* GetStyleSheetAt(int32_t aIndex) const = 0; michael@0: michael@0: /** michael@0: * Insert a sheet at a particular spot in the stylesheet list (zero-based) michael@0: * @param aSheet the sheet to insert michael@0: * @param aIndex the index to insert at. This index will be michael@0: * adjusted for the "special" sheets. michael@0: * @throws no exceptions michael@0: */ michael@0: virtual void InsertStyleSheetAt(nsIStyleSheet* aSheet, int32_t aIndex) = 0; michael@0: michael@0: /** michael@0: * Get the index of a particular stylesheet. This will _always_ michael@0: * consider the "special" sheets as part of the sheet list. michael@0: * @param aSheet the sheet to get the index of michael@0: * @return aIndex the index of the sheet in the full list michael@0: */ michael@0: virtual int32_t GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const = 0; michael@0: michael@0: /** michael@0: * Replace the stylesheets in aOldSheets with the stylesheets in michael@0: * aNewSheets. The two lists must have equal length, and the sheet michael@0: * at positon J in the first list will be replaced by the sheet at michael@0: * position J in the second list. Some sheets in the second list michael@0: * may be null; if so the corresponding sheets in the first list michael@0: * will simply be removed. michael@0: */ michael@0: virtual void UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets, michael@0: nsCOMArray<nsIStyleSheet>& aNewSheets) = 0; michael@0: michael@0: /** michael@0: * Add a stylesheet to the document michael@0: */ michael@0: virtual void AddStyleSheet(nsIStyleSheet* aSheet) = 0; michael@0: michael@0: /** michael@0: * Remove a stylesheet from the document michael@0: */ michael@0: virtual void RemoveStyleSheet(nsIStyleSheet* aSheet) = 0; michael@0: michael@0: /** michael@0: * Notify the document that the applicable state of the sheet changed michael@0: * and that observers should be notified and style sets updated michael@0: */ michael@0: virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet, michael@0: bool aApplicable) = 0; michael@0: michael@0: /** michael@0: * Just like the style sheet API, but for "catalog" sheets, michael@0: * extra sheets inserted at the UA level. michael@0: */ michael@0: virtual int32_t GetNumberOfCatalogStyleSheets() const = 0; michael@0: virtual nsIStyleSheet* GetCatalogStyleSheetAt(int32_t aIndex) const = 0; michael@0: virtual void AddCatalogStyleSheet(nsCSSStyleSheet* aSheet) = 0; michael@0: virtual void EnsureCatalogStyleSheet(const char *aStyleSheetURI) = 0; michael@0: michael@0: enum additionalSheetType { michael@0: eAgentSheet, michael@0: eUserSheet, michael@0: eAuthorSheet, michael@0: SheetTypeCount michael@0: }; michael@0: michael@0: virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) = 0; michael@0: virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) = 0; michael@0: virtual nsIStyleSheet* FirstAdditionalAuthorSheet() = 0; michael@0: michael@0: /** michael@0: * Get this document's CSSLoader. This is guaranteed to not return null. michael@0: */ michael@0: mozilla::css::Loader* CSSLoader() const { michael@0: return mCSSLoader; michael@0: } michael@0: michael@0: /** michael@0: * Get this document's StyleImageLoader. This is guaranteed to not return null. michael@0: */ michael@0: mozilla::css::ImageLoader* StyleImageLoader() const { michael@0: return mStyleImageLoader; michael@0: } michael@0: michael@0: /** michael@0: * Get the channel that was passed to StartDocumentLoad or Reset for this michael@0: * document. Note that this may be null in some cases (eg if michael@0: * StartDocumentLoad or Reset were never called) michael@0: */ michael@0: virtual nsIChannel* GetChannel() const = 0; michael@0: michael@0: /** michael@0: * Get this document's attribute stylesheet. May return null if michael@0: * there isn't one. michael@0: */ michael@0: nsHTMLStyleSheet* GetAttributeStyleSheet() const { michael@0: return mAttrStyleSheet; michael@0: } michael@0: michael@0: /** michael@0: * Get this document's inline style sheet. May return null if there michael@0: * isn't one michael@0: */ michael@0: nsHTMLCSSStyleSheet* GetInlineStyleSheet() const { michael@0: return mStyleAttrStyleSheet; michael@0: } michael@0: michael@0: virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject) = 0; michael@0: michael@0: /** michael@0: * Get/set the object from which the context for the event/script handling can michael@0: * be got. Normally GetScriptHandlingObject() returns the same object as michael@0: * GetScriptGlobalObject(), but if the document is loaded as data, michael@0: * non-null may be returned, even if GetScriptGlobalObject() returns null. michael@0: * aHasHadScriptHandlingObject is set true if document has had the object michael@0: * for event/script handling. Do not process any events/script if the method michael@0: * returns null, but aHasHadScriptHandlingObject is true. michael@0: */ michael@0: nsIScriptGlobalObject* michael@0: GetScriptHandlingObject(bool& aHasHadScriptHandlingObject) const michael@0: { michael@0: aHasHadScriptHandlingObject = mHasHadScriptHandlingObject; michael@0: return mScriptGlobalObject ? mScriptGlobalObject.get() : michael@0: GetScriptHandlingObjectInternal(); michael@0: } michael@0: virtual void SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject) = 0; michael@0: michael@0: /** michael@0: * Get the object that is used as the scope for all of the content michael@0: * wrappers whose owner document is this document. Unlike the script global michael@0: * object, this will only return null when the global object for this michael@0: * document is truly gone. Use this object when you're trying to find a michael@0: * content wrapper in XPConnect. michael@0: */ michael@0: virtual nsIGlobalObject* GetScopeObject() const = 0; michael@0: virtual void SetScopeObject(nsIGlobalObject* aGlobal) = 0; michael@0: michael@0: /** michael@0: * Return the window containing the document (the outer window). michael@0: */ michael@0: nsPIDOMWindow *GetWindow() const michael@0: { michael@0: return mWindow ? mWindow->GetOuterWindow() : GetWindowInternal(); michael@0: } michael@0: michael@0: bool IsInBackgroundWindow() const michael@0: { michael@0: nsPIDOMWindow* outer = mWindow ? mWindow->GetOuterWindow() : nullptr; michael@0: return outer && outer->IsBackground(); michael@0: } michael@0: michael@0: /** michael@0: * Return the inner window used as the script compilation scope for michael@0: * this document. If you're not absolutely sure you need this, use michael@0: * GetWindow(). michael@0: */ michael@0: nsPIDOMWindow* GetInnerWindow() const michael@0: { michael@0: return mRemovedFromDocShell ? nullptr : mWindow; michael@0: } michael@0: michael@0: /** michael@0: * Return the outer window ID. michael@0: */ michael@0: uint64_t OuterWindowID() const michael@0: { michael@0: nsPIDOMWindow *window = GetWindow(); michael@0: return window ? window->WindowID() : 0; michael@0: } michael@0: michael@0: /** michael@0: * Return the inner window ID. michael@0: */ michael@0: uint64_t InnerWindowID() michael@0: { michael@0: nsPIDOMWindow *window = GetInnerWindow(); michael@0: return window ? window->WindowID() : 0; michael@0: } michael@0: michael@0: /** michael@0: * Get the script loader for this document michael@0: */ michael@0: virtual nsScriptLoader* ScriptLoader() = 0; michael@0: michael@0: /** michael@0: * Add/Remove an element to the document's id and name hashes michael@0: */ michael@0: virtual void AddToIdTable(Element* aElement, nsIAtom* aId) = 0; michael@0: virtual void RemoveFromIdTable(Element* aElement, nsIAtom* aId) = 0; michael@0: virtual void AddToNameTable(Element* aElement, nsIAtom* aName) = 0; michael@0: virtual void RemoveFromNameTable(Element* aElement, nsIAtom* aName) = 0; michael@0: michael@0: /** michael@0: * Returns the element which either requested DOM full-screen mode, or michael@0: * contains the element which requested DOM full-screen mode if the michael@0: * requestee is in a subdocument. Note this element must be *in* michael@0: * this document. michael@0: */ michael@0: virtual Element* GetFullScreenElement() = 0; michael@0: michael@0: /** michael@0: * Asynchronously requests that the document make aElement the fullscreen michael@0: * element, and move into fullscreen mode. The current fullscreen element michael@0: * (if any) is pushed onto the fullscreen element stack, and it can be michael@0: * returned to fullscreen status by calling RestorePreviousFullScreenState(). michael@0: * michael@0: * Note that requesting fullscreen in a document also makes the element which michael@0: * contains this document in this document's parent document fullscreen. i.e. michael@0: * the <iframe> or <browser> that contains this document is also mode michael@0: * fullscreen. This happens recursively in all ancestor documents. michael@0: */ michael@0: virtual void AsyncRequestFullScreen(Element* aElement) = 0; michael@0: michael@0: /** michael@0: * Called when a frame in a child process has entered fullscreen or when a michael@0: * fullscreen frame in a child process changes to another origin. michael@0: * aFrameElement is the frame element which contains the child-process michael@0: * fullscreen document, and aNewOrigin is the origin of the new fullscreen michael@0: * document. michael@0: */ michael@0: virtual nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement, michael@0: const nsAString& aNewOrigin) = 0; michael@0: michael@0: /** michael@0: * Called when a frame in a remote child document has rolled back fullscreen michael@0: * so that all its fullscreen element stacks are empty; we must continue the michael@0: * rollback in this parent process' doc tree branch which is fullscreen. michael@0: * Note that only one branch of the document tree can have its documents in michael@0: * fullscreen state at one time. We're in inconsistent state if a michael@0: * fullscreen document has a parent and that parent isn't fullscreen. We michael@0: * preserve this property across process boundaries. michael@0: */ michael@0: virtual nsresult RemoteFrameFullscreenReverted() = 0; michael@0: michael@0: /** michael@0: * Restores the previous full-screen element to full-screen status. If there michael@0: * is no former full-screen element, this exits full-screen, moving the michael@0: * top-level browser window out of full-screen mode. michael@0: */ michael@0: virtual void RestorePreviousFullScreenState() = 0; michael@0: michael@0: /** michael@0: * Returns true if this document is in full-screen mode. michael@0: */ michael@0: virtual bool IsFullScreenDoc() = 0; michael@0: michael@0: /** michael@0: * Returns true if this document is a fullscreen leaf document, i.e. it michael@0: * is in fullscreen mode and has no fullscreen children. michael@0: */ michael@0: virtual bool IsFullscreenLeaf() = 0; michael@0: michael@0: /** michael@0: * Returns the document which is at the root of this document's branch michael@0: * in the in-process document tree. Returns nullptr if the document isn't michael@0: * fullscreen. michael@0: */ michael@0: virtual nsIDocument* GetFullscreenRoot() = 0; michael@0: michael@0: /** michael@0: * Sets the fullscreen root to aRoot. This stores a weak reference to aRoot michael@0: * in this document. michael@0: */ michael@0: virtual void SetFullscreenRoot(nsIDocument* aRoot) = 0; michael@0: michael@0: /** michael@0: * Sets whether this document is approved for fullscreen mode. michael@0: * Documents aren't approved for fullscreen until chrome has sent a michael@0: * "fullscreen-approved" notification with a subject which is a pointer michael@0: * to the approved document. michael@0: */ michael@0: virtual void SetApprovedForFullscreen(bool aIsApproved) = 0; michael@0: michael@0: /** michael@0: * Exits documents out of DOM fullscreen mode. michael@0: * michael@0: * If aDocument is null, all fullscreen documents in all browser windows michael@0: * exit fullscreen. michael@0: * michael@0: * If aDocument is non null, all documents from aDocument's fullscreen root michael@0: * to the fullscreen leaf exit fullscreen. michael@0: * michael@0: * Note that the fullscreen leaf is the bottom-most document which is michael@0: * fullscreen, it may have non-fullscreen child documents. The fullscreen michael@0: * root is usually the chrome document, but if fullscreen is content-only, michael@0: * (see the comment in nsContentUtils.h on IsFullscreenApiContentOnly()) michael@0: * the fullscreen root will be a direct child of the chrome document, and michael@0: * there may be other branches of the same doctree that are fullscreen. michael@0: * michael@0: * If aRunAsync is true, fullscreen is executed asynchronously. michael@0: * michael@0: * Note if aDocument is not fullscreen this function has no effect, even if michael@0: * aDocument has fullscreen ancestors. michael@0: */ michael@0: static void ExitFullscreen(nsIDocument* aDocument, bool aRunAsync); michael@0: michael@0: virtual void RequestPointerLock(Element* aElement) = 0; michael@0: michael@0: static void UnlockPointer(nsIDocument* aDoc = nullptr); michael@0: michael@0: michael@0: //---------------------------------------------------------------------- michael@0: michael@0: // Document notification API's michael@0: michael@0: /** michael@0: * Add a new observer of document change notifications. Whenever michael@0: * content is changed, appended, inserted or removed the observers are michael@0: * informed. An observer that is already observing the document must michael@0: * not be added without being removed first. michael@0: */ michael@0: virtual void AddObserver(nsIDocumentObserver* aObserver) = 0; michael@0: michael@0: /** michael@0: * Remove an observer of document change notifications. This will michael@0: * return false if the observer cannot be found. michael@0: */ michael@0: virtual bool RemoveObserver(nsIDocumentObserver* aObserver) = 0; michael@0: michael@0: // Observation hooks used to propagate notifications to document observers. michael@0: // BeginUpdate must be called before any batch of modifications of the michael@0: // content model or of style data, EndUpdate must be called afterward. michael@0: // To make this easy and painless, use the mozAutoDocUpdate helper class. michael@0: virtual void BeginUpdate(nsUpdateType aUpdateType) = 0; michael@0: virtual void EndUpdate(nsUpdateType aUpdateType) = 0; michael@0: virtual void BeginLoad() = 0; michael@0: virtual void EndLoad() = 0; michael@0: michael@0: enum ReadyState { READYSTATE_UNINITIALIZED = 0, READYSTATE_LOADING = 1, READYSTATE_INTERACTIVE = 3, READYSTATE_COMPLETE = 4}; michael@0: virtual void SetReadyStateInternal(ReadyState rs) = 0; michael@0: ReadyState GetReadyStateEnum() michael@0: { michael@0: return mReadyState; michael@0: } michael@0: michael@0: // notify that a content node changed state. This must happen under michael@0: // a scriptblocker but NOT within a begin/end update. michael@0: virtual void ContentStateChanged(nsIContent* aContent, michael@0: mozilla::EventStates aStateMask) = 0; michael@0: michael@0: // Notify that a document state has changed. michael@0: // This should only be called by callers whose state is also reflected in the michael@0: // implementation of nsDocument::GetDocumentState. michael@0: virtual void DocumentStatesChanged(mozilla::EventStates aStateMask) = 0; michael@0: michael@0: // Observation hooks for style data to propagate notifications michael@0: // to document observers michael@0: virtual void StyleRuleChanged(nsIStyleSheet* aStyleSheet, michael@0: nsIStyleRule* aOldStyleRule, michael@0: nsIStyleRule* aNewStyleRule) = 0; michael@0: virtual void StyleRuleAdded(nsIStyleSheet* aStyleSheet, michael@0: nsIStyleRule* aStyleRule) = 0; michael@0: virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet, michael@0: nsIStyleRule* aStyleRule) = 0; michael@0: michael@0: /** michael@0: * Flush notifications for this document and its parent documents michael@0: * (since those may affect the layout of this one). michael@0: */ michael@0: virtual void FlushPendingNotifications(mozFlushType aType) = 0; michael@0: michael@0: /** michael@0: * Calls FlushPendingNotifications on any external resources this document michael@0: * has. If this document has no external resources or is an external resource michael@0: * itself this does nothing. This should only be called with michael@0: * aType >= Flush_Style. michael@0: */ michael@0: virtual void FlushExternalResources(mozFlushType aType) = 0; michael@0: michael@0: nsBindingManager* BindingManager() const michael@0: { michael@0: return mNodeInfoManager->GetBindingManager(); michael@0: } michael@0: michael@0: /** michael@0: * Only to be used inside Gecko, you can't really do anything with the michael@0: * pointer outside Gecko anyway. michael@0: */ michael@0: nsNodeInfoManager* NodeInfoManager() const michael@0: { michael@0: return mNodeInfoManager; michael@0: } michael@0: michael@0: /** michael@0: * Reset the document using the given channel and loadgroup. This works michael@0: * like ResetToURI, but also sets the document's channel to aChannel. michael@0: * The principal of the document will be set from the channel. michael@0: */ michael@0: virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) = 0; michael@0: michael@0: /** michael@0: * Reset this document to aURI, aLoadGroup, and aPrincipal. aURI must not be michael@0: * null. If aPrincipal is null, a codebase principal based on aURI will be michael@0: * used. michael@0: */ michael@0: virtual void ResetToURI(nsIURI *aURI, nsILoadGroup* aLoadGroup, michael@0: nsIPrincipal* aPrincipal) = 0; michael@0: michael@0: /** michael@0: * Set the container (docshell) for this document. Virtual so that michael@0: * docshell can call it. michael@0: */ michael@0: virtual void SetContainer(nsDocShell* aContainer); michael@0: michael@0: /** michael@0: * Get the container (docshell) for this document. michael@0: */ michael@0: virtual nsISupports* GetContainer() const; michael@0: michael@0: /** michael@0: * Get the container's load context for this document. michael@0: */ michael@0: nsILoadContext* GetLoadContext() const; michael@0: michael@0: /** michael@0: * Get docshell the for this document. michael@0: */ michael@0: nsIDocShell* GetDocShell() const; michael@0: michael@0: /** michael@0: * Set and get XML declaration. If aVersion is null there is no declaration. michael@0: * aStandalone takes values -1, 0 and 1 indicating respectively that there michael@0: * was no standalone parameter in the declaration, that it was given as no, michael@0: * or that it was given as yes. michael@0: */ michael@0: virtual void SetXMLDeclaration(const char16_t *aVersion, michael@0: const char16_t *aEncoding, michael@0: const int32_t aStandalone) = 0; michael@0: virtual void GetXMLDeclaration(nsAString& aVersion, michael@0: nsAString& aEncoding, michael@0: nsAString& Standalone) = 0; michael@0: michael@0: bool IsHTML() const michael@0: { michael@0: return mIsRegularHTML; michael@0: } michael@0: bool IsXUL() const michael@0: { michael@0: return mIsXUL; michael@0: } michael@0: michael@0: virtual bool IsScriptEnabled() = 0; michael@0: michael@0: /** michael@0: * Create an element with the specified name, prefix and namespace ID. michael@0: */ michael@0: virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix, michael@0: int32_t aNamespaceID, michael@0: nsIContent** aResult) = 0; michael@0: michael@0: /** michael@0: * Get the security info (i.e. SSL state etc) that the document got michael@0: * from the channel/document that created the content of the michael@0: * document. michael@0: * michael@0: * @see nsIChannel michael@0: */ michael@0: nsISupports *GetSecurityInfo() michael@0: { michael@0: return mSecurityInfo; michael@0: } michael@0: michael@0: /** michael@0: * Returns the default namespace ID used for elements created in this michael@0: * document. michael@0: */ michael@0: int32_t GetDefaultNamespaceID() const michael@0: { michael@0: return mDefaultElementType; michael@0: } michael@0: michael@0: void DeleteAllProperties(); michael@0: void DeleteAllPropertiesFor(nsINode* aNode); michael@0: michael@0: nsPropertyTable* PropertyTable(uint16_t aCategory) { michael@0: if (aCategory == 0) michael@0: return &mPropertyTable; michael@0: return GetExtraPropertyTable(aCategory); michael@0: } michael@0: uint32_t GetPropertyTableCount() michael@0: { return mExtraPropertyTables.Length() + 1; } michael@0: michael@0: /** michael@0: * Sets the ID used to identify this part of the multipart document michael@0: */ michael@0: void SetPartID(uint32_t aID) { michael@0: mPartID = aID; michael@0: } michael@0: michael@0: /** michael@0: * Return the ID used to identify this part of the multipart document michael@0: */ michael@0: uint32_t GetPartID() const { michael@0: return mPartID; michael@0: } michael@0: michael@0: /** michael@0: * Sanitize the document by resetting all input elements and forms that have michael@0: * autocomplete=off to their default values. michael@0: */ michael@0: virtual void Sanitize() = 0; michael@0: michael@0: /** michael@0: * Enumerate all subdocuments. michael@0: * The enumerator callback should return true to continue enumerating, or michael@0: * false to stop. This will never get passed a null aDocument. michael@0: */ michael@0: typedef bool (*nsSubDocEnumFunc)(nsIDocument *aDocument, void *aData); michael@0: virtual void EnumerateSubDocuments(nsSubDocEnumFunc aCallback, michael@0: void *aData) = 0; michael@0: michael@0: /** michael@0: * Check whether it is safe to cache the presentation of this document michael@0: * and all of its subdocuments. This method checks the following conditions michael@0: * recursively: michael@0: * - Some document types, such as plugin documents, cannot be safely cached. michael@0: * - If there are any pending requests, we don't allow the presentation michael@0: * to be cached. Ideally these requests would be suspended and resumed, michael@0: * but that is difficult in some cases, such as XMLHttpRequest. michael@0: * - If there are any beforeunload or unload listeners, we must fire them michael@0: * for correctness, but this likely puts the document into a state where michael@0: * it would not function correctly if restored. michael@0: * michael@0: * |aNewRequest| should be the request for a new document which will michael@0: * replace this document in the docshell. The new document's request michael@0: * will be ignored when checking for active requests. If there is no michael@0: * request associated with the new document, this parameter may be null. michael@0: */ michael@0: virtual bool CanSavePresentation(nsIRequest *aNewRequest) = 0; michael@0: michael@0: /** michael@0: * Notify the document that its associated ContentViewer is being destroyed. michael@0: * This releases circular references so that the document can go away. michael@0: * Destroy() is only called on documents that have a content viewer. michael@0: */ michael@0: virtual void Destroy() = 0; michael@0: michael@0: /** michael@0: * Notify the document that its associated ContentViewer is no longer michael@0: * the current viewer for the docshell. The document might still michael@0: * be rendered in "zombie state" until the next document is ready. michael@0: * The document should save form control state. michael@0: */ michael@0: virtual void RemovedFromDocShell() = 0; michael@0: michael@0: /** michael@0: * Get the layout history state that should be used to save and restore state michael@0: * for nodes in this document. This may return null; if that happens state michael@0: * saving and restoration is not possible. michael@0: */ michael@0: virtual already_AddRefed<nsILayoutHistoryState> GetLayoutHistoryState() const = 0; michael@0: michael@0: /** michael@0: * Methods that can be used to prevent onload firing while an event that michael@0: * should block onload is posted. onload is guaranteed to not fire until michael@0: * either all calls to BlockOnload() have been matched by calls to michael@0: * UnblockOnload() or the load has been stopped altogether (by the user michael@0: * pressing the Stop button, say). michael@0: */ michael@0: virtual void BlockOnload() = 0; michael@0: /** michael@0: * @param aFireSync whether to fire onload synchronously. If false, michael@0: * onload will fire asynchronously after all onload blocks have been michael@0: * removed. It will NOT fire from inside UnblockOnload. If true, michael@0: * onload may fire from inside UnblockOnload. michael@0: */ michael@0: virtual void UnblockOnload(bool aFireSync) = 0; michael@0: michael@0: void BlockDOMContentLoaded() michael@0: { michael@0: ++mBlockDOMContentLoaded; michael@0: } michael@0: michael@0: virtual void UnblockDOMContentLoaded() = 0; michael@0: michael@0: /** michael@0: * Notification that the page has been shown, for documents which are loaded michael@0: * into a DOM window. This corresponds to the completion of document load, michael@0: * or to the page's presentation being restored into an existing DOM window. michael@0: * This notification fires applicable DOM events to the content window. See michael@0: * nsIDOMPageTransitionEvent.idl for a description of the |aPersisted| michael@0: * parameter. If aDispatchStartTarget is null, the pageshow event is michael@0: * dispatched on the ScriptGlobalObject for this document, otherwise it's michael@0: * dispatched on aDispatchStartTarget. michael@0: * Note: if aDispatchStartTarget isn't null, the showing state of the michael@0: * document won't be altered. michael@0: */ michael@0: virtual void OnPageShow(bool aPersisted, michael@0: mozilla::dom::EventTarget* aDispatchStartTarget) = 0; michael@0: michael@0: /** michael@0: * Notification that the page has been hidden, for documents which are loaded michael@0: * into a DOM window. This corresponds to the unloading of the document, or michael@0: * to the document's presentation being saved but removed from an existing michael@0: * DOM window. This notification fires applicable DOM events to the content michael@0: * window. See nsIDOMPageTransitionEvent.idl for a description of the michael@0: * |aPersisted| parameter. If aDispatchStartTarget is null, the pagehide michael@0: * event is dispatched on the ScriptGlobalObject for this document, michael@0: * otherwise it's dispatched on aDispatchStartTarget. michael@0: * Note: if aDispatchStartTarget isn't null, the showing state of the michael@0: * document won't be altered. michael@0: */ michael@0: virtual void OnPageHide(bool aPersisted, michael@0: mozilla::dom::EventTarget* aDispatchStartTarget) = 0; michael@0: michael@0: /* michael@0: * We record the set of links in the document that are relevant to michael@0: * style. michael@0: */ michael@0: /** michael@0: * Notification that an element is a link that is relevant to style. michael@0: */ michael@0: virtual void AddStyleRelevantLink(mozilla::dom::Link* aLink) = 0; michael@0: /** michael@0: * Notification that an element is a link and its URI might have been michael@0: * changed or the element removed. If the element is still a link relevant michael@0: * to style, then someone must ensure that AddStyleRelevantLink is michael@0: * (eventually) called on it again. michael@0: */ michael@0: virtual void ForgetLink(mozilla::dom::Link* aLink) = 0; michael@0: michael@0: /** michael@0: * Resets and removes a box object from the document's box object cache michael@0: * michael@0: * @param aElement canonical nsIContent pointer of the box object's element michael@0: */ michael@0: virtual void ClearBoxObjectFor(nsIContent *aContent) = 0; michael@0: michael@0: /** michael@0: * Get the box object for an element. This is not exposed through a michael@0: * scriptable interface except for XUL documents. michael@0: */ michael@0: virtual already_AddRefed<nsIBoxObject> michael@0: GetBoxObjectFor(mozilla::dom::Element* aElement, michael@0: mozilla::ErrorResult& aRv) = 0; michael@0: michael@0: /** michael@0: * Get the compatibility mode for this document michael@0: */ michael@0: nsCompatibility GetCompatibilityMode() const { michael@0: return mCompatMode; michael@0: } michael@0: michael@0: /** michael@0: * Check whether we've ever fired a DOMTitleChanged event for this michael@0: * document. michael@0: */ michael@0: bool HaveFiredDOMTitleChange() const { michael@0: return mHaveFiredTitleChange; michael@0: } michael@0: michael@0: /** michael@0: * See GetAnonymousElementByAttribute on nsIDOMDocumentXBL. michael@0: */ michael@0: virtual Element* michael@0: GetAnonymousElementByAttribute(nsIContent* aElement, michael@0: nsIAtom* aAttrName, michael@0: const nsAString& aAttrValue) const = 0; michael@0: michael@0: /** michael@0: * Helper for nsIDOMDocument::elementFromPoint implementation that allows michael@0: * ignoring the scroll frame and/or avoiding layout flushes. michael@0: * michael@0: * @see nsIDOMWindowUtils::elementFromPoint michael@0: */ michael@0: virtual Element* ElementFromPointHelper(float aX, float aY, michael@0: bool aIgnoreRootScrollFrame, michael@0: bool aFlushLayout) = 0; michael@0: michael@0: virtual nsresult NodesFromRectHelper(float aX, float aY, michael@0: float aTopSize, float aRightSize, michael@0: float aBottomSize, float aLeftSize, michael@0: bool aIgnoreRootScrollFrame, michael@0: bool aFlushLayout, michael@0: nsIDOMNodeList** aReturn) = 0; michael@0: michael@0: /** michael@0: * See FlushSkinBindings on nsBindingManager michael@0: */ michael@0: virtual void FlushSkinBindings() = 0; michael@0: michael@0: /** michael@0: * To batch DOMSubtreeModified, document needs to be informed when michael@0: * a mutation event might be dispatched, even if the event isn't actually michael@0: * created because there are no listeners for it. michael@0: * michael@0: * @param aTarget is the target for the mutation event. michael@0: */ michael@0: void MayDispatchMutationEvent(nsINode* aTarget) michael@0: { michael@0: if (mSubtreeModifiedDepth > 0) { michael@0: mSubtreeModifiedTargets.AppendObject(aTarget); michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Marks as not-going-to-be-collected for the given generation of michael@0: * cycle collection. michael@0: */ michael@0: void MarkUncollectableForCCGeneration(uint32_t aGeneration) michael@0: { michael@0: mMarkedCCGeneration = aGeneration; michael@0: } michael@0: michael@0: /** michael@0: * Gets the cycle collector generation this document is marked for. michael@0: */ michael@0: uint32_t GetMarkedCCGeneration() michael@0: { michael@0: return mMarkedCCGeneration; michael@0: } michael@0: michael@0: bool IsLoadedAsData() michael@0: { michael@0: return mLoadedAsData; michael@0: } michael@0: michael@0: bool IsLoadedAsInteractiveData() michael@0: { michael@0: return mLoadedAsInteractiveData; michael@0: } michael@0: michael@0: bool MayStartLayout() michael@0: { michael@0: return mMayStartLayout; michael@0: } michael@0: michael@0: void SetMayStartLayout(bool aMayStartLayout) michael@0: { michael@0: mMayStartLayout = aMayStartLayout; michael@0: } michael@0: michael@0: already_AddRefed<nsIDocumentEncoder> GetCachedEncoder(); michael@0: michael@0: void SetCachedEncoder(already_AddRefed<nsIDocumentEncoder> aEncoder); michael@0: michael@0: // In case of failure, the document really can't initialize the frame loader. michael@0: virtual nsresult InitializeFrameLoader(nsFrameLoader* aLoader) = 0; michael@0: // In case of failure, the caller must handle the error, for example by michael@0: // finalizing frame loader asynchronously. michael@0: virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader) = 0; michael@0: // Removes the frame loader of aShell from the initialization list. michael@0: virtual void TryCancelFrameLoaderInitialization(nsIDocShell* aShell) = 0; michael@0: // Returns true if the frame loader of aShell is in the finalization list. michael@0: virtual bool FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell) = 0; michael@0: michael@0: /** michael@0: * Check whether this document is a root document that is not an michael@0: * external resource. michael@0: */ michael@0: bool IsRootDisplayDocument() const michael@0: { michael@0: return !mParentDocument && !mDisplayDocument; michael@0: } michael@0: michael@0: bool IsBeingUsedAsImage() const { michael@0: return mIsBeingUsedAsImage; michael@0: } michael@0: michael@0: void SetIsBeingUsedAsImage() { michael@0: mIsBeingUsedAsImage = true; michael@0: } michael@0: michael@0: bool IsResourceDoc() const { michael@0: return IsBeingUsedAsImage() || // Are we a helper-doc for an SVG image? michael@0: !!mDisplayDocument; // Are we an external resource doc? michael@0: } michael@0: michael@0: /** michael@0: * Get the document for which this document is an external resource. This michael@0: * will be null if this document is not an external resource. Otherwise, michael@0: * GetDisplayDocument() will return a non-null document, and michael@0: * GetDisplayDocument()->GetDisplayDocument() is guaranteed to be null. michael@0: */ michael@0: nsIDocument* GetDisplayDocument() const michael@0: { michael@0: return mDisplayDocument; michael@0: } michael@0: michael@0: /** michael@0: * Set the display document for this document. aDisplayDocument must not be michael@0: * null. michael@0: */ michael@0: void SetDisplayDocument(nsIDocument* aDisplayDocument) michael@0: { michael@0: NS_PRECONDITION(!GetShell() && michael@0: !GetContainer() && michael@0: !GetWindow(), michael@0: "Shouldn't set mDisplayDocument on documents that already " michael@0: "have a presentation or a docshell or a window"); michael@0: NS_PRECONDITION(aDisplayDocument != this, "Should be different document"); michael@0: NS_PRECONDITION(!aDisplayDocument->GetDisplayDocument(), michael@0: "Display documents should not nest"); michael@0: mDisplayDocument = aDisplayDocument; michael@0: } michael@0: michael@0: /** michael@0: * A class that represents an external resource load that has begun but michael@0: * doesn't have a document yet. Observers can be registered on this object, michael@0: * and will be notified after the document is created. Observers registered michael@0: * after the document has been created will NOT be notified. When observers michael@0: * are notified, the subject will be the newly-created document, the topic michael@0: * will be "external-resource-document-created", and the data will be null. michael@0: * If document creation fails for some reason, observers will still be michael@0: * notified, with a null document pointer. michael@0: */ michael@0: class ExternalResourceLoad : public nsISupports michael@0: { michael@0: public: michael@0: virtual ~ExternalResourceLoad() {} michael@0: michael@0: void AddObserver(nsIObserver* aObserver) { michael@0: NS_PRECONDITION(aObserver, "Must have observer"); michael@0: mObservers.AppendElement(aObserver); michael@0: } michael@0: michael@0: const nsTArray< nsCOMPtr<nsIObserver> > & Observers() { michael@0: return mObservers; michael@0: } michael@0: protected: michael@0: nsAutoTArray< nsCOMPtr<nsIObserver>, 8 > mObservers; michael@0: }; michael@0: michael@0: /** michael@0: * Request an external resource document for aURI. This will return the michael@0: * resource document if available. If one is not available yet, it will michael@0: * start loading as needed, and the pending load object will be returned in michael@0: * aPendingLoad so that the caller can register an observer to wait for the michael@0: * load. If this function returns null and doesn't return a pending load, michael@0: * that means that there is no resource document for this URI and won't be michael@0: * one in the future. michael@0: * michael@0: * @param aURI the URI to get michael@0: * @param aRequestingNode the node making the request michael@0: * @param aPendingLoad the pending load for this request, if any michael@0: */ michael@0: virtual nsIDocument* michael@0: RequestExternalResource(nsIURI* aURI, michael@0: nsINode* aRequestingNode, michael@0: ExternalResourceLoad** aPendingLoad) = 0; michael@0: michael@0: /** michael@0: * Enumerate the external resource documents associated with this document. michael@0: * The enumerator callback should return true to continue enumerating, or michael@0: * false to stop. This callback will never get passed a null aDocument. michael@0: */ michael@0: virtual void EnumerateExternalResources(nsSubDocEnumFunc aCallback, michael@0: void* aData) = 0; michael@0: michael@0: /** michael@0: * Return whether the document is currently showing (in the sense of michael@0: * OnPageShow() having been called already and OnPageHide() not having been michael@0: * called yet. michael@0: */ michael@0: bool IsShowing() const { return mIsShowing; } michael@0: /** michael@0: * Return whether the document is currently visible (in the sense of michael@0: * OnPageHide having been called and OnPageShow not yet having been called) michael@0: */ michael@0: bool IsVisible() const { return mVisible; } michael@0: michael@0: /** michael@0: * Return whether the document and all its ancestors are visible in the sense of michael@0: * pageshow / hide. michael@0: */ michael@0: bool IsVisibleConsideringAncestors() const; michael@0: michael@0: /** michael@0: * Return true when this document is active, i.e., the active document michael@0: * in a content viewer. Note that this will return true for bfcached michael@0: * documents, so this does NOT match the "active document" concept in michael@0: * the WHATWG spec. That would correspond to GetInnerWindow() && michael@0: * GetInnerWindow()->IsCurrentInnerWindow(). michael@0: */ michael@0: bool IsActive() const { return mDocumentContainer && !mRemovedFromDocShell; } michael@0: michael@0: void RegisterFreezableElement(nsIContent* aContent); michael@0: bool UnregisterFreezableElement(nsIContent* aContent); michael@0: typedef void (* FreezableElementEnumerator)(nsIContent*, void*); michael@0: void EnumerateFreezableElements(FreezableElementEnumerator aEnumerator, michael@0: void* aData); michael@0: michael@0: // Indicates whether mAnimationController has been (lazily) initialized. michael@0: // If this returns true, we're promising that GetAnimationController() michael@0: // will have a non-null return value. michael@0: bool HasAnimationController() { return !!mAnimationController; } michael@0: michael@0: // Getter for this document's SMIL Animation Controller. Performs lazy michael@0: // initialization, if this document supports animation and if michael@0: // mAnimationController isn't yet initialized. michael@0: virtual nsSMILAnimationController* GetAnimationController() = 0; michael@0: michael@0: // Makes the images on this document capable of having their animation michael@0: // active or suspended. An Image will animate as long as at least one of its michael@0: // owning Documents needs it to animate; otherwise it can suspend. michael@0: virtual void SetImagesNeedAnimating(bool aAnimating) = 0; michael@0: michael@0: enum SuppressionType { michael@0: eAnimationsOnly = 0x1, michael@0: michael@0: // Note that suppressing events also suppresses animation frames, so michael@0: // there's no need to split out events in its own bitmask. michael@0: eEvents = 0x3, michael@0: }; michael@0: michael@0: /** michael@0: * Prevents user initiated events from being dispatched to the document and michael@0: * subdocuments. michael@0: */ michael@0: virtual void SuppressEventHandling(SuppressionType aWhat, michael@0: uint32_t aIncrease = 1) = 0; michael@0: michael@0: /** michael@0: * Unsuppress event handling. michael@0: * @param aFireEvents If true, delayed events (focus/blur) will be fired michael@0: * asynchronously. michael@0: */ michael@0: virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat, michael@0: bool aFireEvents) = 0; michael@0: michael@0: uint32_t EventHandlingSuppressed() const { return mEventsSuppressed; } michael@0: uint32_t AnimationsPaused() const { return mAnimationsPaused; } michael@0: michael@0: bool IsEventHandlingEnabled() { michael@0: return !EventHandlingSuppressed() && mScriptGlobalObject; michael@0: } michael@0: michael@0: /** michael@0: * Increment the number of external scripts being evaluated. michael@0: */ michael@0: void BeginEvaluatingExternalScript() { ++mExternalScriptsBeingEvaluated; } michael@0: michael@0: /** michael@0: * Decrement the number of external scripts being evaluated. michael@0: */ michael@0: void EndEvaluatingExternalScript() { --mExternalScriptsBeingEvaluated; } michael@0: michael@0: bool IsDNSPrefetchAllowed() const { return mAllowDNSPrefetch; } michael@0: michael@0: /** michael@0: * Returns true if this document is allowed to contain XUL element and michael@0: * use non-builtin XBL bindings. michael@0: */ michael@0: bool AllowXULXBL() { michael@0: return mAllowXULXBL == eTriTrue ? true : michael@0: mAllowXULXBL == eTriFalse ? false : michael@0: InternalAllowXULXBL(); michael@0: } michael@0: michael@0: void ForceEnableXULXBL() { michael@0: mAllowXULXBL = eTriTrue; michael@0: } michael@0: michael@0: /** michael@0: * Returns the template content owner document that owns the content of michael@0: * HTMLTemplateElement. michael@0: */ michael@0: virtual nsIDocument* GetTemplateContentsOwner() = 0; michael@0: michael@0: /** michael@0: * true when this document is a static clone of a normal document. michael@0: * For example print preview and printing use static documents. michael@0: */ michael@0: bool IsStaticDocument() { return mIsStaticDocument; } michael@0: michael@0: /** michael@0: * Clones the document and subdocuments and stylesheet etc. michael@0: * @param aCloneContainer The container for the clone document. michael@0: */ michael@0: virtual already_AddRefed<nsIDocument> michael@0: CreateStaticClone(nsIDocShell* aCloneContainer); michael@0: michael@0: /** michael@0: * If this document is a static clone, this returns the original michael@0: * document. michael@0: */ michael@0: nsIDocument* GetOriginalDocument() michael@0: { michael@0: MOZ_ASSERT(!mOriginalDocument || !mOriginalDocument->GetOriginalDocument()); michael@0: return mOriginalDocument; michael@0: } michael@0: michael@0: /** michael@0: * Called by nsParser to preload images. Can be removed and code moved michael@0: * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the michael@0: * parser-module is linked with gklayout-module. aCrossOriginAttr should michael@0: * be a void string if the attr is not present. michael@0: */ michael@0: virtual void MaybePreLoadImage(nsIURI* uri, michael@0: const nsAString& aCrossOriginAttr) = 0; michael@0: michael@0: /** michael@0: * Called by nsParser to preload style sheets. Can also be merged into the michael@0: * parser if and when the parser is merged with libgklayout. aCrossOriginAttr michael@0: * should be a void string if the attr is not present. michael@0: */ michael@0: virtual void PreloadStyle(nsIURI* aURI, const nsAString& aCharset, michael@0: const nsAString& aCrossOriginAttr) = 0; michael@0: michael@0: /** michael@0: * Called by the chrome registry to load style sheets. Can be put michael@0: * back there if and when when that module is merged with libgklayout. michael@0: * michael@0: * This always does a synchronous load. If aIsAgentSheet is true, michael@0: * it also uses the system principal and enables unsafe rules. michael@0: * DO NOT USE FOR UNTRUSTED CONTENT. michael@0: */ michael@0: virtual nsresult LoadChromeSheetSync(nsIURI* aURI, bool aIsAgentSheet, michael@0: nsCSSStyleSheet** aSheet) = 0; michael@0: michael@0: /** michael@0: * Returns true if the locale used for the document specifies a direction of michael@0: * right to left. For chrome documents, this comes from the chrome registry. michael@0: * This is used to determine the current state for the :-moz-locale-dir pseudoclass michael@0: * so once can know whether a document is expected to be rendered left-to-right michael@0: * or right-to-left. michael@0: */ michael@0: virtual bool IsDocumentRightToLeft() { return false; } michael@0: michael@0: enum DocumentTheme { michael@0: Doc_Theme_Uninitialized, // not determined yet michael@0: Doc_Theme_None, michael@0: Doc_Theme_Neutral, michael@0: Doc_Theme_Dark, michael@0: Doc_Theme_Bright michael@0: }; michael@0: michael@0: /** michael@0: * Set the document's pending state object (as serialized using structured michael@0: * clone). michael@0: */ michael@0: void SetStateObject(nsIStructuredCloneContainer *scContainer); michael@0: michael@0: /** michael@0: * Returns Doc_Theme_None if there is no lightweight theme specified, michael@0: * Doc_Theme_Dark for a dark theme, Doc_Theme_Bright for a light theme, and michael@0: * Doc_Theme_Neutral for any other theme. This is used to determine the state michael@0: * of the pseudoclasses :-moz-lwtheme and :-moz-lwtheme-text. michael@0: */ michael@0: virtual int GetDocumentLWTheme() { return Doc_Theme_None; } michael@0: michael@0: /** michael@0: * Returns the document state. michael@0: * Document state bits have the form NS_DOCUMENT_STATE_* and are declared in michael@0: * nsIDocument.h. michael@0: */ michael@0: virtual mozilla::EventStates GetDocumentState() = 0; michael@0: michael@0: virtual nsISupports* GetCurrentContentSink() = 0; michael@0: michael@0: /** michael@0: * Register/Unregister a hostobject uri as being "owned" by this document. michael@0: * I.e. that its lifetime is connected with this document. When the document michael@0: * goes away it should "kill" the uri by calling michael@0: * nsHostObjectProtocolHandler::RemoveDataEntry michael@0: */ michael@0: virtual void RegisterHostObjectUri(const nsACString& aUri) = 0; michael@0: virtual void UnregisterHostObjectUri(const nsACString& aUri) = 0; michael@0: michael@0: virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0; michael@0: virtual void ScrollToRef() = 0; michael@0: virtual void ResetScrolledToRefAlready() = 0; michael@0: virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) = 0; michael@0: michael@0: /** michael@0: * This method is similar to GetElementById() from nsIDOMDocument but it michael@0: * returns a mozilla::dom::Element instead of a nsIDOMElement. michael@0: * It prevents converting nsIDOMElement to mozilla::dom::Element which is michael@0: * already converted from mozilla::dom::Element. michael@0: */ michael@0: virtual Element* GetElementById(const nsAString& aElementId) = 0; michael@0: michael@0: /** michael@0: * This method returns _all_ the elements in this document which michael@0: * have id aElementId, if there are any. Otherwise it returns null. michael@0: * The entries of the nsSmallVoidArray are Element* michael@0: */ michael@0: virtual const nsSmallVoidArray* GetAllElementsForId(const nsAString& aElementId) const = 0; michael@0: michael@0: /** michael@0: * Lookup an image element using its associated ID, which is usually provided michael@0: * by |-moz-element()|. Similar to GetElementById, with the difference that michael@0: * elements set using mozSetImageElement have higher priority. michael@0: * @param aId the ID associated the element we want to lookup michael@0: * @return the element associated with |aId| michael@0: */ michael@0: virtual Element* LookupImageElement(const nsAString& aElementId) = 0; michael@0: michael@0: virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager() = 0; michael@0: michael@0: typedef mozilla::dom::CallbackObjectHolder< michael@0: mozilla::dom::FrameRequestCallback, michael@0: nsIFrameRequestCallback> FrameRequestCallbackHolder; michael@0: nsresult ScheduleFrameRequestCallback(const FrameRequestCallbackHolder& aCallback, michael@0: int32_t *aHandle); michael@0: void CancelFrameRequestCallback(int32_t aHandle); michael@0: michael@0: typedef nsTArray<FrameRequestCallbackHolder> FrameRequestCallbackList; michael@0: /** michael@0: * Put this document's frame request callbacks into the provided michael@0: * list, and forget about them. michael@0: */ michael@0: void TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks); michael@0: michael@0: // This returns true when the document tree is being teared down. michael@0: bool InUnlinkOrDeletion() { return mInUnlinkOrDeletion; } michael@0: michael@0: /* michael@0: * Image Tracking michael@0: * michael@0: * Style and content images register their imgIRequests with their document michael@0: * so that the document can efficiently tell all descendant images when they michael@0: * are and are not visible. When an image is on-screen, we want to call michael@0: * LockImage() on it so that it doesn't do things like discarding frame data michael@0: * to save memory. The PresShell informs the document whether its images michael@0: * should be locked or not via SetImageLockingState(). michael@0: * michael@0: * See bug 512260. michael@0: */ michael@0: michael@0: // Add/Remove images from the document image tracker michael@0: virtual nsresult AddImage(imgIRequest* aImage) = 0; michael@0: // If the REQUEST_DISCARD flag is passed then if the lock count is zero we michael@0: // will request the image be discarded now (instead of waiting). michael@0: enum { REQUEST_DISCARD = 0x1 }; michael@0: virtual nsresult RemoveImage(imgIRequest* aImage, uint32_t aFlags = 0) = 0; michael@0: michael@0: // Makes the images on this document locked/unlocked. By default, the locking michael@0: // state is unlocked/false. michael@0: virtual nsresult SetImageLockingState(bool aLocked) = 0; michael@0: michael@0: virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin) = 0; michael@0: virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin) = 0; michael@0: virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins) = 0; michael@0: michael@0: virtual nsresult GetStateObject(nsIVariant** aResult) = 0; michael@0: michael@0: virtual nsDOMNavigationTiming* GetNavigationTiming() const = 0; michael@0: michael@0: virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) = 0; michael@0: michael@0: virtual Element* FindImageMap(const nsAString& aNormalizedMapName) = 0; michael@0: michael@0: // Add aLink to the set of links that need their status resolved. michael@0: void RegisterPendingLinkUpdate(mozilla::dom::Link* aLink); michael@0: michael@0: // Remove aLink from the set of links that need their status resolved. michael@0: // This function must be called when links are removed from the document. michael@0: void UnregisterPendingLinkUpdate(mozilla::dom::Link* aElement); michael@0: michael@0: // Update state on links in mLinksToUpdate. This function must michael@0: // be called prior to selector matching. michael@0: void FlushPendingLinkUpdates(); michael@0: michael@0: #define DEPRECATED_OPERATION(_op) e##_op, michael@0: enum DeprecatedOperations { michael@0: #include "nsDeprecatedOperationList.h" michael@0: eDeprecatedOperationCount michael@0: }; michael@0: #undef DEPRECATED_OPERATION michael@0: void WarnOnceAbout(DeprecatedOperations aOperation, bool asError = false); michael@0: michael@0: virtual void PostVisibilityUpdateEvent() = 0; michael@0: michael@0: bool IsSyntheticDocument() const { return mIsSyntheticDocument; } michael@0: michael@0: void SetNeedLayoutFlush() { michael@0: mNeedLayoutFlush = true; michael@0: if (mDisplayDocument) { michael@0: mDisplayDocument->SetNeedLayoutFlush(); michael@0: } michael@0: } michael@0: michael@0: void SetNeedStyleFlush() { michael@0: mNeedStyleFlush = true; michael@0: if (mDisplayDocument) { michael@0: mDisplayDocument->SetNeedStyleFlush(); michael@0: } michael@0: } michael@0: michael@0: // Note: nsIDocument is a sub-class of nsINode, which has a michael@0: // SizeOfExcludingThis function. However, because nsIDocument objects can michael@0: // only appear at the top of the DOM tree, we have a specialized measurement michael@0: // function which returns multiple sizes. michael@0: virtual void DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const; michael@0: // DocAddSizeOfIncludingThis doesn't need to be overridden by sub-classes michael@0: // because nsIDocument inherits from nsINode; see the comment above the michael@0: // declaration of nsINode::SizeOfIncludingThis. michael@0: virtual void DocAddSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const; michael@0: michael@0: bool MayHaveDOMMutationObservers() michael@0: { michael@0: return mMayHaveDOMMutationObservers; michael@0: } michael@0: michael@0: void SetMayHaveDOMMutationObservers() michael@0: { michael@0: mMayHaveDOMMutationObservers = true; michael@0: } michael@0: michael@0: bool IsInSyncOperation() michael@0: { michael@0: return mInSyncOperationCount != 0; michael@0: } michael@0: michael@0: void SetIsInSyncOperation(bool aSync) michael@0: { michael@0: if (aSync) { michael@0: ++mInSyncOperationCount; michael@0: } else { michael@0: --mInSyncOperationCount; michael@0: } michael@0: } michael@0: michael@0: bool CreatingStaticClone() const michael@0: { michael@0: return mCreatingStaticClone; michael@0: } michael@0: michael@0: /** michael@0: * Creates a new element in the HTML namespace with a local name given by michael@0: * aTag. michael@0: */ michael@0: already_AddRefed<Element> CreateHTMLElement(nsIAtom* aTag); michael@0: michael@0: // WebIDL API michael@0: nsIGlobalObject* GetParentObject() const michael@0: { michael@0: return GetScopeObject(); michael@0: } michael@0: static already_AddRefed<nsIDocument> michael@0: Constructor(const GlobalObject& aGlobal, michael@0: mozilla::ErrorResult& rv); michael@0: virtual mozilla::dom::DOMImplementation* michael@0: GetImplementation(mozilla::ErrorResult& rv) = 0; michael@0: void GetURL(nsString& retval) const; michael@0: void GetDocumentURI(nsString& retval) const; michael@0: // Return the URI for the document. michael@0: // The returned value may differ if the document is loaded via XHR, and michael@0: // when accessed from chrome privileged script and michael@0: // from content privileged script for compatibility. michael@0: void GetDocumentURIFromJS(nsString& aDocumentURI) const; michael@0: void GetCompatMode(nsString& retval) const; michael@0: void GetCharacterSet(nsAString& retval) const; michael@0: // Skip GetContentType, because our NS_IMETHOD version above works fine here. michael@0: // GetDoctype defined above michael@0: Element* GetDocumentElement() const michael@0: { michael@0: return GetRootElement(); michael@0: } michael@0: michael@0: enum ElementCallbackType { michael@0: eCreated, michael@0: eAttached, michael@0: eDetached, michael@0: eAttributeChanged michael@0: }; michael@0: michael@0: /** michael@0: * Registers an unresolved custom element that is a candidate for michael@0: * upgrade when the definition is registered via registerElement. michael@0: * |aTypeName| is the name of the custom element type, if it is not michael@0: * provided, then element name is used. |aTypeName| should be provided michael@0: * when registering a custom element that extends an existing michael@0: * element. e.g. <button is="x-button">. michael@0: */ michael@0: virtual nsresult RegisterUnresolvedElement(Element* aElement, michael@0: nsIAtom* aTypeName = nullptr) = 0; michael@0: virtual void EnqueueLifecycleCallback(ElementCallbackType aType, michael@0: Element* aCustomElement, michael@0: mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr, michael@0: mozilla::dom::CustomElementDefinition* aDefinition = nullptr) = 0; michael@0: virtual void SwizzleCustomElement(Element* aElement, michael@0: const nsAString& aTypeExtension, michael@0: uint32_t aNamespaceID, michael@0: mozilla::ErrorResult& rv) = 0; michael@0: virtual void michael@0: RegisterElement(JSContext* aCx, const nsAString& aName, michael@0: const mozilla::dom::ElementRegistrationOptions& aOptions, michael@0: JS::MutableHandle<JSObject*> aRetval, michael@0: mozilla::ErrorResult& rv) = 0; michael@0: michael@0: /** michael@0: * In some cases, new document instances must be associated with michael@0: * an existing web components custom element registry as specified. michael@0: */ michael@0: virtual void UseRegistryFromDocument(nsIDocument* aDocument) = 0; michael@0: michael@0: already_AddRefed<nsContentList> michael@0: GetElementsByTagName(const nsAString& aTagName) michael@0: { michael@0: return NS_GetContentList(this, kNameSpaceID_Unknown, aTagName); michael@0: } michael@0: already_AddRefed<nsContentList> michael@0: GetElementsByTagNameNS(const nsAString& aNamespaceURI, michael@0: const nsAString& aLocalName, michael@0: mozilla::ErrorResult& aResult); michael@0: already_AddRefed<nsContentList> michael@0: GetElementsByClassName(const nsAString& aClasses); michael@0: // GetElementById defined above michael@0: already_AddRefed<Element> CreateElement(const nsAString& aTagName, michael@0: mozilla::ErrorResult& rv); michael@0: already_AddRefed<Element> CreateElementNS(const nsAString& aNamespaceURI, michael@0: const nsAString& aQualifiedName, michael@0: mozilla::ErrorResult& rv); michael@0: virtual already_AddRefed<Element> CreateElement(const nsAString& aTagName, michael@0: const nsAString& aTypeExtension, michael@0: mozilla::ErrorResult& rv) = 0; michael@0: virtual already_AddRefed<Element> CreateElementNS(const nsAString& aNamespaceURI, michael@0: const nsAString& aQualifiedName, michael@0: const nsAString& aTypeExtension, michael@0: mozilla::ErrorResult& rv) = 0; michael@0: already_AddRefed<mozilla::dom::DocumentFragment> michael@0: CreateDocumentFragment() const; michael@0: already_AddRefed<nsTextNode> CreateTextNode(const nsAString& aData) const; michael@0: already_AddRefed<mozilla::dom::Comment> michael@0: CreateComment(const nsAString& aData) const; michael@0: already_AddRefed<mozilla::dom::ProcessingInstruction> michael@0: CreateProcessingInstruction(const nsAString& target, const nsAString& data, michael@0: mozilla::ErrorResult& rv) const; michael@0: already_AddRefed<nsINode> michael@0: ImportNode(nsINode& aNode, bool aDeep, mozilla::ErrorResult& rv) const; michael@0: nsINode* AdoptNode(nsINode& aNode, mozilla::ErrorResult& rv); michael@0: already_AddRefed<mozilla::dom::Event> michael@0: CreateEvent(const nsAString& aEventType, mozilla::ErrorResult& rv) const; michael@0: already_AddRefed<nsRange> CreateRange(mozilla::ErrorResult& rv); michael@0: already_AddRefed<mozilla::dom::NodeIterator> michael@0: CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow, michael@0: mozilla::dom::NodeFilter* aFilter, michael@0: mozilla::ErrorResult& rv) const; michael@0: already_AddRefed<mozilla::dom::NodeIterator> michael@0: CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow, michael@0: const mozilla::dom::NodeFilterHolder& aFilter, michael@0: mozilla::ErrorResult& rv) const; michael@0: already_AddRefed<mozilla::dom::TreeWalker> michael@0: CreateTreeWalker(nsINode& aRoot, uint32_t aWhatToShow, michael@0: mozilla::dom::NodeFilter* aFilter, mozilla::ErrorResult& rv) const; michael@0: already_AddRefed<mozilla::dom::TreeWalker> michael@0: CreateTreeWalker(nsINode& aRoot, uint32_t aWhatToShow, michael@0: const mozilla::dom::NodeFilterHolder& aFilter, michael@0: mozilla::ErrorResult& rv) const; michael@0: michael@0: // Deprecated WebIDL bits michael@0: already_AddRefed<mozilla::dom::CDATASection> michael@0: CreateCDATASection(const nsAString& aData, mozilla::ErrorResult& rv); michael@0: already_AddRefed<mozilla::dom::Attr> michael@0: CreateAttribute(const nsAString& aName, mozilla::ErrorResult& rv); michael@0: already_AddRefed<mozilla::dom::Attr> michael@0: CreateAttributeNS(const nsAString& aNamespaceURI, michael@0: const nsAString& aQualifiedName, michael@0: mozilla::ErrorResult& rv); michael@0: void GetInputEncoding(nsAString& aInputEncoding); michael@0: already_AddRefed<nsIDOMLocation> GetLocation() const; michael@0: void GetReferrer(nsAString& aReferrer) const; michael@0: void GetLastModified(nsAString& aLastModified) const; michael@0: void GetReadyState(nsAString& aReadyState) const; michael@0: // Not const because otherwise the compiler can't figure out whether to call michael@0: // this GetTitle or the nsAString version from non-const methods, since michael@0: // neither is an exact match. michael@0: virtual void GetTitle(nsString& aTitle) = 0; michael@0: virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) = 0; michael@0: void GetDir(nsAString& aDirection) const; michael@0: void SetDir(const nsAString& aDirection); michael@0: nsIDOMWindow* GetDefaultView() const michael@0: { michael@0: return GetWindow(); michael@0: } michael@0: Element* GetActiveElement(); michael@0: bool HasFocus(mozilla::ErrorResult& rv) const; michael@0: // Event handlers are all on nsINode already michael@0: bool MozSyntheticDocument() const michael@0: { michael@0: return IsSyntheticDocument(); michael@0: } michael@0: Element* GetCurrentScript(); michael@0: void ReleaseCapture() const; michael@0: virtual void MozSetImageElement(const nsAString& aImageElementId, michael@0: Element* aElement) = 0; michael@0: nsIURI* GetDocumentURIObject() const; michael@0: // Not const because all the full-screen goop is not const michael@0: virtual bool MozFullScreenEnabled() = 0; michael@0: virtual Element* GetMozFullScreenElement(mozilla::ErrorResult& rv) = 0; michael@0: bool MozFullScreen() michael@0: { michael@0: return IsFullScreenDoc(); michael@0: } michael@0: void MozCancelFullScreen(); michael@0: Element* GetMozPointerLockElement(); michael@0: void MozExitPointerLock() michael@0: { michael@0: UnlockPointer(this); michael@0: } michael@0: bool Hidden() const michael@0: { michael@0: return mVisibilityState != mozilla::dom::VisibilityState::Visible; michael@0: } michael@0: bool MozHidden() // Not const because of WarnOnceAbout michael@0: { michael@0: WarnOnceAbout(ePrefixedVisibilityAPI); michael@0: return Hidden(); michael@0: } michael@0: mozilla::dom::VisibilityState VisibilityState() michael@0: { michael@0: return mVisibilityState; michael@0: } michael@0: mozilla::dom::VisibilityState MozVisibilityState() michael@0: { michael@0: WarnOnceAbout(ePrefixedVisibilityAPI); michael@0: return VisibilityState(); michael@0: } michael@0: virtual mozilla::dom::StyleSheetList* StyleSheets() = 0; michael@0: void GetSelectedStyleSheetSet(nsAString& aSheetSet); michael@0: virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) = 0; michael@0: virtual void GetLastStyleSheetSet(nsString& aSheetSet) = 0; michael@0: void GetPreferredStyleSheetSet(nsAString& aSheetSet); michael@0: virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0; michael@0: virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0; michael@0: Element* ElementFromPoint(float aX, float aY); michael@0: michael@0: /** michael@0: * Retrieve the location of the caret position (DOM node and character michael@0: * offset within that node), given a point. michael@0: * michael@0: * @param aX Horizontal point at which to determine the caret position, in michael@0: * page coordinates. michael@0: * @param aY Vertical point at which to determine the caret position, in michael@0: * page coordinates. michael@0: */ michael@0: already_AddRefed<nsDOMCaretPosition> michael@0: CaretPositionFromPoint(float aX, float aY); michael@0: michael@0: // QuerySelector and QuerySelectorAll already defined on nsINode michael@0: nsINodeList* GetAnonymousNodes(Element& aElement); michael@0: Element* GetAnonymousElementByAttribute(Element& aElement, michael@0: const nsAString& aAttrName, michael@0: const nsAString& aAttrValue); michael@0: Element* GetBindingParent(nsINode& aNode); michael@0: void LoadBindingDocument(const nsAString& aURI, mozilla::ErrorResult& rv); michael@0: already_AddRefed<nsIDOMXPathExpression> michael@0: CreateExpression(const nsAString& aExpression, michael@0: nsIDOMXPathNSResolver* aResolver, michael@0: mozilla::ErrorResult& rv); michael@0: already_AddRefed<nsIDOMXPathNSResolver> michael@0: CreateNSResolver(nsINode* aNodeResolver, mozilla::ErrorResult& rv); michael@0: already_AddRefed<nsISupports> michael@0: Evaluate(const nsAString& aExpression, nsINode* aContextNode, michael@0: nsIDOMXPathNSResolver* aResolver, uint16_t aType, michael@0: nsISupports* aResult, mozilla::ErrorResult& rv); michael@0: // Touch event handlers already on nsINode michael@0: already_AddRefed<mozilla::dom::Touch> michael@0: CreateTouch(nsIDOMWindow* aView, mozilla::dom::EventTarget* aTarget, michael@0: int32_t aIdentifier, int32_t aPageX, int32_t aPageY, michael@0: int32_t aScreenX, int32_t aScreenY, int32_t aClientX, michael@0: int32_t aClientY, int32_t aRadiusX, int32_t aRadiusY, michael@0: float aRotationAngle, float aForce); michael@0: already_AddRefed<mozilla::dom::TouchList> CreateTouchList(); michael@0: already_AddRefed<mozilla::dom::TouchList> michael@0: CreateTouchList(mozilla::dom::Touch& aTouch, michael@0: const mozilla::dom::Sequence<mozilla::dom::OwningNonNull<mozilla::dom::Touch> >& aTouches); michael@0: already_AddRefed<mozilla::dom::TouchList> michael@0: CreateTouchList(const mozilla::dom::Sequence<mozilla::dom::OwningNonNull<mozilla::dom::Touch> >& aTouches); michael@0: michael@0: void SetStyleSheetChangeEventsEnabled(bool aValue) michael@0: { michael@0: mStyleSheetChangeEventsEnabled = aValue; michael@0: } michael@0: michael@0: bool StyleSheetChangeEventsEnabled() const michael@0: { michael@0: return mStyleSheetChangeEventsEnabled; michael@0: } michael@0: michael@0: void ObsoleteSheet(nsIURI *aSheetURI, mozilla::ErrorResult& rv); michael@0: michael@0: void ObsoleteSheet(const nsAString& aSheetURI, mozilla::ErrorResult& rv); michael@0: michael@0: // ParentNode michael@0: nsIHTMLCollection* Children(); michael@0: uint32_t ChildElementCount(); michael@0: michael@0: virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; } michael@0: michael@0: virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE; michael@0: michael@0: private: michael@0: uint64_t mWarnedAbout; michael@0: SelectorCache mSelectorCache; michael@0: michael@0: protected: michael@0: ~nsIDocument(); michael@0: nsPropertyTable* GetExtraPropertyTable(uint16_t aCategory); michael@0: michael@0: // Never ever call this. Only call GetWindow! michael@0: virtual nsPIDOMWindow *GetWindowInternal() const = 0; michael@0: michael@0: // Never ever call this. Only call GetScriptHandlingObject! michael@0: virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const = 0; michael@0: michael@0: // Never ever call this. Only call AllowXULXBL! michael@0: virtual bool InternalAllowXULXBL() = 0; michael@0: michael@0: /** michael@0: * These methods should be called before and after dispatching michael@0: * a mutation event. michael@0: * To make this easy and painless, use the mozAutoSubtreeModified helper class. michael@0: */ michael@0: virtual void WillDispatchMutationEvent(nsINode* aTarget) = 0; michael@0: virtual void MutationEventDispatched(nsINode* aTarget) = 0; michael@0: friend class mozAutoSubtreeModified; michael@0: michael@0: virtual Element* GetNameSpaceElement() michael@0: { michael@0: return GetRootElement(); michael@0: } michael@0: michael@0: void SetContentTypeInternal(const nsACString& aType); michael@0: michael@0: nsCString GetContentTypeInternal() const michael@0: { michael@0: return mContentType; michael@0: } michael@0: michael@0: mozilla::dom::XPathEvaluator* XPathEvaluator(); michael@0: michael@0: nsCString mReferrer; michael@0: nsString mLastModified; michael@0: michael@0: nsCOMPtr<nsIURI> mDocumentURI; michael@0: nsCOMPtr<nsIURI> mOriginalURI; michael@0: nsCOMPtr<nsIURI> mChromeXHRDocURI; michael@0: nsCOMPtr<nsIURI> mDocumentBaseURI; michael@0: nsCOMPtr<nsIURI> mChromeXHRDocBaseURI; michael@0: michael@0: nsWeakPtr mDocumentLoadGroup; michael@0: michael@0: mozilla::WeakPtr<nsDocShell> mDocumentContainer; michael@0: michael@0: nsCString mCharacterSet; michael@0: int32_t mCharacterSetSource; michael@0: michael@0: // This is just a weak pointer; the parent document owns its children. michael@0: nsIDocument* mParentDocument; michael@0: michael@0: // A reference to the element last returned from GetRootElement(). michael@0: mozilla::dom::Element* mCachedRootElement; michael@0: michael@0: // This is a weak reference, but we hold a strong reference to mNodeInfo, michael@0: // which in turn holds a strong reference to this mNodeInfoManager. michael@0: nsNodeInfoManager* mNodeInfoManager; michael@0: nsRefPtr<mozilla::css::Loader> mCSSLoader; michael@0: nsRefPtr<mozilla::css::ImageLoader> mStyleImageLoader; michael@0: nsRefPtr<nsHTMLStyleSheet> mAttrStyleSheet; michael@0: nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet; michael@0: michael@0: // The set of all object, embed, applet, video and audio elements for michael@0: // which this is the owner document. (They might not be in the document.) michael@0: // These are non-owning pointers, the elements are responsible for removing michael@0: // themselves when they go away. michael@0: nsAutoPtr<nsTHashtable<nsPtrHashKey<nsIContent> > > mFreezableElements; michael@0: michael@0: // The set of all links that need their status resolved. Links must add themselves michael@0: // to this set by calling RegisterPendingLinkUpdate when added to a document and must michael@0: // remove themselves by calling UnregisterPendingLinkUpdate when removed from a document. michael@0: nsTHashtable<nsPtrHashKey<mozilla::dom::Link> > mLinksToUpdate; michael@0: michael@0: // SMIL Animation Controller, lazily-initialized in GetAnimationController michael@0: nsRefPtr<nsSMILAnimationController> mAnimationController; michael@0: michael@0: // Table of element properties for this document. michael@0: nsPropertyTable mPropertyTable; michael@0: nsTArray<nsAutoPtr<nsPropertyTable> > mExtraPropertyTables; michael@0: michael@0: // Our cached .children collection michael@0: nsCOMPtr<nsIHTMLCollection> mChildrenCollection; michael@0: michael@0: // Compatibility mode michael@0: nsCompatibility mCompatMode; michael@0: michael@0: // Our readyState michael@0: ReadyState mReadyState; michael@0: michael@0: // Our visibility state michael@0: mozilla::dom::VisibilityState mVisibilityState; michael@0: michael@0: // True if BIDI is enabled. michael@0: bool mBidiEnabled; michael@0: // True if a MathML element has ever been owned by this document. michael@0: bool mMathMLEnabled; michael@0: michael@0: // True if this document is the initial document for a window. This should michael@0: // basically be true only for documents that exist in newly-opened windows or michael@0: // documents created to satisfy a GetDocument() on a window when there's no michael@0: // document in it. michael@0: bool mIsInitialDocumentInWindow; michael@0: michael@0: bool mIsRegularHTML; michael@0: bool mIsXUL; michael@0: michael@0: enum { michael@0: eTriUnset = 0, michael@0: eTriFalse, michael@0: eTriTrue michael@0: } mAllowXULXBL; michael@0: michael@0: // True if we're loaded as data and therefor has any dangerous stuff, such michael@0: // as scripts and plugins, disabled. michael@0: bool mLoadedAsData; michael@0: michael@0: // This flag is only set in XMLDocument, for e.g. documents used in XBL. We michael@0: // don't want animations to play in such documents, so we need to store the michael@0: // flag here so that we can check it in nsDocument::GetAnimationController. michael@0: bool mLoadedAsInteractiveData; michael@0: michael@0: // If true, whoever is creating the document has gotten it to the michael@0: // point where it's safe to start layout on it. michael@0: bool mMayStartLayout; michael@0: michael@0: // True iff we've ever fired a DOMTitleChanged event for this document michael@0: bool mHaveFiredTitleChange; michael@0: michael@0: // True iff IsShowing() should be returning true michael@0: bool mIsShowing; michael@0: michael@0: // True iff the document "page" is not hidden (i.e. currently in the michael@0: // bfcache) michael@0: bool mVisible; michael@0: michael@0: // True if our content viewer has been removed from the docshell michael@0: // (it may still be displayed, but in zombie state). Form control data michael@0: // has been saved. michael@0: bool mRemovedFromDocShell; michael@0: michael@0: // True iff DNS prefetch is allowed for this document. Note that if the michael@0: // document has no window, DNS prefetch won't be performed no matter what. michael@0: bool mAllowDNSPrefetch; michael@0: michael@0: // True when this document is a static clone of a normal document michael@0: bool mIsStaticDocument; michael@0: michael@0: // True while this document is being cloned to a static document. michael@0: bool mCreatingStaticClone; michael@0: michael@0: // True iff the document is being unlinked or deleted. michael@0: bool mInUnlinkOrDeletion; michael@0: michael@0: // True if document has ever had script handling object. michael@0: bool mHasHadScriptHandlingObject; michael@0: michael@0: // True if we're an SVG document being used as an image. michael@0: bool mIsBeingUsedAsImage; michael@0: michael@0: // True is this document is synthetic : stand alone image, video, audio michael@0: // file, etc. michael@0: bool mIsSyntheticDocument; michael@0: michael@0: // True if this document has links whose state needs updating michael@0: bool mHasLinksToUpdate; michael@0: michael@0: // True if a layout flush might not be a no-op michael@0: bool mNeedLayoutFlush; michael@0: michael@0: // True if a style flush might not be a no-op michael@0: bool mNeedStyleFlush; michael@0: michael@0: // True if a DOMMutationObserver is perhaps attached to a node in the document. michael@0: bool mMayHaveDOMMutationObservers; michael@0: michael@0: // True if a document has loaded Mixed Active Script (see nsMixedContentBlocker.cpp) michael@0: bool mHasMixedActiveContentLoaded; michael@0: michael@0: // True if a document has blocked Mixed Active Script (see nsMixedContentBlocker.cpp) michael@0: bool mHasMixedActiveContentBlocked; michael@0: michael@0: // True if a document has loaded Mixed Display/Passive Content (see nsMixedContentBlocker.cpp) michael@0: bool mHasMixedDisplayContentLoaded; michael@0: michael@0: // True if a document has blocked Mixed Display/Passive Content (see nsMixedContentBlocker.cpp) michael@0: bool mHasMixedDisplayContentBlocked; michael@0: michael@0: // True if DisallowBFCaching has been called on this document. michael@0: bool mBFCacheDisallowed; michael@0: michael@0: // If true, we have an input encoding. If this is false, then the michael@0: // document was created entirely in memory michael@0: bool mHaveInputEncoding; michael@0: michael@0: bool mHasHadDefaultView; michael@0: michael@0: // Whether style sheet change events will be dispatched for this document michael@0: bool mStyleSheetChangeEventsEnabled; michael@0: michael@0: // Whether the document was created by a srcdoc iframe. michael@0: bool mIsSrcdocDocument; michael@0: michael@0: // Records whether we've done a document.open. If this is true, it's possible michael@0: // for nodes from this document to have outdated wrappers in their wrapper michael@0: // caches. michael@0: bool mDidDocumentOpen; michael@0: michael@0: #ifdef DEBUG michael@0: /** michael@0: * This is true while FlushPendingLinkUpdates executes. Calls to michael@0: * [Un]RegisterPendingLinkUpdate will assert when this is true. michael@0: */ michael@0: bool mIsLinkUpdateRegistrationsForbidden; michael@0: #endif michael@0: michael@0: // The document's script global object, the object from which the michael@0: // document can get its script context and scope. This is the michael@0: // *inner* window object. michael@0: nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject; michael@0: michael@0: // If mIsStaticDocument is true, mOriginalDocument points to the original michael@0: // document. michael@0: nsCOMPtr<nsIDocument> mOriginalDocument; michael@0: michael@0: // The bidi options for this document. What this bitfield means is michael@0: // defined in nsBidiUtils.h michael@0: uint32_t mBidiOptions; michael@0: michael@0: // The sandbox flags on the document. These reflect the value of the sandbox attribute of the michael@0: // associated IFRAME or CSP-protectable content, if existent. These are set at load time and michael@0: // are immutable - see nsSandboxFlags.h for the possible flags. michael@0: uint32_t mSandboxFlags; michael@0: michael@0: nsCString mContentLanguage; michael@0: michael@0: // The channel that got passed to nsDocument::StartDocumentLoad(), if any. michael@0: nsCOMPtr<nsIChannel> mChannel; michael@0: private: michael@0: nsCString mContentType; michael@0: protected: michael@0: michael@0: // The document's security info michael@0: nsCOMPtr<nsISupports> mSecurityInfo; michael@0: michael@0: // if this document is part of a multipart document, michael@0: // the ID can be used to distinguish it from the other parts. michael@0: uint32_t mPartID; michael@0: michael@0: // Cycle collector generation in which we're certain that this document michael@0: // won't be collected michael@0: uint32_t mMarkedCCGeneration; michael@0: michael@0: nsIPresShell* mPresShell; michael@0: michael@0: nsCOMArray<nsINode> mSubtreeModifiedTargets; michael@0: uint32_t mSubtreeModifiedDepth; michael@0: michael@0: // If we're an external resource document, this will be non-null and will michael@0: // point to our "display document": the one that all resource lookups should michael@0: // go to. michael@0: nsCOMPtr<nsIDocument> mDisplayDocument; michael@0: michael@0: uint32_t mEventsSuppressed; michael@0: michael@0: uint32_t mAnimationsPaused; michael@0: michael@0: /** michael@0: * The number number of external scripts (ones with the src attribute) that michael@0: * have this document as their owner and that are being evaluated right now. michael@0: */ michael@0: uint32_t mExternalScriptsBeingEvaluated; michael@0: michael@0: /** michael@0: * The current frame request callback handle michael@0: */ michael@0: int32_t mFrameRequestCallbackCounter; michael@0: michael@0: // Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow, michael@0: // updated on every set of mSecriptGlobalObject. michael@0: nsPIDOMWindow *mWindow; michael@0: michael@0: nsCOMPtr<nsIDocumentEncoder> mCachedEncoder; michael@0: michael@0: struct FrameRequest; michael@0: michael@0: nsTArray<FrameRequest> mFrameRequestCallbacks; michael@0: michael@0: // This object allows us to evict ourself from the back/forward cache. The michael@0: // pointer is non-null iff we're currently in the bfcache. michael@0: nsIBFCacheEntry *mBFCacheEntry; michael@0: michael@0: // Our base target. michael@0: nsString mBaseTarget; michael@0: michael@0: nsCOMPtr<nsIStructuredCloneContainer> mStateObjectContainer; michael@0: nsCOMPtr<nsIVariant> mStateObjectCached; michael@0: michael@0: uint8_t mDefaultElementType; michael@0: michael@0: uint32_t mInSyncOperationCount; michael@0: michael@0: nsRefPtr<mozilla::dom::XPathEvaluator> mXPathEvaluator; michael@0: michael@0: uint32_t mBlockDOMContentLoaded; michael@0: bool mDidFireDOMContentLoaded:1; michael@0: }; michael@0: michael@0: NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID) michael@0: michael@0: /** michael@0: * mozAutoSubtreeModified batches DOM mutations so that a DOMSubtreeModified michael@0: * event is dispatched, if necessary, when the outermost mozAutoSubtreeModified michael@0: * object is deleted. michael@0: */ michael@0: class MOZ_STACK_CLASS mozAutoSubtreeModified michael@0: { michael@0: public: michael@0: /** michael@0: * @param aSubTreeOwner The document in which a subtree will be modified. michael@0: * @param aTarget The target of the possible DOMSubtreeModified event. michael@0: * Can be nullptr, in which case mozAutoSubtreeModified michael@0: * is just used to batch DOM mutations. michael@0: */ michael@0: mozAutoSubtreeModified(nsIDocument* aSubtreeOwner, nsINode* aTarget) michael@0: { michael@0: UpdateTarget(aSubtreeOwner, aTarget); michael@0: } michael@0: michael@0: ~mozAutoSubtreeModified() michael@0: { michael@0: UpdateTarget(nullptr, nullptr); michael@0: } michael@0: michael@0: void UpdateTarget(nsIDocument* aSubtreeOwner, nsINode* aTarget) michael@0: { michael@0: if (mSubtreeOwner) { michael@0: mSubtreeOwner->MutationEventDispatched(mTarget); michael@0: } michael@0: michael@0: mTarget = aTarget; michael@0: mSubtreeOwner = aSubtreeOwner; michael@0: if (mSubtreeOwner) { michael@0: mSubtreeOwner->WillDispatchMutationEvent(mTarget); michael@0: } michael@0: } michael@0: michael@0: private: michael@0: nsCOMPtr<nsINode> mTarget; michael@0: nsCOMPtr<nsIDocument> mSubtreeOwner; michael@0: }; michael@0: michael@0: class MOZ_STACK_CLASS nsAutoSyncOperation michael@0: { michael@0: public: michael@0: nsAutoSyncOperation(nsIDocument* aDocument); michael@0: ~nsAutoSyncOperation(); michael@0: private: michael@0: nsCOMArray<nsIDocument> mDocuments; michael@0: uint32_t mMicroTaskLevel; michael@0: }; michael@0: michael@0: // XXX These belong somewhere else michael@0: nsresult michael@0: NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData = false); michael@0: michael@0: nsresult michael@0: NS_NewXMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData = false); michael@0: michael@0: nsresult michael@0: NS_NewSVGDocument(nsIDocument** aInstancePtrResult); michael@0: michael@0: nsresult michael@0: NS_NewImageDocument(nsIDocument** aInstancePtrResult); michael@0: michael@0: nsresult michael@0: NS_NewVideoDocument(nsIDocument** aInstancePtrResult); michael@0: michael@0: // Note: it's the caller's responsibility to create or get aPrincipal as needed michael@0: // -- this method will not attempt to get a principal based on aDocumentURI. michael@0: // Also, both aDocumentURI and aBaseURI must not be null. michael@0: nsresult michael@0: NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult, michael@0: const nsAString& aNamespaceURI, michael@0: const nsAString& aQualifiedName, michael@0: nsIDOMDocumentType* aDoctype, michael@0: nsIURI* aDocumentURI, michael@0: nsIURI* aBaseURI, michael@0: nsIPrincipal* aPrincipal, michael@0: bool aLoadedAsData, michael@0: nsIGlobalObject* aEventObject, michael@0: DocumentFlavor aFlavor); michael@0: michael@0: // This is used only for xbl documents created from the startup cache. michael@0: // Non-cached documents are created in the same manner as xml documents. michael@0: nsresult michael@0: NS_NewXBLDocument(nsIDOMDocument** aInstancePtrResult, michael@0: nsIURI* aDocumentURI, michael@0: nsIURI* aBaseURI, michael@0: nsIPrincipal* aPrincipal); michael@0: michael@0: nsresult michael@0: NS_NewPluginDocument(nsIDocument** aInstancePtrResult); michael@0: michael@0: inline nsIDocument* michael@0: nsINode::GetOwnerDocument() const michael@0: { michael@0: nsIDocument* ownerDoc = OwnerDoc(); michael@0: michael@0: return ownerDoc != this ? ownerDoc : nullptr; michael@0: } michael@0: michael@0: inline nsINode* michael@0: nsINode::OwnerDocAsNode() const michael@0: { michael@0: return OwnerDoc(); michael@0: } michael@0: michael@0: inline mozilla::dom::ParentObject michael@0: nsINode::GetParentObject() const michael@0: { michael@0: return GetParentObjectInternal(OwnerDoc()); michael@0: } michael@0: michael@0: #endif /* nsIDocument_h___ */