mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1487659 - Make Selection treat SelectionChangeListener as a concrete class rather than nsISelectionListener r=smaug
SelectionChangeListener is an nsISelectionListener class. This is added only to Selection for "normal" and added by nsFrameSelection::Init() after AccessibleCaretEventHub. So, we can make Selection directly treat SelectionChangeListener. Differential Revision: https://phabricator.services.mozilla.com/D4757 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
9c349ade9b
commit
9ab2669f86
@ -60,7 +60,6 @@
|
||||
#include "nsINamed.h"
|
||||
|
||||
#include "nsISelectionController.h" //for the enums
|
||||
#include "SelectionChangeListener.h"
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsIFrameInlines.h"
|
||||
@ -738,6 +737,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Selection)
|
||||
// in JS!).
|
||||
tmp->mNotifyAutoCopy = false;
|
||||
tmp->StopNotifyingAccessibleCaretEventHub();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectionChangeListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectionListeners)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedRange)
|
||||
tmp->RemoveAllRanges(IgnoreErrors());
|
||||
@ -754,6 +754,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Selection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnchorFocusRange)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedRange)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameSelection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectionChangeListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectionListeners)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Selection)
|
||||
@ -3490,7 +3491,7 @@ Selection::NotifySelectionListeners()
|
||||
// We've notified all selection listeners even when some of them are removed
|
||||
// (and may be destroyed) during notifying one of them. Therefore, we should
|
||||
// copy all listeners to the local variable first.
|
||||
AutoTArray<nsCOMPtr<nsISelectionListener>, 8>
|
||||
AutoTArray<nsCOMPtr<nsISelectionListener>, 5>
|
||||
selectionListeners(mSelectionListeners);
|
||||
|
||||
int16_t reason = frameSelection->PopReason();
|
||||
@ -3504,6 +3505,10 @@ Selection::NotifySelectionListeners()
|
||||
hub->OnSelectionChange(doc, this, reason);
|
||||
}
|
||||
|
||||
if (mSelectionChangeListener) {
|
||||
RefPtr<SelectionChangeListener> listener(mSelectionChangeListener);
|
||||
listener->OnSelectionChange(doc, this, reason);
|
||||
}
|
||||
for (auto& listener : selectionListeners) {
|
||||
listener->NotifySelectionChanged(doc, this, reason);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/AccessibleCaretEventHub.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/RangeBoundary.h"
|
||||
#include "mozilla/SelectionChangeListener.h"
|
||||
#include "mozilla/TextRange.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
@ -115,6 +116,18 @@ public:
|
||||
mAccessibleCaretEventHub = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* EnableSelectionChangeEvent() starts to notify SelectionChangeListener of
|
||||
* selection change to dispatch a selectionchange event at every selection
|
||||
* change.
|
||||
*/
|
||||
void EnableSelectionChangeEvent()
|
||||
{
|
||||
if (!mSelectionChangeListener) {
|
||||
mSelectionChangeListener = new SelectionChangeListener();
|
||||
}
|
||||
}
|
||||
|
||||
nsIDocument* GetParentObject() const;
|
||||
DocGroup* GetDocGroup() const;
|
||||
|
||||
@ -718,6 +731,7 @@ private:
|
||||
RefPtr<nsRange> mCachedRange;
|
||||
RefPtr<nsFrameSelection> mFrameSelection;
|
||||
RefPtr<AccessibleCaretEventHub> mAccessibleCaretEventHub;
|
||||
RefPtr<SelectionChangeListener> mSelectionChangeListener;
|
||||
RefPtr<nsAutoScrollTimer> mAutoScrollTimer;
|
||||
nsTArray<nsCOMPtr<nsISelectionListener>> mSelectionListeners;
|
||||
nsRevocableEventPtr<ScrollSelectionIntoViewEvent> mScrollEvent;
|
||||
|
@ -71,22 +71,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SelectionChangeListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOldRanges);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SelectionChangeListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISelectionListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(SelectionChangeListener, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(SelectionChangeListener, Release)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(SelectionChangeListener)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(SelectionChangeListener)
|
||||
|
||||
NS_IMETHODIMP
|
||||
SelectionChangeListener::NotifySelectionChanged(nsIDocument* aDoc,
|
||||
Selection* aSel, int16_t aReason)
|
||||
void
|
||||
SelectionChangeListener::OnSelectionChange(nsIDocument* aDoc,
|
||||
Selection* aSel,
|
||||
int16_t aReason)
|
||||
{
|
||||
nsIDocument* doc = aSel->GetParentObject();
|
||||
if (!(doc && nsContentUtils::IsSystemPrincipal(doc->NodePrincipal())) &&
|
||||
!nsFrameSelection::sSelectionEventsEnabled) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the ranges have actually changed
|
||||
@ -103,7 +99,7 @@ SelectionChangeListener::NotifySelectionChanged(nsIDocument* aDoc,
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +112,7 @@ SelectionChangeListener::NotifySelectionChanged(nsIDocument* aDoc,
|
||||
if (doc) {
|
||||
nsPIDOMWindowInner* inner = doc->GetInnerWindow();
|
||||
if (inner && !inner->HasSelectionChangeEventListeners()) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,7 +120,7 @@ SelectionChangeListener::NotifySelectionChanged(nsIDocument* aDoc,
|
||||
// update mOldRanges so that changes after the changes stop being hidden don't
|
||||
// incorrectly trigger a change, even though they didn't change anything
|
||||
if (aSel->IsBlockingSelectionChangeEvents()) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
// The spec currently doesn't say that we should dispatch this event on text
|
||||
@ -163,7 +159,7 @@ SelectionChangeListener::NotifySelectionChanged(nsIDocument* aDoc,
|
||||
if (const nsFrameSelection* fs = aSel->GetFrameSelection()) {
|
||||
if (nsCOMPtr<nsIContent> root = fs->GetLimiter()) {
|
||||
if (root->IsInNativeAnonymousSubtree()) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,6 +170,4 @@ SelectionChangeListener::NotifySelectionChanged(nsIDocument* aDoc,
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef mozilla_SelectionChangeListener_h_
|
||||
#define mozilla_SelectionChangeListener_h_
|
||||
|
||||
#include "nsISelectionListener.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsTArray.h"
|
||||
@ -19,14 +18,21 @@ class nsINode;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class SelectionChangeListener final : public nsISelectionListener
|
||||
// XXX This class name is too generic. Perhaps, SelectionChangeEventDispatcher?
|
||||
// And also it's odd that this is in |dom| namespace since this is not
|
||||
// an implementation of any DOM object.
|
||||
class SelectionChangeListener final
|
||||
{
|
||||
public:
|
||||
// SelectionChangeListener has to participate in cycle collection because
|
||||
// it holds strong references to nsINodes in its mOldRanges array.
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(SelectionChangeListener)
|
||||
NS_DECL_NSISELECTIONLISTENER
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(SelectionChangeListener)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(SelectionChangeListener)
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void OnSelectionChange(nsIDocument* aDocument,
|
||||
Selection* aSelection,
|
||||
int16_t aReason);
|
||||
|
||||
// This field is used to keep track of the ranges which were present in the
|
||||
// selection when the selectionchange event was previously fired. This allows
|
||||
|
@ -132,6 +132,7 @@ EXPORTS.mozilla += [
|
||||
'FeedWriterEnabled.h',
|
||||
'FlushType.h',
|
||||
'RangeBoundary.h',
|
||||
'SelectionChangeListener.h',
|
||||
'TextInputProcessor.h',
|
||||
'UseCounter.h',
|
||||
]
|
||||
|
@ -60,7 +60,6 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
||||
#include "nsIDocument.h"
|
||||
|
||||
#include "nsISelectionController.h" //for the enums
|
||||
#include "SelectionChangeListener.h"
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsIFrameInlines.h"
|
||||
@ -667,10 +666,7 @@ nsFrameSelection::Init(nsIPresShell *aShell, nsIContent *aLimiter,
|
||||
(doc && nsContentUtils::IsSystemPrincipal(doc->NodePrincipal()))) {
|
||||
int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
|
||||
if (mDomSelections[index]) {
|
||||
// The Selection instance will hold a strong reference to its selectionchangelistener
|
||||
// so we don't have to worry about that!
|
||||
RefPtr<SelectionChangeListener> listener = new SelectionChangeListener;
|
||||
mDomSelections[index]->AddSelectionListener(listener);
|
||||
mDomSelections[index]->EnableSelectionChangeEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user