diff --git a/docshell/base/moz.build b/docshell/base/moz.build index f5a398b51912..2fe80c744f23 100644 --- a/docshell/base/moz.build +++ b/docshell/base/moz.build @@ -37,6 +37,7 @@ XPIDL_MODULE = 'docshell' EXPORTS += [ 'nsDocShellLoadTypes.h', 'nsILinkHandler.h', + 'nsIScrollObserver.h', 'nsIWebShellServices.h', 'SerializedLoadContext.h', ] diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 25f6c4e553b9..91e2e37a73a7 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -67,6 +67,7 @@ #include "nsITimedChannel.h" #include "nsIPrivacyTransitionObserver.h" #include "nsIReflowObserver.h" +#include "nsIScrollObserver.h" #include "nsIDocShellTreeItem.h" #include "nsIChannel.h" #include "IHistory.h" @@ -2857,6 +2858,39 @@ nsDocShell::GetCurrentDocChannel() return nullptr; } +NS_IMETHODIMP +nsDocShell::AddWeakScrollObserver(nsIScrollObserver* aObserver) +{ + nsWeakPtr weakObs = do_GetWeakReference(aObserver); + if (!weakObs) { + return NS_ERROR_FAILURE; + } + return mScrollObservers.AppendElement(weakObs) ? NS_OK : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsDocShell::RemoveWeakScrollObserver(nsIScrollObserver* aObserver) +{ + nsWeakPtr obs = do_GetWeakReference(aObserver); + return mScrollObservers.RemoveElement(obs) ? NS_OK : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsDocShell::NotifyScrollObservers() +{ + nsTObserverArray::ForwardIterator iter(mScrollObservers); + while (iter.HasMore()) { + nsWeakPtr ref = iter.GetNext(); + nsCOMPtr obs = do_QueryReferent(ref); + if (obs) { + obs->ScrollPositionChanged(); + } else { + mScrollObservers.RemoveElement(ref); + } + } + return NS_OK; +} + //***************************************************************************** // nsDocShell::nsIDocShellTreeItem //***************************************************************************** diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 83ac34f86588..c19177742107 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -900,6 +900,7 @@ private: nsCOMPtr mParentCharsetPrincipal; nsTObserverArray mPrivacyObservers; nsTObserverArray mReflowObservers; + nsTObserverArray mScrollObservers; nsCString mOriginalUriString; // Separate function to do the actual name (i.e. not _top, _self etc.) diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 1a9cf2bccf9c..2d2cb57df9a1 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -41,6 +41,7 @@ interface nsIWebBrowserPrint; interface nsIVariant; interface nsIPrivacyTransitionObserver; interface nsIReflowObserver; +interface nsIScrollObserver; typedef unsigned long nsLoadFlags; @@ -667,6 +668,24 @@ interface nsIDocShell : nsIDocShellTreeItem in DOMHighResTimeStamp start, in DOMHighResTimeStamp end); + /** + * Add an observer to the list of parties to be notified when scroll position + * of some elements is changed. + */ + [noscript] void addWeakScrollObserver(in nsIScrollObserver obs); + + /** + * Add an observer to the list of parties to be notified when scroll position + * of some elements is changed. + */ + [noscript] void removeWeakScrollObserver(in nsIScrollObserver obs); + + /** + * Notify all attached observers that the scroll position of some element + * has changed. + */ + [noscript] void notifyScrollObservers(); + /** * Returns true if this docshell corresponds to an