2001-09-25 01:32:19 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-04-17 21:52:36 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
1998-09-03 01:03:33 +00:00
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
1998-09-03 01:03:33 +00:00
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
1998-09-03 01:03:33 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
2001-09-25 01:32:19 +00:00
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
1999-11-06 03:40:37 +00:00
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2004-04-17 21:52:36 +00:00
|
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
2001-09-25 01:32:19 +00:00
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
2004-04-17 21:52:36 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2001-09-25 01:32:19 +00:00
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
2004-04-17 21:52:36 +00:00
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2001-09-25 01:32:19 +00:00
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
2011-05-25 00:18:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of HTML <label> elements.
|
|
|
|
*/
|
|
|
|
#include "nsHTMLLabelElement.h"
|
2000-01-28 23:29:36 +00:00
|
|
|
#include "nsCOMPtr.h"
|
1998-10-22 23:00:37 +00:00
|
|
|
#include "nsIDOMHTMLFormElement.h"
|
2007-05-14 09:11:38 +00:00
|
|
|
#include "nsIDOMEventTarget.h"
|
2006-12-26 17:47:52 +00:00
|
|
|
#include "nsGkAtoms.h"
|
1998-09-03 01:03:33 +00:00
|
|
|
#include "nsStyleConsts.h"
|
2004-07-31 23:15:21 +00:00
|
|
|
#include "nsPresContext.h"
|
1998-10-22 23:00:37 +00:00
|
|
|
#include "nsIFormControl.h"
|
|
|
|
#include "nsIForm.h"
|
2009-03-24 00:55:29 +00:00
|
|
|
#include "nsIDOMDocument.h"
|
1999-11-02 23:38:17 +00:00
|
|
|
#include "nsIDocument.h"
|
2001-07-16 02:40:48 +00:00
|
|
|
#include "nsGUIEvent.h"
|
2006-03-07 17:08:51 +00:00
|
|
|
#include "nsEventDispatcher.h"
|
2007-02-13 15:02:57 +00:00
|
|
|
#include "nsPIDOMWindow.h"
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 18:00:39 +00:00
|
|
|
#include "nsFocusManager.h"
|
1998-09-03 01:03:33 +00:00
|
|
|
|
1998-10-22 23:00:37 +00:00
|
|
|
// construction, destruction
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2011-05-25 00:18:31 +00:00
|
|
|
using namespace mozilla::dom;
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2004-05-18 20:58:12 +00:00
|
|
|
NS_IMPL_NS_NEW_HTML_ELEMENT(Label)
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-03 01:03:33 +00:00
|
|
|
|
2010-07-23 09:49:57 +00:00
|
|
|
nsHTMLLabelElement::nsHTMLLabelElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
2007-11-17 00:30:53 +00:00
|
|
|
: nsGenericHTMLFormElement(aNodeInfo)
|
|
|
|
, mHandlingEvent(PR_FALSE)
|
1998-09-03 01:03:33 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsHTMLLabelElement::~nsHTMLLabelElement()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
1998-10-22 23:00:37 +00:00
|
|
|
// nsISupports
|
|
|
|
|
1998-09-03 01:03:33 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMPL_ADDREF_INHERITED(nsHTMLLabelElement, nsGenericElement)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(nsHTMLLabelElement, nsGenericElement)
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
|
2010-07-23 09:49:57 +00:00
|
|
|
DOMCI_NODE_DATA(HTMLLabelElement, nsHTMLLabelElement)
|
2010-01-12 13:08:43 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
// QueryInterface implementation for nsHTMLLabelElement
|
2008-11-03 10:31:47 +00:00
|
|
|
NS_INTERFACE_TABLE_HEAD(nsHTMLLabelElement)
|
2010-07-28 23:43:52 +00:00
|
|
|
NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLLabelElement,
|
|
|
|
nsIDOMHTMLLabelElement)
|
2008-11-03 10:31:47 +00:00
|
|
|
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLLabelElement,
|
|
|
|
nsGenericHTMLFormElement)
|
2007-08-20 22:55:06 +00:00
|
|
|
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLLabelElement)
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-03 01:03:33 +00:00
|
|
|
|
1998-10-22 23:00:37 +00:00
|
|
|
// nsIDOMHTMLLabelElement
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2006-09-05 10:22:54 +00:00
|
|
|
NS_IMPL_ELEMENT_CLONE(nsHTMLLabelElement)
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1999-07-28 05:26:55 +00:00
|
|
|
|
1998-09-03 01:03:33 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLLabelElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
|
|
|
{
|
2004-02-10 19:36:43 +00:00
|
|
|
return nsGenericHTMLFormElement::GetForm(aForm);
|
1998-10-22 23:00:37 +00:00
|
|
|
}
|
|
|
|
|
2010-05-20 02:28:10 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLLabelElement::GetControl(nsIDOMHTMLElement** aElement)
|
|
|
|
{
|
|
|
|
*aElement = nsnull;
|
|
|
|
|
2011-05-25 00:18:31 +00:00
|
|
|
nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(GetLabeledElement());
|
2010-05-20 02:28:10 +00:00
|
|
|
|
|
|
|
element.swap(*aElement);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-06-23 14:12:24 +00:00
|
|
|
|
2004-02-24 23:55:18 +00:00
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLLabelElement, HtmlFor, _for)
|
1998-09-03 01:03:33 +00:00
|
|
|
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 18:00:39 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLLabelElement::Focus()
|
|
|
|
{
|
|
|
|
// retarget the focus method at the for content
|
|
|
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
if (fm) {
|
2011-05-25 00:18:31 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(GetLabeledElement());
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 18:00:39 +00:00
|
|
|
if (elem)
|
|
|
|
fm->SetFocus(elem, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-04-05 23:54:35 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLLabelElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|
|
|
nsIContent* aBindingParent,
|
|
|
|
PRBool aCompileEventHandlers)
|
2002-05-22 00:14:51 +00:00
|
|
|
{
|
2011-04-11 16:56:37 +00:00
|
|
|
return nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
|
|
|
aBindingParent,
|
|
|
|
aCompileEventHandlers);
|
2005-04-05 23:54:35 +00:00
|
|
|
}
|
2002-05-22 00:14:51 +00:00
|
|
|
|
2005-04-05 23:54:35 +00:00
|
|
|
void
|
|
|
|
nsHTMLLabelElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
|
|
|
{
|
|
|
|
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
2002-05-22 00:14:51 +00:00
|
|
|
}
|
|
|
|
|
2002-05-23 00:23:12 +00:00
|
|
|
static PRBool
|
2006-03-12 19:57:14 +00:00
|
|
|
EventTargetIn(nsEvent *aEvent, nsIContent *aChild, nsIContent *aStop)
|
2002-05-23 00:23:12 +00:00
|
|
|
{
|
2006-03-12 19:57:14 +00:00
|
|
|
nsCOMPtr<nsIContent> c = do_QueryInterface(aEvent->target);
|
2003-07-28 22:32:31 +00:00
|
|
|
nsIContent *content = c;
|
|
|
|
while (content) {
|
|
|
|
if (content == aChild) {
|
2002-05-23 00:23:12 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
2003-06-13 20:10:01 +00:00
|
|
|
|
2003-07-28 22:32:31 +00:00
|
|
|
if (content == aStop) {
|
2002-05-23 00:23:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2003-06-13 20:10:01 +00:00
|
|
|
|
2003-07-28 22:32:31 +00:00
|
|
|
content = content->GetParent();
|
2002-05-23 00:23:12 +00:00
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-03-24 00:55:29 +00:00
|
|
|
static void
|
|
|
|
DestroyMouseDownPoint(void * /*aObject*/,
|
|
|
|
nsIAtom * /*aPropertyName*/,
|
|
|
|
void * aPropertyValue,
|
|
|
|
void * /*aData*/)
|
|
|
|
{
|
|
|
|
nsIntPoint *pt = (nsIntPoint *)aPropertyValue;
|
|
|
|
delete pt;
|
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
nsresult
|
2006-03-07 17:08:51 +00:00
|
|
|
nsHTMLLabelElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
1998-09-03 01:03:33 +00:00
|
|
|
{
|
2002-05-22 00:14:51 +00:00
|
|
|
if (mHandlingEvent ||
|
2006-11-16 21:35:39 +00:00
|
|
|
(!NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent) &&
|
2009-03-24 00:55:29 +00:00
|
|
|
aVisitor.mEvent->message != NS_MOUSE_BUTTON_DOWN) ||
|
2006-03-07 17:08:51 +00:00
|
|
|
aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
|
2011-07-19 16:19:32 +00:00
|
|
|
!aVisitor.mPresContext ||
|
|
|
|
// Don't handle the event if it's already been handled by another label
|
|
|
|
(aVisitor.mEvent->flags & NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS)) {
|
2002-05-22 00:14:51 +00:00
|
|
|
return NS_OK;
|
2006-03-07 17:08:51 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2011-05-25 00:18:31 +00:00
|
|
|
// Strong ref because event dispatch is going to happen.
|
|
|
|
nsRefPtr<Element> content = GetLabeledElement();
|
2010-05-20 02:28:10 +00:00
|
|
|
|
2006-03-12 19:57:14 +00:00
|
|
|
if (content && !EventTargetIn(aVisitor.mEvent, content, this)) {
|
2002-05-22 00:14:51 +00:00
|
|
|
mHandlingEvent = PR_TRUE;
|
2006-03-07 17:08:51 +00:00
|
|
|
switch (aVisitor.mEvent->message) {
|
2009-03-24 00:55:29 +00:00
|
|
|
case NS_MOUSE_BUTTON_DOWN:
|
|
|
|
NS_ASSERTION(aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT,
|
|
|
|
"wrong event struct for event");
|
|
|
|
if (static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
|
|
|
|
nsMouseEvent::eLeftButton) {
|
|
|
|
// We reset the mouse-down point on every event because there is
|
|
|
|
// no guarantee we will reach the NS_MOUSE_CLICK code below.
|
|
|
|
nsIntPoint *curPoint = new nsIntPoint(aVisitor.mEvent->refPoint);
|
|
|
|
SetProperty(nsGkAtoms::labelMouseDownPtProperty,
|
|
|
|
static_cast<void *>(curPoint),
|
|
|
|
DestroyMouseDownPoint);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2006-11-16 21:35:39 +00:00
|
|
|
case NS_MOUSE_CLICK:
|
|
|
|
if (NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent)) {
|
2009-03-24 00:55:29 +00:00
|
|
|
const nsMouseEvent* event =
|
|
|
|
static_cast<const nsMouseEvent*>(aVisitor.mEvent);
|
|
|
|
nsIntPoint *mouseDownPoint = static_cast<nsIntPoint *>
|
|
|
|
(GetProperty(nsGkAtoms::labelMouseDownPtProperty));
|
|
|
|
|
|
|
|
PRBool dragSelect = PR_FALSE;
|
|
|
|
if (mouseDownPoint) {
|
|
|
|
nsIntPoint dragDistance = *mouseDownPoint;
|
|
|
|
DeleteProperty(nsGkAtoms::labelMouseDownPtProperty);
|
|
|
|
|
|
|
|
dragDistance -= aVisitor.mEvent->refPoint;
|
|
|
|
const int CLICK_DISTANCE = 2;
|
|
|
|
dragSelect = dragDistance.x > CLICK_DISTANCE ||
|
|
|
|
dragDistance.x < -CLICK_DISTANCE ||
|
|
|
|
dragDistance.y > CLICK_DISTANCE ||
|
|
|
|
dragDistance.y < -CLICK_DISTANCE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't click the for-content if we did drag-select text or if we
|
|
|
|
// have a kbd modifier (which adjusts a selection), or if it's a
|
|
|
|
// double click (we already forwarded the first click event).
|
|
|
|
if (dragSelect || event->clickCount > 1 ||
|
|
|
|
event->isShift || event->isControl || event->isAlt ||
|
|
|
|
event->isMeta) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 18:00:39 +00:00
|
|
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
if (fm) {
|
2009-08-26 16:19:41 +00:00
|
|
|
// Use FLAG_BYMOVEFOCUS here so that the label is scrolled to.
|
|
|
|
// Also, within nsHTMLInputElement::PostHandleEvent, inputs will
|
|
|
|
// be selected only when focused via a key or when the navigation
|
|
|
|
// flag is used and we want to select the text on label clicks as
|
|
|
|
// well.
|
Bug 178324, refactor focus by moving all focus handling into one place and simplifying it, add many tests, fixes many other bugs too numerous to mention in this small checkin comment, r=josh,smichaud,ere,dbaron,marco,neil,gavin,smaug,sr=smaug (CLOSED TREE)
2009-06-10 18:00:39 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(content);
|
2009-08-26 16:19:41 +00:00
|
|
|
fm->SetFocus(elem, nsIFocusManager::FLAG_BYMOVEFOCUS);
|
2005-01-20 16:59:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Dispatch a new click event to |content|
|
|
|
|
// (For compatibility with IE, we do only left click. If
|
|
|
|
// we wanted to interpret the HTML spec very narrowly, we
|
|
|
|
// would do nothing. If we wanted to do something
|
|
|
|
// sensible, we might send more events through like
|
|
|
|
// this.) See bug 7554, bug 49897, and bug 96813.
|
2006-03-07 17:08:51 +00:00
|
|
|
nsEventStatus status = aVisitor.mEventStatus;
|
|
|
|
// Ok to use aVisitor.mEvent as parameter because DispatchClickEvent
|
|
|
|
// will actually create a new event.
|
|
|
|
DispatchClickEvent(aVisitor.mPresContext,
|
2007-07-08 07:08:04 +00:00
|
|
|
static_cast<nsInputEvent*>(aVisitor.mEvent),
|
2011-07-19 16:19:32 +00:00
|
|
|
content, PR_FALSE,
|
|
|
|
NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS, &status);
|
2005-01-20 16:59:42 +00:00
|
|
|
// Do we care about the status this returned? I don't think we do...
|
2011-07-19 16:19:32 +00:00
|
|
|
// Don't run another <label> off of this click
|
|
|
|
aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
|
2004-11-04 01:36:18 +00:00
|
|
|
}
|
2002-05-22 00:14:51 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
mHandlingEvent = PR_FALSE;
|
|
|
|
}
|
2006-03-07 17:08:51 +00:00
|
|
|
return NS_OK;
|
1999-11-02 23:38:17 +00:00
|
|
|
}
|
1999-10-07 00:35:04 +00:00
|
|
|
|
2001-11-02 07:40:01 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLLabelElement::Reset()
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_IMETHODIMP
|
2010-08-19 21:58:20 +00:00
|
|
|
nsHTMLLabelElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
2001-11-02 07:40:01 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-05-22 00:14:51 +00:00
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
nsresult
|
2004-01-15 17:07:27 +00:00
|
|
|
nsHTMLLabelElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
2002-05-22 00:14:51 +00:00
|
|
|
const nsAString& aValue, PRBool aNotify)
|
|
|
|
{
|
2011-04-11 16:56:37 +00:00
|
|
|
return nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
|
|
|
aNotify);
|
2002-05-22 00:14:51 +00:00
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
nsresult
|
2002-05-22 00:14:51 +00:00
|
|
|
nsHTMLLabelElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
|
|
|
PRBool aNotify)
|
|
|
|
{
|
2010-08-24 01:11:04 +00:00
|
|
|
return nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
2002-05-22 00:14:51 +00:00
|
|
|
}
|
|
|
|
|
2007-02-13 15:02:57 +00:00
|
|
|
void
|
|
|
|
nsHTMLLabelElement::PerformAccesskey(PRBool aKeyCausesActivation,
|
|
|
|
PRBool aIsTrustedEvent)
|
|
|
|
{
|
|
|
|
if (!aKeyCausesActivation) {
|
2011-05-25 00:18:31 +00:00
|
|
|
nsRefPtr<Element> element = GetLabeledElement();
|
|
|
|
if (element)
|
|
|
|
element->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent);
|
2007-02-13 15:02:57 +00:00
|
|
|
} else {
|
|
|
|
nsPresContext *presContext = GetPresContext();
|
|
|
|
if (!presContext)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Click on it if the users prefs indicate to do so.
|
|
|
|
nsMouseEvent event(aIsTrustedEvent, NS_MOUSE_CLICK,
|
|
|
|
nsnull, nsMouseEvent::eReal);
|
2010-04-06 12:59:24 +00:00
|
|
|
event.inputSource = nsIDOMNSMouseEvent::MOZ_SOURCE_KEYBOARD;
|
2007-02-13 15:02:57 +00:00
|
|
|
|
|
|
|
nsAutoPopupStatePusher popupStatePusher(aIsTrustedEvent ?
|
|
|
|
openAllowed : openAbused);
|
|
|
|
|
2007-07-08 07:08:04 +00:00
|
|
|
nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this), presContext,
|
2007-02-13 15:02:57 +00:00
|
|
|
&event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-25 00:18:31 +00:00
|
|
|
Element*
|
|
|
|
nsHTMLLabelElement::GetLabeledElement()
|
2002-05-22 00:14:51 +00:00
|
|
|
{
|
|
|
|
nsAutoString elementId;
|
2010-05-20 02:28:10 +00:00
|
|
|
|
|
|
|
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::_for, elementId)) {
|
|
|
|
// No @for, so we are a label for our first form control element.
|
|
|
|
// Do a depth-first traversal to look for the first form control element.
|
2011-05-25 00:18:31 +00:00
|
|
|
return GetFirstDescendantFormControl();
|
2003-02-22 13:01:03 +00:00
|
|
|
}
|
2010-05-20 02:28:10 +00:00
|
|
|
|
|
|
|
// We have a @for. The id has to be linked to an element in the same document
|
|
|
|
// and this element should be a labelable form control.
|
|
|
|
nsIDocument* doc = GetCurrentDoc();
|
|
|
|
if (!doc) {
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2011-05-25 00:18:31 +00:00
|
|
|
Element* element = doc->GetElementById(elementId);
|
|
|
|
if (!element) {
|
2010-05-20 02:28:10 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2011-05-25 00:18:31 +00:00
|
|
|
nsCOMPtr<nsIFormControl> controlElement = do_QueryInterface(element);
|
|
|
|
if (controlElement && controlElement->IsLabelableControl()) {
|
2010-06-23 21:35:57 +00:00
|
|
|
// Transfer the reference count of element to the returned value.
|
2011-05-25 00:18:31 +00:00
|
|
|
return element;
|
2010-05-20 02:28:10 +00:00
|
|
|
}
|
|
|
|
|
2003-02-22 13:01:03 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2011-05-25 00:18:31 +00:00
|
|
|
Element*
|
|
|
|
nsHTMLLabelElement::GetFirstDescendantFormControl()
|
2003-02-22 13:01:03 +00:00
|
|
|
{
|
2011-05-25 00:18:31 +00:00
|
|
|
// Have to cast do disambiguate GetFirstChild from the DOM method of that name
|
|
|
|
for (nsINode* cur = static_cast<nsINode*>(this)->GetFirstChild();
|
|
|
|
cur;
|
|
|
|
cur = cur->GetNextNode(this)) {
|
|
|
|
nsCOMPtr<nsIFormControl> element = do_QueryInterface(cur);
|
2010-05-20 02:28:10 +00:00
|
|
|
if (element && element->IsLabelableControl()) {
|
2011-05-25 00:18:31 +00:00
|
|
|
NS_ASSERTION(cur->IsElement(), "How did that happen?");
|
|
|
|
return cur->AsElement();
|
2002-05-22 00:14:51 +00:00
|
|
|
}
|
|
|
|
}
|
2003-02-22 13:01:03 +00:00
|
|
|
|
2002-05-22 00:14:51 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
2010-05-20 02:28:10 +00:00
|
|
|
|