mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 21:05:36 +00:00
Bug 378775 - Implement Opera's behavior for selecting text inside of a link and link drag and drop. r=Enn
This commit is contained in:
parent
7e93c9c452
commit
82d6d889e0
@ -516,13 +516,13 @@ function synthesizeNativeMouseLUp(aElement) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a synthetic mouse drag event on the current about:newtab page.
|
||||
* Fires a synthetic mouse vertical drag event on the current about:newtab page.
|
||||
* @param aElement The element used to determine the cursor position.
|
||||
* @param aOffsetX The left offset that is added to the position.
|
||||
* @param aOffsetY The top offset that is added to the position.
|
||||
*/
|
||||
function synthesizeNativeMouseDrag(aElement, aOffsetX) {
|
||||
function synthesizeNativeMouseDrag(aElement, aOffsetY) {
|
||||
let msg = isMac ? 6 : 1;
|
||||
synthesizeNativeMouseEvent(aElement, msg, aOffsetX);
|
||||
synthesizeNativeMouseEvent(aElement, msg, 0, aOffsetY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1562,17 +1562,6 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if selection is tracking drag gestures, if so
|
||||
// don't interfere!
|
||||
if (mCurrentTarget)
|
||||
{
|
||||
nsRefPtr<nsFrameSelection> frameSel = mCurrentTarget->GetFrameSelection();
|
||||
if (frameSel && frameSel->GetMouseDownState()) {
|
||||
StopTrackingDragGesture();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If non-native code is capturing the mouse don't start a drag.
|
||||
if (nsIPresShell::IsMouseCapturePreventingDrag()) {
|
||||
StopTrackingDragGesture();
|
||||
@ -1596,14 +1585,51 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
// fire drag gesture if mouse has moved enough
|
||||
LayoutDeviceIntPoint pt = aEvent->refPoint +
|
||||
LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset());
|
||||
if (DeprecatedAbs(pt.x - mGestureDownPoint.x) > pixelThresholdX ||
|
||||
DeprecatedAbs(pt.y - mGestureDownPoint.y) > pixelThresholdY) {
|
||||
if (Abs(pt.x - mGestureDownPoint.x) > Abs(pixelThresholdX) ||
|
||||
Abs(pt.y - mGestureDownPoint.y) > Abs(pixelThresholdY)) {
|
||||
if (Prefs::ClickHoldContextMenu()) {
|
||||
// stop the click-hold before we fire off the drag gesture, in case
|
||||
// it takes a long time
|
||||
KillClickHoldTimer();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> eventContent;
|
||||
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
|
||||
|
||||
// Make it easier to select link text by only dragging in the vertical direction
|
||||
bool isLinkDraggedVertical = false;
|
||||
bool isDraggableLink = false;
|
||||
nsCOMPtr<nsIContent> dragLinkNode = eventContent;
|
||||
while (dragLinkNode) {
|
||||
if (nsContentUtils::IsDraggableLink(dragLinkNode)) {
|
||||
isDraggableLink = true;
|
||||
// Treat as vertical drag when cursor exceeds the top or bottom of the threshold box
|
||||
isLinkDraggedVertical = Abs(pt.y - mGestureDownPoint.y) > Abs(pixelThresholdY);
|
||||
break;
|
||||
}
|
||||
dragLinkNode = dragLinkNode->GetParent();
|
||||
}
|
||||
|
||||
// Check if selection is tracking drag gestures, if so
|
||||
// don't interfere!
|
||||
if (mCurrentTarget) {
|
||||
nsRefPtr<nsFrameSelection> frameSel = mCurrentTarget->GetFrameSelection();
|
||||
if (frameSel && frameSel->GetMouseDownState()) {
|
||||
if (isLinkDraggedVertical) {
|
||||
// Stop selecting when link dragged vertically
|
||||
frameSel->SetMouseDownState(PR_FALSE);
|
||||
// Clear any selection to prevent it being dragged instead of link
|
||||
frameSel->ClearNormalSelection();
|
||||
} else {
|
||||
StopTrackingDragGesture();
|
||||
// Don't register click for draggable links when selecting
|
||||
if (isDraggableLink)
|
||||
mLClickCount = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> container = aPresContext->GetContainerWeak();
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(container);
|
||||
if (!window)
|
||||
@ -1613,8 +1639,7 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
new DataTransfer(window, NS_DRAGDROP_START, false, -1);
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsCOMPtr<nsIContent> eventContent, targetContent;
|
||||
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
if (eventContent)
|
||||
DetermineDragTarget(window, eventContent, dataTransfer,
|
||||
getter_AddRefs(selection), getter_AddRefs(targetContent));
|
||||
|
@ -63,8 +63,15 @@ function afterDragTests()
|
||||
true, false, true, true, 2, document.documentElement, null);
|
||||
$("synthetic2").dispatchEvent(evt);
|
||||
|
||||
// next, dragging links and images
|
||||
sendMouseEventsForDrag("link");
|
||||
// link vertical dragging
|
||||
sendMouseEventsForVerticalDrag("link");
|
||||
is(window.getSelection().isCollapsed, true, "link vertical drag clears selection");
|
||||
|
||||
// link horizontal selection
|
||||
sendMouseEventsForHorizontalSelection("link");
|
||||
is(window.getSelection().isCollapsed, false, "link horizontal selection");
|
||||
|
||||
// images
|
||||
sendMouseEventsForDrag("image");
|
||||
|
||||
// disable testing input dragging for now, as it doesn't seem to be testable
|
||||
@ -85,8 +92,10 @@ function afterDragTests()
|
||||
sendMouseEventsForDrag("spanfalse");
|
||||
|
||||
synthesizeMouse(draggable, 12, 12, { type: "mouseup" });
|
||||
if (gExtraDragTests == 4)
|
||||
SimpleTest.finish();
|
||||
|
||||
is(gExtraDragTests, 4, "number of drag events");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function sendMouseEventsForDrag(nodeid)
|
||||
@ -97,6 +106,23 @@ function sendMouseEventsForDrag(nodeid)
|
||||
synthesizeMouse(draggable, 12, 12, { type: "mousemove" });
|
||||
}
|
||||
|
||||
function sendMouseEventsForVerticalDrag(nodeid)
|
||||
{
|
||||
var draggable = $(nodeid);
|
||||
synthesizeMouse(draggable, 3, 3, { type: "mousedown" });
|
||||
synthesizeMouse(draggable, 3, 10, { type: "mousemove" });
|
||||
synthesizeMouse(draggable, 3, 12, { type: "mousemove" });
|
||||
}
|
||||
|
||||
function sendMouseEventsForHorizontalSelection(nodeid)
|
||||
{
|
||||
var draggable = $(nodeid);
|
||||
synthesizeMouse(draggable, 3, 3, { type: "mousedown" });
|
||||
synthesizeMouse(draggable, 10, 3, { type: "mousemove" });
|
||||
synthesizeMouse(draggable, 12, 3, { type: "mousemove" });
|
||||
synthesizeMouse(draggable, 12, 3, { type: "mouseup" });
|
||||
}
|
||||
|
||||
function doDragStartSelection(event)
|
||||
{
|
||||
is(event.type, "dragstart", "dragstart event type");
|
||||
|
@ -2682,8 +2682,10 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
|
||||
if (!mouseEvent->IsAlt()) {
|
||||
for (nsIContent* content = mContent; content;
|
||||
content = content->GetParent()) {
|
||||
// Prevent selection of draggable content with the exception of links
|
||||
if (nsContentUtils::ContentIsDraggable(content) &&
|
||||
!content->IsEditable()) {
|
||||
!content->IsEditable() &&
|
||||
!nsContentUtils::IsDraggableLink(content)) {
|
||||
// coordinate stuff is the fix for bug #55921
|
||||
if ((mRect - GetPosition()).Contains(
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this))) {
|
||||
|
Loading…
Reference in New Issue
Block a user