WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-79443-20120307125406.patch (text/plain), 17.70 KB, created by
Andy Estes
on 2012-03-07 12:54:07 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Andy Estes
Created:
2012-03-07 12:54:07 PST
Size:
17.70 KB
patch
obsolete
>Subversion Revision: 109802 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8f29bbe31178b022d173fd8b5ee07fe75f63f1a8..157cec87c9e362e72aafe6addaed33cbc7595564 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,43 @@ >+2012-03-07 Andy Estes <aestes@apple.com> >+ >+ REGRESSION (r105396): Dragging an iWork document into icloud.com opens it in the Mac app instead of uploading it to icloud.com >+ https://bugs.webkit.org/show_bug.cgi?id=79443 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ icloud.com registers a drop event handler that sets display:none on the >+ file input element receiving the drop. DragController was later hit >+ testing for the element under the mouse to see if it is a file input >+ element in need of receiving files. However, since the file input >+ element receiving the drop no longer has a renderer, hit testing will >+ overlook it, leading to DragController assuming a different element is >+ under the mouse than what received the drop event. >+ >+ Fix this by having DragController keep track of the element under the >+ mouse. If this is a file input element, set received files on it even >+ if it no longer has a renderer. DragController already keeps track of >+ the element under the mouse if it is a file input element, so this >+ patch just uses that element in places where unnecessary hit testing >+ was taking place before. >+ >+ Note that this duplicates the element tracking done by EventHandler in >+ the case of DHTML drag actions. We should remove that duplication at >+ some point. >+ >+ Test: fast/events/file-input-hidden-in-ondrop.html >+ >+ * html/HTMLInputElement.cpp: >+ (WebCore::HTMLInputElement::setCanReceiveDroppedFiles): >+ * page/DragController.cpp: >+ (WebCore::DragController::DragController): >+ (WebCore::DragController::dragExited): >+ (WebCore::DragController::performDrag): >+ (WebCore::DragController::tryDocumentDrag): >+ (WebCore::DragController::concludeEditDrag): >+ (WebCore::DragController::canProcessDrag): >+ * page/DragController.h: >+ (DragController): >+ > 2012-03-05 Anders Carlsson <andersca@apple.com> > > Always update the scroll layer position on the main thread when we have an overlay >diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp >index 0e1f9df200dd58f81ce3988fcc678f3cf432a726..a07cea6f059d63ac8d1288d48488ca428ff62263 100644 >--- a/Source/WebCore/html/HTMLInputElement.cpp >+++ b/Source/WebCore/html/HTMLInputElement.cpp >@@ -1356,7 +1356,8 @@ void HTMLInputElement::setCanReceiveDroppedFiles(bool canReceiveDroppedFiles) > if (m_canReceiveDroppedFiles == canReceiveDroppedFiles) > return; > m_canReceiveDroppedFiles = canReceiveDroppedFiles; >- renderer()->updateFromElement(); >+ if (renderer()) >+ renderer()->updateFromElement(); > } > > String HTMLInputElement::visibleValue() const >diff --git a/Source/WebCore/page/DragController.cpp b/Source/WebCore/page/DragController.cpp >index 4891aad0b620bf621b2ddce9ff1645d69545ce17..cb5e9d366bf55907e1d2a03e30121a09fb00c38b 100644 >--- a/Source/WebCore/page/DragController.cpp >+++ b/Source/WebCore/page/DragController.cpp >@@ -88,7 +88,7 @@ DragController::DragController(Page* page, DragClient* client) > , m_client(client) > , m_documentUnderMouse(0) > , m_dragInitiator(0) >- , m_fileInputElementUnderMouse(0) >+ , m_elementUnderMouse(0) > , m_dragDestinationAction(DragDestinationActionNone) > , m_dragSourceAction(DragSourceActionNone) > , m_didInitiateDrag(false) >@@ -174,6 +174,27 @@ DragSession DragController::dragEntered(DragData* dragData) > return dragEnteredOrUpdated(dragData); > } > >+static HTMLInputElement* asFileInput(Node* node) >+{ >+ ASSERT(node); >+ >+ HTMLInputElement* inputElement = node->toInputElement(); >+ >+ // If this is a button inside of the a file input, move up to the file input. >+ if (inputElement && inputElement->isTextButton() && inputElement->treeScope()->rootNode()->isShadowRoot()) >+ inputElement = inputElement->treeScope()->rootNode()->shadowHost()->toInputElement(); >+ >+ return inputElement && inputElement->isFileUpload() ? inputElement : 0; >+} >+ >+static void setCanReceiveDroppedFilesForElement(Element* element, bool canReceiveDroppedFiles) >+{ >+ if (!element) >+ return; >+ if (HTMLInputElement* elementAsFileInput = asFileInput(element)) >+ elementAsFileInput->setCanReceiveDroppedFiles(canReceiveDroppedFiles); >+} >+ > void DragController::dragExited(DragData* dragData) > { > ASSERT(dragData); >@@ -187,9 +208,8 @@ void DragController::dragExited(DragData* dragData) > clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security > } > mouseMovedIntoDocument(0); >- if (m_fileInputElementUnderMouse) >- m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false); >- m_fileInputElementUnderMouse = 0; >+ setCanReceiveDroppedFilesForElement(m_elementUnderMouse.get(), false); >+ m_elementUnderMouse = 0; > } > > DragSession DragController::dragUpdated(DragData* dragData) >@@ -201,6 +221,7 @@ bool DragController::performDrag(DragData* dragData) > { > ASSERT(dragData); > m_documentUnderMouse = m_page->mainFrame()->documentAtPoint(dragData->clientPosition()); >+ ASSERT(!m_elementUnderMouse || m_elementUnderMouse->document() == m_documentUnderMouse); > if (m_dragDestinationAction & DragDestinationActionDHTML) { > m_client->willPerformDragDestinationAction(DragDestinationActionDHTML, dragData); > RefPtr<Frame> mainFrame = m_page->mainFrame(); >@@ -217,13 +238,14 @@ bool DragController::performDrag(DragData* dragData) > return true; > } > } >- >- if ((m_dragDestinationAction & DragDestinationActionEdit) && concludeEditDrag(dragData)) { >- m_documentUnderMouse = 0; >- return true; >- } >- >+ >+ bool didConcludeEditDrag = (m_dragDestinationAction & DragDestinationActionEdit) && concludeEditDrag(dragData); >+ >+ setCanReceiveDroppedFilesForElement(m_elementUnderMouse.get(), false); >+ m_elementUnderMouse = 0; > m_documentUnderMouse = 0; >+ if (didConcludeEditDrag) >+ return true; > > if (operationForLoad(dragData) == DragOperationNone) > return false; >@@ -263,19 +285,6 @@ DragSession DragController::dragEnteredOrUpdated(DragData* dragData) > return dragSession; > } > >-static HTMLInputElement* asFileInput(Node* node) >-{ >- ASSERT(node); >- >- HTMLInputElement* inputElement = node->toInputElement(); >- >- // If this is a button inside of the a file input, move up to the file input. >- if (inputElement && inputElement->isTextButton() && inputElement->treeScope()->rootNode()->isShadowRoot()) >- inputElement = inputElement->treeScope()->rootNode()->shadowHost()->toInputElement(); >- >- return inputElement && inputElement->isFileUpload() ? inputElement : 0; >-} >- > // This can return null if an empty document is loaded. > static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint& p) > { >@@ -323,41 +332,37 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a > RefPtr<FrameView> frameView = m_documentUnderMouse->view(); > if (!frameView) > return false; >+ >+ IntPoint point = frameView->windowToContents(dragData->clientPosition()); >+ Element* element = elementUnderMouse(m_documentUnderMouse.get(), point); >+ if (m_elementUnderMouse != element) { >+ setCanReceiveDroppedFilesForElement(m_elementUnderMouse.get(), false); >+ m_elementUnderMouse = element; >+ } > >- if (m_isHandlingDrag) { >- m_page->dragCaretController()->clear(); >- return true; >- } else if ((actionMask & DragDestinationActionEdit) && canProcessDrag(dragData)) { >+ if ((actionMask & DragDestinationActionEdit) && canProcessDrag(dragData)) { > if (dragData->containsColor()) { > dragSession.operation = DragOperationGeneric; > return true; > } > >- IntPoint point = frameView->windowToContents(dragData->clientPosition()); >- Element* element = elementUnderMouse(m_documentUnderMouse.get(), point); >- if (!element) >+ if (!m_elementUnderMouse) > return false; > >- HTMLInputElement* elementAsFileInput = asFileInput(element); >- if (m_fileInputElementUnderMouse != elementAsFileInput) { >- if (m_fileInputElementUnderMouse) >- m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false); >- m_fileInputElementUnderMouse = elementAsFileInput; >- } >- >- if (!m_fileInputElementUnderMouse) >+ HTMLInputElement* elementAsFileInput = m_elementUnderMouse ? asFileInput(m_elementUnderMouse.get()) : 0; >+ if (!elementAsFileInput) > m_page->dragCaretController()->setCaretPosition(m_documentUnderMouse->frame()->visiblePositionForPoint(point)); > > Frame* innerFrame = element->document()->frame(); > dragSession.operation = dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy; >- dragSession.mouseIsOverFileInput = m_fileInputElementUnderMouse; >+ dragSession.mouseIsOverFileInput = elementAsFileInput; > dragSession.numberOfItemsToBeAccepted = 0; > > unsigned numberOfFiles = dragData->numberOfFiles(); >- if (m_fileInputElementUnderMouse) { >- if (m_fileInputElementUnderMouse->disabled()) >+ if (elementAsFileInput) { >+ if (elementAsFileInput->disabled()) > dragSession.numberOfItemsToBeAccepted = 0; >- else if (m_fileInputElementUnderMouse->multiple()) >+ else if (elementAsFileInput->multiple()) > dragSession.numberOfItemsToBeAccepted = numberOfFiles; > else if (numberOfFiles > 1) > dragSession.numberOfItemsToBeAccepted = 0; >@@ -366,7 +371,7 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a > > if (!dragSession.numberOfItemsToBeAccepted) > dragSession.operation = DragOperationNone; >- m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(dragSession.numberOfItemsToBeAccepted); >+ elementAsFileInput->setCanReceiveDroppedFiles(dragSession.numberOfItemsToBeAccepted); > } else { > // We are not over a file input element. The dragged item(s) will only > // be loaded into the view the number of dragged items is 1. >@@ -378,10 +383,9 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a > > // We are not over an editable region. Make sure we're clearing any prior drag cursor. > m_page->dragCaretController()->clear(); >- if (m_fileInputElementUnderMouse) >- m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false); >- m_fileInputElementUnderMouse = 0; >- return false; >+ setCanReceiveDroppedFilesForElement(m_elementUnderMouse.get(), false); >+ m_elementUnderMouse = 0; >+ return m_isHandlingDrag; > } > > DragSourceAction DragController::delegateDragSourceAction(const IntPoint& rootViewPoint) >@@ -424,19 +428,11 @@ bool DragController::concludeEditDrag(DragData* dragData) > ASSERT(dragData); > ASSERT(!m_isHandlingDrag); > >- if (m_fileInputElementUnderMouse) { >- m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false); >- m_fileInputElementUnderMouse = 0; >- } >- >- if (!m_documentUnderMouse) >+ if (!m_documentUnderMouse || !m_elementUnderMouse) > return false; > > IntPoint point = m_documentUnderMouse->view()->windowToContents(dragData->clientPosition()); >- Element* element = elementUnderMouse(m_documentUnderMouse.get(), point); >- if (!element) >- return false; >- Frame* innerFrame = element->ownerDocument()->frame(); >+ Frame* innerFrame = m_elementUnderMouse->ownerDocument()->frame(); > ASSERT(innerFrame); > > if (m_page->dragCaretController()->hasCaret() && !dispatchTextInputEventFor(innerFrame, dragData)) >@@ -461,7 +457,7 @@ bool DragController::concludeEditDrag(DragData* dragData) > return false; > } > >- if (HTMLInputElement* fileInput = asFileInput(element)) { >+ if (HTMLInputElement* fileInput = asFileInput(m_elementUnderMouse.get())) { > if (fileInput->disabled()) > return false; > >@@ -538,22 +534,21 @@ bool DragController::canProcessDrag(DragData* dragData) > if (!dragData->containsCompatibleContent()) > return false; > >- IntPoint point = m_page->mainFrame()->view()->windowToContents(dragData->clientPosition()); >- HitTestResult result = HitTestResult(point); >- if (!m_page->mainFrame()->contentRenderer()) >- return false; >- >- result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, true); >- >- if (!result.innerNonSharedNode()) >+ if (!m_elementUnderMouse) > return false; > >- if (dragData->containsFiles() && asFileInput(result.innerNonSharedNode())) >+ if (dragData->containsFiles() && asFileInput(m_elementUnderMouse.get())) > return true; > >- if (!result.innerNonSharedNode()->rendererIsEditable()) >+ if (!m_elementUnderMouse->rendererIsEditable()) >+ return false; >+ >+ IntPoint point = m_page->mainFrame()->view()->windowToContents(dragData->clientPosition()); >+ HitTestResult result = HitTestResult(point); >+ if (!m_page->mainFrame()->contentRenderer()) > return false; > >+ result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, true); > if (m_didInitiateDrag && m_documentUnderMouse == m_dragInitiator && result.isSelected()) > return false; > >diff --git a/Source/WebCore/page/DragController.h b/Source/WebCore/page/DragController.h >index 74d61782e8f69e6401369e091e5bfbfa6a6595a9..ba9f6dd00493a60921eabcaf7e96c17fb64d6290 100644 >--- a/Source/WebCore/page/DragController.h >+++ b/Source/WebCore/page/DragController.h >@@ -122,7 +122,7 @@ namespace WebCore { > > RefPtr<Document> m_documentUnderMouse; // The document the mouse was last dragged over. > RefPtr<Document> m_dragInitiator; // The Document (if any) that initiated the drag. >- RefPtr<HTMLInputElement> m_fileInputElementUnderMouse; >+ RefPtr<Element> m_elementUnderMouse; > > DragDestinationAction m_dragDestinationAction; > DragSourceAction m_dragSourceAction; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 1237b9e1a2d31103150d69926577196632b47e95..52fdd3e6a35691fbff4fac5b406473080bbf57c7 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,15 @@ >+2012-03-07 Andy Estes <aestes@apple.com> >+ >+ REGRESSION (r105396): Dragging an iWork document into icloud.com opens it in the Mac app instead of uploading it to icloud.com >+ https://bugs.webkit.org/show_bug.cgi?id=79443 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/events/file-input-hidden-in-ondrop-expected.txt: Added. >+ * fast/events/file-input-hidden-in-ondrop.html: Added. >+ * platform/wk2/Skipped: WebKitTestRunner doesn't support >+ EventSender.beginDragWithFiles(). >+ > 2012-03-05 Tony Chang <tony@chromium.org> > > Implement flex-wrap: wrap >diff --git a/LayoutTests/fast/events/file-input-hidden-in-ondrop-expected.txt b/LayoutTests/fast/events/file-input-hidden-in-ondrop-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2da019e85098642bf1302cc6f6be47c4d8c211bf >--- /dev/null >+++ b/LayoutTests/fast/events/file-input-hidden-in-ondrop-expected.txt >@@ -0,0 +1,2 @@ >+PASS dropTarget.value is "C:\\fakepath\\abe.png" >+ >diff --git a/LayoutTests/fast/events/file-input-hidden-in-ondrop.html b/LayoutTests/fast/events/file-input-hidden-in-ondrop.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9c70ef60302f2f929b5c5a3358e96f7d48239369 >--- /dev/null >+++ b/LayoutTests/fast/events/file-input-hidden-in-ondrop.html >@@ -0,0 +1,38 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <script src="../js/resources/js-test-pre.js"></script> >+ <script> >+ if (window.layoutTestController) { >+ layoutTestController.dumpAsText(); >+ layoutTestController.waitUntilDone(); >+ } >+ >+ var dropTarget; >+ >+ function test() >+ { >+ dropTarget = document.getElementById("drop-target"); >+ dropTarget.addEventListener("drop", function() { >+ dropTarget.style.display = "none"; >+ setTimeout(function() { >+ shouldBeEqualToString("dropTarget.value", "C:\\fakepath\\abe.png"); >+ if (window.layoutTestController) >+ layoutTestController.notifyDone(); >+ }, 0); >+ }, false); >+ >+ if (window.eventSender) { >+ eventSender.beginDragWithFiles(["resources/abe.png"]); >+ var x = dropTarget.offsetLeft + dropTarget.offsetWidth / 2; >+ var y = dropTarget.offsetTop + dropTarget.offsetHeight / 2; >+ eventSender.mouseMoveTo(x, y); >+ eventSender.mouseUp(); >+ } >+ } >+ </script> >+</head> >+<body onload="test()"> >+ <input type="file" id="drop-target"> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/platform/wk2/Skipped b/LayoutTests/platform/wk2/Skipped >index c944aecf38808e9bd8c3d0a9f3d09a819c1ce7ec..2ae147d06b149280563ca73753abaf0dce639a4a 100644 >--- a/LayoutTests/platform/wk2/Skipped >+++ b/LayoutTests/platform/wk2/Skipped >@@ -1344,6 +1344,7 @@ fast/dom/Window/window-postmessage-clone-frames.html > fast/events/drag-file-crash.html > fast/events/drag-to-navigate.html > fast/events/dropzone-004.html >+fast/events/file-input-hidden-in-ondrop.html > fast/events/prevent-drag-to-navigate.html > fast/files/apply-blob-url-to-img.html > fast/files/apply-blob-url-to-xhr.html
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 79443
:
130013
|
130674
|
130769
|
130893