/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * The interface to nsISHentry. Each document or subframe in 
 * Session History will have a nsISHEntry associated with it which will
 * hold all information required to recreate the document from history
 * 
 */
#include "nsIHistoryEntry.idl"

interface nsILayoutHistoryState;
interface nsIContentViewer;
interface nsIURI;
interface nsIInputStream;
interface nsIDocShellTreeItem;
interface nsISupportsArray;
interface nsIStructuredCloneContainer;
interface nsIBFCacheEntry;

%{C++
struct nsIntRect;
class nsDocShellEditorData;
class nsSHEntryShared;
%}
[ref] native nsIntRect(nsIntRect);
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
[ptr] native nsSHEntryShared(nsSHEntryShared);

[scriptable, uuid(162EA0EB-E577-4B9A-AF9D-A94E8350B029)]
interface nsISHEntry : nsIHistoryEntry
{
    /** URI for the document */
    void setURI(in nsIURI aURI);

    /** Referrer URI */
    attribute nsIURI referrerURI;

    /** Content viewer, for fast restoration of presentation */
    attribute nsIContentViewer contentViewer;

    /** Whether the content viewer is marked "sticky" */
    attribute boolean sticky;

    /** Saved state of the global window object */
    attribute nsISupports windowState;

    /**
     * Saved position and dimensions of the content viewer; we must adjust the
     * root view's widget accordingly if this has changed when the presentation
     * is restored.
     */
    [noscript] void getViewerBounds(in nsIntRect bounds);
    [noscript] void setViewerBounds([const] in nsIntRect bounds);

    /**
     * Saved child docshells corresponding to contentViewer.  The child shells
     * are restored as children of the parent docshell, in this order, when the
     * parent docshell restores a saved presentation.
     */

    /** Append a child shell to the end of our list. */
    void addChildShell(in nsIDocShellTreeItem shell);

    /**
     * Get the child shell at |index|; returns null if |index| is out of bounds.
     */
    nsIDocShellTreeItem childShellAt(in long index);

    /**
     * Clear the child shell list.
     */
    void clearChildShells();

    /** Saved refresh URI list for the content viewer */
    attribute nsISupportsArray refreshURIList;

    /**
     * Ensure that the cached presentation members are self-consistent.
     * If either |contentViewer| or |windowState| are null, then all of the
     * following members are cleared/reset:
     *  contentViewer, sticky, windowState, viewerBounds, childShells,
     *  refreshURIList.
     */
    void syncPresentationState();

    /** Title for the document */
    void setTitle(in AString aTitle);

    /** Post Data for the document */
    attribute nsIInputStream postData;

    /** LayoutHistoryState for scroll position and form values */
    attribute nsILayoutHistoryState layoutHistoryState;

    /** parent of this entry */
    attribute nsISHEntry parent;

    /**
     * The loadType for this entry. This is typically loadHistory except
     * when reload is pressed, it has the appropriate reload flag
     */
    attribute unsigned long loadType;

    /**
     * An ID to help identify this entry from others during
     * subframe navigation
     */
    attribute unsigned long ID;

    /** attribute to set and get the cache key for the entry */
    attribute nsISupports cacheKey;

    /** attribute to indicate whether layoutHistoryState should be saved */
    attribute boolean saveLayoutStateFlag;

    /** attribute to indicate whether the page is already expired in cache */
    attribute boolean expirationStatus;

    /**
     * attribute to indicate the content-type of the document that this
     * is a session history entry for
     */
    attribute ACString contentType; 

    /**
     * If we created this SHEntry via history.pushState or modified it via
     * history.replaceState, and if we changed the SHEntry's URI via the
     * push/replaceState call, and if the SHEntry's new URI differs from its
     * old URI by more than just the hash, then we set this field to true.
     *
     * Additionally, if this SHEntry was created by calling pushState from a
     * SHEntry whose URI was modified, this SHEntry's URIWasModified field is
     * true.
     *
     */
    attribute boolean URIWasModified;
 
    /** Set/Get scrollers' positon in anchored pages */
    void setScrollPosition(in long x, in long y);
    void getScrollPosition(out long x, out long y);

    /** Additional ways to create an entry */
    [noscript] void create(in nsIURI URI, in AString title,
                           in nsIInputStream inputStream,
                           in nsILayoutHistoryState layoutHistoryState,
                           in nsISupports cacheKey, in ACString contentType,
                           in nsISupports owner,
                           in unsigned long long docshellID,
                           in boolean dynamicCreation);

    nsISHEntry clone();

