Bug 875252, make type=file click() to work (again) even when the element isn't in the DOM, r=jst

--HG--
extra : rebase_source : e8fecce550d5fe91a524f1b47a8429165354ac90
This commit is contained in:
Olli Pettay 2013-06-04 00:40:41 +03:00
parent f2ce1e419e
commit 46f9017a71
3 changed files with 37 additions and 14 deletions

View File

@ -2761,10 +2761,30 @@ HTMLInputElement::ShouldPreventDOMActivateDispatch(EventTarget* aOriginalTarget)
nsGkAtoms::button, eCaseMatters);
}
void
HTMLInputElement::MaybeFireAsyncClickHandler(nsEventChainPostVisitor& aVisitor)
{
// Open a file picker when we receive a click on a <input type='file'>, or
// open a color picker when we receive a click on a <input type='color'>.
// A click is handled in the following cases:
// - preventDefault() has not been called (or something similar);
// - it's the left mouse button.
// We do not prevent non-trusted click because authors can already use
// .click(). However, the file picker will follow the rules of popup-blocking.
if ((mType == NS_FORM_INPUT_FILE || mType == NS_FORM_INPUT_COLOR) &&
NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent) &&
!aVisitor.mEvent->mFlags.mDefaultPrevented) {
FireAsyncClickHandler();
}
}
nsresult
HTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
{
if (!aVisitor.mPresContext) {
// Hack alert! In order to open file picker even in case the element isn't
// in document, fire click handler even without PresContext.
MaybeFireAsyncClickHandler(aVisitor);
return NS_OK;
}
@ -3168,18 +3188,7 @@ HTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
PostHandleEventForRangeThumb(aVisitor);
}
// Open a file picker when we receive a click on a <input type='file'>, or
// open a color picker when we receive a click on a <input type='color'>.
// A click is handled in the following cases:
// - preventDefault() has not been called (or something similar);
// - it's the left mouse button.
// We do not prevent non-trusted click because authors can already use
// .click(). However, the file picker will follow the rules of popup-blocking.
if ((mType == NS_FORM_INPUT_FILE || mType == NS_FORM_INPUT_COLOR) &&
NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent) &&
!aVisitor.mEvent->mFlags.mDefaultPrevented) {
return FireAsyncClickHandler();
}
MaybeFireAsyncClickHandler(aVisitor);
return rv;
}

View File

@ -223,6 +223,7 @@ public:
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
void MaybeFireAsyncClickHandler(nsEventChainPostVisitor& aVisitor);
NS_IMETHOD FireAsyncClickHandler();
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLInputElement,

View File

@ -193,8 +193,7 @@ function runTests() {
"File picker should show the correct filter index (" + testName + ")");
if (++currentTest == testData.length) {
MockFilePicker.cleanup();
SimpleTest.finish();
setTimeout(testDisconnectedElement, 0);
} else {
launchNextTest();
}
@ -204,6 +203,20 @@ function runTests() {
launchNextTest();
}
function testDisconnectedElement() {
MockFilePicker.shown = false;
MockFilePicker.showCallback = function(filepicker) {
ok(MockFilePicker.shown, "FilePicker should be open!");
MockFilePicker.shown = false;
MockFilePicker.cleanup();
SimpleTest.finish();
}
var f = document.createElement("input");
f.setAttribute("type", "file");
f.click();
ok(!MockFilePicker.shown, "FilePicker should open asynchronously!");
}
</script>
</pre>
</body>