/src/mozilla-central/dom/html/HTMLButtonElement.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "mozilla/dom/HTMLButtonElement.h" |
8 | | |
9 | | #include "HTMLFormSubmissionConstants.h" |
10 | | #include "mozilla/dom/HTMLButtonElementBinding.h" |
11 | | #include "mozilla/dom/HTMLFormSubmission.h" |
12 | | #include "nsAttrValueInlines.h" |
13 | | #include "nsGkAtoms.h" |
14 | | #include "nsIPresShell.h" |
15 | | #include "nsStyleConsts.h" |
16 | | #include "nsPresContext.h" |
17 | | #include "nsIFormControl.h" |
18 | | #include "nsIURL.h" |
19 | | #include "nsIFrame.h" |
20 | | #include "nsIFormControlFrame.h" |
21 | | #include "nsIDocument.h" |
22 | | #include "mozilla/ContentEvents.h" |
23 | | #include "mozilla/EventDispatcher.h" |
24 | | #include "mozilla/EventStateManager.h" |
25 | | #include "mozilla/EventStates.h" |
26 | | #include "mozilla/MouseEvents.h" |
27 | | #include "mozilla/TextEvents.h" |
28 | | #include "nsUnicharUtils.h" |
29 | | #include "nsLayoutUtils.h" |
30 | | #include "mozilla/PresState.h" |
31 | | #include "nsError.h" |
32 | | #include "nsFocusManager.h" |
33 | | #include "mozilla/dom/HTMLFormElement.h" |
34 | | #include "mozAutoDocUpdate.h" |
35 | | |
36 | 0 | #define NS_IN_SUBMIT_CLICK (1 << 0) |
37 | 0 | #define NS_OUTER_ACTIVATE_EVENT (1 << 1) |
38 | | |
39 | | NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Button) |
40 | | |
41 | | namespace mozilla { |
42 | | namespace dom { |
43 | | |
44 | | static const nsAttrValue::EnumTable kButtonTypeTable[] = { |
45 | | { "button", NS_FORM_BUTTON_BUTTON }, |
46 | | { "reset", NS_FORM_BUTTON_RESET }, |
47 | | { "submit", NS_FORM_BUTTON_SUBMIT }, |
48 | | { nullptr, 0 } |
49 | | }; |
50 | | |
51 | | // Default type is 'submit'. |
52 | | static const nsAttrValue::EnumTable* kButtonDefaultType = &kButtonTypeTable[2]; |
53 | | |
54 | | |
55 | | // Construction, destruction |
56 | | HTMLButtonElement::HTMLButtonElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, |
57 | | FromParser aFromParser) |
58 | | : nsGenericHTMLFormElementWithState(std::move(aNodeInfo), kButtonDefaultType->value), |
59 | | mDisabledChanged(false), |
60 | | mInInternalActivate(false), |
61 | | mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)) |
62 | 0 | { |
63 | 0 | // Set up our default state: enabled |
64 | 0 | AddStatesSilently(NS_EVENT_STATE_ENABLED); |
65 | 0 | } |
66 | | |
67 | | HTMLButtonElement::~HTMLButtonElement() |
68 | 0 | { |
69 | 0 | } |
70 | | |
71 | | // nsISupports |
72 | | |
73 | | NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLButtonElement, |
74 | | nsGenericHTMLFormElementWithState, |
75 | | mValidity) |
76 | | |
77 | | NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLButtonElement, |
78 | | nsGenericHTMLFormElementWithState, |
79 | | nsIConstraintValidation) |
80 | | |
81 | | void |
82 | | HTMLButtonElement::SetCustomValidity(const nsAString& aError) |
83 | 0 | { |
84 | 0 | nsIConstraintValidation::SetCustomValidity(aError); |
85 | 0 |
|
86 | 0 | UpdateState(true); |
87 | 0 | } |
88 | | |
89 | | void |
90 | | HTMLButtonElement::UpdateBarredFromConstraintValidation() |
91 | 0 | { |
92 | 0 | SetBarredFromConstraintValidation(mType == NS_FORM_BUTTON_BUTTON || |
93 | 0 | mType == NS_FORM_BUTTON_RESET || |
94 | 0 | IsDisabled()); |
95 | 0 | } |
96 | | |
97 | | void |
98 | | HTMLButtonElement::FieldSetDisabledChanged(bool aNotify) |
99 | 0 | { |
100 | 0 |
|
101 | 0 | // FieldSetDisabledChanged *has* to be called *before* |
102 | 0 | // UpdateBarredFromConstraintValidation, because the latter depends on our |
103 | 0 | // disabled state. |
104 | 0 | nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify); |
105 | 0 |
|
106 | 0 | UpdateBarredFromConstraintValidation(); |
107 | 0 | UpdateState(aNotify); |
108 | 0 | } |
109 | | |
110 | | NS_IMPL_ELEMENT_CLONE(HTMLButtonElement) |
111 | | |
112 | | void |
113 | | HTMLButtonElement::GetFormEnctype(nsAString& aFormEncType) |
114 | 0 | { |
115 | 0 | GetEnumAttr(nsGkAtoms::formenctype, "", kFormDefaultEnctype->tag, aFormEncType); |
116 | 0 | } |
117 | | |
118 | | void |
119 | | HTMLButtonElement::GetFormMethod(nsAString& aFormMethod) |
120 | 0 | { |
121 | 0 | GetEnumAttr(nsGkAtoms::formmethod, "", kFormDefaultMethod->tag, aFormMethod); |
122 | 0 | } |
123 | | |
124 | | void |
125 | | HTMLButtonElement::GetType(nsAString& aType) |
126 | 0 | { |
127 | 0 | GetEnumAttr(nsGkAtoms::type, kButtonDefaultType->tag, aType); |
128 | 0 | } |
129 | | |
130 | | int32_t |
131 | | HTMLButtonElement::TabIndexDefault() |
132 | 0 | { |
133 | 0 | return 0; |
134 | 0 | } |
135 | | |
136 | | bool |
137 | | HTMLButtonElement::IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) |
138 | 0 | { |
139 | 0 | if (nsGenericHTMLFormElementWithState::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) { |
140 | 0 | return true; |
141 | 0 | } |
142 | 0 | |
143 | 0 | *aIsFocusable = |
144 | | #ifdef XP_MACOSX |
145 | | (!aWithMouse || nsFocusManager::sMouseFocusesFormControl) && |
146 | | #endif |
147 | | !IsDisabled(); |
148 | 0 |
|
149 | 0 | return false; |
150 | 0 | } |
151 | | |
152 | | bool |
153 | | HTMLButtonElement::ParseAttribute(int32_t aNamespaceID, |
154 | | nsAtom* aAttribute, |
155 | | const nsAString& aValue, |
156 | | nsIPrincipal* aMaybeScriptedPrincipal, |
157 | | nsAttrValue& aResult) |
158 | 0 | { |
159 | 0 | if (aNamespaceID == kNameSpaceID_None) { |
160 | 0 | if (aAttribute == nsGkAtoms::type) { |
161 | 0 | return aResult.ParseEnumValue(aValue, kButtonTypeTable, false, |
162 | 0 | kButtonDefaultType); |
163 | 0 | } |
164 | 0 | |
165 | 0 | if (aAttribute == nsGkAtoms::formmethod) { |
166 | 0 | return aResult.ParseEnumValue(aValue, kFormMethodTable, false); |
167 | 0 | } |
168 | 0 | if (aAttribute == nsGkAtoms::formenctype) { |
169 | 0 | return aResult.ParseEnumValue(aValue, kFormEnctypeTable, false); |
170 | 0 | } |
171 | 0 | } |
172 | 0 | |
173 | 0 | return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, |
174 | 0 | aMaybeScriptedPrincipal, aResult); |
175 | 0 | } |
176 | | |
177 | | bool |
178 | | HTMLButtonElement::IsDisabledForEvents(EventMessage aMessage) |
179 | 0 | { |
180 | 0 | nsIFormControlFrame* formControlFrame = GetFormControlFrame(false); |
181 | 0 | nsIFrame* formFrame = do_QueryFrame(formControlFrame); |
182 | 0 | return IsElementDisabledForEvents(aMessage, formFrame); |
183 | 0 | } |
184 | | |
185 | | void |
186 | | HTMLButtonElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) |
187 | 0 | { |
188 | 0 | aVisitor.mCanHandle = false; |
189 | 0 | if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) { |
190 | 0 | return; |
191 | 0 | } |
192 | 0 | |
193 | 0 | // Track whether we're in the outermost Dispatch invocation that will |
194 | 0 | // cause activation of the input. That is, if we're a click event, or a |
195 | 0 | // DOMActivate that was dispatched directly, this will be set, but if we're |
196 | 0 | // a DOMActivate dispatched from click handling, it will not be set. |
197 | 0 | WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent(); |
198 | 0 | bool outerActivateEvent = |
199 | 0 | ((mouseEvent && mouseEvent->IsLeftClickEvent()) || |
200 | 0 | (aVisitor.mEvent->mMessage == eLegacyDOMActivate && |
201 | 0 | !mInInternalActivate)); |
202 | 0 |
|
203 | 0 | if (outerActivateEvent) { |
204 | 0 | aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT; |
205 | 0 | if (mType == NS_FORM_BUTTON_SUBMIT && mForm) { |
206 | 0 | aVisitor.mItemFlags |= NS_IN_SUBMIT_CLICK; |
207 | 0 | // tell the form that we are about to enter a click handler. |
208 | 0 | // that means that if there are scripted submissions, the |
209 | 0 | // latest one will be deferred until after the exit point of the handler. |
210 | 0 | mForm->OnSubmitClickBegin(this); |
211 | 0 | } |
212 | 0 | } |
213 | 0 |
|
214 | 0 | nsGenericHTMLElement::GetEventTargetParent(aVisitor); |
215 | 0 | } |
216 | | |
217 | | nsresult |
218 | | HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor) |
219 | 0 | { |
220 | 0 | nsresult rv = NS_OK; |
221 | 0 | if (!aVisitor.mPresContext) { |
222 | 0 | return rv; |
223 | 0 | } |
224 | 0 | |
225 | 0 | if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) { |
226 | 0 | WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent(); |
227 | 0 | if (mouseEvent && mouseEvent->IsLeftClickEvent()) { |
228 | 0 | // DOMActive event should be trusted since the activation is actually |
229 | 0 | // occurred even if the cause is an untrusted click event. |
230 | 0 | InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent); |
231 | 0 | actEvent.mDetail = 1; |
232 | 0 |
|
233 | 0 | nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell(); |
234 | 0 | if (shell) { |
235 | 0 | nsEventStatus status = nsEventStatus_eIgnore; |
236 | 0 | mInInternalActivate = true; |
237 | 0 | shell->HandleDOMEventWithTarget(this, &actEvent, &status); |
238 | 0 | mInInternalActivate = false; |
239 | 0 |
|
240 | 0 | // If activate is cancelled, we must do the same as when click is |
241 | 0 | // cancelled (revert the checkbox to its original value). |
242 | 0 | if (status == nsEventStatus_eConsumeNoDefault) { |
243 | 0 | aVisitor.mEventStatus = status; |
244 | 0 | } |
245 | 0 | } |
246 | 0 | } |
247 | 0 | } |
248 | 0 |
|
249 | 0 | // mForm is null if the event handler removed us from the document (bug 194582). |
250 | 0 | if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) { |
251 | 0 | // tell the form that we are about to exit a click handler |
252 | 0 | // so the form knows not to defer subsequent submissions |
253 | 0 | // the pending ones that were created during the handler |
254 | 0 | // will be flushed or forgoten. |
255 | 0 | mForm->OnSubmitClickEnd(); |
256 | 0 | } |
257 | 0 |
|
258 | 0 | if (nsEventStatus_eIgnore == aVisitor.mEventStatus) { |
259 | 0 | switch (aVisitor.mEvent->mMessage) { |
260 | 0 | case eKeyPress: |
261 | 0 | case eKeyUp: |
262 | 0 | { |
263 | 0 | // For backwards compat, trigger buttons with space or enter |
264 | 0 | // (bug 25300) |
265 | 0 | WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent(); |
266 | 0 | if ((keyEvent->mKeyCode == NS_VK_RETURN && |
267 | 0 | eKeyPress == aVisitor.mEvent->mMessage) || |
268 | 0 | (keyEvent->mKeyCode == NS_VK_SPACE && |
269 | 0 | eKeyUp == aVisitor.mEvent->mMessage)) { |
270 | 0 | DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(), |
271 | 0 | aVisitor.mPresContext); |
272 | 0 | aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; |
273 | 0 | } |
274 | 0 | } |
275 | 0 | break; |
276 | 0 |
|
277 | 0 | default: |
278 | 0 | break; |
279 | 0 | } |
280 | 0 | if (aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT) { |
281 | 0 | if (mForm && (mType == NS_FORM_BUTTON_SUBMIT || |
282 | 0 | mType == NS_FORM_BUTTON_RESET)) { |
283 | 0 | InternalFormEvent event(true, |
284 | 0 | (mType == NS_FORM_BUTTON_RESET) ? eFormReset : eFormSubmit); |
285 | 0 | event.mOriginator = this; |
286 | 0 | nsEventStatus status = nsEventStatus_eIgnore; |
287 | 0 |
|
288 | 0 | nsCOMPtr<nsIPresShell> presShell = |
289 | 0 | aVisitor.mPresContext->GetPresShell(); |
290 | 0 | // If |nsIPresShell::Destroy| has been called due to |
291 | 0 | // handling the event, the pres context will return |
292 | 0 | // a null pres shell. See bug 125624. |
293 | 0 | // |
294 | 0 | // Using presShell to dispatch the event. It makes sure that |
295 | 0 | // event is not handled if the window is being destroyed. |
296 | 0 | if (presShell && (event.mMessage != eFormSubmit || |
297 | 0 | mForm->SubmissionCanProceed(this))) { |
298 | 0 | // TODO: removing this code and have the submit event sent by the form |
299 | 0 | // see bug 592124. |
300 | 0 | // Hold a strong ref while dispatching |
301 | 0 | RefPtr<HTMLFormElement> form(mForm); |
302 | 0 | presShell->HandleDOMEventWithTarget(form, &event, &status); |
303 | 0 | aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; |
304 | 0 | } |
305 | 0 | } |
306 | 0 | } |
307 | 0 | } else if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) { |
308 | 0 | // Tell the form to flush a possible pending submission. |
309 | 0 | // the reason is that the script returned false (the event was |
310 | 0 | // not ignored) so if there is a stored submission, it needs to |
311 | 0 | // be submitted immediatelly. |
312 | 0 | // Note, NS_IN_SUBMIT_CLICK is set only when we're in outer activate event. |
313 | 0 | mForm->FlushPendingSubmission(); |
314 | 0 | } //if |
315 | 0 |
|
316 | 0 | return rv; |
317 | 0 | } |
318 | | |
319 | | nsresult |
320 | | HTMLButtonElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, |
321 | | nsIContent* aBindingParent) |
322 | 0 | { |
323 | 0 | nsresult rv = |
324 | 0 | nsGenericHTMLFormElementWithState::BindToTree(aDocument, aParent, aBindingParent); |
325 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
326 | 0 |
|
327 | 0 | // Update our state; we may now be the default submit element |
328 | 0 | UpdateState(false); |
329 | 0 |
|
330 | 0 | return NS_OK; |
331 | 0 | } |
332 | | |
333 | | void |
334 | | HTMLButtonElement::UnbindFromTree(bool aDeep, bool aNullParent) |
335 | 0 | { |
336 | 0 | nsGenericHTMLFormElementWithState::UnbindFromTree(aDeep, aNullParent); |
337 | 0 |
|
338 | 0 | // Update our state; we may no longer be the default submit element |
339 | 0 | UpdateState(false); |
340 | 0 | } |
341 | | |
342 | | NS_IMETHODIMP |
343 | | HTMLButtonElement::Reset() |
344 | 0 | { |
345 | 0 | return NS_OK; |
346 | 0 | } |
347 | | |
348 | | NS_IMETHODIMP |
349 | | HTMLButtonElement::SubmitNamesValues(HTMLFormSubmission* aFormSubmission) |
350 | 0 | { |
351 | 0 | // |
352 | 0 | // We only submit if we were the button pressed |
353 | 0 | // |
354 | 0 | if (aFormSubmission->GetOriginatingElement() != this) { |
355 | 0 | return NS_OK; |
356 | 0 | } |
357 | 0 | |
358 | 0 | // Disabled elements don't submit |
359 | 0 | if (IsDisabled()) { |
360 | 0 | return NS_OK; |
361 | 0 | } |
362 | 0 | |
363 | 0 | // |
364 | 0 | // Get the name (if no name, no submit) |
365 | 0 | // |
366 | 0 | nsAutoString name; |
367 | 0 | GetHTMLAttr(nsGkAtoms::name, name); |
368 | 0 | if (name.IsEmpty()) { |
369 | 0 | return NS_OK; |
370 | 0 | } |
371 | 0 | |
372 | 0 | // |
373 | 0 | // Get the value |
374 | 0 | // |
375 | 0 | nsAutoString value; |
376 | 0 | GetHTMLAttr(nsGkAtoms::value, value); |
377 | 0 |
|
378 | 0 | // |
379 | 0 | // Submit |
380 | 0 | // |
381 | 0 | return aFormSubmission->AddNameValuePair(name, value); |
382 | 0 | } |
383 | | |
384 | | void |
385 | | HTMLButtonElement::DoneCreatingElement() |
386 | 0 | { |
387 | 0 | if (!mInhibitStateRestoration) { |
388 | 0 | nsresult rv = GenerateStateKey(); |
389 | 0 | if (NS_SUCCEEDED(rv)) { |
390 | 0 | RestoreFormControlState(); |
391 | 0 | } |
392 | 0 | } |
393 | 0 | } |
394 | | |
395 | | nsresult |
396 | | HTMLButtonElement::BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName, |
397 | | const nsAttrValueOrString* aValue, |
398 | | bool aNotify) |
399 | 0 | { |
400 | 0 | if (aNotify && aName == nsGkAtoms::disabled && |
401 | 0 | aNameSpaceID == kNameSpaceID_None) { |
402 | 0 | mDisabledChanged = true; |
403 | 0 | } |
404 | 0 |
|
405 | 0 | return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName, |
406 | 0 | aValue, aNotify); |
407 | 0 | } |
408 | | |
409 | | nsresult |
410 | | HTMLButtonElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, |
411 | | const nsAttrValue* aValue, |
412 | | const nsAttrValue* aOldValue, |
413 | | nsIPrincipal* aSubjectPrincipal, |
414 | | bool aNotify) |
415 | 0 | { |
416 | 0 | if (aNameSpaceID == kNameSpaceID_None) { |
417 | 0 | if (aName == nsGkAtoms::type) { |
418 | 0 | if (aValue) { |
419 | 0 | mType = aValue->GetEnumValue(); |
420 | 0 | } else { |
421 | 0 | mType = kButtonDefaultType->value; |
422 | 0 | } |
423 | 0 | } |
424 | 0 |
|
425 | 0 | if (aName == nsGkAtoms::type || aName == nsGkAtoms::disabled) { |
426 | 0 | if (aName == nsGkAtoms::disabled) { |
427 | 0 | // This *has* to be called *before* validity state check because |
428 | 0 | // UpdateBarredFromConstraintValidation depends on our disabled state. |
429 | 0 | UpdateDisabledState(aNotify); |
430 | 0 | } |
431 | 0 |
|
432 | 0 | UpdateBarredFromConstraintValidation(); |
433 | 0 | } |
434 | 0 | } |
435 | 0 |
|
436 | 0 | return nsGenericHTMLFormElementWithState::AfterSetAttr(aNameSpaceID, aName, |
437 | 0 | aValue, aOldValue, |
438 | 0 | aSubjectPrincipal, aNotify); |
439 | 0 | } |
440 | | |
441 | | NS_IMETHODIMP |
442 | | HTMLButtonElement::SaveState() |
443 | 0 | { |
444 | 0 | if (!mDisabledChanged) { |
445 | 0 | return NS_OK; |
446 | 0 | } |
447 | 0 | |
448 | 0 | PresState* state = GetPrimaryPresState(); |
449 | 0 | if (state) { |
450 | 0 | // We do not want to save the real disabled state but the disabled |
451 | 0 | // attribute. |
452 | 0 | state->disabled() = HasAttr(kNameSpaceID_None, nsGkAtoms::disabled); |
453 | 0 | state->disabledSet() = true; |
454 | 0 | } |
455 | 0 |
|
456 | 0 | return NS_OK; |
457 | 0 | } |
458 | | |
459 | | bool |
460 | | HTMLButtonElement::RestoreState(PresState* aState) |
461 | 0 | { |
462 | 0 | if (aState && aState->disabledSet() && !aState->disabled()) { |
463 | 0 | SetDisabled(false, IgnoreErrors()); |
464 | 0 | } |
465 | 0 |
|
466 | 0 | return false; |
467 | 0 | } |
468 | | |
469 | | EventStates |
470 | | HTMLButtonElement::IntrinsicState() const |
471 | 0 | { |
472 | 0 | EventStates state = nsGenericHTMLFormElementWithState::IntrinsicState(); |
473 | 0 |
|
474 | 0 | if (IsCandidateForConstraintValidation()) { |
475 | 0 | if (IsValid()) { |
476 | 0 | state |= NS_EVENT_STATE_VALID; |
477 | 0 | if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) { |
478 | 0 | state |= NS_EVENT_STATE_MOZ_UI_VALID; |
479 | 0 | } |
480 | 0 | } else { |
481 | 0 | state |= NS_EVENT_STATE_INVALID; |
482 | 0 | if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) { |
483 | 0 | state |= NS_EVENT_STATE_MOZ_UI_INVALID; |
484 | 0 | } |
485 | 0 | } |
486 | 0 | } |
487 | 0 |
|
488 | 0 | if (mForm && !mForm->GetValidity() && IsSubmitControl()) { |
489 | 0 | state |= NS_EVENT_STATE_MOZ_SUBMITINVALID; |
490 | 0 | } |
491 | 0 |
|
492 | 0 | return state; |
493 | 0 | } |
494 | | |
495 | | JSObject* |
496 | | HTMLButtonElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) |
497 | 0 | { |
498 | 0 | return HTMLButtonElement_Binding::Wrap(aCx, this, aGivenProto); |
499 | 0 | } |
500 | | |
501 | | } // namespace dom |
502 | | } // namespace mozilla |