mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 605124 (4/5) - :-moz-ui-invalid applies if the user tried to submit the form in an invalid state. r=bz a=bsmedberg
This commit is contained in:
parent
c63d9ebdb1
commit
932d6a2d2a
@ -265,7 +265,8 @@ nsHTMLFormElement::nsHTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
mDefaultSubmitElement(nsnull),
|
||||
mFirstSubmitInElements(nsnull),
|
||||
mFirstSubmitNotInElements(nsnull),
|
||||
mInvalidElementsCount(0)
|
||||
mInvalidElementsCount(0),
|
||||
mEverTriedInvalidSubmit(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -477,6 +478,10 @@ CollectOrphans(nsINode* aRemovalRoot, nsTArray<nsGenericHTMLFormElement*> aArray
|
||||
#endif
|
||||
)
|
||||
{
|
||||
// Prepare document update batch.
|
||||
nsIDocument* doc = aArray.IsEmpty() ? nsnull : aArray[0]->GetCurrentDoc();
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
|
||||
// Walk backwards so that if we remove elements we can just keep iterating
|
||||
PRUint32 length = aArray.Length();
|
||||
for (PRUint32 i = length; i > 0; --i) {
|
||||
@ -495,14 +500,18 @@ CollectOrphans(nsINode* aRemovalRoot, nsTArray<nsGenericHTMLFormElement*> aArray
|
||||
if (!nsContentUtils::ContentIsDescendantOf(node, aRemovalRoot)) {
|
||||
node->ClearForm(PR_TRUE);
|
||||
|
||||
// When submit controls have no more form, they need to be updated.
|
||||
// When a form control loses its form owner,
|
||||
// NS_EVENT_STATE_MOZ_UI_INVALID might not apply any more.
|
||||
nsEventStates states = NS_EVENT_STATE_MOZ_UI_INVALID;
|
||||
|
||||
// In addition, submit controls shouldn't have
|
||||
// NS_EVENT_STATE_MOZ_SUBMITINVALID applying if they do not have a form.
|
||||
if (node->IsSubmitControl()) {
|
||||
nsIDocument* doc = node->GetCurrentDoc();
|
||||
if (doc) {
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
doc->ContentStatesChanged(node, nsnull,
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID);
|
||||
}
|
||||
states |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
doc->ContentStatesChanged(node, nsnull, states);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
removed = PR_TRUE;
|
||||
@ -1705,10 +1714,39 @@ nsHTMLFormElement::CheckValidFormSubmission()
|
||||
observer = do_QueryInterface(inst);
|
||||
|
||||
if (observer) {
|
||||
rv = observer->
|
||||
NotifyInvalidSubmit(this,
|
||||
static_cast<nsIArray*>(invalidElements));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
observer->NotifyInvalidSubmit(this,
|
||||
static_cast<nsIArray*>(invalidElements));
|
||||
}
|
||||
}
|
||||
|
||||
// For the first invalid submission, we should update element states.
|
||||
if (!mEverTriedInvalidSubmit) {
|
||||
mEverTriedInvalidSubmit = true;
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
/*
|
||||
* We are going to call ContentStatesChanged assuming elements want to
|
||||
* be notified because we can't know.
|
||||
* Submissions shouldn't happen during parsing so it _should_ be safe.
|
||||
*/
|
||||
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
|
||||
for (PRUint32 i = 0, length = mControls->mElements.Length();
|
||||
i < length; ++i) {
|
||||
doc->ContentStatesChanged(mControls->mElements[i], nsnull,
|
||||
NS_EVENT_STATE_MOZ_UI_INVALID);
|
||||
}
|
||||
|
||||
// Because of backward compatibility, <input type='image'> is not in
|
||||
// elements but can be invalid.
|
||||
// TODO: should probably be removed when bug 606491 will be fixed.
|
||||
for (PRUint32 i = 0, length = mControls->mNotInElements.Length();
|
||||
i < length; ++i) {
|
||||
doc->ContentStatesChanged(mControls->mNotInElements[i], nsnull,
|
||||
NS_EVENT_STATE_MOZ_UI_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,6 +296,15 @@ public:
|
||||
*/
|
||||
nsresult WalkFormElements(nsFormSubmission* aFormSubmission);
|
||||
|
||||
/**
|
||||
* Whether the submission of this form has been ever prevented because of
|
||||
* being invalid.
|
||||
*
|
||||
* @return Whether the submission of this form has been prevented because of
|
||||
* being invalid.
|
||||
*/
|
||||
bool HasEverTriedInvalidSubmit() const { return mEverTriedInvalidSubmit; }
|
||||
|
||||
protected:
|
||||
class RemoveElementRunnable;
|
||||
friend class RemoveElementRunnable;
|
||||
@ -441,6 +450,12 @@ protected:
|
||||
*/
|
||||
PRInt32 mInvalidElementsCount;
|
||||
|
||||
/**
|
||||
* Whether the submission of this form has been ever prevented because of
|
||||
* being invalid.
|
||||
*/
|
||||
bool mEverTriedInvalidSubmit;
|
||||
|
||||
protected:
|
||||
/** Detection of first form to notify observers */
|
||||
static PRBool gFirstFormSubmitted;
|
||||
|
@ -3316,11 +3316,14 @@ nsHTMLInputElement::IntrinsicState() const
|
||||
// Otherwise, NS_EVENT_STATE_MOZ_UI_INVALID applies if the element's value
|
||||
// has been modified.
|
||||
// For VALUE_MODE_DEFAULT case, value being modified has no sense.
|
||||
if (valueMode == VALUE_MODE_DEFAULT ||
|
||||
GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
|
||||
(valueMode == VALUE_MODE_DEFAULT_ON && GetCheckedChanged()) ||
|
||||
((valueMode == VALUE_MODE_FILENAME || valueMode == VALUE_MODE_VALUE) &&
|
||||
GET_BOOLBIT(mBitField, BF_VALUE_CHANGED))) {
|
||||
// NS_EVENT_STATE_MOZ_UI_INVALID always applies if the form submission has
|
||||
// been tried while invalid.
|
||||
if ((mForm && mForm->HasEverTriedInvalidSubmit()) ||
|
||||
(valueMode == VALUE_MODE_DEFAULT ||
|
||||
GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
|
||||
(valueMode == VALUE_MODE_DEFAULT_ON && GetCheckedChanged()) ||
|
||||
((valueMode == VALUE_MODE_FILENAME || valueMode == VALUE_MODE_VALUE) &&
|
||||
GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)))) {
|
||||
state |= NS_EVENT_STATE_MOZ_UI_INVALID;
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,7 @@
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIConstraintValidation.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
|
||||
#include "nsTextEditorState.h"
|
||||
|
||||
@ -1019,7 +1020,10 @@ nsHTMLTextAreaElement::IntrinsicState() const
|
||||
// NS_EVENT_STATE_MOZ_UI_INVALID always apply if the element suffers from
|
||||
// VALIDITY_STATE_CUSTOM_ERROR.
|
||||
// Otherwise, it applies if the value has been modified.
|
||||
if (mValueChanged || GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
|
||||
// NS_EVENT_STATE_MOZ_UI_INVALID always applies if the form submission has
|
||||
// been tried while invalid.
|
||||
if ((mForm && mForm->HasEverTriedInvalidSubmit()) ||
|
||||
(mValueChanged || GetValidityState(VALIDITY_STATE_CUSTOM_ERROR))) {
|
||||
state |= NS_EVENT_STATE_MOZ_UI_INVALID;
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +243,7 @@ _TEST_FILES = \
|
||||
test_bug596511.html \
|
||||
reflect.js \
|
||||
test_bug613113.html \
|
||||
test_bug605124.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
95
content/html/content/test/test_bug605124.html
Normal file
95
content/html/content/test/test_bug605124.html
Normal file
@ -0,0 +1,95 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=605124
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 605124</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=605124">Mozilla Bug 605124</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<form>
|
||||
<textarea required></textarea>
|
||||
<input required>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
|
||||
<table>
|
||||
<form>
|
||||
<tr>
|
||||
<textarea required></textarea>
|
||||
<input required>
|
||||
<button type='submit'></button>
|
||||
</tr>
|
||||
</form>
|
||||
</table>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 605124 **/
|
||||
|
||||
function checkPseudoClass(aElement, aExpected)
|
||||
{
|
||||
is(aElement.mozMatchesSelector(":-moz-ui-invalid"), aExpected,
|
||||
"mozMatchesSelector(':-moz-ui-invalid') should return " + aExpected + " for " + aElement);
|
||||
}
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var os = Components.classes['@mozilla.org/observer-service;1']
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
var observers = os.enumerateObservers("invalidformsubmit");
|
||||
|
||||
if (observers.hasMoreElements()) {
|
||||
var content = document.getElementById('content');
|
||||
var textarea = document.getElementsByTagName('textarea')[0];
|
||||
var input = document.getElementsByTagName('input')[0];
|
||||
var button = document.getElementsByTagName('button')[0];
|
||||
var form = document.forms[0];
|
||||
|
||||
checkPseudoClass(textarea, false);
|
||||
checkPseudoClass(input, false);
|
||||
|
||||
// Try to submit.
|
||||
button.click();
|
||||
checkPseudoClass(textarea, true);
|
||||
checkPseudoClass(input, true);
|
||||
|
||||
// No longer in the form.
|
||||
content.appendChild(textarea);
|
||||
content.appendChild(input);
|
||||
checkPseudoClass(textarea, false);
|
||||
checkPseudoClass(input, false);
|
||||
|
||||
// Back in the form.
|
||||
form.appendChild(textarea);
|
||||
form.appendChild(input);
|
||||
checkPseudoClass(textarea, true);
|
||||
checkPseudoClass(input, true);
|
||||
|
||||
/* Case when elements get orphaned. */
|
||||
var textarea = document.getElementsByTagName('textarea')[1];
|
||||
var input = document.getElementsByTagName('input')[1];
|
||||
var button = document.getElementsByTagName('button')[1];
|
||||
var form = document.forms[1];
|
||||
|
||||
// Try to submit.
|
||||
button.click();
|
||||
checkPseudoClass(textarea, true);
|
||||
checkPseudoClass(input, true);
|
||||
|
||||
// Remove the form.
|
||||
document.getElementsByTagName('table')[0].removeChild(form);
|
||||
checkPseudoClass(textarea, false);
|
||||
checkPseudoClass(input, false);
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user