mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 1067728 - Part 5 - Dispatch updateposition after scroll end and reflow. r=roc, sr=smaug
Add a selection state "updateposition" and a field "visible" to indicate that the current selection's boundingClientRect or visible is changed. We dispatch this state after scrolling or reflowing is done.
This commit is contained in:
parent
09c7f0faf5
commit
f674a2ec9b
@ -657,6 +657,7 @@ BrowserElementChild.prototype = {
|
||||
zoomFactor: zoomFactor,
|
||||
states: e.states,
|
||||
isCollapsed: (e.selectedText.length == 0),
|
||||
visible: e.visible,
|
||||
};
|
||||
|
||||
// Get correct geometry information if we have nested iframe.
|
||||
|
@ -12,10 +12,12 @@ enum SelectionState {
|
||||
"selectall",
|
||||
"collapsetostart",
|
||||
"collapsetoend",
|
||||
"blur"
|
||||
"blur",
|
||||
"updateposition"
|
||||
};
|
||||
|
||||
dictionary SelectionStateChangedEventInit : EventInit {
|
||||
boolean visible = true;
|
||||
DOMString selectedText = "";
|
||||
DOMRectReadOnly? boundingClientRect = null;
|
||||
sequence<SelectionState> states = [];
|
||||
@ -24,6 +26,7 @@ dictionary SelectionStateChangedEventInit : EventInit {
|
||||
[Constructor(DOMString type, optional SelectionStateChangedEventInit eventInit),
|
||||
ChromeOnly]
|
||||
interface SelectionStateChangedEvent : Event {
|
||||
readonly attribute boolean visible;
|
||||
readonly attribute DOMString selectedText;
|
||||
readonly attribute DOMRectReadOnly? boundingClientRect;
|
||||
[Cached, Pure] readonly attribute sequence<SelectionState> states;
|
||||
|
@ -87,6 +87,7 @@ SelectionCarets::SelectionCarets(nsIPresShell* aPresShell)
|
||||
, mAsyncPanZoomEnabled(false)
|
||||
, mEndCaretVisible(false)
|
||||
, mStartCaretVisible(false)
|
||||
, mSelectionVisibleInScrollFrames(true)
|
||||
, mVisible(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -488,6 +489,22 @@ SelectionCarets::UpdateSelectionCarets()
|
||||
|
||||
mPresShell->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
// If the selection is not visible, we should dispatch a event.
|
||||
nsIFrame* commonAncestorFrame =
|
||||
nsLayoutUtils::FindNearestCommonAncestorFrame(startFrame, endFrame);
|
||||
|
||||
nsRect selectionRectInRootFrame = GetSelectionBoundingRect(selection);
|
||||
nsRect selectionRectInCommonAncestorFrame = selectionRectInRootFrame;
|
||||
nsLayoutUtils::TransformRect(rootFrame, commonAncestorFrame,
|
||||
selectionRectInCommonAncestorFrame);
|
||||
|
||||
mSelectionVisibleInScrollFrames =
|
||||
nsLayoutUtils::IsRectVisibleInScrollFrames(commonAncestorFrame,
|
||||
selectionRectInCommonAncestorFrame);
|
||||
SELECTIONCARETS_LOG("Selection visibility %s",
|
||||
(mSelectionVisibleInScrollFrames ? "shown" : "hidden"));
|
||||
|
||||
|
||||
nsRect firstRectInStartFrame =
|
||||
nsCaret::GetGeometryForFrame(startFrame, startOffset, nullptr);
|
||||
nsRect lastRectInEndFrame =
|
||||
@ -989,6 +1006,15 @@ SelectionCarets::GetSelectionBoundingRect(Selection* aSel)
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
SelectionCarets::DispatchSelectionStateChangedEvent(Selection* aSelection,
|
||||
SelectionState aState)
|
||||
{
|
||||
dom::Sequence<SelectionState> state;
|
||||
state.AppendElement(aState);
|
||||
DispatchSelectionStateChangedEvent(aSelection, state);
|
||||
}
|
||||
|
||||
void
|
||||
SelectionCarets::DispatchSelectionStateChangedEvent(Selection* aSelection,
|
||||
const Sequence<SelectionState>& aStates)
|
||||
@ -1008,6 +1034,7 @@ SelectionCarets::DispatchSelectionStateChangedEvent(Selection* aSelection,
|
||||
|
||||
domRect->SetLayoutRect(rect);
|
||||
init.mBoundingClientRect = domRect;
|
||||
init.mVisible = mSelectionVisibleInScrollFrames;
|
||||
|
||||
aSelection->Stringify(init.mSelectedText);
|
||||
}
|
||||
@ -1026,10 +1053,7 @@ void
|
||||
SelectionCarets::NotifyBlur()
|
||||
{
|
||||
SetVisibility(false);
|
||||
|
||||
dom::Sequence<SelectionState> state;
|
||||
state.AppendElement(dom::SelectionState::Blur);
|
||||
DispatchSelectionStateChangedEvent(nullptr, state);
|
||||
DispatchSelectionStateChangedEvent(nullptr, SelectionState::Blur);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1088,8 +1112,13 @@ SelectionCarets::AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos)
|
||||
SELECTIONCARETS_LOG("Update selection carets after APZ is stopped!");
|
||||
UpdateSelectionCarets();
|
||||
|
||||
// SelectionStateChangedEvent should be dispatched before ScrollViewChangeEvent.
|
||||
DispatchSelectionStateChangedEvent(GetSelection(),
|
||||
SelectionState::Updateposition);
|
||||
|
||||
SELECTIONCARETS_LOG("Dispatch scroll stopped with position x=%d, y=%d",
|
||||
aScrollPos.x, aScrollPos.y);
|
||||
|
||||
DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Stopped, aScrollPos);
|
||||
}
|
||||
|
||||
@ -1179,6 +1208,8 @@ SelectionCarets::FireScrollEnd(nsITimer* aTimer, void* aSelectionCarets)
|
||||
SELECTIONCARETS_LOG_STATIC("Update selection carets!");
|
||||
self->SetVisibility(true);
|
||||
self->UpdateSelectionCarets();
|
||||
self->DispatchSelectionStateChangedEvent(self->GetSelection(),
|
||||
SelectionState::Updateposition);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1187,6 +1218,9 @@ SelectionCarets::Reflow(DOMHighResTimeStamp aStart, DOMHighResTimeStamp aEnd)
|
||||
if (mVisible) {
|
||||
SELECTIONCARETS_LOG("Update selection carets after reflow!");
|
||||
UpdateSelectionCarets();
|
||||
|
||||
DispatchSelectionStateChangedEvent(GetSelection(),
|
||||
SelectionState::Updateposition);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -203,6 +203,8 @@ private:
|
||||
dom::Selection* GetSelection();
|
||||
already_AddRefed<nsFrameSelection> GetFrameSelection();
|
||||
nsIContent* GetFocusedContent();
|
||||
void DispatchSelectionStateChangedEvent(dom::Selection* aSelection,
|
||||
dom::SelectionState aState);
|
||||
void DispatchSelectionStateChangedEvent(dom::Selection* aSelection,
|
||||
const dom::Sequence<dom::SelectionState>& aStates);
|
||||
nsRect GetSelectionBoundingRect(dom::Selection* aSel);
|
||||
@ -246,6 +248,7 @@ private:
|
||||
|
||||
bool mEndCaretVisible;
|
||||
bool mStartCaretVisible;
|
||||
bool mSelectionVisibleInScrollFrames;
|
||||
bool mVisible;
|
||||
|
||||
// Preference
|
||||
|
Loading…
Reference in New Issue
Block a user