mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 20:22:00 +00:00
Bug 1609338 - Optimize usage and implementation of UIEvent::GetRangeParent()
and UIEvent::RangeOffset()
r=smaug
`UIEvent::GetRangeParent()` retrieves `nsIContent` instance but it needs to return `already_AddRefed<nsINode>` because of a WebIDL method. However, `nsIContent` is better type in C++ code. Therefore, this patch renames it to `UIEvent::GetRangeParentContent()` and makes new `UIEvent::GetRangeParent()` and just call it. Additionally, some callers call `UIEvent::RangeOffset()` too, but that means that they compute same things twice because both of them use `nsLayoutUtils::GetContainerAndOffsetAtEvent()` with same input arguments. Thus, `UIEvent::GetRangeParentContent()` should also return offset with optional out argument. (Note that this does not make `RangeOffset()` use `GetRangeParentContent()` because using out parameter for range parent causes unnecessary computation cost for `RangeOffset()`.) Therefore, finally, `UIEvent::GetRangeParentContent()` becomes also an alias of raw method `UIEvent::GetRangeParentContentAndOffset()` which also returns offset with out argument. Differential Revision: https://phabricator.services.mozilla.com/D60095 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
d55e0a5916
commit
527b3ff65b
@ -132,7 +132,8 @@ void UIEvent::InitUIEvent(const nsAString& typeArg, bool canBubbleArg,
|
||||
mView = viewArg ? viewArg->GetOuterWindow() : nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<nsINode> UIEvent::GetRangeParent() {
|
||||
already_AddRefed<nsIContent> UIEvent::GetRangeParentContentAndOffset(
|
||||
int32_t* aOffset) {
|
||||
if (NS_WARN_IF(!mPresContext)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -142,7 +143,7 @@ already_AddRefed<nsINode> UIEvent::GetRangeParent() {
|
||||
}
|
||||
nsCOMPtr<nsIContent> container;
|
||||
nsLayoutUtils::GetContainerAndOffsetAtEvent(
|
||||
presShell, mEvent, getter_AddRefs(container), nullptr);
|
||||
presShell, mEvent, getter_AddRefs(container), aOffset);
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
|
@ -70,11 +70,28 @@ class UIEvent : public Event {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
already_AddRefed<nsINode> GetRangeParent();
|
||||
/**
|
||||
* GetRangeParent() should be used only by JS. C++ callers should use
|
||||
* GetRangeParentContent() or GetRangeParentContentAndOffset() instead.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT already_AddRefed<nsINode> GetRangeParent() {
|
||||
return GetRangeParentContent();
|
||||
}
|
||||
MOZ_CAN_RUN_SCRIPT already_AddRefed<nsIContent> GetRangeParentContent() {
|
||||
return GetRangeParentContentAndOffset(nullptr);
|
||||
}
|
||||
/**
|
||||
* aOffset is optional (i.e., can be nullptr), but when you call this with
|
||||
* nullptr, you should use GetRangeParentContent() instead.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT already_AddRefed<nsIContent>
|
||||
GetRangeParentContentAndOffset(int32_t* aOffset);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t RangeOffset() const;
|
||||
/**
|
||||
* If you also need to compute range parent in C++ code, you should use
|
||||
* GetRangeParentContentAndOffset() instead.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT int32_t RangeOffset() const;
|
||||
|
||||
protected:
|
||||
~UIEvent() {}
|
||||
|
@ -728,11 +728,14 @@ nsresult EditorEventListener::DragOver(DragEvent* aDragEvent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> parent = aDragEvent->GetRangeParent();
|
||||
nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
|
||||
NS_ENSURE_TRUE(dropParent, NS_ERROR_FAILURE);
|
||||
int32_t dropOffset = -1;
|
||||
nsCOMPtr<nsIContent> dropParentContent =
|
||||
aDragEvent->GetRangeParentContentAndOffset(&dropOffset);
|
||||
if (NS_WARN_IF(!dropParentContent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (dropParent->IsEditable() && CanDrop(aDragEvent)) {
|
||||
if (dropParentContent->IsEditable() && CanDrop(aDragEvent)) {
|
||||
aDragEvent->PreventDefault(); // consumed
|
||||
|
||||
// If we handle the dragged item, we need should adjust drop effect here
|
||||
@ -756,10 +759,8 @@ nsresult EditorEventListener::DragOver(DragEvent* aDragEvent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t offset = aDragEvent->RangeOffset();
|
||||
|
||||
mCaret->SetVisible(true);
|
||||
mCaret->SetCaretPosition(dropParent, offset);
|
||||
mCaret->SetCaretPosition(dropParentContent, dropOffset);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -818,8 +819,7 @@ nsresult EditorEventListener::Drop(DragEvent* aDragEvent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> dropParentNode = aDragEvent->GetRangeParent();
|
||||
nsIContent* dropParentContent = nsIContent::FromNodeOrNull(dropParentNode);
|
||||
nsCOMPtr<nsIContent> dropParentContent = aDragEvent->GetRangeParentContent();
|
||||
if (NS_WARN_IF(!dropParentContent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -911,13 +911,13 @@ bool EditorEventListener::CanDrop(DragEvent* aEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> parent = aEvent->GetRangeParent();
|
||||
if (!parent) {
|
||||
int32_t dropOffset = -1;
|
||||
nsCOMPtr<nsIContent> dropParentContent =
|
||||
aEvent->GetRangeParentContentAndOffset(&dropOffset);
|
||||
if (!dropParentContent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t offset = aEvent->RangeOffset();
|
||||
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
for (uint32_t i = 0; i < rangeCount; i++) {
|
||||
RefPtr<nsRange> range = selection->GetRangeAt(i);
|
||||
@ -927,7 +927,7 @@ bool EditorEventListener::CanDrop(DragEvent* aEvent) {
|
||||
}
|
||||
|
||||
IgnoredErrorResult rv;
|
||||
bool inRange = range->IsPointInRange(*parent, offset, rv);
|
||||
bool inRange = range->IsPointInRange(*dropParentContent, dropOffset, rv);
|
||||
if (!rv.Failed() && inRange) {
|
||||
// Okay, now you can bail, we are over the orginal selection
|
||||
return false;
|
||||
|
@ -286,10 +286,12 @@ nsresult HTMLEditorEventListener::MouseDown(MouseEvent* aMouseEvent) {
|
||||
NS_ENSURE_TRUE(selection, NS_OK);
|
||||
|
||||
// Get location of mouse within target node
|
||||
nsCOMPtr<nsINode> parent = aMouseEvent->GetRangeParent();
|
||||
NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
|
||||
|
||||
int32_t offset = aMouseEvent->RangeOffset();
|
||||
int32_t offset = -1;
|
||||
nsCOMPtr<nsIContent> parentContent =
|
||||
aMouseEvent->GetRangeParentContentAndOffset(&offset);
|
||||
if (NS_WARN_IF(!parentContent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Detect if mouse point is within current selection for context click
|
||||
bool nodeIsInSelection = false;
|
||||
@ -305,7 +307,7 @@ nsresult HTMLEditorEventListener::MouseDown(MouseEvent* aMouseEvent) {
|
||||
|
||||
IgnoredErrorResult err;
|
||||
nodeIsInSelection =
|
||||
range->IsPointInRange(*parent, offset, err) && !err.Failed();
|
||||
range->IsPointInRange(*parentContent, offset, err) && !err.Failed();
|
||||
|
||||
// Done when we find a range that we are in
|
||||
if (nodeIsInSelection) {
|
||||
@ -318,7 +320,7 @@ nsresult HTMLEditorEventListener::MouseDown(MouseEvent* aMouseEvent) {
|
||||
if (!element) {
|
||||
if (isContextClick) {
|
||||
// Set the selection to the point under the mouse cursor:
|
||||
selection->Collapse(parent, offset);
|
||||
selection->Collapse(parentContent, offset);
|
||||
} else {
|
||||
// Get enclosing link if in text so we can select the link
|
||||
Element* linkElement =
|
||||
@ -332,7 +334,7 @@ nsresult HTMLEditorEventListener::MouseDown(MouseEvent* aMouseEvent) {
|
||||
// and not the entire body, or table-related elements
|
||||
if (element) {
|
||||
if (isContextClick && !HTMLEditUtils::IsImage(node)) {
|
||||
selection->Collapse(parent, offset);
|
||||
selection->Collapse(parentContent, offset);
|
||||
} else {
|
||||
htmlEditor->SelectElement(element);
|
||||
}
|
||||
|
@ -210,8 +210,10 @@ nsresult TextEditor::OnDrop(DragEvent* aDropEvent) {
|
||||
|
||||
// We have to figure out whether to delete and relocate caret only once
|
||||
// Parent and offset are under the mouse cursor.
|
||||
EditorDOMPoint droppedAt(aDropEvent->GetRangeParent(),
|
||||
aDropEvent->RangeOffset());
|
||||
int32_t dropOffset = -1;
|
||||
nsCOMPtr<nsIContent> dropParentContent =
|
||||
aDropEvent->GetRangeParentContentAndOffset(&dropOffset);
|
||||
EditorDOMPoint droppedAt(dropParentContent, dropOffset);
|
||||
if (NS_WARN_IF(!droppedAt.IsSet()) ||
|
||||
NS_WARN_IF(!droppedAt.GetContainerAsContent())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -166,7 +166,7 @@ nsXULPopupManager::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
mKeyListener->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
|
||||
mKeyListener = nullptr;
|
||||
}
|
||||
mRangeParent = nullptr;
|
||||
mRangeParentContent = nullptr;
|
||||
// mOpeningPopup is cleared explicitly soon after using it.
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
@ -556,10 +556,6 @@ nsMenuChainItem* nsXULPopupManager::GetTopVisibleMenu() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsINode* nsXULPopupManager::GetMouseLocationParent() { return mRangeParent; }
|
||||
|
||||
int32_t nsXULPopupManager::MouseLocationOffset() { return mRangeOffset; }
|
||||
|
||||
void nsXULPopupManager::InitTriggerEvent(Event* aEvent, nsIContent* aPopup,
|
||||
nsIContent** aTriggerContent) {
|
||||
mCachedMousePoint = LayoutDeviceIntPoint(0, 0);
|
||||
@ -577,8 +573,9 @@ void nsXULPopupManager::InitTriggerEvent(Event* aEvent, nsIContent* aPopup,
|
||||
|
||||
RefPtr<UIEvent> uiEvent = aEvent ? aEvent->AsUIEvent() : nullptr;
|
||||
if (uiEvent) {
|
||||
mRangeParent = uiEvent->GetRangeParent();
|
||||
mRangeOffset = uiEvent->RangeOffset();
|
||||
mRangeOffset = -1;
|
||||
mRangeParentContent =
|
||||
uiEvent->GetRangeParentContentAndOffset(&mRangeOffset);
|
||||
|
||||
// get the event coordinates relative to the root frame of the document
|
||||
// containing the popup.
|
||||
@ -628,7 +625,7 @@ void nsXULPopupManager::InitTriggerEvent(Event* aEvent, nsIContent* aPopup,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mRangeParent = nullptr;
|
||||
mRangeParentContent = nullptr;
|
||||
mRangeOffset = 0;
|
||||
}
|
||||
}
|
||||
@ -1355,7 +1352,7 @@ void nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup,
|
||||
}
|
||||
|
||||
// clear these as they are no longer valid
|
||||
mRangeParent = nullptr;
|
||||
mRangeParentContent = nullptr;
|
||||
mRangeOffset = 0;
|
||||
|
||||
// get the frame again in case it went away
|
||||
|
@ -414,8 +414,8 @@ class nsXULPopupManager final : public nsIDOMEventListener,
|
||||
// the rangeOffset of the event supplied to ShowPopup or ShowPopupAtScreen.
|
||||
// This is used by the implementation of Document::GetPopupRangeParent
|
||||
// and Document::GetPopupRangeOffset.
|
||||
nsINode* GetMouseLocationParent();
|
||||
int32_t MouseLocationOffset();
|
||||
nsIContent* GetMouseLocationParent() const { return mRangeParentContent; }
|
||||
int32_t MouseLocationOffset() const { return mRangeOffset; }
|
||||
|
||||
/**
|
||||
* Open a <menu> given its content node. If aSelectFirstItem is
|
||||
@ -795,7 +795,7 @@ class nsXULPopupManager final : public nsIDOMEventListener,
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
|
||||
// range parent and offset set in SetTriggerEvent
|
||||
nsCOMPtr<nsINode> mRangeParent;
|
||||
nsCOMPtr<nsIContent> mRangeParentContent;
|
||||
int32_t mRangeOffset;
|
||||
// Device pixels relative to the showing popup's presshell's
|
||||
// root prescontext's root frame.
|
||||
|
Loading…
x
Reference in New Issue
Block a user