    /** Attribute that indicates if this entry is for a subframe navigation */
    void setIsSubFrame(in boolean aFlag);

    /** Return any content viewer present in or below this node in the
        nsSHEntry tree.  This will differ from contentViewer in the case
        where a child nsSHEntry has the content viewer for this tree. */
    nsIContentViewer getAnyContentViewer(out nsISHEntry ownerEntry);

    /**
     * Get the owner, if any, that was associated with the channel
     * that the document that was loaded to create this history entry
     * came from.
     */
    attribute nsISupports owner;

    /**
     * Get/set data associated with this history state via a pushState() call,
     * serialized using structured clone.
     **/
    attribute nsIStructuredCloneContainer stateData;

    /**
     * Gets the owning pointer to the editor data assosicated with
     * this shistory entry. This forgets its pointer, so free it when
     * you're done.
     */
    [noscript, notxpcom] nsDocShellEditorDataPtr forgetEditorData();

    /**
     * Sets the owning pointer to the editor data assosicated with
     * this shistory entry. Unless forgetEditorData() is called, this
     * shentry will destroy the editor data when it's destroyed.
     */
    [noscript, notxpcom] void setEditorData(in nsDocShellEditorDataPtr aData);

    /** Returns true if this shistory entry is storing a detached editor. */
    [noscript, notxpcom] boolean hasDetachedEditor();

    /**
     * Returns true if the related docshell was added because of
     * dynamic addition of an iframe/frame.
     */
    boolean isDynamicallyAdded();

    /**
     * Returns true if any of the child entries returns true
     * when isDynamicallyAdded is called on it.
     */
    boolean hasDynamicallyAddedChild();

    /**
     * The history ID of the docshell.
     */
    attribute unsigned long long docshellID;

    readonly attribute nsIBFCacheEntry BFCacheEntry;

    /**
     * Does this SHEntry point to the given BFCache entry?  If so, evicting
     * the BFCache entry will evict the SHEntry, since the two entries
     * correspond to the same document.
     */
    [notxpcom, noscript]
    boolean hasBFCacheEntry(in nsIBFCacheEntry aEntry);

    /**
     * Adopt aEntry's BFCacheEntry, so now both this and aEntry point to
     * aEntry's BFCacheEntry.
     */
    void adoptBFCacheEntry(in nsISHEntry aEntry);

    /**
     * Create a new BFCache entry and drop our reference to our old one.  This
     * call unlinks this SHEntry from any other SHEntries for its document.
     */
    void abandonBFCacheEntry();

    /**
     * Does this SHEntry correspond to the same document as aEntry?  This is
     * true iff the two SHEntries have the same BFCacheEntry.  So in
     * particular, sharesDocumentWith(aEntry) is guaranteed to return true if
     * it's preceeded by a call to adoptBFCacheEntry(aEntry).
     */
    boolean sharesDocumentWith(in nsISHEntry aEntry);

    /**
     * True if this SHEntry corresponds to a document created by a srcdoc iframe.
     * Set when a value is assigned to  srcdocData.
     */
    readonly attribute boolean isSrcdocEntry;

    /**
     * Contents of the srcdoc attribute in a srcdoc iframe to be loaded instead
     * of the URI.  Similar to a Data URI, this information is needed to
     * recreate the document at a later stage.
     * Setting this sets isSrcdocEntry to true
     */
    attribute AString srcdocData;
};

[scriptable, uuid(bb66ac35-253b-471f-a317-3ece940f04c5)]
interface nsISHEntryInternal : nsISupports
{
    [notxpcom] void RemoveFromBFCacheAsync();
    [notxpcom] void RemoveFromBFCacheSync();

    /**
     * A number that is assigned by the sHistory when the entry is activated
     */
    attribute unsigned long lastTouched;

    /**
     * Some state, particularly that related to the back/forward cache, is
     * shared between SHEntries which correspond to the same document.  This
     * method gets a pointer to that shared state.
     *
     * This shared state is the SHEntry's BFCacheEntry.  So
     * hasBFCacheEntry(getSharedState()) is guaranteed to return true.
     */
    [noscript, notxpcom]
    nsSHEntryShared getSharedState();
};

%{ C++
// {BFD1A791-AD9F-11d3-BDC7-0050040A9B44}
#define NS_SHENTRY_CID \
{0xbfd1a791, 0xad9f, 0x11d3, {0xbd, 0xc7, 0x0, 0x50, 0x4, 0xa, 0x9b, 0x44}}

#define NS_SHENTRY_CONTRACTID \
    "@mozilla.org/browser/session-history-entry;1"

%}

