2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-10-11 09:50:08 +04:00
|
|
|
|
2013-12-09 06:52:54 +04:00
|
|
|
#include "mozilla/ArrayUtils.h"
|
2014-03-18 08:48:21 +04:00
|
|
|
#include "mozilla/EventDispatcher.h"
|
2014-03-17 10:56:53 +04:00
|
|
|
#include "mozilla/EventListenerManager.h"
|
2014-04-01 08:09:23 +04:00
|
|
|
#include "mozilla/EventStateManager.h"
|
2014-04-03 08:18:36 +04:00
|
|
|
#include "mozilla/EventStates.h"
|
2013-09-25 15:21:18 +04:00
|
|
|
#include "mozilla/MouseEvents.h"
|
2012-10-26 17:32:10 +04:00
|
|
|
#include "mozilla/Likely.h"
|
2011-10-11 09:50:08 +04:00
|
|
|
|
2001-08-14 11:59:59 +04:00
|
|
|
#include "nscore.h"
|
1998-09-03 03:53:16 +04:00
|
|
|
#include "nsGenericHTMLElement.h"
|
2012-09-30 20:40:24 +04:00
|
|
|
#include "nsAttrValueInlines.h"
|
1999-02-12 20:45:58 +03:00
|
|
|
#include "nsCOMPtr.h"
|
1998-08-29 03:27:19 +04:00
|
|
|
#include "nsIAtom.h"
|
2015-04-15 19:47:03 +03:00
|
|
|
#include "nsQueryObject.h"
|
2013-10-02 15:40:07 +04:00
|
|
|
#include "nsIContentInlines.h"
|
2004-07-25 01:12:43 +04:00
|
|
|
#include "nsIContentViewer.h"
|
2015-11-09 10:57:16 +03:00
|
|
|
#include "mozilla/css/Declaration.h"
|
1998-08-29 03:27:19 +04:00
|
|
|
#include "nsIDocument.h"
|
2000-05-12 01:49:16 +04:00
|
|
|
#include "nsIDocumentEncoder.h"
|
2001-06-30 02:44:20 +04:00
|
|
|
#include "nsIDOMHTMLDocument.h"
|
1998-10-20 21:07:23 +04:00
|
|
|
#include "nsIDOMAttr.h"
|
1998-11-30 10:59:11 +03:00
|
|
|
#include "nsIDOMDocumentFragment.h"
|
2011-10-30 00:03:55 +04:00
|
|
|
#include "nsIDOMHTMLElement.h"
|
2011-08-08 21:31:32 +04:00
|
|
|
#include "nsIDOMHTMLMenuElement.h"
|
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 20:46:42 +04:00
|
|
|
#include "nsIDOMElementCSSInlineStyle.h"
|
2004-04-13 02:47:24 +04:00
|
|
|
#include "nsIDOMWindow.h"
|
|
|
|
#include "nsIDOMDocument.h"
|
2004-01-26 22:22:05 +03:00
|
|
|
#include "nsMappedAttributes.h"
|
2004-04-13 01:56:09 +04:00
|
|
|
#include "nsHTMLStyleSheet.h"
|
1998-09-02 06:05:53 +04:00
|
|
|
#include "nsIHTMLDocument.h"
|
2000-11-27 10:55:20 +03:00
|
|
|
#include "nsPIDOMWindow.h"
|
1998-08-29 07:15:55 +04:00
|
|
|
#include "nsIURL.h"
|
2002-03-06 10:48:55 +03:00
|
|
|
#include "nsEscape.h"
|
2013-10-02 01:00:38 +04:00
|
|
|
#include "nsIFrameInlines.h"
|
2001-10-17 05:17:47 +04:00
|
|
|
#include "nsIScrollableFrame.h"
|
2013-01-03 17:23:11 +04:00
|
|
|
#include "nsView.h"
|
2013-01-05 07:12:24 +04:00
|
|
|
#include "nsViewManager.h"
|
2011-11-27 15:51:53 +04:00
|
|
|
#include "nsIWidget.h"
|
1998-12-30 11:28:16 +03:00
|
|
|
#include "nsRange.h"
|
1998-09-11 08:16:18 +04:00
|
|
|
#include "nsIPresShell.h"
|
2004-08-01 03:15:21 +04:00
|
|
|
#include "nsPresContext.h"
|
2003-05-30 04:21:01 +04:00
|
|
|
#include "nsIDocShell.h"
|
2014-02-28 03:04:46 +04:00
|
|
|
#include "nsNameSpaceManager.h"
|
2012-07-27 18:03:27 +04:00
|
|
|
#include "nsError.h"
|
2006-11-04 08:45:02 +03:00
|
|
|
#include "nsScriptLoader.h"
|
2004-07-20 10:11:27 +04:00
|
|
|
#include "nsRuleData.h"
|
2013-11-21 00:23:43 +04:00
|
|
|
#include "nsIPrincipal.h"
|
2014-05-25 02:20:39 +04:00
|
|
|
#include "nsContainerFrame.h"
|
2015-11-28 03:56:33 +03:00
|
|
|
#include "nsStyleUtil.h"
|
1998-08-29 03:27:19 +04:00
|
|
|
|
2005-01-28 01:52:53 +03:00
|
|
|
#include "nsPresState.h"
|
2000-01-14 12:28:54 +03:00
|
|
|
#include "nsILayoutHistoryState.h"
|
|
|
|
|
1998-09-04 04:19:32 +04:00
|
|
|
#include "nsHTMLParts.h"
|
2003-05-30 04:21:01 +04:00
|
|
|
#include "nsContentUtils.h"
|
2012-04-17 08:03:10 +04:00
|
|
|
#include "mozilla/dom/DirectionalityUtils.h"
|
1998-08-29 03:27:19 +04:00
|
|
|
#include "nsString.h"
|
2001-10-20 01:00:02 +04:00
|
|
|
#include "nsUnicharUtils.h"
|
2007-01-30 03:06:41 +03:00
|
|
|
#include "nsGkAtoms.h"
|
2000-12-30 22:22:22 +03:00
|
|
|
#include "nsIDOMEvent.h"
|
1998-10-06 05:39:33 +04:00
|
|
|
#include "nsDOMCSSDeclaration.h"
|
2005-09-07 22:19:26 +04:00
|
|
|
#include "nsITextControlFrame.h"
|
1999-07-28 09:26:55 +04:00
|
|
|
#include "nsIForm.h"
|
|
|
|
#include "nsIFormControl.h"
|
|
|
|
#include "nsIDOMHTMLFormElement.h"
|
2013-06-19 18:24:37 +04:00
|
|
|
#include "mozilla/dom/HTMLFormElement.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 22:00:39 +04:00
|
|
|
#include "nsFocusManager.h"
|
2012-11-21 14:13:57 +04:00
|
|
|
#include "nsAttrValueOrString.h"
|
1998-08-29 03:27:19 +04:00
|
|
|
|
2014-02-27 14:51:15 +04:00
|
|
|
#include "mozilla/InternalMutationEvent.h"
|
2011-05-20 21:23:49 +04:00
|
|
|
#include "nsDOMStringMap.h"
|
|
|
|
|
2005-11-15 02:55:24 +03:00
|
|
|
#include "nsIEditor.h"
|
|
|
|
#include "nsIEditorIMESupport.h"
|
2006-06-21 01:21:47 +04:00
|
|
|
#include "nsLayoutUtils.h"
|
2008-04-11 21:29:06 +04:00
|
|
|
#include "mozAutoDocUpdate.h"
|
2010-05-04 12:36:42 +04:00
|
|
|
#include "nsHtml5Module.h"
|
2010-04-22 00:17:41 +04:00
|
|
|
#include "nsITextControlElement.h"
|
2010-05-09 22:32:57 +04:00
|
|
|
#include "mozilla/dom/Element.h"
|
2013-02-08 20:34:47 +04:00
|
|
|
#include "HTMLFieldSetElement.h"
|
2015-10-30 08:37:03 +03:00
|
|
|
#include "nsTextNode.h"
|
|
|
|
#include "HTMLBRElement.h"
|
2013-02-18 15:59:08 +04:00
|
|
|
#include "HTMLMenuElement.h"
|
2012-03-31 20:30:13 +04:00
|
|
|
#include "nsDOMMutationObserver.h"
|
2011-05-25 10:31:59 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2011-11-10 16:02:22 +04:00
|
|
|
#include "mozilla/dom/FromParser.h"
|
2013-08-08 09:26:32 +04:00
|
|
|
#include "mozilla/dom/Link.h"
|
2013-01-04 10:54:26 +04:00
|
|
|
#include "mozilla/dom/UndoManager.h"
|
2012-06-01 13:59:16 +04:00
|
|
|
#include "mozilla/BloomFilter.h"
|
2011-05-25 10:31:59 +04:00
|
|
|
|
2012-06-05 03:49:57 +04:00
|
|
|
#include "HTMLPropertiesCollection.h"
|
|
|
|
#include "nsVariant.h"
|
2016-02-12 01:50:42 +03:00
|
|
|
#include "nsDOMTokenList.h"
|
2012-06-06 11:40:02 +04:00
|
|
|
#include "nsThreadUtils.h"
|
2012-07-02 03:45:59 +04:00
|
|
|
#include "nsTextFragment.h"
|
2012-09-06 00:49:53 +04:00
|
|
|
#include "mozilla/dom/BindingUtils.h"
|
2014-02-28 18:58:42 +04:00
|
|
|
#include "mozilla/dom/TouchEvent.h"
|
2012-09-06 00:49:53 +04:00
|
|
|
#include "mozilla/ErrorResult.h"
|
2012-11-11 03:30:15 +04:00
|
|
|
#include "nsHTMLDocument.h"
|
2012-11-26 18:19:02 +04:00
|
|
|
#include "nsGlobalWindow.h"
|
2013-01-13 01:53:01 +04:00
|
|
|
#include "mozilla/dom/HTMLBodyElement.h"
|
2013-10-02 01:00:38 +04:00
|
|
|
#include "imgIContainer.h"
|
2015-10-30 08:37:03 +03:00
|
|
|
#include "nsComputedDOMStyle.h"
|
2016-02-24 10:01:11 +03:00
|
|
|
#include "mozilla/StyleSetHandle.h"
|
|
|
|
#include "mozilla/StyleSetHandleInlines.h"
|
2012-06-05 03:49:57 +04:00
|
|
|
|
2011-05-25 10:31:59 +04:00
|
|
|
using namespace mozilla;
|
2010-05-09 22:32:57 +04:00
|
|
|
using namespace mozilla::dom;
|
2005-11-15 02:55:24 +03:00
|
|
|
|
2010-05-19 21:52:17 +04:00
|
|
|
/**
|
|
|
|
* nsAutoFocusEvent is used to dispatch a focus event when a
|
|
|
|
* nsGenericHTMLFormElement is binded to the tree with the autofocus attribute
|
|
|
|
* enabled.
|
|
|
|
*/
|
|
|
|
class nsAutoFocusEvent : public nsRunnable
|
|
|
|
{
|
|
|
|
public:
|
2014-09-02 04:49:25 +04:00
|
|
|
explicit nsAutoFocusEvent(nsGenericHTMLFormElement* aElement) : mElement(aElement) {}
|
2010-05-19 21:52:17 +04:00
|
|
|
|
|
|
|
NS_IMETHOD Run() {
|
|
|
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
|
|
if (!fm) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument* document = mElement->OwnerDoc();
|
2010-05-19 21:52:17 +04:00
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowOuter* window = document->GetWindow();
|
2010-12-22 03:58:24 +03:00
|
|
|
if (!window) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2010-12-17 20:47:58 +03:00
|
|
|
|
|
|
|
// Trying to found the top window (equivalent to window.top).
|
2016-01-30 20:05:36 +03:00
|
|
|
if (nsCOMPtr<nsPIDOMWindowOuter> top = window->GetTop()) {
|
2015-10-27 00:37:32 +03:00
|
|
|
window = top;
|
2010-12-17 20:47:58 +03:00
|
|
|
}
|
|
|
|
|
2010-12-22 03:58:24 +03:00
|
|
|
if (window->GetFocusedNode()) {
|
2010-12-18 05:01:12 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-10-06 11:19:52 +04:00
|
|
|
nsCOMPtr<nsIDocument> topDoc = window->GetExtantDoc();
|
2010-12-22 03:58:24 +03:00
|
|
|
if (topDoc && topDoc->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE) {
|
2010-05-19 21:52:17 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If something is focused in the same document, ignore autofocus.
|
|
|
|
if (!fm->GetFocusedContent() ||
|
2011-10-18 14:53:36 +04:00
|
|
|
fm->GetFocusedContent()->OwnerDoc() != document) {
|
2012-10-06 11:19:52 +04:00
|
|
|
mozilla::ErrorResult rv;
|
|
|
|
mElement->Focus(rv);
|
2015-04-27 16:18:51 +03:00
|
|
|
return rv.StealNSResult();
|
2010-05-19 21:52:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
// NOTE: nsGenericHTMLFormElement is saved as a nsGenericHTMLElement
|
|
|
|
// because AddRef/Release are ambiguous with nsGenericHTMLFormElement
|
|
|
|
// and Focus() is declared (and defined) in nsGenericHTMLElement class.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsGenericHTMLElement> mElement;
|
2010-05-19 21:52:17 +04:00
|
|
|
};
|
2001-10-30 13:14:06 +03:00
|
|
|
|
2011-10-30 00:03:55 +04:00
|
|
|
class nsGenericHTMLElementTearoff : public nsIDOMElementCSSInlineStyle
|
2008-02-21 23:39:20 +03:00
|
|
|
{
|
2014-06-25 06:09:15 +04:00
|
|
|
virtual ~nsGenericHTMLElementTearoff()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2008-02-21 23:39:20 +03:00
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
|
|
|
2014-09-02 04:49:25 +04:00
|
|
|
explicit nsGenericHTMLElementTearoff(nsGenericHTMLElement* aElement)
|
2008-02-21 23:39:20 +03:00
|
|
|
: mElement(aElement)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle) override
|
2010-08-06 01:59:36 +04:00
|
|
|
{
|
2013-01-11 12:42:59 +04:00
|
|
|
NS_ADDREF(*aStyle = mElement->Style());
|
|
|
|
return NS_OK;
|
2010-08-06 01:59:36 +04:00
|
|
|
}
|
2008-02-21 23:39:20 +03:00
|
|
|
|
|
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGenericHTMLElementTearoff,
|
2011-10-30 00:03:55 +04:00
|
|
|
nsIDOMElementCSSInlineStyle)
|
2008-02-21 23:39:20 +03:00
|
|
|
|
|
|
|
private:
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsGenericHTMLElement> mElement;
|
2008-02-21 23:39:20 +03:00
|
|
|
};
|
|
|
|
|
2014-04-25 20:49:00 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTION(nsGenericHTMLElementTearoff, mElement)
|
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 20:46:42 +04:00
|
|
|
|
2011-03-06 14:11:31 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGenericHTMLElementTearoff)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGenericHTMLElementTearoff)
|
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 20:46:42 +04:00
|
|
|
|
2007-08-21 02:55:06 +04:00
|
|
|
NS_INTERFACE_TABLE_HEAD(nsGenericHTMLElementTearoff)
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_INTERFACE_TABLE_INHERITED(nsGenericHTMLElementTearoff,
|
|
|
|
nsIDOMElementCSSInlineStyle)
|
2007-08-21 02:55:06 +04:00
|
|
|
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsGenericHTMLElementTearoff)
|
2004-01-06 03:36:01 +03:00
|
|
|
NS_INTERFACE_MAP_END_AGGREGATED(mElement)
|
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 20:46:42 +04:00
|
|
|
|
2013-08-08 00:23:08 +04:00
|
|
|
NS_IMPL_ADDREF_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase)
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2013-08-08 00:23:08 +04:00
|
|
|
NS_INTERFACE_MAP_BEGIN(nsGenericHTMLElement)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLElement)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
|
2007-08-21 02:55:06 +04:00
|
|
|
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMElementCSSInlineStyle,
|
|
|
|
new nsGenericHTMLElementTearoff(this))
|
2013-08-08 00:23:08 +04:00
|
|
|
NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElementBase)
|
2011-05-20 21:23:49 +04:00
|
|
|
|
2000-12-23 13:56:31 +03:00
|
|
|
nsresult
|
2012-11-15 02:10:08 +04:00
|
|
|
nsGenericHTMLElement::CopyInnerTo(Element* aDst)
|
1999-01-15 02:14:02 +03:00
|
|
|
{
|
2006-09-05 14:22:54 +04:00
|
|
|
nsresult rv;
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t i, count = GetAttrCount();
|
2004-01-26 22:22:05 +03:00
|
|
|
for (i = 0; i < count; ++i) {
|
2005-12-30 23:12:35 +03:00
|
|
|
const nsAttrName *name = mAttrsAndChildren.AttrNameAt(i);
|
2005-09-11 21:15:08 +04:00
|
|
|
const nsAttrValue *value = mAttrsAndChildren.AttrAt(i);
|
2012-04-05 21:14:54 +04:00
|
|
|
|
|
|
|
nsAutoString valStr;
|
|
|
|
value->ToString(valStr);
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
if (name->Equals(nsGkAtoms::style, kNameSpaceID_None) &&
|
2015-11-09 10:57:16 +03:00
|
|
|
value->Type() == nsAttrValue::eCSSDeclaration) {
|
2004-01-26 22:22:05 +03:00
|
|
|
// We can't just set this as a string, because that will fail
|
|
|
|
// to reparse the string into style data until the node is
|
2011-04-08 05:23:46 +04:00
|
|
|
// inserted into the document. Clone the Rule instead.
|
2015-11-09 10:57:16 +03:00
|
|
|
RefPtr<css::Declaration> declClone =
|
|
|
|
new css::Declaration(*value->GetCSSDeclarationValue());
|
2005-09-11 21:15:08 +04:00
|
|
|
|
2015-11-09 10:57:16 +03:00
|
|
|
rv = aDst->SetInlineStyleDeclaration(declClone, &valStr, false);
|
2005-09-11 21:15:08 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2005-09-11 19:42:31 +04:00
|
|
|
|
2005-09-11 21:15:08 +04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
|
2011-10-17 18:59:28 +04:00
|
|
|
name->GetPrefix(), valStr, false);
|
2004-01-26 22:22:05 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
1999-01-15 02:14:02 +03:00
|
|
|
}
|
|
|
|
|
2006-09-05 14:22:54 +04:00
|
|
|
return NS_OK;
|
1999-01-15 02:14:02 +03:00
|
|
|
}
|
|
|
|
|
2012-10-17 05:14:32 +04:00
|
|
|
already_AddRefed<nsDOMStringMap>
|
|
|
|
nsGenericHTMLElement::Dataset()
|
2011-05-20 21:23:49 +04:00
|
|
|
{
|
|
|
|
nsDOMSlots *slots = DOMSlots();
|
|
|
|
|
|
|
|
if (!slots->mDataset) {
|
|
|
|
// mDataset is a weak reference so assignment will not AddRef.
|
2012-10-17 05:14:32 +04:00
|
|
|
// AddRef is called before returning the pointer.
|
2011-05-20 21:23:49 +04:00
|
|
|
slots->mDataset = new nsDOMStringMap(this);
|
|
|
|
}
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsDOMStringMap> ret = slots->mDataset;
|
2013-04-28 15:52:10 +04:00
|
|
|
return ret.forget();
|
2012-10-17 05:14:32 +04:00
|
|
|
}
|
|
|
|
|
2013-08-08 00:23:08 +04:00
|
|
|
NS_IMETHODIMP
|
2012-11-05 20:58:03 +04:00
|
|
|
nsGenericHTMLElement::GetDataset(nsISupports** aDataset)
|
2012-10-17 05:14:32 +04:00
|
|
|
{
|
2014-03-15 23:00:15 +04:00
|
|
|
*aDataset = Dataset().take();
|
2011-05-20 21:23:49 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericHTMLElement::ClearDataset()
|
|
|
|
{
|
|
|
|
nsDOMSlots *slots = GetExistingDOMSlots();
|
|
|
|
|
|
|
|
NS_ASSERTION(slots && slots->mDataset,
|
|
|
|
"Slots should exist and dataset should not be null.");
|
2012-07-30 18:20:58 +04:00
|
|
|
slots->mDataset = nullptr;
|
2011-05-20 21:23:49 +04:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-01-25 03:02:58 +03:00
|
|
|
static const nsAttrValue::EnumTable kDirTable[] = {
|
2012-11-21 14:13:57 +04:00
|
|
|
{ "ltr", eDir_LTR },
|
|
|
|
{ "rtl", eDir_RTL },
|
|
|
|
{ "auto", eDir_Auto },
|
1999-09-22 03:23:53 +04:00
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
void
|
2013-08-08 00:23:08 +04:00
|
|
|
nsGenericHTMLElement::GetAccessKeyLabel(nsString& aLabel)
|
2011-07-31 23:43:54 +04:00
|
|
|
{
|
2014-10-15 09:42:00 +04:00
|
|
|
nsAutoString suffix;
|
|
|
|
GetAccessKey(suffix);
|
|
|
|
if (!suffix.IsEmpty()) {
|
|
|
|
EventStateManager::GetAccessKeyLabelPrefix(this, aLabel);
|
|
|
|
aLabel.Append(suffix);
|
2011-07-31 23:43:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
static bool IS_TABLE_CELL(nsIAtom* frameType) {
|
2007-06-14 04:08:10 +04:00
|
|
|
return nsGkAtoms::tableCellFrame == frameType ||
|
|
|
|
nsGkAtoms::bcTableCellFrame == frameType;
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
static bool
|
2007-06-14 04:08:10 +04:00
|
|
|
IsOffsetParent(nsIFrame* aFrame)
|
2001-11-29 08:08:25 +03:00
|
|
|
{
|
2007-06-14 04:08:10 +04:00
|
|
|
nsIAtom* frameType = aFrame->GetType();
|
2012-12-11 17:48:04 +04:00
|
|
|
|
|
|
|
if (IS_TABLE_CELL(frameType) || frameType == nsGkAtoms::tableFrame) {
|
|
|
|
// Per the IDL for Element, only td, th, and table are acceptable offsetParents
|
|
|
|
// apart from body or positioned elements; we need to check the content type as
|
|
|
|
// well as the frame type so we ignore anonymous tables created by an element
|
|
|
|
// with display: table-cell with no actual table
|
|
|
|
nsIContent* content = aFrame->GetContent();
|
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
return content->IsAnyOfHTMLElements(nsGkAtoms::table,
|
|
|
|
nsGkAtoms::td,
|
|
|
|
nsGkAtoms::th);
|
2012-12-11 17:48:04 +04:00
|
|
|
}
|
|
|
|
return false;
|
2001-11-29 08:08:25 +03:00
|
|
|
}
|
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
Element*
|
2013-06-12 11:00:08 +04:00
|
|
|
nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect)
|
2000-02-16 05:25:07 +03:00
|
|
|
{
|
2013-06-12 11:00:08 +04:00
|
|
|
aRect = CSSIntRect();
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2008-08-16 02:26:37 +04:00
|
|
|
nsIFrame* frame = GetStyledFrame();
|
2007-03-15 23:43:02 +03:00
|
|
|
if (!frame) {
|
2012-11-11 03:30:15 +04:00
|
|
|
return nullptr;
|
2001-06-30 02:44:20 +04:00
|
|
|
}
|
|
|
|
|
2007-03-15 23:43:02 +03:00
|
|
|
nsIFrame* parent = frame->GetParent();
|
|
|
|
nsPoint origin(0, 0);
|
2001-06-30 02:44:20 +04:00
|
|
|
|
2012-01-13 22:44:06 +04:00
|
|
|
if (parent && parent->GetType() == nsGkAtoms::tableOuterFrame &&
|
|
|
|
frame->GetType() == nsGkAtoms::tableFrame) {
|
2007-03-15 23:43:02 +03:00
|
|
|
origin = parent->GetPositionIgnoringScrolling();
|
|
|
|
parent = parent->GetParent();
|
2001-06-30 02:44:20 +04:00
|
|
|
}
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
nsIContent* offsetParent = nullptr;
|
2014-09-05 14:54:00 +04:00
|
|
|
Element* docElement = GetComposedDoc()->GetRootElement();
|
2003-08-06 07:07:12 +04:00
|
|
|
nsIContent* content = frame->GetContent();
|
2001-06-30 02:44:20 +04:00
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
if (content && (content->IsHTMLElement(nsGkAtoms::body) ||
|
|
|
|
content == docElement)) {
|
2007-03-15 23:43:02 +03:00
|
|
|
parent = frame;
|
2001-06-30 02:44:20 +04:00
|
|
|
}
|
2007-03-15 23:43:02 +03:00
|
|
|
else {
|
2015-03-12 06:21:01 +03:00
|
|
|
const bool isPositioned = frame->IsAbsPosContaininingBlock();
|
2012-08-02 15:38:50 +04:00
|
|
|
const bool isAbsolutelyPositioned = frame->IsAbsolutelyPositioned();
|
2007-03-15 23:43:02 +03:00
|
|
|
origin += frame->GetPositionIgnoringScrolling();
|
2001-06-30 02:44:20 +04:00
|
|
|
|
2007-03-15 23:43:02 +03:00
|
|
|
for ( ; parent ; parent = parent->GetParent()) {
|
|
|
|
content = parent->GetContent();
|
2001-06-30 02:44:20 +04:00
|
|
|
|
2007-03-15 23:43:02 +03:00
|
|
|
// Stop at the first ancestor that is positioned.
|
2015-03-12 06:21:01 +03:00
|
|
|
if (parent->IsAbsPosContaininingBlock()) {
|
2012-11-11 03:30:15 +04:00
|
|
|
offsetParent = content;
|
2003-05-15 07:42:21 +04:00
|
|
|
break;
|
2001-06-30 02:44:20 +04:00
|
|
|
}
|
2000-02-16 05:25:07 +03:00
|
|
|
|
2001-06-30 02:44:20 +04:00
|
|
|
// Add the parent's origin to our own to get to the
|
2007-03-15 23:43:02 +03:00
|
|
|
// right coordinate system.
|
2011-09-29 10:19:26 +04:00
|
|
|
const bool isOffsetParent = !isPositioned && IsOffsetParent(parent);
|
2007-06-14 04:08:10 +04:00
|
|
|
if (!isAbsolutelyPositioned && !isOffsetParent) {
|
2006-06-21 01:21:47 +04:00
|
|
|
origin += parent->GetPositionIgnoringScrolling();
|
2001-06-30 02:44:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (content) {
|
2007-03-15 23:43:02 +03:00
|
|
|
// If we've hit the document element, break here.
|
2001-06-30 02:44:20 +04:00
|
|
|
if (content == docElement) {
|
|
|
|
break;
|
2000-02-16 05:25:07 +03:00
|
|
|
}
|
|
|
|
|
2007-06-23 11:39:04 +04:00
|
|
|
// Break if the ancestor frame type makes it suitable as offset parent
|
|
|
|
// and this element is *not* positioned or if we found the body element.
|
2015-03-03 14:08:59 +03:00
|
|
|
if (isOffsetParent || content->IsHTMLElement(nsGkAtoms::body)) {
|
2012-11-11 03:30:15 +04:00
|
|
|
offsetParent = content;
|
2001-06-30 02:44:20 +04:00
|
|
|
break;
|
2000-02-16 05:25:07 +03:00
|
|
|
}
|
2001-06-30 02:44:20 +04:00
|
|
|
}
|
|
|
|
}
|
2000-02-16 05:25:07 +03:00
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
if (isAbsolutelyPositioned && !offsetParent) {
|
2001-06-30 02:44:20 +04:00
|
|
|
// If this element is absolutely positioned, but we don't have
|
|
|
|
// an offset parent it means this element is an absolutely
|
|
|
|
// positioned child that's not nested inside another positioned
|
|
|
|
// element, in this case the element's frame's parent is the
|
|
|
|
// frame for the HTML element so we fail to find the body in the
|
|
|
|
// parent chain. We want the offset parent in this case to be
|
|
|
|
// the body, so we just get the body element from the document.
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2014-09-05 14:54:00 +04:00
|
|
|
nsCOMPtr<nsIDOMHTMLDocument> html_doc(do_QueryInterface(GetComposedDoc()));
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2001-06-30 02:44:20 +04:00
|
|
|
if (html_doc) {
|
2012-11-11 03:30:15 +04:00
|
|
|
offsetParent = static_cast<nsHTMLDocument*>(html_doc.get())->GetBody();
|
2000-02-16 05:25:07 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2007-03-15 23:43:02 +03:00
|
|
|
// Subtract the parent border unless it uses border-box sizing.
|
|
|
|
if (parent &&
|
2015-11-20 05:09:29 +03:00
|
|
|
parent->StylePosition()->mBoxSizing != StyleBoxSizing::Border) {
|
2013-02-17 01:51:02 +04:00
|
|
|
const nsStyleBorder* border = parent->StyleBorder();
|
2012-05-31 09:19:49 +04:00
|
|
|
origin.x -= border->GetComputedBorderWidth(NS_SIDE_LEFT);
|
|
|
|
origin.y -= border->GetComputedBorderWidth(NS_SIDE_TOP);
|
2001-06-30 02:44:20 +04:00
|
|
|
}
|
|
|
|
|
2002-09-11 05:58:59 +04:00
|
|
|
// XXX We should really consider subtracting out padding for
|
|
|
|
// content-box sizing, but we should see what IE does....
|
2001-06-30 02:44:20 +04:00
|
|
|
|
2008-02-27 12:26:15 +03:00
|
|
|
// Get the union of all rectangles in this and continuation frames.
|
|
|
|
// It doesn't really matter what we use as aRelativeTo here, since
|
2008-04-11 02:36:10 +04:00
|
|
|
// we only care about the size. We just have to use something non-null.
|
|
|
|
nsRect rcFrame = nsLayoutUtils::GetAllInFlowRectsUnion(frame, frame);
|
2013-06-12 11:00:08 +04:00
|
|
|
rcFrame.MoveTo(origin);
|
|
|
|
aRect = CSSIntRect::FromAppUnitsRounded(rcFrame);
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
return offsetParent ? offsetParent->AsElement() : nullptr;
|
2000-02-16 05:25:07 +03:00
|
|
|
}
|
|
|
|
|
2011-10-30 00:03:55 +04:00
|
|
|
NS_IMETHODIMP
|
2011-08-01 11:48:28 +04:00
|
|
|
nsGenericHTMLElement::InsertAdjacentHTML(const nsAString& aPosition,
|
|
|
|
const nsAString& aText)
|
2012-11-11 03:30:15 +04:00
|
|
|
{
|
|
|
|
ErrorResult rv;
|
2012-12-24 06:38:41 +04:00
|
|
|
Element::InsertAdjacentHTML(aPosition, aText, rv);
|
2015-04-27 16:18:51 +03:00
|
|
|
return rv.StealNSResult();
|
2012-11-11 03:30:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
nsGenericHTMLElement::Spellcheck()
|
2006-07-29 04:04:40 +04:00
|
|
|
{
|
|
|
|
// Has the state has been explicitly set?
|
2009-08-25 00:02:07 +04:00
|
|
|
nsIContent* node;
|
|
|
|
for (node = this; node; node = node->GetParent()) {
|
2015-03-03 14:08:59 +03:00
|
|
|
if (node->IsHTMLElement()) {
|
2006-07-29 04:04:40 +04:00
|
|
|
static nsIContent::AttrValuesArray strings[] =
|
2012-07-30 18:20:58 +04:00
|
|
|
{&nsGkAtoms::_true, &nsGkAtoms::_false, nullptr};
|
2009-08-25 00:02:07 +04:00
|
|
|
switch (node->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::spellcheck,
|
|
|
|
strings, eCaseMatters)) {
|
2006-07-29 04:04:40 +04:00
|
|
|
case 0: // spellcheck = "true"
|
2012-11-11 03:30:15 +04:00
|
|
|
return true;
|
2006-07-29 04:04:40 +04:00
|
|
|
case 1: // spellcheck = "false"
|
2012-11-11 03:30:15 +04:00
|
|
|
return false;
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-20 00:54:53 +04:00
|
|
|
// contenteditable/designMode are spellchecked by default
|
|
|
|
if (IsEditable()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-07-29 04:04:40 +04:00
|
|
|
// Is this a chrome element?
|
2011-10-18 14:53:36 +04:00
|
|
|
if (nsContentUtils::IsChromeDoc(OwnerDoc())) {
|
2012-11-11 03:30:15 +04:00
|
|
|
return false; // Not spellchecked by default
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
|
2013-06-20 00:54:53 +04:00
|
|
|
// Anything else that's not a form control is not spellchecked by default
|
2013-08-08 00:23:08 +04:00
|
|
|
nsCOMPtr<nsIFormControl> formControl = do_QueryObject(this);
|
2006-07-29 04:04:40 +04:00
|
|
|
if (!formControl) {
|
2012-11-11 03:30:15 +04:00
|
|
|
return false; // Not spellchecked by default
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Is this a multiline plaintext input?
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t controlType = formControl->GetType();
|
2006-07-29 04:04:40 +04:00
|
|
|
if (controlType == NS_FORM_TEXTAREA) {
|
2012-11-11 03:30:15 +04:00
|
|
|
return true; // Spellchecked by default
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
|
2010-05-12 11:17:07 +04:00
|
|
|
// Is this anything other than an input text?
|
|
|
|
// Other inputs are not spellchecked.
|
2006-07-29 04:04:40 +04:00
|
|
|
if (controlType != NS_FORM_INPUT_TEXT) {
|
2012-11-11 03:30:15 +04:00
|
|
|
return false; // Not spellchecked by default
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
|
2010-05-12 11:17:07 +04:00
|
|
|
// Does the user want input text spellchecked by default?
|
2006-07-29 04:04:40 +04:00
|
|
|
// NOTE: Do not reflect a pref value of 0 back to the DOM getter.
|
|
|
|
// The web page should not know if the user has disabled spellchecking.
|
|
|
|
// We'll catch this in the editor itself.
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t spellcheckLevel = Preferences::GetInt("layout.spellcheckDefault", 1);
|
2012-11-11 03:30:15 +04:00
|
|
|
return spellcheckLevel == 2; // "Spellcheck multi- and single-line"
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
2001-10-17 05:17:47 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2000-12-23 13:56:31 +03:00
|
|
|
nsGenericHTMLElement::InNavQuirksMode(nsIDocument* aDoc)
|
1999-08-28 01:42:08 +04:00
|
|
|
{
|
2006-12-05 18:46:18 +03:00
|
|
|
return aDoc && aDoc->GetCompatibilityMode() == eCompatibility_NavQuirks;
|
1999-08-28 01:42:08 +04:00
|
|
|
}
|
|
|
|
|
2007-06-28 06:48:16 +04:00
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLElement::UpdateEditableState(bool aNotify)
|
2007-06-28 06:48:16 +04:00
|
|
|
{
|
|
|
|
// XXX Should we do this only when in a document?
|
|
|
|
ContentEditableTristate value = GetContentEditableValue();
|
|
|
|
if (value != eInherit) {
|
2011-06-01 05:46:57 +04:00
|
|
|
DoSetEditableFlag(!!value, aNotify);
|
2007-06-28 06:48:16 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-06-01 05:46:57 +04:00
|
|
|
nsStyledElement::UpdateEditableState(aNotify);
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
2014-04-03 08:18:36 +04:00
|
|
|
EventStates
|
2012-04-17 08:03:10 +04:00
|
|
|
nsGenericHTMLElement::IntrinsicState() const
|
|
|
|
{
|
2014-04-03 08:18:36 +04:00
|
|
|
EventStates state = nsGenericHTMLElementBase::IntrinsicState();
|
2012-04-17 08:03:10 +04:00
|
|
|
|
|
|
|
if (GetDirectionality() == eDir_RTL) {
|
|
|
|
state |= NS_EVENT_STATE_RTL;
|
|
|
|
state &= ~NS_EVENT_STATE_LTR;
|
|
|
|
} else { // at least for HTML, directionality is exclusively LTR or RTL
|
|
|
|
NS_ASSERTION(GetDirectionality() == eDir_LTR,
|
|
|
|
"HTML element's directionality must be either RTL or LTR");
|
|
|
|
state |= NS_EVENT_STATE_LTR;
|
|
|
|
state &= ~NS_EVENT_STATE_RTL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2015-08-14 20:52:38 +03:00
|
|
|
uint32_t
|
|
|
|
nsGenericHTMLElement::EditableInclusiveDescendantCount()
|
|
|
|
{
|
|
|
|
bool isEditable = IsInUncomposedDoc() && HasFlag(NODE_IS_EDITABLE) &&
|
|
|
|
GetContentEditableValue() == eTrue;
|
|
|
|
return EditableDescendantCount() + isEditable;
|
|
|
|
}
|
|
|
|
|
2005-04-06 03:54:35 +04:00
|
|
|
nsresult
|
|
|
|
nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|
|
|
nsIContent* aBindingParent,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aCompileEventHandlers)
|
1998-08-29 03:27:19 +04:00
|
|
|
{
|
2007-08-06 19:27:19 +04:00
|
|
|
nsresult rv = nsGenericHTMLElementBase::BindToTree(aDocument, aParent,
|
|
|
|
aBindingParent,
|
|
|
|
aCompileEventHandlers);
|
2005-04-06 03:54:35 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
1998-10-27 02:26:01 +03:00
|
|
|
|
2007-08-06 19:27:19 +04:00
|
|
|
if (aDocument) {
|
2012-06-05 03:49:57 +04:00
|
|
|
if (HasProperties()) {
|
|
|
|
HTMLPropertiesCollection* properties =
|
|
|
|
static_cast<HTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
|
|
|
|
if (properties) {
|
|
|
|
properties->SetDocument(aDocument);
|
|
|
|
}
|
|
|
|
}
|
2011-04-11 20:56:37 +04:00
|
|
|
RegAccessKey();
|
2011-04-08 06:29:50 +04:00
|
|
|
if (HasName()) {
|
2010-06-04 05:09:20 +04:00
|
|
|
aDocument->
|
|
|
|
AddToNameTable(this, GetParsedAttr(nsGkAtoms::name)->GetAtomValue());
|
|
|
|
}
|
2015-08-14 20:52:38 +03:00
|
|
|
|
2007-08-06 19:27:19 +04:00
|
|
|
if (HasFlag(NODE_IS_EDITABLE) && GetContentEditableValue() == eTrue) {
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(aDocument);
|
|
|
|
if (htmlDocument) {
|
|
|
|
htmlDocument->ChangeContentEditableCount(this, +1);
|
|
|
|
}
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
1998-08-29 03:27:19 +04:00
|
|
|
}
|
2005-04-06 03:54:35 +04:00
|
|
|
|
|
|
|
return rv;
|
1998-08-29 03:27:19 +04:00
|
|
|
}
|
|
|
|
|
2007-06-28 06:48:16 +04:00
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
2007-06-28 06:48:16 +04:00
|
|
|
{
|
2016-03-31 13:58:25 +03:00
|
|
|
if (IsInUncomposedDoc()) {
|
2011-04-11 20:56:37 +04:00
|
|
|
UnregAccessKey();
|
|
|
|
}
|
2012-06-05 03:49:57 +04:00
|
|
|
|
|
|
|
if(HasProperties()) {
|
|
|
|
HTMLPropertiesCollection* properties =
|
|
|
|
static_cast<HTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
|
|
|
|
if (properties) {
|
2012-07-30 18:20:58 +04:00
|
|
|
properties->SetDocument(nullptr);
|
2012-06-05 03:49:57 +04:00
|
|
|
}
|
|
|
|
}
|
2011-04-11 20:56:37 +04:00
|
|
|
|
2010-07-21 04:40:54 +04:00
|
|
|
RemoveFromNameTable();
|
|
|
|
|
2007-06-28 06:48:16 +04:00
|
|
|
if (GetContentEditableValue() == eTrue) {
|
2014-10-02 23:07:24 +04:00
|
|
|
//XXXsmaug Fix this for Shadow DOM, bug 1066965.
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(GetUncomposedDoc());
|
2007-06-28 06:48:16 +04:00
|
|
|
if (htmlDocument) {
|
|
|
|
htmlDocument->ChangeContentEditableCount(this, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-04 05:09:20 +04:00
|
|
|
nsStyledElement::UnbindFromTree(aDeep, aNullParent);
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
2013-06-19 18:24:37 +04:00
|
|
|
HTMLFormElement*
|
|
|
|
nsGenericHTMLElement::FindAncestorForm(HTMLFormElement* aCurrentForm)
|
1999-07-28 09:26:55 +04:00
|
|
|
{
|
2013-06-20 22:07:57 +04:00
|
|
|
NS_ASSERTION(!HasAttr(kNameSpaceID_None, nsGkAtoms::form) ||
|
2015-03-03 14:08:59 +03:00
|
|
|
IsHTMLElement(nsGkAtoms::img),
|
2010-08-24 05:11:04 +04:00
|
|
|
"FindAncestorForm should not be called if @form is set!");
|
|
|
|
|
2007-07-18 05:50:18 +04:00
|
|
|
// Make sure we don't end up finding a form that's anonymous from
|
|
|
|
// our point of view.
|
|
|
|
nsIContent* bindingParent = GetBindingParent();
|
|
|
|
|
2003-07-29 05:15:55 +04:00
|
|
|
nsIContent* content = this;
|
2007-07-18 05:50:18 +04:00
|
|
|
while (content != bindingParent && content) {
|
2003-09-27 08:18:26 +04:00
|
|
|
// If the current ancestor is a form, return it as our form
|
2015-03-03 14:08:59 +03:00
|
|
|
if (content->IsHTMLElement(nsGkAtoms::form)) {
|
2007-08-03 02:46:36 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (!nsContentUtils::IsInSameAnonymousTree(this, content)) {
|
|
|
|
// It's possible that we started unbinding at |content| or
|
|
|
|
// some ancestor of it, and |content| and |this| used to all be
|
|
|
|
// anonymous. Check for this the hard way.
|
|
|
|
for (nsIContent* child = this; child != content;
|
|
|
|
child = child->GetParent()) {
|
|
|
|
NS_ASSERTION(child->GetParent()->IndexOf(child) != -1,
|
|
|
|
"Walked too far?");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2013-06-19 18:24:37 +04:00
|
|
|
return static_cast<HTMLFormElement*>(content);
|
1999-07-28 09:26:55 +04:00
|
|
|
}
|
|
|
|
|
2005-05-02 08:41:06 +04:00
|
|
|
nsIContent *prevContent = content;
|
|
|
|
content = prevContent->GetParent();
|
|
|
|
|
|
|
|
if (!content && aCurrentForm) {
|
|
|
|
// We got to the root of the subtree we're in, and we're being removed
|
|
|
|
// from the DOM (the only time we get into this method with a non-null
|
|
|
|
// aCurrentForm). Check whether aCurrentForm is in the same subtree. If
|
|
|
|
// it is, we want to return aCurrentForm, since this case means that
|
|
|
|
// we're one of those inputs-in-a-table that have a hacked mForm pointer
|
|
|
|
// and a subtree containing both us and the form got removed from the
|
|
|
|
// DOM.
|
2009-10-30 04:49:11 +03:00
|
|
|
if (nsContentUtils::ContentIsDescendantOf(aCurrentForm, prevContent)) {
|
|
|
|
return aCurrentForm;
|
|
|
|
}
|
2005-05-02 08:41:06 +04:00
|
|
|
}
|
1999-07-28 09:26:55 +04:00
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2001-03-02 18:45:35 +03:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2014-03-18 08:48:18 +04:00
|
|
|
nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions(
|
|
|
|
EventChainVisitor& aVisitor)
|
2000-02-11 04:24:59 +03:00
|
|
|
{
|
2013-08-08 09:26:32 +04:00
|
|
|
NS_PRECONDITION(nsCOMPtr<Link>(do_QueryObject(this)),
|
|
|
|
"should be called only when |this| implements |Link|");
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2006-03-07 20:08:51 +03:00
|
|
|
if (!aVisitor.mPresContext) {
|
2006-04-11 17:17:29 +04:00
|
|
|
// We need a pres context to do link stuff. Some events (e.g. mutation
|
|
|
|
// events) don't have one.
|
|
|
|
// XXX: ideally, shouldn't we be able to do what we need without one?
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2003-06-16 14:37:59 +04:00
|
|
|
}
|
|
|
|
|
2000-09-15 10:15:31 +04:00
|
|
|
//Need to check if we hit an imagemap area and if so see if we're handling
|
|
|
|
//the event on that map or on a link farther up the tree. If we're on a
|
|
|
|
//link farther up, do nothing.
|
2011-04-21 21:35:52 +04:00
|
|
|
nsCOMPtr<nsIContent> target = aVisitor.mPresContext->EventStateManager()->
|
|
|
|
GetEventTargetContent(aVisitor.mEvent);
|
2000-09-15 10:15:31 +04:00
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
return !target || !target->IsHTMLElement(nsGkAtoms::area) ||
|
|
|
|
IsHTMLElement(nsGkAtoms::area);
|
2007-04-23 11:31:21 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2014-03-18 08:48:19 +04:00
|
|
|
nsGenericHTMLElement::PreHandleEventForAnchors(EventChainPreVisitor& aVisitor)
|
2007-04-23 11:31:21 +04:00
|
|
|
{
|
2007-08-06 19:27:19 +04:00
|
|
|
nsresult rv = nsGenericHTMLElementBase::PreHandleEvent(aVisitor);
|
2007-04-23 11:31:21 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (!CheckHandleEventForAnchorsPreconditions(aVisitor)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PreHandleEventForLinks(aVisitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2014-03-18 08:48:20 +04:00
|
|
|
nsGenericHTMLElement::PostHandleEventForAnchors(EventChainPostVisitor& aVisitor)
|
2007-04-23 11:31:21 +04:00
|
|
|
{
|
|
|
|
if (!CheckHandleEventForAnchorsPreconditions(aVisitor)) {
|
2007-01-04 13:53:59 +03:00
|
|
|
return NS_OK;
|
2000-09-15 10:15:31 +04:00
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2007-01-04 13:53:59 +03:00
|
|
|
return PostHandleEventForLinks(aVisitor);
|
|
|
|
}
|
2006-08-03 21:21:27 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2007-01-04 13:53:59 +03:00
|
|
|
nsGenericHTMLElement::IsHTMLLink(nsIURI** aURI) const
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aURI, "Must provide aURI out param");
|
2000-02-11 04:24:59 +03:00
|
|
|
|
2014-03-15 23:00:15 +04:00
|
|
|
*aURI = GetHrefURIForAnchors().take();
|
2007-01-04 13:53:59 +03:00
|
|
|
// We promise out param is non-null if we return true, so base rv on it
|
2012-07-30 18:20:58 +04:00
|
|
|
return *aURI != nullptr;
|
2000-02-11 04:24:59 +03:00
|
|
|
}
|
|
|
|
|
2009-07-13 15:48:06 +04:00
|
|
|
already_AddRefed<nsIURI>
|
|
|
|
nsGenericHTMLElement::GetHrefURIForAnchors() const
|
2003-06-17 20:22:51 +04:00
|
|
|
{
|
2013-08-08 09:26:32 +04:00
|
|
|
// This is used by the three Link implementations and
|
2003-06-17 20:22:51 +04:00
|
|
|
// nsHTMLStyleElement.
|
|
|
|
|
2004-01-10 02:54:21 +03:00
|
|
|
// Get href= attribute (relative URI).
|
2003-06-17 20:22:51 +04:00
|
|
|
|
2004-11-03 22:44:59 +03:00
|
|
|
// We use the nsAttrValue's copy of the URI string to avoid copying.
|
2009-07-13 15:48:06 +04:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
2012-07-30 18:20:58 +04:00
|
|
|
GetURIAttr(nsGkAtoms::href, nullptr, getter_AddRefs(uri));
|
2003-06-17 20:22:51 +04:00
|
|
|
|
2009-07-13 15:48:06 +04:00
|
|
|
return uri.forget();
|
2003-06-17 20:22:51 +04:00
|
|
|
}
|
|
|
|
|
2005-10-28 06:59:38 +04:00
|
|
|
nsresult
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
2012-02-14 06:00:56 +04:00
|
|
|
const nsAttrValue* aValue, bool aNotify)
|
2005-10-28 06:59:38 +04:00
|
|
|
{
|
2006-07-29 04:04:40 +04:00
|
|
|
if (aNamespaceID == kNameSpaceID_None) {
|
2013-01-03 00:24:07 +04:00
|
|
|
if (IsEventAttributeName(aName) && aValue) {
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(aValue->Type() == nsAttrValue::eString,
|
|
|
|
"Expected string value for script body");
|
2012-08-30 20:25:10 +04:00
|
|
|
nsresult rv = SetEventHandler(aName, aValue->GetStringValue());
|
2006-07-29 04:04:40 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2006-12-26 20:47:52 +03:00
|
|
|
else if (aNotify && aName == nsGkAtoms::spellcheck) {
|
2006-08-25 04:15:14 +04:00
|
|
|
SyncEditorsOnSubtree(this);
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
2012-04-17 08:03:10 +04:00
|
|
|
else if (aName == nsGkAtoms::dir) {
|
2012-11-21 14:13:57 +04:00
|
|
|
Directionality dir = eDir_LTR;
|
|
|
|
if (aValue && aValue->Type() == nsAttrValue::eEnum) {
|
2012-04-17 08:03:10 +04:00
|
|
|
SetHasValidDir();
|
2012-11-21 14:13:57 +04:00
|
|
|
Directionality dirValue = (Directionality)aValue->GetEnumValue();
|
|
|
|
if (dirValue == eDir_Auto) {
|
|
|
|
SetHasDirAuto();
|
|
|
|
ClearHasFixedDir();
|
|
|
|
} else {
|
|
|
|
dir = dirValue;
|
|
|
|
SetDirectionality(dir, aNotify);
|
|
|
|
ClearHasDirAuto();
|
|
|
|
SetHasFixedDir();
|
|
|
|
}
|
2012-04-17 08:03:10 +04:00
|
|
|
} else {
|
|
|
|
ClearHasValidDir();
|
2012-11-21 14:13:57 +04:00
|
|
|
ClearHasFixedDir();
|
|
|
|
if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
|
|
|
|
SetHasDirAuto();
|
|
|
|
} else {
|
2013-02-21 10:57:51 +04:00
|
|
|
ClearHasDirAuto();
|
2012-11-21 14:13:57 +04:00
|
|
|
dir = RecomputeDirectionality(this, aNotify);
|
|
|
|
}
|
2012-04-17 08:03:10 +04:00
|
|
|
}
|
|
|
|
SetDirectionalityOnDescendants(this, dir, aNotify);
|
|
|
|
}
|
2005-10-28 06:59:38 +04:00
|
|
|
}
|
|
|
|
|
2007-08-06 19:27:19 +04:00
|
|
|
return nsGenericHTMLElementBase::AfterSetAttr(aNamespaceID, aName,
|
|
|
|
aValue, aNotify);
|
2005-10-28 06:59:38 +04:00
|
|
|
}
|
|
|
|
|
2014-03-17 10:56:53 +04:00
|
|
|
EventListenerManager*
|
2011-09-28 19:54:50 +04:00
|
|
|
nsGenericHTMLElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool* aDefer)
|
2005-10-28 06:59:38 +04:00
|
|
|
{
|
|
|
|
// Attributes on the body and frameset tags get set on the global object
|
2011-09-28 19:54:50 +04:00
|
|
|
if ((mNodeInfo->Equals(nsGkAtoms::body) ||
|
|
|
|
mNodeInfo->Equals(nsGkAtoms::frameset)) &&
|
|
|
|
// We only forward some event attributes from body/frameset to window
|
|
|
|
(0
|
|
|
|
#define EVENT(name_, id_, type_, struct_) /* nothing */
|
|
|
|
#define FORWARDED_EVENT(name_, id_, type_, struct_) \
|
|
|
|
|| nsGkAtoms::on##name_ == aAttrName
|
|
|
|
#define WINDOW_EVENT FORWARDED_EVENT
|
2014-04-01 15:42:12 +04:00
|
|
|
#include "mozilla/EventNameList.h" // IWYU pragma: keep
|
2011-09-28 19:54:50 +04:00
|
|
|
#undef WINDOW_EVENT
|
|
|
|
#undef FORWARDED_EVENT
|
|
|
|
#undef EVENT
|
|
|
|
)
|
|
|
|
) {
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowInner *win;
|
2005-10-28 06:59:38 +04:00
|
|
|
|
2005-11-29 04:34:37 +03:00
|
|
|
// If we have a document, and it has a window, add the event
|
|
|
|
// listener on the window (the inner window). If not, proceed as
|
|
|
|
// normal.
|
2014-10-02 23:07:24 +04:00
|
|
|
// XXXbz sXBL/XBL2 issue: should we instead use GetComposedDoc() here,
|
2005-10-28 06:59:38 +04:00
|
|
|
// override BindToTree for those classes and munge event listeners there?
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument *document = OwnerDoc();
|
2008-05-04 08:29:12 +04:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
*aDefer = false;
|
2013-04-29 19:34:16 +04:00
|
|
|
if ((win = document->GetInnerWindow())) {
|
2013-04-06 04:44:15 +04:00
|
|
|
nsCOMPtr<EventTarget> piTarget(do_QueryInterface(win));
|
2005-10-28 06:59:38 +04:00
|
|
|
|
2013-10-23 03:32:04 +04:00
|
|
|
return piTarget->GetOrCreateListenerManager();
|
2005-10-28 06:59:38 +04:00
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2005-10-28 06:59:38 +04:00
|
|
|
}
|
|
|
|
|
2011-09-28 19:54:50 +04:00
|
|
|
return nsGenericHTMLElementBase::GetEventListenerManagerForAttr(aAttrName,
|
|
|
|
aDefer);
|
2005-10-28 06:59:38 +04:00
|
|
|
}
|
|
|
|
|
2012-11-26 18:19:02 +04:00
|
|
|
#define EVENT(name_, id_, type_, struct_) /* nothing; handled by nsINode */
|
|
|
|
#define FORWARDED_EVENT(name_, id_, type_, struct_) \
|
|
|
|
EventHandlerNonNull* \
|
|
|
|
nsGenericHTMLElement::GetOn##name_() \
|
|
|
|
{ \
|
2015-03-03 14:09:00 +03:00
|
|
|
if (IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset)) { \
|
2012-11-26 18:19:02 +04:00
|
|
|
/* XXXbz note to self: add tests for this! */ \
|
2016-01-30 20:05:36 +03:00
|
|
|
if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) { \
|
|
|
|
nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \
|
2012-11-26 18:19:02 +04:00
|
|
|
return globalWin->GetOn##name_(); \
|
|
|
|
} \
|
|
|
|
return nullptr; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
return nsINode::GetOn##name_(); \
|
|
|
|
} \
|
|
|
|
void \
|
2013-09-17 15:01:28 +04:00
|
|
|
nsGenericHTMLElement::SetOn##name_(EventHandlerNonNull* handler) \
|
2012-11-26 18:19:02 +04:00
|
|
|
{ \
|
2015-03-03 14:09:00 +03:00
|
|
|
if (IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset)) { \
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow(); \
|
2013-04-29 19:34:16 +04:00
|
|
|
if (!win) { \
|
2012-11-26 18:19:02 +04:00
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
\
|
2016-01-30 20:05:36 +03:00
|
|
|
nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \
|
2013-09-17 15:01:28 +04:00
|
|
|
return globalWin->SetOn##name_(handler); \
|
2012-11-26 18:19:02 +04:00
|
|
|
} \
|
|
|
|
\
|
2013-09-17 15:01:28 +04:00
|
|
|
return nsINode::SetOn##name_(handler); \
|
2012-11-26 18:19:02 +04:00
|
|
|
}
|
|
|
|
#define ERROR_EVENT(name_, id_, type_, struct_) \
|
|
|
|
already_AddRefed<EventHandlerNonNull> \
|
|
|
|
nsGenericHTMLElement::GetOn##name_() \
|
|
|
|
{ \
|
2015-03-03 14:09:00 +03:00
|
|
|
if (IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset)) { \
|
2012-11-26 18:19:02 +04:00
|
|
|
/* XXXbz note to self: add tests for this! */ \
|
2016-01-30 20:05:36 +03:00
|
|
|
if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) { \
|
|
|
|
nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \
|
2012-11-26 18:19:02 +04:00
|
|
|
OnErrorEventHandlerNonNull* errorHandler = globalWin->GetOn##name_(); \
|
|
|
|
if (errorHandler) { \
|
2016-01-30 20:05:36 +03:00
|
|
|
RefPtr<EventHandlerNonNull> handler = \
|
2012-11-26 18:19:02 +04:00
|
|
|
new EventHandlerNonNull(errorHandler); \
|
|
|
|
return handler.forget(); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
return nullptr; \
|
|
|
|
} \
|
|
|
|
\
|
2016-01-30 20:05:36 +03:00
|
|
|
RefPtr<EventHandlerNonNull> handler = nsINode::GetOn##name_(); \
|
2012-11-26 18:19:02 +04:00
|
|
|
return handler.forget(); \
|
|
|
|
} \
|
|
|
|
void \
|
2013-09-17 15:01:28 +04:00
|
|
|
nsGenericHTMLElement::SetOn##name_(EventHandlerNonNull* handler) \
|
2012-11-26 18:19:02 +04:00
|
|
|
{ \
|
2015-03-03 14:09:00 +03:00
|
|
|
if (IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset)) { \
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow(); \
|
2013-04-29 19:34:16 +04:00
|
|
|
if (!win) { \
|
2012-11-26 18:19:02 +04:00
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
\
|
2016-01-30 20:05:36 +03:00
|
|
|
nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \
|
|
|
|
RefPtr<OnErrorEventHandlerNonNull> errorHandler; \
|
2012-12-10 23:31:25 +04:00
|
|
|
if (handler) { \
|
|
|
|
errorHandler = new OnErrorEventHandlerNonNull(handler); \
|
|
|
|
} \
|
2013-09-17 15:01:28 +04:00
|
|
|
return globalWin->SetOn##name_(errorHandler); \
|
2012-11-26 18:19:02 +04:00
|
|
|
} \
|
|
|
|
\
|
2013-09-17 15:01:28 +04:00
|
|
|
return nsINode::SetOn##name_(handler); \
|
2012-11-26 18:19:02 +04:00
|
|
|
}
|
2014-04-01 15:42:12 +04:00
|
|
|
#include "mozilla/EventNameList.h" // IWYU pragma: keep
|
2012-11-26 18:19:02 +04:00
|
|
|
#undef ERROR_EVENT
|
|
|
|
#undef FORWARDED_EVENT
|
|
|
|
#undef EVENT
|
|
|
|
|
2007-06-28 06:48:16 +04:00
|
|
|
nsresult
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
2007-06-28 06:48:16 +04:00
|
|
|
nsIAtom* aPrefix, const nsAString& aValue,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aNotify)
|
2007-06-28 06:48:16 +04:00
|
|
|
{
|
2011-09-29 10:19:26 +04:00
|
|
|
bool contentEditable = aNameSpaceID == kNameSpaceID_None &&
|
2007-06-28 06:48:16 +04:00
|
|
|
aName == nsGkAtoms::contenteditable;
|
2013-01-04 10:54:26 +04:00
|
|
|
bool undoScope = aNameSpaceID == kNameSpaceID_None &&
|
|
|
|
aName == nsGkAtoms::undoscope;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool accessKey = aName == nsGkAtoms::accesskey &&
|
2011-04-11 20:56:37 +04:00
|
|
|
aNameSpaceID == kNameSpaceID_None;
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t change = 0;
|
2007-06-28 06:48:16 +04:00
|
|
|
if (contentEditable) {
|
|
|
|
change = GetContentEditableValue() == eTrue ? -1 : 0;
|
2011-04-08 06:29:50 +04:00
|
|
|
SetMayHaveContentEditableAttr();
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
2011-04-11 20:56:37 +04:00
|
|
|
if (accessKey) {
|
|
|
|
UnregAccessKey();
|
|
|
|
}
|
|
|
|
|
2010-06-04 05:09:20 +04:00
|
|
|
nsresult rv = nsStyledElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
|
|
|
aNotify);
|
2007-06-28 06:48:16 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (contentEditable) {
|
|
|
|
if (aValue.IsEmpty() || aValue.LowerCaseEqualsLiteral("true")) {
|
|
|
|
change += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ChangeEditableState(change);
|
|
|
|
}
|
|
|
|
|
2013-01-04 10:54:26 +04:00
|
|
|
if (undoScope) {
|
|
|
|
rv = SetUndoScopeInternal(true);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2011-04-11 20:56:37 +04:00
|
|
|
if (accessKey && !aValue.IsEmpty()) {
|
|
|
|
SetFlags(NODE_HAS_ACCESSKEY);
|
|
|
|
RegAccessKey();
|
|
|
|
}
|
|
|
|
|
2007-06-28 06:48:16 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-08-30 00:20:38 +04:00
|
|
|
nsresult
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aNotify)
|
1998-08-29 03:27:19 +04:00
|
|
|
{
|
2011-09-29 10:19:26 +04:00
|
|
|
bool contentEditable = false;
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t contentEditableChange = 0;
|
2008-10-25 20:21:56 +04:00
|
|
|
|
2001-05-04 09:34:58 +04:00
|
|
|
// Check for event handlers
|
2007-06-28 06:48:16 +04:00
|
|
|
if (aNameSpaceID == kNameSpaceID_None) {
|
2010-06-04 05:09:20 +04:00
|
|
|
if (aAttribute == nsGkAtoms::name) {
|
|
|
|
// Have to do this before clearing flag. See RemoveFromNameTable
|
|
|
|
RemoveFromNameTable();
|
2011-04-08 06:29:50 +04:00
|
|
|
ClearHasName();
|
2010-06-04 05:09:20 +04:00
|
|
|
}
|
|
|
|
else if (aAttribute == nsGkAtoms::contenteditable) {
|
2011-10-17 18:59:28 +04:00
|
|
|
contentEditable = true;
|
2009-07-09 05:54:43 +04:00
|
|
|
contentEditableChange = GetContentEditableValue() == eTrue ? -1 : 0;
|
|
|
|
}
|
2013-01-04 10:54:26 +04:00
|
|
|
else if (aAttribute == nsGkAtoms::undoscope) {
|
|
|
|
nsresult rv = SetUndoScopeInternal(false);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2011-04-11 20:56:37 +04:00
|
|
|
else if (aAttribute == nsGkAtoms::accesskey) {
|
|
|
|
// Have to unregister before clearing flag. See UnregAccessKey
|
|
|
|
UnregAccessKey();
|
|
|
|
UnsetFlags(NODE_HAS_ACCESSKEY);
|
|
|
|
}
|
2013-01-03 00:24:07 +04:00
|
|
|
else if (IsEventAttributeName(aAttribute)) {
|
2014-03-17 10:56:53 +04:00
|
|
|
if (EventListenerManager* manager = GetExistingListenerManager()) {
|
2013-08-16 14:06:24 +04:00
|
|
|
manager->RemoveEventHandler(aAttribute, EmptyString());
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
2000-11-27 10:55:20 +03:00
|
|
|
}
|
2002-03-27 03:13:57 +03:00
|
|
|
}
|
2000-11-27 10:55:20 +03:00
|
|
|
|
2008-10-25 20:21:56 +04:00
|
|
|
nsresult rv = nsGenericHTMLElementBase::UnsetAttr(aNameSpaceID, aAttribute,
|
|
|
|
aNotify);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (contentEditable) {
|
|
|
|
ChangeEditableState(contentEditableChange);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2003-10-21 20:16:42 +04:00
|
|
|
}
|
|
|
|
|
2004-02-20 22:00:43 +03:00
|
|
|
void
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::GetBaseTarget(nsAString& aBaseTarget) const
|
1999-01-15 04:59:42 +03:00
|
|
|
{
|
2011-10-18 15:19:44 +04:00
|
|
|
OwnerDoc()->GetBaseTarget(aBaseTarget);
|
1999-01-15 04:59:42 +03:00
|
|
|
}
|
|
|
|
|
1998-08-29 03:27:19 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
|
2005-11-29 19:37:15 +03:00
|
|
|
nsIAtom* aAttribute,
|
2004-03-04 05:06:28 +03:00
|
|
|
const nsAString& aValue,
|
|
|
|
nsAttrValue& aResult)
|
2004-01-26 22:22:05 +03:00
|
|
|
{
|
2005-11-29 19:37:15 +03:00
|
|
|
if (aNamespaceID == kNameSpaceID_None) {
|
2006-12-26 20:47:52 +03:00
|
|
|
if (aAttribute == nsGkAtoms::dir) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aValue, kDirTable, false);
|
2005-11-29 19:37:15 +03:00
|
|
|
}
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
if (aAttribute == nsGkAtoms::tabindex) {
|
2014-05-20 00:37:59 +04:00
|
|
|
return aResult.ParseIntValue(aValue);
|
2005-11-29 19:37:15 +03:00
|
|
|
}
|
2004-07-07 04:58:57 +04:00
|
|
|
|
2015-12-01 03:13:03 +03:00
|
|
|
if (aAttribute == nsGkAtoms::referrerpolicy) {
|
2015-06-06 01:25:24 +03:00
|
|
|
return ParseReferrerAttribute(aValue, aResult);
|
|
|
|
}
|
|
|
|
|
2010-06-04 05:09:20 +04:00
|
|
|
if (aAttribute == nsGkAtoms::name) {
|
2005-11-29 19:37:15 +03:00
|
|
|
// Store name as an atom. name="" means that the element has no name,
|
|
|
|
// not that it has an emptystring as the name.
|
2010-06-04 05:09:20 +04:00
|
|
|
RemoveFromNameTable();
|
|
|
|
if (aValue.IsEmpty()) {
|
2011-04-08 06:29:50 +04:00
|
|
|
ClearHasName();
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2010-06-04 05:09:20 +04:00
|
|
|
}
|
|
|
|
|
2005-11-29 19:37:15 +03:00
|
|
|
aResult.ParseAtom(aValue);
|
2010-06-04 05:09:20 +04:00
|
|
|
|
2015-03-03 14:09:00 +03:00
|
|
|
if (CanHaveName(NodeInfo()->NameAtom())) {
|
2011-04-08 06:29:50 +04:00
|
|
|
SetHasName();
|
2010-06-04 05:09:20 +04:00
|
|
|
AddToNameTable(aResult.GetAtomValue());
|
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2005-11-29 19:37:15 +03:00
|
|
|
}
|
2007-06-28 06:48:16 +04:00
|
|
|
|
|
|
|
if (aAttribute == nsGkAtoms::contenteditable) {
|
|
|
|
aResult.ParseAtom(aValue);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
2012-06-05 03:49:57 +04:00
|
|
|
|
|
|
|
if (aAttribute == nsGkAtoms::itemref ||
|
|
|
|
aAttribute == nsGkAtoms::itemprop ||
|
2014-03-11 16:04:26 +04:00
|
|
|
aAttribute == nsGkAtoms::itemtype ||
|
|
|
|
aAttribute == nsGkAtoms::rel) {
|
2012-06-05 03:49:57 +04:00
|
|
|
aResult.ParseAtomArray(aValue);
|
|
|
|
return true;
|
|
|
|
}
|
2005-11-16 05:55:29 +03:00
|
|
|
}
|
|
|
|
|
2007-08-06 19:27:19 +04:00
|
|
|
return nsGenericHTMLElementBase::ParseAttribute(aNamespaceID, aAttribute,
|
|
|
|
aValue, aResult);
|
2004-01-26 22:22:05 +03:00
|
|
|
}
|
|
|
|
|
2012-08-24 21:50:49 +04:00
|
|
|
bool
|
|
|
|
nsGenericHTMLElement::ParseBackgroundAttribute(int32_t aNamespaceID,
|
|
|
|
nsIAtom* aAttribute,
|
|
|
|
const nsAString& aValue,
|
|
|
|
nsAttrValue& aResult)
|
|
|
|
{
|
|
|
|
if (aNamespaceID == kNameSpaceID_None &&
|
2012-09-04 19:53:11 +04:00
|
|
|
aAttribute == nsGkAtoms::background &&
|
|
|
|
!aValue.IsEmpty()) {
|
2012-08-24 21:50:49 +04:00
|
|
|
// Resolve url to an absolute url
|
|
|
|
nsIDocument* doc = OwnerDoc();
|
|
|
|
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(
|
|
|
|
getter_AddRefs(uri), aValue, doc, baseURI);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsString value(aValue);
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsStringBuffer> buffer = nsCSSValue::BufferFromString(value);
|
2012-10-26 17:32:10 +04:00
|
|
|
if (MOZ_UNLIKELY(!buffer)) {
|
2012-08-24 21:50:49 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::css::URLValue *url =
|
2012-12-07 00:21:19 +04:00
|
|
|
new mozilla::css::URLValue(uri, buffer, doc->GetDocumentURI(),
|
|
|
|
NodePrincipal());
|
2012-08-24 21:50:49 +04:00
|
|
|
aResult.SetTo(url, &aValue);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2004-02-26 00:04:50 +03:00
|
|
|
nsGenericHTMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
2000-12-23 13:56:31 +03:00
|
|
|
{
|
2004-02-26 00:04:50 +03:00
|
|
|
static const MappedAttributeEntry* const map[] = {
|
2003-04-17 00:54:20 +04:00
|
|
|
sCommonAttributeMap
|
|
|
|
};
|
|
|
|
|
2011-12-18 14:09:27 +04:00
|
|
|
return FindAttributeDependence(aAttribute, map);
|
2000-12-23 13:56:31 +03:00
|
|
|
}
|
|
|
|
|
2005-01-12 22:45:38 +03:00
|
|
|
nsMapRuleToAttributesFunc
|
|
|
|
nsGenericHTMLElement::GetAttributeMappingFunction() const
|
2000-12-23 13:56:31 +03:00
|
|
|
{
|
2005-01-12 22:45:38 +03:00
|
|
|
return &MapCommonAttributesInto;
|
2000-12-23 13:56:31 +03:00
|
|
|
}
|
|
|
|
|
2006-06-12 20:14:31 +04:00
|
|
|
nsIFormControlFrame*
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLElement::GetFormControlFrame(bool aFlushFrames)
|
2001-11-02 10:40:01 +03:00
|
|
|
{
|
2014-08-06 03:23:02 +04:00
|
|
|
if (aFlushFrames && IsInComposedDoc()) {
|
2009-04-22 03:53:52 +04:00
|
|
|
// Cause a flush of the frames, so we get up-to-date frame information
|
2014-08-06 03:23:02 +04:00
|
|
|
GetComposedDoc()->FlushPendingNotifications(Flush_Frames);
|
2001-12-12 10:31:15 +03:00
|
|
|
}
|
2009-12-25 00:20:05 +03:00
|
|
|
nsIFrame* frame = GetPrimaryFrame();
|
2002-05-16 22:26:05 +04:00
|
|
|
if (frame) {
|
2009-01-12 22:20:59 +03:00
|
|
|
nsIFormControlFrame* form_frame = do_QueryFrame(frame);
|
2003-12-20 15:15:48 +03:00
|
|
|
if (form_frame) {
|
|
|
|
return form_frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have generated content, the primary frame will be a
|
2003-12-20 15:19:41 +03:00
|
|
|
// wrapper frame.. out real frame will be in its child list.
|
2016-01-29 17:42:14 +03:00
|
|
|
for (frame = frame->PrincipalChildList().FirstChild();
|
2003-12-20 15:15:48 +03:00
|
|
|
frame;
|
|
|
|
frame = frame->GetNextSibling()) {
|
2009-01-12 22:20:59 +03:00
|
|
|
form_frame = do_QueryFrame(frame);
|
2003-12-20 15:15:48 +03:00
|
|
|
if (form_frame) {
|
|
|
|
return form_frame;
|
|
|
|
}
|
|
|
|
}
|
1999-10-26 08:44:41 +04:00
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2000-12-23 13:56:31 +03:00
|
|
|
}
|
1999-10-26 08:44:41 +04:00
|
|
|
|
2004-08-21 00:34:37 +04:00
|
|
|
nsPresContext*
|
2014-08-23 00:11:27 +04:00
|
|
|
nsGenericHTMLElement::GetPresContext(PresContextFor aFor)
|
1999-10-26 08:44:41 +04:00
|
|
|
{
|
2003-06-14 00:10:01 +04:00
|
|
|
// Get the document
|
2014-08-23 00:11:27 +04:00
|
|
|
nsIDocument* doc = (aFor == eForComposedDoc) ?
|
|
|
|
GetComposedDoc() : GetUncomposedDoc();
|
2003-06-14 00:10:01 +04:00
|
|
|
if (doc) {
|
2011-11-16 11:50:19 +04:00
|
|
|
// Get presentation shell.
|
2010-06-25 17:59:57 +04:00
|
|
|
nsIPresShell *presShell = doc->GetShell();
|
2003-06-14 00:10:01 +04:00
|
|
|
if (presShell) {
|
2004-08-21 00:34:37 +04:00
|
|
|
return presShell->GetPresContext();
|
1999-02-01 21:44:59 +03:00
|
|
|
}
|
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2000-12-23 13:56:31 +03:00
|
|
|
}
|
|
|
|
|
2005-01-25 03:02:58 +03:00
|
|
|
static const nsAttrValue::EnumTable kDivAlignTable[] = {
|
2005-06-16 03:45:06 +04:00
|
|
|
{ "left", NS_STYLE_TEXT_ALIGN_MOZ_LEFT },
|
1999-03-25 06:48:06 +03:00
|
|
|
{ "right", NS_STYLE_TEXT_ALIGN_MOZ_RIGHT },
|
|
|
|
{ "center", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
|
|
|
|
{ "middle", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
|
|
|
|
{ "justify", NS_STYLE_TEXT_ALIGN_JUSTIFY },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2005-01-25 03:02:58 +03:00
|
|
|
static const nsAttrValue::EnumTable kFrameborderTable[] = {
|
1998-09-10 03:30:30 +04:00
|
|
|
{ "yes", NS_STYLE_FRAME_YES },
|
|
|
|
{ "no", NS_STYLE_FRAME_NO },
|
|
|
|
{ "1", NS_STYLE_FRAME_1 },
|
|
|
|
{ "0", NS_STYLE_FRAME_0 },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2005-01-25 03:02:58 +03:00
|
|
|
static const nsAttrValue::EnumTable kScrollingTable[] = {
|
1998-09-10 03:30:30 +04:00
|
|
|
{ "yes", NS_STYLE_FRAME_YES },
|
|
|
|
{ "no", NS_STYLE_FRAME_NO },
|
|
|
|
{ "on", NS_STYLE_FRAME_ON },
|
|
|
|
{ "off", NS_STYLE_FRAME_OFF },
|
|
|
|
{ "scroll", NS_STYLE_FRAME_SCROLL },
|
|
|
|
{ "noscroll", NS_STYLE_FRAME_NOSCROLL },
|
|
|
|
{ "auto", NS_STYLE_FRAME_AUTO },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2005-01-25 03:02:58 +03:00
|
|
|
static const nsAttrValue::EnumTable kTableVAlignTable[] = {
|
1998-09-15 21:58:24 +04:00
|
|
|
{ "top", NS_STYLE_VERTICAL_ALIGN_TOP },
|
|
|
|
{ "middle", NS_STYLE_VERTICAL_ALIGN_MIDDLE },
|
|
|
|
{ "bottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM },
|
|
|
|
{ "baseline",NS_STYLE_VERTICAL_ALIGN_BASELINE },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::ParseAlignValue(const nsAString& aString,
|
2004-03-04 05:06:28 +03:00
|
|
|
nsAttrValue& aResult)
|
1998-09-01 05:36:11 +04:00
|
|
|
{
|
2013-11-19 23:21:29 +04:00
|
|
|
static const nsAttrValue::EnumTable kAlignTable[] = {
|
|
|
|
{ "left", NS_STYLE_TEXT_ALIGN_LEFT },
|
|
|
|
{ "right", NS_STYLE_TEXT_ALIGN_RIGHT },
|
|
|
|
|
|
|
|
{ "top", NS_STYLE_VERTICAL_ALIGN_TOP },
|
|
|
|
{ "middle", NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE },
|
|
|
|
{ "bottom", NS_STYLE_VERTICAL_ALIGN_BASELINE },
|
|
|
|
|
|
|
|
{ "center", NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE },
|
|
|
|
{ "baseline", NS_STYLE_VERTICAL_ALIGN_BASELINE },
|
|
|
|
|
|
|
|
{ "texttop", NS_STYLE_VERTICAL_ALIGN_TEXT_TOP },
|
|
|
|
{ "absmiddle", NS_STYLE_VERTICAL_ALIGN_MIDDLE },
|
|
|
|
{ "abscenter", NS_STYLE_VERTICAL_ALIGN_MIDDLE },
|
|
|
|
{ "absbottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aString, kAlignTable, false);
|
1998-09-01 05:36:11 +04:00
|
|
|
}
|
|
|
|
|
1999-09-21 04:12:09 +04:00
|
|
|
//----------------------------------------
|
|
|
|
|
2005-01-25 03:02:58 +03:00
|
|
|
static const nsAttrValue::EnumTable kTableHAlignTable[] = {
|
1999-09-21 04:12:09 +04:00
|
|
|
{ "left", NS_STYLE_TEXT_ALIGN_LEFT },
|
|
|
|
{ "right", NS_STYLE_TEXT_ALIGN_RIGHT },
|
|
|
|
{ "center", NS_STYLE_TEXT_ALIGN_CENTER },
|
|
|
|
{ "char", NS_STYLE_TEXT_ALIGN_CHAR },
|
|
|
|
{ "justify",NS_STYLE_TEXT_ALIGN_JUSTIFY },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::ParseTableHAlignValue(const nsAString& aString,
|
2010-06-11 22:47:56 +04:00
|
|
|
nsAttrValue& aResult)
|
1999-09-21 04:12:09 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aString, kTableHAlignTable, false);
|
1999-09-21 04:12:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
|
2010-07-31 03:48:57 +04:00
|
|
|
// This table is used for td, th, tr, col, thead, tbody and tfoot.
|
2005-01-25 03:02:58 +03:00
|
|
|
static const nsAttrValue::EnumTable kTableCellHAlignTable[] = {
|
2005-06-16 03:45:06 +04:00
|
|
|
{ "left", NS_STYLE_TEXT_ALIGN_MOZ_LEFT },
|
2000-07-28 03:37:44 +04:00
|
|
|
{ "right", NS_STYLE_TEXT_ALIGN_MOZ_RIGHT },
|
|
|
|
{ "center", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
|
|
|
|
{ "char", NS_STYLE_TEXT_ALIGN_CHAR },
|
|
|
|
{ "justify",NS_STYLE_TEXT_ALIGN_JUSTIFY },
|
2000-02-16 04:08:54 +03:00
|
|
|
{ "middle", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
|
2000-07-06 17:42:57 +04:00
|
|
|
{ "absmiddle", NS_STYLE_TEXT_ALIGN_CENTER },
|
1999-09-21 04:12:09 +04:00
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::ParseTableCellHAlignValue(const nsAString& aString,
|
2010-07-31 03:48:57 +04:00
|
|
|
nsAttrValue& aResult)
|
1998-09-15 21:58:24 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aString, kTableCellHAlignTable, false);
|
1998-09-15 21:58:24 +04:00
|
|
|
}
|
|
|
|
|
1999-09-21 04:12:09 +04:00
|
|
|
//----------------------------------------
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::ParseTableVAlignValue(const nsAString& aString,
|
2004-03-04 05:06:28 +03:00
|
|
|
nsAttrValue& aResult)
|
1998-09-15 21:58:24 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aString, kTableVAlignTable, false);
|
1998-09-15 21:58:24 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::ParseDivAlignValue(const nsAString& aString,
|
2010-07-06 08:25:52 +04:00
|
|
|
nsAttrValue& aResult)
|
1998-09-04 02:21:32 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aString, kDivAlignTable, false);
|
1998-09-04 02:21:32 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
1998-09-04 02:21:32 +04:00
|
|
|
nsGenericHTMLElement::ParseImageAttribute(nsIAtom* aAttribute,
|
2002-03-24 02:13:20 +03:00
|
|
|
const nsAString& aString,
|
2004-03-04 05:06:28 +03:00
|
|
|
nsAttrValue& aResult)
|
1998-09-01 05:36:11 +04:00
|
|
|
{
|
2006-12-26 20:47:52 +03:00
|
|
|
if ((aAttribute == nsGkAtoms::width) ||
|
|
|
|
(aAttribute == nsGkAtoms::height)) {
|
2011-02-04 22:46:16 +03:00
|
|
|
return aResult.ParseSpecialIntValue(aString);
|
1998-09-01 05:36:11 +04:00
|
|
|
}
|
2011-11-16 11:50:19 +04:00
|
|
|
if ((aAttribute == nsGkAtoms::hspace) ||
|
|
|
|
(aAttribute == nsGkAtoms::vspace) ||
|
|
|
|
(aAttribute == nsGkAtoms::border)) {
|
2004-03-04 05:06:28 +03:00
|
|
|
return aResult.ParseIntWithBounds(aString, 0);
|
1998-09-01 05:36:11 +04:00
|
|
|
}
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
1998-09-01 05:36:11 +04:00
|
|
|
}
|
|
|
|
|
2015-06-06 01:25:24 +03:00
|
|
|
bool
|
|
|
|
nsGenericHTMLElement::ParseReferrerAttribute(const nsAString& aString,
|
|
|
|
nsAttrValue& aResult)
|
|
|
|
{
|
|
|
|
static const nsAttrValue::EnumTable kReferrerTable[] = {
|
|
|
|
{ "no-referrer", net::RP_No_Referrer },
|
|
|
|
{ "origin", net::RP_Origin },
|
|
|
|
{ "unsafe-url", net::RP_Unsafe_URL },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
return aResult.ParseEnumValue(aString, kReferrerTable, false);
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::ParseFrameborderValue(const nsAString& aString,
|
2004-03-04 05:06:28 +03:00
|
|
|
nsAttrValue& aResult)
|
1998-09-10 03:30:30 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aString, kFrameborderTable, false);
|
1998-09-10 03:30:30 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2002-03-24 02:13:20 +03:00
|
|
|
nsGenericHTMLElement::ParseScrollingValue(const nsAString& aString,
|
2004-03-04 05:06:28 +03:00
|
|
|
nsAttrValue& aResult)
|
1998-09-10 03:30:30 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return aResult.ParseEnumValue(aString, kScrollingTable, false);
|
1998-09-10 03:30:30 +04:00
|
|
|
}
|
|
|
|
|
2015-12-07 19:12:44 +03:00
|
|
|
static inline void
|
|
|
|
MapLangAttributeInto(const nsMappedAttributes* aAttributes, nsRuleData* aData)
|
|
|
|
{
|
|
|
|
if (!(aData->mSIDs & (NS_STYLE_INHERIT_BIT(Font) |
|
|
|
|
NS_STYLE_INHERIT_BIT(Text)))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsAttrValue* langValue = aAttributes->GetAttr(nsGkAtoms::lang);
|
|
|
|
if (!langValue || langValue->Type() != nsAttrValue::eString) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
|
|
|
|
nsCSSValue* lang = aData->ValueForLang();
|
|
|
|
if (lang->GetUnit() == eCSSUnit_Null) {
|
|
|
|
lang->SetStringValue(langValue->GetStringValue(), eCSSUnit_Ident);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) {
|
|
|
|
nsCSSValue* emphasisPos = aData->ValueForTextEmphasisPosition();
|
|
|
|
if (emphasisPos->GetUnit() == eCSSUnit_Null) {
|
|
|
|
const nsAString& lang = langValue->GetStringValue();
|
|
|
|
if (nsStyleUtil::MatchesLanguagePrefix(lang, MOZ_UTF16("zh"))) {
|
|
|
|
emphasisPos->SetIntValue(NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT_ZH,
|
|
|
|
eCSSUnit_Enumerated);
|
|
|
|
} else if (nsStyleUtil::MatchesLanguagePrefix(lang, MOZ_UTF16("ja")) ||
|
|
|
|
nsStyleUtil::MatchesLanguagePrefix(lang, MOZ_UTF16("mn"))) {
|
|
|
|
// This branch is currently no part of the spec.
|
|
|
|
// See bug 1040668 comment 69 and comment 75.
|
|
|
|
emphasisPos->SetIntValue(NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT,
|
|
|
|
eCSSUnit_Enumerated);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
/**
|
|
|
|
* Handle attributes common to all html elements
|
|
|
|
*/
|
|
|
|
void
|
2013-07-11 18:39:18 +04:00
|
|
|
nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(const nsMappedAttributes* aAttributes,
|
|
|
|
nsRuleData* aData)
|
2001-06-01 02:19:43 +04:00
|
|
|
{
|
2007-10-09 01:58:22 +04:00
|
|
|
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(UserInterface)) {
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* userModify = aData->ValueForUserModify();
|
|
|
|
if (userModify->GetUnit() == eCSSUnit_Null) {
|
2007-06-28 06:48:16 +04:00
|
|
|
const nsAttrValue* value =
|
|
|
|
aAttributes->GetAttr(nsGkAtoms::contenteditable);
|
|
|
|
if (value) {
|
|
|
|
if (value->Equals(nsGkAtoms::_empty, eCaseMatters) ||
|
|
|
|
value->Equals(nsGkAtoms::_true, eIgnoreCase)) {
|
2011-03-18 06:14:31 +03:00
|
|
|
userModify->SetIntValue(NS_STYLE_USER_MODIFY_READ_WRITE,
|
|
|
|
eCSSUnit_Enumerated);
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
2008-10-10 20:09:37 +04:00
|
|
|
else if (value->Equals(nsGkAtoms::_false, eIgnoreCase)) {
|
2011-03-18 06:14:31 +03:00
|
|
|
userModify->SetIntValue(NS_STYLE_USER_MODIFY_READ_ONLY,
|
|
|
|
eCSSUnit_Enumerated);
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-08-02 07:07:07 +04:00
|
|
|
|
2015-12-07 19:12:44 +03:00
|
|
|
MapLangAttributeInto(aAttributes, aData);
|
2013-07-11 18:39:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttributes,
|
|
|
|
nsRuleData* aData)
|
|
|
|
{
|
|
|
|
MapCommonAttributesIntoExceptHidden(aAttributes, aData);
|
2010-08-02 07:07:07 +04:00
|
|
|
|
|
|
|
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* display = aData->ValueForDisplay();
|
|
|
|
if (display->GetUnit() == eCSSUnit_Null) {
|
2012-07-14 03:29:14 +04:00
|
|
|
if (aAttributes->IndexOfAttr(nsGkAtoms::hidden) >= 0) {
|
2011-03-18 06:14:31 +03:00
|
|
|
display->SetIntValue(NS_STYLE_DISPLAY_NONE, eCSSUnit_Enumerated);
|
2010-08-02 07:07:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-07-07 05:24:40 +04:00
|
|
|
}
|
|
|
|
|
2004-02-26 00:04:50 +03:00
|
|
|
/* static */ const nsGenericHTMLElement::MappedAttributeEntry
|
2003-04-17 00:54:20 +04:00
|
|
|
nsGenericHTMLElement::sCommonAttributeMap[] = {
|
2007-06-28 06:48:16 +04:00
|
|
|
{ &nsGkAtoms::contenteditable },
|
2006-12-26 20:47:52 +03:00
|
|
|
{ &nsGkAtoms::lang },
|
2010-08-02 07:07:07 +04:00
|
|
|
{ &nsGkAtoms::hidden },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr }
|
2003-04-17 00:54:20 +04:00
|
|
|
};
|
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
/* static */ const Element::MappedAttributeEntry
|
2003-07-12 01:16:12 +04:00
|
|
|
nsGenericHTMLElement::sImageMarginSizeAttributeMap[] = {
|
2006-12-26 20:47:52 +03:00
|
|
|
{ &nsGkAtoms::width },
|
|
|
|
{ &nsGkAtoms::height },
|
|
|
|
{ &nsGkAtoms::hspace },
|
|
|
|
{ &nsGkAtoms::vspace },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr }
|
2003-04-17 00:54:20 +04:00
|
|
|
};
|
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
/* static */ const Element::MappedAttributeEntry
|
2003-04-17 00:54:20 +04:00
|
|
|
nsGenericHTMLElement::sImageAlignAttributeMap[] = {
|
2006-12-26 20:47:52 +03:00
|
|
|
{ &nsGkAtoms::align },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr }
|
2003-04-17 00:54:20 +04:00
|
|
|
};
|
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
/* static */ const Element::MappedAttributeEntry
|
2003-07-12 01:16:12 +04:00
|
|
|
nsGenericHTMLElement::sDivAlignAttributeMap[] = {
|
2006-12-26 20:47:52 +03:00
|
|
|
{ &nsGkAtoms::align },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr }
|
2003-04-17 00:54:20 +04:00
|
|
|
};
|
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
/* static */ const Element::MappedAttributeEntry
|
2003-07-12 01:16:12 +04:00
|
|
|
nsGenericHTMLElement::sImageBorderAttributeMap[] = {
|
2006-12-26 20:47:52 +03:00
|
|
|
{ &nsGkAtoms::border },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr }
|
2003-07-12 01:16:12 +04:00
|
|
|
};
|
2003-04-17 00:54:20 +04:00
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
/* static */ const Element::MappedAttributeEntry
|
2003-04-17 00:54:20 +04:00
|
|
|
nsGenericHTMLElement::sBackgroundAttributeMap[] = {
|
2006-12-26 20:47:52 +03:00
|
|
|
{ &nsGkAtoms::background },
|
|
|
|
{ &nsGkAtoms::bgcolor },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr }
|
2003-04-17 00:54:20 +04:00
|
|
|
};
|
|
|
|
|
2012-11-15 02:10:08 +04:00
|
|
|
/* static */ const Element::MappedAttributeEntry
|
2005-10-27 00:23:56 +04:00
|
|
|
nsGenericHTMLElement::sBackgroundColorAttributeMap[] = {
|
2006-12-26 20:47:52 +03:00
|
|
|
{ &nsGkAtoms::bgcolor },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr }
|
2005-10-27 00:23:56 +04:00
|
|
|
};
|
|
|
|
|
1998-09-01 05:36:11 +04:00
|
|
|
void
|
2004-01-26 22:22:05 +03:00
|
|
|
nsGenericHTMLElement::MapImageAlignAttributeInto(const nsMappedAttributes* aAttributes,
|
2003-07-12 01:16:12 +04:00
|
|
|
nsRuleData* aRuleData)
|
1998-09-01 05:36:11 +04:00
|
|
|
{
|
2016-04-12 08:52:41 +03:00
|
|
|
if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
|
2006-12-26 20:47:52 +03:00
|
|
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
|
2004-04-13 20:45:59 +04:00
|
|
|
if (value && value->Type() == nsAttrValue::eEnum) {
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t align = value->GetEnumValue();
|
2016-04-12 08:52:41 +03:00
|
|
|
nsCSSValue* cssFloat = aRuleData->ValueForFloat();
|
|
|
|
if (cssFloat->GetUnit() == eCSSUnit_Null) {
|
|
|
|
if (align == NS_STYLE_TEXT_ALIGN_LEFT) {
|
|
|
|
cssFloat->SetIntValue(NS_STYLE_FLOAT_LEFT, eCSSUnit_Enumerated);
|
|
|
|
} else if (align == NS_STYLE_TEXT_ALIGN_RIGHT) {
|
|
|
|
cssFloat->SetIntValue(NS_STYLE_FLOAT_RIGHT, eCSSUnit_Enumerated);
|
2011-03-18 06:14:31 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2016-04-12 08:52:41 +03:00
|
|
|
nsCSSValue* verticalAlign = aRuleData->ValueForVerticalAlign();
|
|
|
|
if (verticalAlign->GetUnit() == eCSSUnit_Null) {
|
|
|
|
switch (align) {
|
|
|
|
case NS_STYLE_TEXT_ALIGN_LEFT:
|
|
|
|
case NS_STYLE_TEXT_ALIGN_RIGHT:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
verticalAlign->SetIntValue(align, eCSSUnit_Enumerated);
|
|
|
|
break;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
}
|
1998-09-01 05:36:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-26 12:18:42 +04:00
|
|
|
void
|
2004-01-26 22:22:05 +03:00
|
|
|
nsGenericHTMLElement::MapDivAlignAttributeInto(const nsMappedAttributes* aAttributes,
|
2002-09-26 12:18:42 +04:00
|
|
|
nsRuleData* aRuleData)
|
|
|
|
{
|
2007-10-09 01:58:22 +04:00
|
|
|
if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) {
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* textAlign = aRuleData->ValueForTextAlign();
|
|
|
|
if (textAlign->GetUnit() == eCSSUnit_Null) {
|
2002-09-26 12:18:42 +04:00
|
|
|
// align: enum
|
2006-12-26 20:47:52 +03:00
|
|
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
|
2004-04-13 20:45:59 +04:00
|
|
|
if (value && value->Type() == nsAttrValue::eEnum)
|
2011-03-18 06:14:31 +03:00
|
|
|
textAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
|
2002-09-26 12:18:42 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-09-01 05:36:11 +04:00
|
|
|
|
1999-07-07 05:24:40 +04:00
|
|
|
void
|
2004-01-26 22:22:05 +03:00
|
|
|
nsGenericHTMLElement::MapImageMarginAttributeInto(const nsMappedAttributes* aAttributes,
|
2001-06-01 02:19:43 +04:00
|
|
|
nsRuleData* aData)
|
1999-07-07 05:24:40 +04:00
|
|
|
{
|
2007-10-09 01:58:22 +04:00
|
|
|
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)))
|
2001-06-01 02:19:43 +04:00
|
|
|
return;
|
|
|
|
|
2004-04-13 20:45:59 +04:00
|
|
|
const nsAttrValue* value;
|
1998-09-01 05:36:11 +04:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// hspace: value
|
2006-12-26 20:47:52 +03:00
|
|
|
value = aAttributes->GetAttr(nsGkAtoms::hspace);
|
2004-04-13 20:45:59 +04:00
|
|
|
if (value) {
|
|
|
|
nsCSSValue hval;
|
|
|
|
if (value->Type() == nsAttrValue::eInteger)
|
|
|
|
hval.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
|
|
|
|
else if (value->Type() == nsAttrValue::ePercent)
|
|
|
|
hval.SetPercentValue(value->GetPercentValue());
|
|
|
|
|
|
|
|
if (hval.GetUnit() != eCSSUnit_Null) {
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* left = aData->ValueForMarginLeft();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (left->GetUnit() == eCSSUnit_Null)
|
|
|
|
*left = hval;
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* right = aData->ValueForMarginRight();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (right->GetUnit() == eCSSUnit_Null)
|
|
|
|
*right = hval;
|
2004-04-13 20:45:59 +04:00
|
|
|
}
|
1999-07-07 05:24:40 +04:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
|
|
|
|
// vspace: value
|
2006-12-26 20:47:52 +03:00
|
|
|
value = aAttributes->GetAttr(nsGkAtoms::vspace);
|
2004-04-13 20:45:59 +04:00
|
|
|
if (value) {
|
|
|
|
nsCSSValue vval;
|
|
|
|
if (value->Type() == nsAttrValue::eInteger)
|
|
|
|
vval.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
|
|
|
|
else if (value->Type() == nsAttrValue::ePercent)
|
|
|
|
vval.SetPercentValue(value->GetPercentValue());
|
|
|
|
|
|
|
|
if (vval.GetUnit() != eCSSUnit_Null) {
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* top = aData->ValueForMarginTop();
|
|
|
|
if (top->GetUnit() == eCSSUnit_Null)
|
|
|
|
*top = vval;
|
|
|
|
nsCSSValue* bottom = aData->ValueForMarginBottom();
|
|
|
|
if (bottom->GetUnit() == eCSSUnit_Null)
|
|
|
|
*bottom = vval;
|
2004-04-13 20:45:59 +04:00
|
|
|
}
|
1999-07-24 23:55:35 +04:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
1999-07-07 05:24:40 +04:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
void
|
2004-01-26 22:22:05 +03:00
|
|
|
nsGenericHTMLElement::MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
|
2003-07-12 01:16:12 +04:00
|
|
|
nsRuleData* aData)
|
2001-06-01 02:19:43 +04:00
|
|
|
{
|
2007-10-09 01:58:22 +04:00
|
|
|
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)))
|
2001-06-01 02:19:43 +04:00
|
|
|
return;
|
1999-07-07 05:24:40 +04:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// width: value
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* width = aData->ValueForWidth();
|
|
|
|
if (width->GetUnit() == eCSSUnit_Null) {
|
2006-12-26 20:47:52 +03:00
|
|
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
|
2004-04-13 20:45:59 +04:00
|
|
|
if (value && value->Type() == nsAttrValue::eInteger)
|
2011-03-18 06:14:31 +03:00
|
|
|
width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
|
2004-04-13 20:45:59 +04:00
|
|
|
else if (value && value->Type() == nsAttrValue::ePercent)
|
2011-03-18 06:14:31 +03:00
|
|
|
width->SetPercentValue(value->GetPercentValue());
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2001-02-07 12:57:26 +03:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// height: value
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* height = aData->ValueForHeight();
|
|
|
|
if (height->GetUnit() == eCSSUnit_Null) {
|
2006-12-26 20:47:52 +03:00
|
|
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
|
2004-04-13 20:45:59 +04:00
|
|
|
if (value && value->Type() == nsAttrValue::eInteger)
|
2011-03-18 06:14:31 +03:00
|
|
|
height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
|
2004-04-13 20:45:59 +04:00
|
|
|
else if (value && value->Type() == nsAttrValue::ePercent)
|
2011-03-18 06:14:31 +03:00
|
|
|
height->SetPercentValue(value->GetPercentValue());
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
void
|
2004-01-26 22:22:05 +03:00
|
|
|
nsGenericHTMLElement::MapImageBorderAttributeInto(const nsMappedAttributes* aAttributes,
|
2001-06-01 02:19:43 +04:00
|
|
|
nsRuleData* aData)
|
|
|
|
{
|
2007-10-09 01:58:22 +04:00
|
|
|
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Border)))
|
2001-06-01 02:19:43 +04:00
|
|
|
return;
|
1998-12-07 21:55:19 +03:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// border: pixels
|
2006-12-26 20:47:52 +03:00
|
|
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::border);
|
2004-04-13 20:45:59 +04:00
|
|
|
if (!value)
|
2001-06-01 02:19:43 +04:00
|
|
|
return;
|
|
|
|
|
2004-04-13 20:45:59 +04:00
|
|
|
nscoord val = 0;
|
|
|
|
if (value->Type() == nsAttrValue::eInteger)
|
|
|
|
val = value->GetIntegerValue();
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (borderLeftWidth->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderLeftWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
|
|
|
|
nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
|
|
|
|
if (borderTopWidth->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderTopWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (borderRightWidth->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderRightWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
|
|
|
|
nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
|
|
|
|
if (borderBottomWidth->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderBottomWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
|
|
|
|
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyle();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (borderLeftStyle->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderLeftStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
|
|
|
|
nsCSSValue* borderTopStyle = aData->ValueForBorderTopStyle();
|
|
|
|
if (borderTopStyle->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderTopStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyle();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (borderRightStyle->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderRightStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
|
|
|
|
nsCSSValue* borderBottomStyle = aData->ValueForBorderBottomStyle();
|
|
|
|
if (borderBottomStyle->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderBottomStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
|
|
|
|
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColor();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (borderLeftColor->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderLeftColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
|
|
|
|
nsCSSValue* borderTopColor = aData->ValueForBorderTopColor();
|
|
|
|
if (borderTopColor->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderTopColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
|
2015-01-17 07:16:02 +03:00
|
|
|
nsCSSValue* borderRightColor = aData->ValueForBorderRightColor();
|
2011-03-18 06:14:31 +03:00
|
|
|
if (borderRightColor->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderRightColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
|
|
|
|
nsCSSValue* borderBottomColor = aData->ValueForBorderBottomColor();
|
|
|
|
if (borderBottomColor->GetUnit() == eCSSUnit_Null)
|
|
|
|
borderBottomColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
|
1998-09-01 05:36:11 +04:00
|
|
|
}
|
|
|
|
|
1998-08-29 07:15:55 +04:00
|
|
|
void
|
2005-10-27 00:23:56 +04:00
|
|
|
nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
2007-05-03 05:15:53 +04:00
|
|
|
nsRuleData* aData)
|
1998-09-04 02:21:32 +04:00
|
|
|
{
|
2007-10-09 01:58:22 +04:00
|
|
|
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)))
|
2001-06-01 02:19:43 +04:00
|
|
|
return;
|
1998-09-04 02:21:32 +04:00
|
|
|
|
2007-11-16 06:46:42 +03:00
|
|
|
nsPresContext* presContext = aData->mPresContext;
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* backImage = aData->ValueForBackgroundImage();
|
|
|
|
if (backImage->GetUnit() == eCSSUnit_Null &&
|
2010-08-19 23:33:44 +04:00
|
|
|
presContext->UseDocumentColors()) {
|
2001-06-01 02:19:43 +04:00
|
|
|
// background
|
2012-08-24 21:50:49 +04:00
|
|
|
nsAttrValue* value =
|
|
|
|
const_cast<nsAttrValue*>(aAttributes->GetAttr(nsGkAtoms::background));
|
|
|
|
// If the value is an image, or it is a URL and we attempted a load,
|
|
|
|
// put it in the style tree.
|
2012-09-04 19:53:11 +04:00
|
|
|
if (value) {
|
|
|
|
if (value->Type() == nsAttrValue::eURL) {
|
|
|
|
value->LoadImage(presContext->Document());
|
|
|
|
}
|
|
|
|
if (value->Type() == nsAttrValue::eImage) {
|
|
|
|
nsCSSValueList* list = backImage->SetListValue();
|
|
|
|
list->mValue.SetImageValue(value->GetImageValue());
|
|
|
|
}
|
1998-09-04 02:21:32 +04:00
|
|
|
}
|
|
|
|
}
|
2005-10-27 00:23:56 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLElement::MapBGColorInto(const nsMappedAttributes* aAttributes,
|
|
|
|
nsRuleData* aData)
|
|
|
|
{
|
2007-10-09 01:58:22 +04:00
|
|
|
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)))
|
2005-10-27 00:23:56 +04:00
|
|
|
return;
|
1998-09-04 02:21:32 +04:00
|
|
|
|
2011-03-18 06:14:31 +03:00
|
|
|
nsCSSValue* backColor = aData->ValueForBackgroundColor();
|
|
|
|
if (backColor->GetUnit() == eCSSUnit_Null &&
|
2007-11-16 06:46:42 +03:00
|
|
|
aData->mPresContext->UseDocumentColors()) {
|
2006-12-26 20:47:52 +03:00
|
|
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bgcolor);
|
2004-02-11 03:09:59 +03:00
|
|
|
nscolor color;
|
2004-04-13 20:45:59 +04:00
|
|
|
if (value && value->GetColorValue(color)) {
|
2011-03-18 06:14:31 +03:00
|
|
|
backColor->SetColorValue(color);
|
2004-02-11 03:09:59 +03:00
|
|
|
}
|
1998-09-04 02:21:32 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-10-27 00:23:56 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLElement::MapBackgroundAttributesInto(const nsMappedAttributes* aAttributes,
|
|
|
|
nsRuleData* aData)
|
|
|
|
{
|
|
|
|
MapBackgroundInto(aAttributes, aData);
|
|
|
|
MapBGColorInto(aAttributes, aData);
|
|
|
|
}
|
|
|
|
|
1998-08-29 03:27:19 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2004-06-01 02:26:41 +04:00
|
|
|
nsresult
|
|
|
|
nsGenericHTMLElement::SetAttrHelper(nsIAtom* aAttr, const nsAString& aValue)
|
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return SetAttr(kNameSpaceID_None, aAttr, aValue, true);
|
2004-06-01 02:26:41 +04:00
|
|
|
}
|
|
|
|
|
2012-10-02 12:24:12 +04:00
|
|
|
int32_t
|
|
|
|
nsGenericHTMLElement::GetIntAttr(nsIAtom* aAttr, int32_t aDefault) const
|
2004-02-25 02:55:18 +03:00
|
|
|
{
|
|
|
|
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(aAttr);
|
2004-03-04 05:06:28 +03:00
|
|
|
if (attrVal && attrVal->Type() == nsAttrValue::eInteger) {
|
2012-10-02 12:24:12 +04:00
|
|
|
return attrVal->GetIntegerValue();
|
2004-02-25 02:55:18 +03:00
|
|
|
}
|
2012-10-02 12:24:12 +04:00
|
|
|
return aDefault;
|
2004-02-25 02:55:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLElement::SetIntAttr(nsIAtom* aAttr, int32_t aValue)
|
2004-02-25 02:55:18 +03:00
|
|
|
{
|
|
|
|
nsAutoString value;
|
|
|
|
value.AppendInt(aValue);
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return SetAttr(kNameSpaceID_None, aAttr, value, true);
|
2004-02-25 02:55:18 +03:00
|
|
|
}
|
|
|
|
|
2013-04-04 11:03:50 +04:00
|
|
|
uint32_t
|
|
|
|
nsGenericHTMLElement::GetUnsignedIntAttr(nsIAtom* aAttr,
|
|
|
|
uint32_t aDefault) const
|
2010-11-06 12:30:27 +03:00
|
|
|
{
|
|
|
|
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(aAttr);
|
2013-04-04 11:03:50 +04:00
|
|
|
if (!attrVal || attrVal->Type() != nsAttrValue::eInteger) {
|
|
|
|
return aDefault;
|
2010-11-06 12:30:27 +03:00
|
|
|
}
|
|
|
|
|
2013-04-04 11:03:50 +04:00
|
|
|
return attrVal->GetIntegerValue();
|
2010-11-06 12:30:27 +03:00
|
|
|
}
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLElement::GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr,
|
|
|
|
nsAString& aResult) const
|
2004-02-25 02:55:18 +03:00
|
|
|
{
|
2009-03-10 16:51:34 +03:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool hadAttr = GetURIAttr(aAttr, aBaseAttr, getter_AddRefs(uri));
|
2010-10-29 01:48:48 +04:00
|
|
|
if (!hadAttr) {
|
2010-10-29 00:49:14 +04:00
|
|
|
aResult.Truncate();
|
2012-11-11 03:30:15 +04:00
|
|
|
return;
|
2004-02-25 02:55:18 +03:00
|
|
|
}
|
|
|
|
|
2010-10-29 01:48:48 +04:00
|
|
|
if (!uri) {
|
|
|
|
// Just return the attr value
|
|
|
|
GetAttr(kNameSpaceID_None, aAttr, aResult);
|
2012-11-11 03:30:15 +04:00
|
|
|
return;
|
2010-10-29 01:48:48 +04:00
|
|
|
}
|
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString spec;
|
2009-03-10 16:51:34 +03:00
|
|
|
uri->GetSpec(spec);
|
|
|
|
CopyUTF8toUTF16(spec, aResult);
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2011-05-17 17:54:09 +04:00
|
|
|
nsGenericHTMLElement::GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsIURI** aURI) const
|
2009-03-10 16:51:34 +03:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
*aURI = nullptr;
|
2009-03-10 16:51:34 +03:00
|
|
|
|
|
|
|
const nsAttrValue* attr = mAttrsAndChildren.GetAttr(aAttr);
|
|
|
|
if (!attr) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2009-03-10 16:51:34 +03:00
|
|
|
}
|
|
|
|
|
2004-02-25 02:55:18 +03:00
|
|
|
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
2006-07-21 03:42:51 +04:00
|
|
|
|
|
|
|
if (aBaseAttr) {
|
|
|
|
nsAutoString baseAttrValue;
|
|
|
|
if (GetAttr(kNameSpaceID_None, aBaseAttr, baseAttrValue)) {
|
|
|
|
nsCOMPtr<nsIURI> baseAttrURI;
|
2009-03-10 16:51:34 +03:00
|
|
|
nsresult rv =
|
|
|
|
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(baseAttrURI),
|
2011-10-18 14:53:36 +04:00
|
|
|
baseAttrValue, OwnerDoc(),
|
2009-03-10 16:51:34 +03:00
|
|
|
baseURI);
|
2006-07-21 03:42:51 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2006-07-21 03:42:51 +04:00
|
|
|
}
|
|
|
|
baseURI.swap(baseAttrURI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-10 16:51:34 +03:00
|
|
|
// Don't care about return value. If it fails, we still want to
|
2011-10-17 18:59:28 +04:00
|
|
|
// return true, and *aURI will be null.
|
2009-03-10 16:51:34 +03:00
|
|
|
nsContentUtils::NewURIWithDocumentCharset(aURI,
|
2009-11-09 21:00:54 +03:00
|
|
|
attr->GetStringValue(),
|
2011-10-18 14:53:36 +04:00
|
|
|
OwnerDoc(), baseURI);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2004-02-25 02:55:18 +03:00
|
|
|
}
|
|
|
|
|
2013-11-21 00:23:43 +04:00
|
|
|
/* static */ bool
|
|
|
|
nsGenericHTMLElement::IsScrollGrabAllowed(JSContext*, JSObject*)
|
|
|
|
{
|
|
|
|
// Only allow scroll grabbing in chrome and certified apps.
|
2014-05-13 13:58:00 +04:00
|
|
|
nsIPrincipal* prin = nsContentUtils::SubjectPrincipal();
|
2013-11-21 00:23:43 +04:00
|
|
|
return nsContentUtils::IsSystemPrincipal(prin) ||
|
|
|
|
prin->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED;
|
|
|
|
}
|
|
|
|
|
2006-01-24 08:48:32 +03:00
|
|
|
nsresult
|
|
|
|
nsGenericHTMLElement::GetURIListAttr(nsIAtom* aAttr, nsAString& aResult)
|
|
|
|
{
|
|
|
|
aResult.Truncate();
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
if (!GetAttr(kNameSpaceID_None, aAttr, value))
|
|
|
|
return NS_OK;
|
|
|
|
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument* doc = OwnerDoc();
|
2006-01-24 08:48:32 +03:00
|
|
|
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
|
|
|
|
2015-06-17 17:02:18 +03:00
|
|
|
nsString::const_iterator end;
|
|
|
|
value.EndReading(end);
|
|
|
|
|
|
|
|
nsAString::const_iterator iter;
|
|
|
|
value.BeginReading(iter);
|
|
|
|
|
|
|
|
while (iter != end) {
|
2015-06-17 19:00:37 +03:00
|
|
|
while (*iter == ' ' && iter != end) {
|
2015-06-17 17:02:18 +03:00
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iter == end) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAString::const_iterator start = iter;
|
|
|
|
|
2015-06-17 19:00:37 +03:00
|
|
|
while (iter != end && *iter != ' ') {
|
2015-06-17 16:59:45 +03:00
|
|
|
++iter;
|
2015-06-17 14:43:53 +03:00
|
|
|
}
|
2015-06-17 17:02:18 +03:00
|
|
|
|
|
|
|
if (!aResult.IsEmpty()) {
|
|
|
|
aResult.Append(NS_LITERAL_STRING(" "));
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsSubstring& uriPart = Substring(start, iter);
|
|
|
|
nsCOMPtr<nsIURI> attrURI;
|
|
|
|
nsresult rv =
|
|
|
|
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(attrURI),
|
|
|
|
uriPart, doc, baseURI);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aResult.Append(uriPart);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(attrURI);
|
|
|
|
|
|
|
|
nsAutoCString spec;
|
|
|
|
rv = attrURI->GetSpec(spec);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
aResult.Append(uriPart);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
AppendUTF8toUTF16(spec, aResult);
|
2006-01-24 08:48:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-02-18 15:59:08 +04:00
|
|
|
HTMLMenuElement*
|
2012-11-11 03:30:15 +04:00
|
|
|
nsGenericHTMLElement::GetContextMenu() const
|
2007-06-28 06:48:16 +04:00
|
|
|
{
|
2012-11-11 03:30:15 +04:00
|
|
|
nsAutoString value;
|
|
|
|
GetHTMLAttr(nsGkAtoms::contextmenu, value);
|
|
|
|
if (!value.IsEmpty()) {
|
2014-10-02 23:07:24 +04:00
|
|
|
//XXXsmaug How should this work in Shadow DOM?
|
|
|
|
nsIDocument* doc = GetUncomposedDoc();
|
2012-11-11 03:30:15 +04:00
|
|
|
if (doc) {
|
2013-02-18 15:59:08 +04:00
|
|
|
return HTMLMenuElement::FromContentOrNull(doc->GetElementById(value));
|
2010-03-10 22:10:09 +03:00
|
|
|
}
|
|
|
|
}
|
2012-11-11 03:30:15 +04:00
|
|
|
return nullptr;
|
2010-03-10 22:10:09 +03:00
|
|
|
}
|
|
|
|
|
2013-08-08 00:23:08 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsGenericHTMLElement::GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu)
|
2011-08-08 21:31:32 +04:00
|
|
|
{
|
2012-11-11 03:30:15 +04:00
|
|
|
NS_IF_ADDREF(*aContextMenu = GetContextMenu());
|
2013-08-08 00:23:08 +04:00
|
|
|
return NS_OK;
|
2011-08-08 21:31:32 +04:00
|
|
|
}
|
|
|
|
|
2012-06-07 22:41:59 +04:00
|
|
|
bool
|
|
|
|
nsGenericHTMLElement::IsLabelable() const
|
|
|
|
{
|
2015-03-03 14:09:00 +03:00
|
|
|
return IsAnyOfHTMLElements(nsGkAtoms::progress, nsGkAtoms::meter);
|
2012-06-07 22:41:59 +04:00
|
|
|
}
|
|
|
|
|
2015-01-20 23:39:28 +03:00
|
|
|
bool
|
2015-03-17 23:42:14 +03:00
|
|
|
nsGenericHTMLElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
2015-01-20 23:39:28 +03:00
|
|
|
{
|
2015-03-03 14:09:00 +03:00
|
|
|
return IsAnyOfHTMLElements(nsGkAtoms::details, nsGkAtoms::embed,
|
|
|
|
nsGkAtoms::keygen) ||
|
2015-03-17 23:42:14 +03:00
|
|
|
(!aIgnoreTabindex && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex));
|
2015-01-20 23:39:28 +03:00
|
|
|
}
|
|
|
|
|
2013-01-04 10:54:26 +04:00
|
|
|
already_AddRefed<UndoManager>
|
|
|
|
nsGenericHTMLElement::GetUndoManager()
|
|
|
|
{
|
|
|
|
nsDOMSlots* slots = GetExistingDOMSlots();
|
|
|
|
if (slots && slots->mUndoManager) {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<UndoManager> undoManager = slots->mUndoManager;
|
2013-01-04 10:54:26 +04:00
|
|
|
return undoManager.forget();
|
|
|
|
} else {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
nsGenericHTMLElement::UndoScope()
|
|
|
|
{
|
|
|
|
nsDOMSlots* slots = GetExistingDOMSlots();
|
|
|
|
return slots && slots->mUndoManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLElement::SetUndoScope(bool aUndoScope, mozilla::ErrorResult& aError)
|
|
|
|
{
|
|
|
|
nsresult rv = SetUndoScopeInternal(aUndoScope);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aError.Throw(rv);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The undoScope property must reflect the undoscope boolean attribute.
|
|
|
|
if (aUndoScope) {
|
|
|
|
rv = SetAttr(kNameSpaceID_None, nsGkAtoms::undoscope,
|
|
|
|
NS_LITERAL_STRING(""), true);
|
|
|
|
} else {
|
|
|
|
rv = UnsetAttr(kNameSpaceID_None, nsGkAtoms::undoscope, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aError.Throw(rv);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericHTMLElement::SetUndoScopeInternal(bool aUndoScope)
|
|
|
|
{
|
|
|
|
if (aUndoScope) {
|
|
|
|
nsDOMSlots* slots = DOMSlots();
|
|
|
|
if (!slots->mUndoManager) {
|
|
|
|
slots->mUndoManager = new UndoManager(this);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nsDOMSlots* slots = GetExistingDOMSlots();
|
|
|
|
if (slots && slots->mUndoManager) {
|
|
|
|
// Clear transaction history and disconnect.
|
|
|
|
ErrorResult rv;
|
|
|
|
slots->mUndoManager->ClearRedo(rv);
|
|
|
|
if (rv.Failed()) {
|
2015-04-27 16:18:51 +03:00
|
|
|
return rv.StealNSResult();
|
2013-01-04 10:54:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
slots->mUndoManager->ClearUndo(rv);
|
|
|
|
if (rv.Failed()) {
|
2015-04-27 16:18:51 +03:00
|
|
|
return rv.StealNSResult();
|
2013-01-04 10:54:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
slots->mUndoManager->Disconnect();
|
|
|
|
slots->mUndoManager = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-11-19 14:59:13 +04:00
|
|
|
// static
|
|
|
|
bool
|
2013-02-19 20:54:41 +04:00
|
|
|
nsGenericHTMLElement::TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */)
|
|
|
|
{
|
2014-02-28 18:58:42 +04:00
|
|
|
return TouchEvent::PrefEnabled();
|
2012-11-19 14:59:13 +04:00
|
|
|
}
|
|
|
|
|
2000-04-19 11:49:07 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2014-06-20 06:01:40 +04:00
|
|
|
nsGenericHTMLFormElement::nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
2010-09-19 01:33:16 +04:00
|
|
|
: nsGenericHTMLElement(aNodeInfo)
|
2012-07-30 18:20:58 +04:00
|
|
|
, mForm(nullptr)
|
|
|
|
, mFieldSet(nullptr)
|
2000-04-19 11:49:07 +04:00
|
|
|
{
|
2011-06-01 05:46:57 +04:00
|
|
|
// We should add the NS_EVENT_STATE_ENABLED bit here as needed, but
|
|
|
|
// that depends on our type, which is not initialized yet. So we
|
|
|
|
// have to do this in subclasses.
|
2000-04-19 11:49:07 +04:00
|
|
|
}
|
|
|
|
|
2004-02-10 22:36:43 +03:00
|
|
|
nsGenericHTMLFormElement::~nsGenericHTMLFormElement()
|
2000-04-19 11:49:07 +04:00
|
|
|
{
|
2010-11-05 20:15:05 +03:00
|
|
|
if (mFieldSet) {
|
2011-09-18 13:22:18 +04:00
|
|
|
mFieldSet->RemoveElement(this);
|
2010-11-05 20:15:05 +03:00
|
|
|
}
|
|
|
|
|
2009-10-01 02:56:50 +04:00
|
|
|
// Check that this element doesn't know anything about its form at this point.
|
2010-09-19 01:33:16 +04:00
|
|
|
NS_ASSERTION(!mForm, "mForm should be null at this point!");
|
2000-04-19 11:49:07 +04:00
|
|
|
}
|
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED(nsGenericHTMLFormElement,
|
|
|
|
nsGenericHTMLElement,
|
|
|
|
nsIFormControl)
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2014-10-31 00:38:48 +03:00
|
|
|
nsINode*
|
|
|
|
nsGenericHTMLFormElement::GetScopeChainParent() const
|
|
|
|
{
|
|
|
|
return mForm ? mForm : nsGenericHTMLElement::GetScopeChainParent();
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLFormElement::IsNodeOfType(uint32_t aFlags) const
|
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 20:46:42 +04:00
|
|
|
{
|
2010-04-30 17:12:06 +04:00
|
|
|
return !(aFlags & ~(eCONTENT | eHTML_FORM_CONTROL));
|
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 20:46:42 +04:00
|
|
|
}
|
|
|
|
|
2007-11-30 20:57:03 +03:00
|
|
|
void
|
2008-04-11 02:47:01 +04:00
|
|
|
nsGenericHTMLFormElement::SaveSubtreeState()
|
2007-11-30 20:57:03 +03:00
|
|
|
{
|
|
|
|
SaveState();
|
2008-04-11 02:47:01 +04:00
|
|
|
|
|
|
|
nsGenericHTMLElement::SaveSubtreeState();
|
2007-11-30 20:57:03 +03:00
|
|
|
}
|
|
|
|
|
2008-09-11 07:21:33 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLFormElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
2000-12-23 13:56:31 +03:00
|
|
|
{
|
2008-09-11 07:21:33 +04:00
|
|
|
NS_PRECONDITION(aForm, "Don't pass null here");
|
|
|
|
NS_ASSERTION(!mForm,
|
2008-09-08 17:19:49 +04:00
|
|
|
"We don't support switching from one non-null form to another.");
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2008-09-11 07:21:33 +04:00
|
|
|
// keep a *weak* ref to the form here
|
2013-06-19 18:24:37 +04:00
|
|
|
mForm = static_cast<HTMLFormElement*>(aForm);
|
2008-09-11 07:21:33 +04:00
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2008-09-11 07:21:33 +04:00
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLFormElement::ClearForm(bool aRemoveFromForm)
|
2008-09-11 07:21:33 +04:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
NS_ASSERTION((mForm != nullptr) == HasFlag(ADDED_TO_FORM),
|
2008-09-11 07:21:33 +04:00
|
|
|
"Form control should have had flag set correctly");
|
2001-03-22 11:51:52 +03:00
|
|
|
|
2008-09-11 07:21:33 +04:00
|
|
|
if (!mForm) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aRemoveFromForm) {
|
|
|
|
nsAutoString nameVal, idVal;
|
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::name, nameVal);
|
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::id, idVal);
|
2001-11-28 14:00:14 +03:00
|
|
|
|
2010-11-11 15:36:42 +03:00
|
|
|
mForm->RemoveElement(this, true);
|
2008-09-11 07:21:33 +04:00
|
|
|
|
|
|
|
if (!nameVal.IsEmpty()) {
|
2013-06-18 16:54:27 +04:00
|
|
|
mForm->RemoveElementFromTable(this, nameVal,
|
2013-06-19 18:24:37 +04:00
|
|
|
HTMLFormElement::ElementRemoved);
|
2001-03-22 11:51:52 +03:00
|
|
|
}
|
2007-07-26 08:26:07 +04:00
|
|
|
|
2008-09-11 07:21:33 +04:00
|
|
|
if (!idVal.IsEmpty()) {
|
2013-06-18 16:54:27 +04:00
|
|
|
mForm->RemoveElementFromTable(this, idVal,
|
2013-06-19 18:24:37 +04:00
|
|
|
HTMLFormElement::ElementRemoved);
|
2008-09-11 07:21:33 +04:00
|
|
|
}
|
2002-05-09 04:29:23 +04:00
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2008-09-11 07:21:33 +04:00
|
|
|
UnsetFlags(ADDED_TO_FORM);
|
2012-07-30 18:20:58 +04:00
|
|
|
mForm = nullptr;
|
2000-12-23 13:56:31 +03:00
|
|
|
}
|
|
|
|
|
2010-05-09 22:32:57 +04:00
|
|
|
Element*
|
|
|
|
nsGenericHTMLFormElement::GetFormElement()
|
|
|
|
{
|
|
|
|
return mForm;
|
|
|
|
}
|
|
|
|
|
2013-08-17 04:32:47 +04:00
|
|
|
HTMLFieldSetElement*
|
|
|
|
nsGenericHTMLFormElement::GetFieldSet()
|
|
|
|
{
|
|
|
|
return mFieldSet;
|
|
|
|
}
|
|
|
|
|
2010-05-09 22:32:57 +04:00
|
|
|
nsresult
|
2004-02-10 22:36:43 +03:00
|
|
|
nsGenericHTMLFormElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
2000-12-23 13:56:31 +03:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aForm);
|
2009-10-30 04:49:11 +03:00
|
|
|
NS_IF_ADDREF(*aForm = mForm);
|
2000-12-23 13:56:31 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-11-27 15:51:53 +04:00
|
|
|
nsIContent::IMEState
|
2005-11-15 02:55:24 +03:00
|
|
|
nsGenericHTMLFormElement::GetDesiredIMEState()
|
|
|
|
{
|
2012-12-24 06:38:41 +04:00
|
|
|
nsIEditor* editor = GetEditorInternal();
|
|
|
|
if (!editor)
|
2005-11-18 08:22:04 +03:00
|
|
|
return nsGenericHTMLElement::GetDesiredIMEState();
|
2005-11-15 02:55:24 +03:00
|
|
|
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
|
|
|
|
if (!imeEditor)
|
2005-11-18 08:22:04 +03:00
|
|
|
return nsGenericHTMLElement::GetDesiredIMEState();
|
2011-11-27 15:51:53 +04:00
|
|
|
IMEState state;
|
2012-12-24 06:38:41 +04:00
|
|
|
nsresult rv = imeEditor->GetPreferredIMEState(&state);
|
2005-11-15 02:55:24 +03:00
|
|
|
if (NS_FAILED(rv))
|
2005-11-18 08:22:04 +03:00
|
|
|
return nsGenericHTMLElement::GetDesiredIMEState();
|
2005-11-15 02:55:24 +03:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2005-04-06 03:54:35 +04:00
|
|
|
nsresult
|
|
|
|
nsGenericHTMLFormElement::BindToTree(nsIDocument* aDocument,
|
|
|
|
nsIContent* aParent,
|
|
|
|
nsIContent* aBindingParent,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aCompileEventHandlers)
|
2005-04-06 03:54:35 +04:00
|
|
|
{
|
|
|
|
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
|
|
|
aBindingParent,
|
|
|
|
aCompileEventHandlers);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2010-05-19 21:52:17 +04:00
|
|
|
|
|
|
|
// An autofocus event has to be launched if the autofocus attribute is
|
|
|
|
// specified and the element accept the autofocus attribute. In addition,
|
|
|
|
// the document should not be already loaded and the "browser.autofocus"
|
|
|
|
// preference should be 'true'.
|
2011-03-24 18:10:42 +03:00
|
|
|
if (IsAutofocusable() && HasAttr(kNameSpaceID_None, nsGkAtoms::autofocus) &&
|
2011-09-29 10:19:26 +04:00
|
|
|
Preferences::GetBool("browser.autofocus", true)) {
|
2010-05-19 21:52:17 +04:00
|
|
|
nsCOMPtr<nsIRunnable> event = new nsAutoFocusEvent(this);
|
|
|
|
rv = NS_DispatchToCurrentThread(event);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2010-08-26 00:45:43 +04:00
|
|
|
// If @form is set, the element *has* to be in a document, otherwise it
|
|
|
|
// wouldn't be possible to find an element with the corresponding id.
|
|
|
|
// If @form isn't set, the element *has* to have a parent, otherwise it
|
|
|
|
// wouldn't be possible to find a form ancestor.
|
2010-08-26 02:45:35 +04:00
|
|
|
// We should not call UpdateFormOwner if none of these conditions are
|
2010-08-26 00:45:43 +04:00
|
|
|
// fulfilled.
|
2014-10-02 23:07:24 +04:00
|
|
|
if (HasAttr(kNameSpaceID_None, nsGkAtoms::form) ? !!GetUncomposedDoc()
|
2010-08-26 00:45:43 +04:00
|
|
|
: !!aParent) {
|
2012-07-30 18:20:58 +04:00
|
|
|
UpdateFormOwner(true, nullptr);
|
2007-07-26 08:26:07 +04:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:33:16 +04:00
|
|
|
// Set parent fieldset which should be used for the disabled state.
|
2011-10-17 18:59:28 +04:00
|
|
|
UpdateFieldSet(false);
|
2010-09-19 01:33:16 +04:00
|
|
|
|
2007-07-26 08:26:07 +04:00
|
|
|
return NS_OK;
|
2000-04-19 11:49:07 +04:00
|
|
|
}
|
|
|
|
|
2004-01-10 02:54:21 +03:00
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLFormElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
2000-04-19 11:49:07 +04:00
|
|
|
{
|
2005-05-13 00:53:33 +04:00
|
|
|
// Save state before doing anything
|
|
|
|
SaveState();
|
2010-06-04 05:09:20 +04:00
|
|
|
|
2005-04-06 03:54:35 +04:00
|
|
|
if (mForm) {
|
|
|
|
// Might need to unset mForm
|
|
|
|
if (aNullParent) {
|
|
|
|
// No more parent means no more form
|
2011-10-17 18:59:28 +04:00
|
|
|
ClearForm(true);
|
2005-04-06 03:54:35 +04:00
|
|
|
} else {
|
|
|
|
// Recheck whether we should still have an mForm.
|
2010-08-24 05:11:04 +04:00
|
|
|
if (HasAttr(kNameSpaceID_None, nsGkAtoms::form) ||
|
|
|
|
!FindAncestorForm(mForm)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
ClearForm(true);
|
2007-11-07 20:01:23 +03:00
|
|
|
} else {
|
|
|
|
UnsetFlags(MAYBE_ORPHAN_FORM_ELEMENT);
|
2005-04-06 03:54:35 +04:00
|
|
|
}
|
2001-11-29 17:12:06 +03:00
|
|
|
}
|
2011-06-01 05:46:57 +04:00
|
|
|
|
|
|
|
if (!mForm) {
|
|
|
|
// Our novalidate state might have changed
|
|
|
|
UpdateState(false);
|
|
|
|
}
|
2000-05-17 06:03:10 +04:00
|
|
|
}
|
2000-04-19 11:49:07 +04:00
|
|
|
|
2010-08-24 05:11:04 +04:00
|
|
|
// We have to remove the form id observer if there was one.
|
|
|
|
// We will re-add one later if needed (during bind to tree).
|
|
|
|
if (nsContentUtils::HasNonEmptyAttr(this, kNameSpaceID_None,
|
|
|
|
nsGkAtoms::form)) {
|
|
|
|
RemoveFormIdObserver();
|
|
|
|
}
|
|
|
|
|
2005-04-06 03:54:35 +04:00
|
|
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
2010-09-19 01:33:16 +04:00
|
|
|
|
|
|
|
// The element might not have a fieldset anymore.
|
2011-10-17 18:59:28 +04:00
|
|
|
UpdateFieldSet(false);
|
2000-04-19 11:49:07 +04:00
|
|
|
}
|
|
|
|
|
2001-03-22 11:51:52 +03:00
|
|
|
nsresult
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLFormElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
2015-08-01 08:14:06 +03:00
|
|
|
nsAttrValueOrString* aValue,
|
2012-02-14 06:00:56 +04:00
|
|
|
bool aNotify)
|
2000-05-12 17:46:59 +04:00
|
|
|
{
|
2005-10-28 06:59:38 +04:00
|
|
|
if (aNameSpaceID == kNameSpaceID_None) {
|
2005-08-30 07:31:47 +04:00
|
|
|
nsAutoString tmp;
|
2001-03-22 11:51:52 +03:00
|
|
|
|
2005-10-28 06:59:38 +04:00
|
|
|
// remove the control from the hashtable as needed
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
if (mForm && (aName == nsGkAtoms::name || aName == nsGkAtoms::id)) {
|
2005-08-30 07:31:47 +04:00
|
|
|
GetAttr(kNameSpaceID_None, aName, tmp);
|
2001-03-22 11:51:52 +03:00
|
|
|
|
2005-08-30 07:31:47 +04:00
|
|
|
if (!tmp.IsEmpty()) {
|
2013-06-18 16:54:27 +04:00
|
|
|
mForm->RemoveElementFromTable(this, tmp,
|
2013-06-19 18:24:37 +04:00
|
|
|
HTMLFormElement::AttributeUpdated);
|
2005-08-30 07:31:47 +04:00
|
|
|
}
|
2001-03-22 11:51:52 +03:00
|
|
|
}
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
if (mForm && aName == nsGkAtoms::type) {
|
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::name, tmp);
|
2005-08-30 07:31:47 +04:00
|
|
|
|
|
|
|
if (!tmp.IsEmpty()) {
|
2013-06-18 16:54:27 +04:00
|
|
|
mForm->RemoveElementFromTable(this, tmp,
|
2013-06-19 18:24:37 +04:00
|
|
|
HTMLFormElement::AttributeUpdated);
|
2005-08-30 07:31:47 +04:00
|
|
|
}
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::id, tmp);
|
2001-03-22 11:51:52 +03:00
|
|
|
|
2005-08-30 07:31:47 +04:00
|
|
|
if (!tmp.IsEmpty()) {
|
2013-06-18 16:54:27 +04:00
|
|
|
mForm->RemoveElementFromTable(this, tmp,
|
2013-06-19 18:24:37 +04:00
|
|
|
HTMLFormElement::AttributeUpdated);
|
2005-08-30 07:31:47 +04:00
|
|
|
}
|
|
|
|
|
2010-11-11 15:36:42 +03:00
|
|
|
mForm->RemoveElement(this, false);
|
2007-07-13 00:05:45 +04:00
|
|
|
|
|
|
|
// Removing the element from the form can make it not be the default
|
|
|
|
// control anymore. Go ahead and notify on that change, though we might
|
|
|
|
// end up readding and becoming the default control again in
|
|
|
|
// AfterSetAttr.
|
2011-06-01 05:46:57 +04:00
|
|
|
// FIXME: Bug 656197
|
|
|
|
UpdateState(aNotify);
|
2001-03-22 11:51:52 +03:00
|
|
|
}
|
2010-08-24 05:11:04 +04:00
|
|
|
|
|
|
|
if (aName == nsGkAtoms::form) {
|
|
|
|
// If @form isn't set or set to the empty string, there were no observer
|
|
|
|
// so we don't have to remove it.
|
|
|
|
if (nsContentUtils::HasNonEmptyAttr(this, kNameSpaceID_None,
|
|
|
|
nsGkAtoms::form)) {
|
|
|
|
// The current form id observer is no longer needed.
|
|
|
|
// A new one may be added in AfterSetAttr.
|
|
|
|
RemoveFormIdObserver();
|
|
|
|
}
|
|
|
|
}
|
2005-10-28 06:59:38 +04:00
|
|
|
}
|
2000-05-12 17:46:59 +04:00
|
|
|
|
2005-10-28 06:59:38 +04:00
|
|
|
return nsGenericHTMLElement::BeforeSetAttr(aNameSpaceID, aName,
|
|
|
|
aValue, aNotify);
|
|
|
|
}
|
2005-08-30 07:31:47 +04:00
|
|
|
|
2005-10-28 06:59:38 +04:00
|
|
|
nsresult
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLFormElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
2012-02-14 06:00:56 +04:00
|
|
|
const nsAttrValue* aValue, bool aNotify)
|
2005-10-28 06:59:38 +04:00
|
|
|
{
|
|
|
|
if (aNameSpaceID == kNameSpaceID_None) {
|
|
|
|
// add the control to the hashtable as needed
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
if (mForm && (aName == nsGkAtoms::name || aName == nsGkAtoms::id) &&
|
2012-02-14 06:00:56 +04:00
|
|
|
aValue && !aValue->IsEmptyString()) {
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(aValue->Type() == nsAttrValue::eAtom,
|
|
|
|
"Expected atom value for name/id");
|
2012-02-14 06:00:56 +04:00
|
|
|
mForm->AddElementToTable(this,
|
|
|
|
nsDependentAtomString(aValue->GetAtomValue()));
|
2000-12-23 13:56:31 +03:00
|
|
|
}
|
2000-05-12 17:46:59 +04:00
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
if (mForm && aName == nsGkAtoms::type) {
|
2005-10-28 06:59:38 +04:00
|
|
|
nsAutoString tmp;
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::name, tmp);
|
2000-05-12 17:46:59 +04:00
|
|
|
|
2005-08-30 07:31:47 +04:00
|
|
|
if (!tmp.IsEmpty()) {
|
2006-05-19 14:01:22 +04:00
|
|
|
mForm->AddElementToTable(this, tmp);
|
2005-08-30 07:31:47 +04:00
|
|
|
}
|
2001-03-22 11:51:52 +03:00
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::id, tmp);
|
2001-03-22 11:51:52 +03:00
|
|
|
|
2005-08-30 07:31:47 +04:00
|
|
|
if (!tmp.IsEmpty()) {
|
2006-05-19 14:01:22 +04:00
|
|
|
mForm->AddElementToTable(this, tmp);
|
2005-08-30 07:31:47 +04:00
|
|
|
}
|
|
|
|
|
2010-10-08 17:42:09 +04:00
|
|
|
mForm->AddElement(this, false, aNotify);
|
2007-02-09 09:20:47 +03:00
|
|
|
|
2007-07-13 00:05:45 +04:00
|
|
|
// Adding the element to the form can make it be the default control .
|
|
|
|
// Go ahead and notify on that change.
|
2007-02-09 09:20:47 +03:00
|
|
|
// Note: no need to notify on CanBeDisabled(), since type attr
|
|
|
|
// changes can't affect that.
|
2011-06-01 05:46:57 +04:00
|
|
|
UpdateState(aNotify);
|
2001-03-22 11:51:52 +03:00
|
|
|
}
|
2010-08-24 05:11:04 +04:00
|
|
|
|
|
|
|
if (aName == nsGkAtoms::form) {
|
|
|
|
// We need a new form id observer.
|
2014-10-02 23:07:24 +04:00
|
|
|
//XXXsmaug How should this work in Shadow DOM?
|
|
|
|
nsIDocument* doc = GetUncomposedDoc();
|
2010-08-24 05:11:04 +04:00
|
|
|
if (doc) {
|
2012-07-30 18:20:58 +04:00
|
|
|
Element* formIdElement = nullptr;
|
2012-02-14 06:00:56 +04:00
|
|
|
if (aValue && !aValue->IsEmptyString()) {
|
2010-08-24 05:11:04 +04:00
|
|
|
formIdElement = AddFormIdObserver();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Because we have a new @form value (or no more @form), we have to
|
|
|
|
// update our form owner.
|
|
|
|
UpdateFormOwner(false, formIdElement);
|
|
|
|
}
|
|
|
|
}
|
2005-10-28 06:59:38 +04:00
|
|
|
}
|
2001-03-22 11:51:52 +03:00
|
|
|
|
2005-10-28 06:59:38 +04:00
|
|
|
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
|
|
|
|
aValue, aNotify);
|
2005-08-30 07:31:47 +04:00
|
|
|
}
|
2001-03-22 11:51:52 +03: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 22:00:39 +04:00
|
|
|
nsresult
|
2014-03-18 08:48:19 +04:00
|
|
|
nsGenericHTMLFormElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
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 22:00:39 +04:00
|
|
|
{
|
2016-03-17 10:01:30 +03:00
|
|
|
if (aVisitor.mEvent->IsTrusted()) {
|
2015-08-22 04:34:51 +03:00
|
|
|
switch (aVisitor.mEvent->mMessage) {
|
2015-09-02 09:08:00 +03:00
|
|
|
case eFocus: {
|
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 22:00:39 +04:00
|
|
|
// Check to see if focus has bubbled up from a form control's
|
|
|
|
// child textfield or button. If that's the case, don't focus
|
|
|
|
// this parent file control -- leave focus on the child.
|
2011-10-17 18:59:28 +04:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(true);
|
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 22:00:39 +04:00
|
|
|
if (formControlFrame &&
|
|
|
|
aVisitor.mEvent->originalTarget == static_cast<nsINode*>(this))
|
2011-10-17 18:59:28 +04:00
|
|
|
formControlFrame->SetFocus(true, true);
|
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 22:00:39 +04:00
|
|
|
break;
|
|
|
|
}
|
2015-09-02 09:08:00 +03:00
|
|
|
case eBlur: {
|
2011-10-17 18:59:28 +04:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(true);
|
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 22:00:39 +04:00
|
|
|
if (formControlFrame)
|
2011-10-17 18:59:28 +04:00
|
|
|
formControlFrame->SetFocus(false, false);
|
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 22:00:39 +04:00
|
|
|
break;
|
|
|
|
}
|
2015-08-26 15:56:59 +03:00
|
|
|
default:
|
|
|
|
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 22:00:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
|
|
|
}
|
|
|
|
|
2011-09-18 13:22:18 +04:00
|
|
|
/* virtual */
|
|
|
|
bool
|
|
|
|
nsGenericHTMLFormElement::IsDisabled() const
|
|
|
|
{
|
|
|
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) ||
|
|
|
|
(mFieldSet && mFieldSet->IsDisabled());
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLFormElement::ForgetFieldSet(nsIContent* aFieldset)
|
|
|
|
{
|
|
|
|
if (mFieldSet == aFieldset) {
|
2012-07-30 18:20:58 +04:00
|
|
|
mFieldSet = nullptr;
|
2011-09-18 13:22:18 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2005-09-01 20:49:36 +04:00
|
|
|
nsGenericHTMLFormElement::CanBeDisabled() const
|
2005-08-30 07:31:47 +04:00
|
|
|
{
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t type = GetType();
|
2005-09-01 20:49:36 +04:00
|
|
|
// It's easier to test the types that _cannot_ be disabled
|
2005-08-30 07:31:47 +04:00
|
|
|
return
|
|
|
|
type != NS_FORM_LABEL &&
|
2010-04-26 11:42:00 +04:00
|
|
|
type != NS_FORM_OBJECT &&
|
2012-06-07 22:42:45 +04:00
|
|
|
type != NS_FORM_OUTPUT;
|
2005-08-30 07:31:47 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
|
|
|
nsGenericHTMLFormElement::IsHTMLFocusable(bool aWithMouse,
|
|
|
|
bool* aIsFocusable,
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t* aTabIndex)
|
2011-01-05 16:23:37 +03:00
|
|
|
{
|
|
|
|
if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-01-05 16:23:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
*aIsFocusable =
|
|
|
|
(!aWithMouse || nsFocusManager::sMouseFocusesFormControl) && *aIsFocusable;
|
|
|
|
#endif
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2011-01-05 16:23:37 +03:00
|
|
|
}
|
|
|
|
|
2014-04-03 08:18:36 +04:00
|
|
|
EventStates
|
2005-08-30 07:31:47 +04:00
|
|
|
nsGenericHTMLFormElement::IntrinsicState() const
|
|
|
|
{
|
2007-02-09 09:20:47 +03:00
|
|
|
// If you add attribute-dependent states here, you need to add them them to
|
|
|
|
// AfterSetAttr too. And add them to AfterSetAttr for all subclasses that
|
|
|
|
// implement IntrinsicState() and are affected by that attribute.
|
2014-04-03 08:18:36 +04:00
|
|
|
EventStates state = nsGenericHTMLElement::IntrinsicState();
|
2005-08-30 07:31:47 +04:00
|
|
|
|
2005-09-01 20:49:36 +04:00
|
|
|
if (CanBeDisabled()) {
|
2005-08-30 07:31:47 +04:00
|
|
|
// :enabled/:disabled
|
2010-09-19 01:33:16 +04:00
|
|
|
if (IsDisabled()) {
|
2005-08-30 07:31:47 +04:00
|
|
|
state |= NS_EVENT_STATE_DISABLED;
|
|
|
|
state &= ~NS_EVENT_STATE_ENABLED;
|
|
|
|
} else {
|
|
|
|
state &= ~NS_EVENT_STATE_DISABLED;
|
|
|
|
state |= NS_EVENT_STATE_ENABLED;
|
|
|
|
}
|
|
|
|
}
|
2006-08-16 07:20:19 +04:00
|
|
|
|
2009-09-18 22:52:27 +04:00
|
|
|
if (mForm && mForm->IsDefaultSubmitElement(this)) {
|
2006-08-16 07:20:19 +04:00
|
|
|
NS_ASSERTION(IsSubmitControl(),
|
|
|
|
"Default submit element that isn't a submit control.");
|
|
|
|
// We are the default submit element (:default)
|
|
|
|
state |= NS_EVENT_STATE_DEFAULT;
|
|
|
|
}
|
2005-08-30 07:31:47 +04:00
|
|
|
|
2010-11-16 23:45:49 +03:00
|
|
|
// Make the text controls read-write
|
|
|
|
if (!state.HasState(NS_EVENT_STATE_MOZ_READWRITE) &&
|
2016-03-03 01:39:34 +03:00
|
|
|
IsTextOrNumberControl(/*aExcludePassword*/ false)) {
|
2012-10-02 12:24:12 +04:00
|
|
|
bool roState = GetBoolAttr(nsGkAtoms::readonly);
|
2010-11-16 23:45:49 +03:00
|
|
|
|
|
|
|
if (!roState) {
|
|
|
|
state |= NS_EVENT_STATE_MOZ_READWRITE;
|
|
|
|
state &= ~NS_EVENT_STATE_MOZ_READONLY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-30 07:31:47 +04:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2008-10-07 22:53:23 +04:00
|
|
|
nsGenericHTMLFormElement::FocusTristate
|
|
|
|
nsGenericHTMLFormElement::FocusState()
|
|
|
|
{
|
2014-08-06 03:23:02 +04:00
|
|
|
// We can't be focused if we aren't in a (composed) document
|
|
|
|
nsIDocument* doc = GetComposedDoc();
|
2008-10-07 22:53:23 +04:00
|
|
|
if (!doc)
|
|
|
|
return eUnfocusable;
|
|
|
|
|
|
|
|
// first see if we are disabled or not. If disabled then do nothing.
|
2010-09-19 01:33:16 +04:00
|
|
|
if (IsDisabled()) {
|
2008-10-07 22:53:23 +04:00
|
|
|
return eUnfocusable;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the window is not active, do not allow the focus to bring the
|
|
|
|
// window to the front. We update the focus controller, but do
|
|
|
|
// nothing else.
|
2016-01-30 20:05:36 +03:00
|
|
|
if (nsPIDOMWindowOuter* win = doc->GetWindow()) {
|
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> rootWindow = win->GetPrivateRoot();
|
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 22:00:39 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
|
|
|
if (fm && rootWindow) {
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<mozIDOMWindowProxy> activeWindow;
|
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 22:00:39 +04:00
|
|
|
fm->GetActiveWindow(getter_AddRefs(activeWindow));
|
|
|
|
if (activeWindow == rootWindow) {
|
|
|
|
return eActiveWindow;
|
2008-10-07 22:53:23 +04: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 22:00:39 +04:00
|
|
|
return eInactiveWindow;
|
2008-10-07 22:53:23 +04:00
|
|
|
}
|
|
|
|
|
2010-08-24 05:11:04 +04:00
|
|
|
Element*
|
|
|
|
nsGenericHTMLFormElement::AddFormIdObserver()
|
|
|
|
{
|
2014-10-02 23:07:24 +04:00
|
|
|
NS_ASSERTION(GetUncomposedDoc(), "When adding a form id observer, "
|
|
|
|
"we should be in a document!");
|
2010-08-24 05:11:04 +04:00
|
|
|
|
|
|
|
nsAutoString formId;
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument* doc = OwnerDoc();
|
2010-08-24 05:11:04 +04:00
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::form, formId);
|
|
|
|
NS_ASSERTION(!formId.IsEmpty(),
|
|
|
|
"@form value should not be the empty string!");
|
2016-03-29 02:09:43 +03:00
|
|
|
nsCOMPtr<nsIAtom> atom = NS_Atomize(formId);
|
2010-08-24 05:11:04 +04:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return doc->AddIDTargetObserver(atom, FormIdUpdated, this, false);
|
2010-08-24 05:11:04 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLFormElement::RemoveFormIdObserver()
|
|
|
|
{
|
|
|
|
/**
|
2011-10-18 14:53:36 +04:00
|
|
|
* We are using OwnerDoc() because we don't really care about having the
|
2010-08-24 05:11:04 +04:00
|
|
|
* element actually being in the tree. If it is not and @form value changes,
|
|
|
|
* this method will be called for nothing but removing an observer which does
|
|
|
|
* not exist doesn't cost so much (no entry in the hash table) so having a
|
2014-10-02 23:07:24 +04:00
|
|
|
* boolean for GetUncomposedDoc()/GetOwnerDoc() would make everything look
|
|
|
|
* more complex for nothing.
|
2010-08-24 05:11:04 +04:00
|
|
|
*/
|
|
|
|
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument* doc = OwnerDoc();
|
2010-08-24 05:11:04 +04:00
|
|
|
|
|
|
|
// At this point, we may not have a document anymore. In that case, we can't
|
|
|
|
// remove the observer. The document did that for us.
|
|
|
|
if (!doc) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString formId;
|
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::form, formId);
|
|
|
|
NS_ASSERTION(!formId.IsEmpty(),
|
|
|
|
"@form value should not be the empty string!");
|
2016-03-29 02:09:43 +03:00
|
|
|
nsCOMPtr<nsIAtom> atom = NS_Atomize(formId);
|
2010-08-24 05:11:04 +04:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
doc->RemoveIDTargetObserver(atom, FormIdUpdated, this, false);
|
2010-08-24 05:11:04 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* static */
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2010-08-24 05:11:04 +04:00
|
|
|
nsGenericHTMLFormElement::FormIdUpdated(Element* aOldElement,
|
|
|
|
Element* aNewElement,
|
|
|
|
void* aData)
|
|
|
|
{
|
|
|
|
nsGenericHTMLFormElement* element =
|
|
|
|
static_cast<nsGenericHTMLFormElement*>(aData);
|
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
NS_ASSERTION(element->IsHTMLElement(), "aData should be an HTML element");
|
2010-08-24 05:11:04 +04:00
|
|
|
|
|
|
|
element->UpdateFormOwner(false, aNewElement);
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2010-08-24 05:11:04 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2015-08-26 15:56:59 +03:00
|
|
|
nsGenericHTMLFormElement::IsElementDisabledForEvents(EventMessage aMessage,
|
|
|
|
nsIFrame* aFrame)
|
2011-07-19 03:16:44 +04:00
|
|
|
{
|
2015-10-16 21:36:19 +03:00
|
|
|
switch (aMessage) {
|
|
|
|
case eMouseMove:
|
|
|
|
case eMouseOver:
|
|
|
|
case eMouseOut:
|
|
|
|
case eMouseEnter:
|
|
|
|
case eMouseLeave:
|
|
|
|
case ePointerMove:
|
|
|
|
case ePointerOver:
|
|
|
|
case ePointerOut:
|
|
|
|
case ePointerEnter:
|
|
|
|
case ePointerLeave:
|
2016-02-27 00:04:34 +03:00
|
|
|
case eWheel:
|
|
|
|
case eLegacyMouseLineOrPageScroll:
|
|
|
|
case eLegacyMousePixelScroll:
|
2015-10-16 21:36:19 +03:00
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool disabled = IsDisabled();
|
2011-08-04 13:02:49 +04:00
|
|
|
if (!disabled && aFrame) {
|
2013-02-17 01:51:02 +04:00
|
|
|
const nsStyleUserInterface* uiStyle = aFrame->StyleUserInterface();
|
2011-08-04 13:02:49 +04:00
|
|
|
disabled = uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
|
|
|
|
uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED;
|
|
|
|
|
|
|
|
}
|
2015-10-16 21:36:19 +03:00
|
|
|
return disabled;
|
2011-08-04 13:02:49 +04:00
|
|
|
}
|
2011-07-19 03:16:44 +04:00
|
|
|
|
2010-08-24 05:11:04 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree,
|
|
|
|
Element* aFormIdElement)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(!aBindToTree || !aFormIdElement,
|
|
|
|
"aFormIdElement shouldn't be set if aBindToTree is true!");
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool needStateUpdate = false;
|
2010-08-24 05:11:04 +04:00
|
|
|
if (!aBindToTree) {
|
2011-06-01 05:46:57 +04:00
|
|
|
needStateUpdate = mForm && mForm->IsDefaultSubmitElement(this);
|
2011-10-17 18:59:28 +04:00
|
|
|
ClearForm(true);
|
2010-08-24 05:11:04 +04:00
|
|
|
}
|
|
|
|
|
2013-06-19 18:24:37 +04:00
|
|
|
HTMLFormElement *oldForm = mForm;
|
2011-06-01 05:46:57 +04:00
|
|
|
|
2010-08-24 05:11:04 +04:00
|
|
|
if (!mForm) {
|
|
|
|
// If @form is set, we have to use that to find the form.
|
|
|
|
nsAutoString formId;
|
|
|
|
if (GetAttr(kNameSpaceID_None, nsGkAtoms::form, formId)) {
|
|
|
|
if (!formId.IsEmpty()) {
|
2012-07-30 18:20:58 +04:00
|
|
|
Element* element = nullptr;
|
2010-08-24 05:11:04 +04:00
|
|
|
|
|
|
|
if (aBindToTree) {
|
|
|
|
element = AddFormIdObserver();
|
|
|
|
} else {
|
|
|
|
element = aFormIdElement;
|
|
|
|
}
|
|
|
|
|
2014-10-02 23:07:24 +04:00
|
|
|
NS_ASSERTION(GetUncomposedDoc(), "The element should be in a document "
|
|
|
|
"when UpdateFormOwner is called!");
|
|
|
|
NS_ASSERTION(!GetUncomposedDoc() ||
|
|
|
|
element == GetUncomposedDoc()->GetElementById(formId),
|
2010-08-24 05:11:04 +04:00
|
|
|
"element should be equals to the current element "
|
|
|
|
"associated with the id in @form!");
|
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
if (element && element->IsHTMLElement(nsGkAtoms::form)) {
|
2013-06-19 18:24:37 +04:00
|
|
|
mForm = static_cast<HTMLFormElement*>(element);
|
2010-08-24 05:11:04 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// We now have a parent, so we may have picked up an ancestor form. Search
|
|
|
|
// for it. Note that if mForm is already set we don't want to do this,
|
|
|
|
// because that means someone (probably the content sink) has already set
|
|
|
|
// it to the right value. Also note that even if being bound here didn't
|
|
|
|
// change our parent, we still need to search, since our parent chain
|
|
|
|
// probably changed _somewhere_.
|
|
|
|
mForm = FindAncestorForm();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mForm && !HasFlag(ADDED_TO_FORM)) {
|
|
|
|
// Now we need to add ourselves to the form
|
|
|
|
nsAutoString nameVal, idVal;
|
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::name, nameVal);
|
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::id, idVal);
|
|
|
|
|
|
|
|
SetFlags(ADDED_TO_FORM);
|
|
|
|
|
|
|
|
// Notify only if we just found this mForm.
|
2012-07-30 18:20:58 +04:00
|
|
|
mForm->AddElement(this, true, oldForm == nullptr);
|
2010-08-24 05:11:04 +04:00
|
|
|
|
|
|
|
if (!nameVal.IsEmpty()) {
|
|
|
|
mForm->AddElementToTable(this, nameVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!idVal.IsEmpty()) {
|
|
|
|
mForm->AddElementToTable(this, idVal);
|
|
|
|
}
|
|
|
|
}
|
2011-06-01 05:46:57 +04:00
|
|
|
|
|
|
|
if (mForm != oldForm || needStateUpdate) {
|
|
|
|
UpdateState(true);
|
|
|
|
}
|
2010-08-24 05:11:04 +04:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:33:16 +04:00
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLFormElement::UpdateFieldSet(bool aNotify)
|
2010-09-19 01:33:16 +04:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
nsIContent* parent = nullptr;
|
|
|
|
nsIContent* prev = nullptr;
|
2010-09-19 05:47:15 +04:00
|
|
|
|
|
|
|
for (parent = GetParent(); parent;
|
|
|
|
prev = parent, parent = parent->GetParent()) {
|
2013-02-08 20:34:47 +04:00
|
|
|
HTMLFieldSetElement* fieldset =
|
|
|
|
HTMLFieldSetElement::FromContent(parent);
|
2011-09-18 13:22:18 +04:00
|
|
|
if (fieldset &&
|
|
|
|
(!prev || fieldset->GetFirstLegend() != prev)) {
|
|
|
|
if (mFieldSet == fieldset) {
|
|
|
|
// We already have the right fieldset;
|
2010-09-19 05:47:15 +04:00
|
|
|
return;
|
|
|
|
}
|
2011-09-18 13:22:18 +04:00
|
|
|
|
|
|
|
if (mFieldSet) {
|
|
|
|
mFieldSet->RemoveElement(this);
|
|
|
|
}
|
|
|
|
mFieldSet = fieldset;
|
|
|
|
fieldset->AddElement(this);
|
|
|
|
|
|
|
|
// The disabled state may have changed
|
|
|
|
FieldSetDisabledChanged(aNotify);
|
|
|
|
return;
|
2010-09-19 01:33:16 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No fieldset found.
|
2010-11-05 20:15:05 +03:00
|
|
|
if (mFieldSet) {
|
2011-09-18 13:22:18 +04:00
|
|
|
mFieldSet->RemoveElement(this);
|
2012-07-30 18:20:58 +04:00
|
|
|
mFieldSet = nullptr;
|
2011-06-01 05:46:57 +04:00
|
|
|
// The disabled state may have changed
|
|
|
|
FieldSetDisabledChanged(aNotify);
|
2010-11-05 20:15:05 +03:00
|
|
|
}
|
2010-09-19 01:33:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLFormElement::FieldSetDisabledChanged(bool aNotify)
|
2010-09-19 01:33:16 +04:00
|
|
|
{
|
2011-06-01 05:46:57 +04:00
|
|
|
UpdateState(aNotify);
|
2010-09-19 01:33:16 +04:00
|
|
|
}
|
|
|
|
|
2012-06-07 22:41:23 +04:00
|
|
|
bool
|
|
|
|
nsGenericHTMLFormElement::IsLabelable() const
|
|
|
|
{
|
|
|
|
// TODO: keygen should be in that list, see bug 101019.
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t type = GetType();
|
2014-06-10 05:51:00 +04:00
|
|
|
return (type & NS_FORM_INPUT_ELEMENT && type != NS_FORM_INPUT_HIDDEN) ||
|
2012-06-07 22:41:23 +04:00
|
|
|
type & NS_FORM_BUTTON_ELEMENT ||
|
|
|
|
// type == NS_FORM_KEYGEN ||
|
|
|
|
type == NS_FORM_OUTPUT ||
|
|
|
|
type == NS_FORM_SELECT ||
|
|
|
|
type == NS_FORM_TEXTAREA;
|
|
|
|
}
|
|
|
|
|
2004-04-13 02:47:24 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLElement::Blur(mozilla::ErrorResult& aError)
|
2004-07-07 04:58:57 +04:00
|
|
|
{
|
2011-11-16 11:50:19 +04:00
|
|
|
if (!ShouldBlur(this)) {
|
2012-11-11 03:30:15 +04:00
|
|
|
return;
|
2011-11-16 11:50:19 +04:00
|
|
|
}
|
2004-07-07 04:58:57 +04:00
|
|
|
|
2014-08-06 03:23:02 +04:00
|
|
|
nsIDocument* doc = GetComposedDoc();
|
2011-11-16 11:50:19 +04:00
|
|
|
if (!doc) {
|
2012-11-11 03:30:15 +04:00
|
|
|
return;
|
2011-11-16 11:50:19 +04:00
|
|
|
}
|
2004-07-07 04:58:57 +04:00
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowOuter* win = doc->GetWindow();
|
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 22:00:39 +04:00
|
|
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
2012-11-11 03:30:15 +04:00
|
|
|
if (win && fm) {
|
|
|
|
aError = fm->ClearFocus(win);
|
|
|
|
}
|
2004-07-25 01:12:43 +04:00
|
|
|
}
|
|
|
|
|
2012-10-06 11:19:52 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLElement::Focus(ErrorResult& aError)
|
2004-07-25 01:12:43 +04: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 22:00:39 +04:00
|
|
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
2012-10-06 11:19:52 +04:00
|
|
|
if (fm) {
|
2013-08-08 00:23:08 +04:00
|
|
|
aError = fm->SetFocus(this, 0);
|
2012-10-06 11:19:52 +04:00
|
|
|
}
|
2004-07-25 01:12:43 +04:00
|
|
|
}
|
|
|
|
|
2012-10-06 11:19:52 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLElement::Click()
|
2011-04-11 20:56:37 +04:00
|
|
|
{
|
2013-06-08 12:54:59 +04:00
|
|
|
if (HandlingClick())
|
2012-10-06 11:19:52 +04:00
|
|
|
return;
|
2011-04-11 20:56:37 +04:00
|
|
|
|
|
|
|
// Strong in case the event kills it
|
2014-08-06 03:23:02 +04:00
|
|
|
nsCOMPtr<nsIDocument> doc = GetComposedDoc();
|
2011-04-11 20:56:37 +04:00
|
|
|
|
2011-11-16 11:50:19 +04:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsPresContext> context;
|
2011-04-11 20:56:37 +04:00
|
|
|
if (doc) {
|
|
|
|
shell = doc->GetShell();
|
|
|
|
if (shell) {
|
|
|
|
context = shell->GetPresContext();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-08 12:54:59 +04:00
|
|
|
SetHandlingClick();
|
2011-04-11 20:56:37 +04:00
|
|
|
|
|
|
|
// Click() is never called from native code, but it may be
|
|
|
|
// called from chrome JS. Mark this event trusted if Click()
|
|
|
|
// is called from chrome code.
|
2013-10-02 10:38:27 +04:00
|
|
|
WidgetMouseEvent event(nsContentUtils::IsCallerChrome(),
|
2015-08-29 02:58:32 +03:00
|
|
|
eMouseClick, nullptr, WidgetMouseEvent::eReal);
|
2011-08-26 11:43:56 +04:00
|
|
|
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
2011-04-11 20:56:37 +04:00
|
|
|
|
2014-03-18 08:48:21 +04:00
|
|
|
EventDispatcher::Dispatch(static_cast<nsIContent*>(this), context, &event);
|
2011-04-11 20:56:37 +04:00
|
|
|
|
2013-06-08 12:54:59 +04:00
|
|
|
ClearHandlingClick();
|
2011-04-11 20:56:37 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
|
|
|
nsGenericHTMLElement::IsHTMLFocusable(bool aWithMouse,
|
|
|
|
bool *aIsFocusable,
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t *aTabIndex)
|
2004-07-25 01:12:43 +04:00
|
|
|
{
|
2014-08-06 03:23:02 +04:00
|
|
|
nsIDocument* doc = GetComposedDoc();
|
2008-02-26 17:09:52 +03:00
|
|
|
if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) {
|
|
|
|
// In designMode documents we only allow focusing the document.
|
|
|
|
if (aTabIndex) {
|
|
|
|
*aTabIndex = -1;
|
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
*aIsFocusable = false;
|
2008-04-15 22:40:38 +04:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2008-02-26 17:09:52 +03:00
|
|
|
}
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
int32_t tabIndex = TabIndex();
|
2016-03-18 08:47:50 +03:00
|
|
|
bool disabled = false;
|
|
|
|
bool disallowOverridingFocusability = true;
|
2004-07-30 17:00:36 +04:00
|
|
|
|
2007-06-28 06:48:16 +04:00
|
|
|
if (IsEditableRoot()) {
|
2008-04-15 22:40:38 +04:00
|
|
|
// Editable roots should always be focusable.
|
2016-03-18 08:47:50 +03:00
|
|
|
disallowOverridingFocusability = true;
|
2008-04-15 22:40:38 +04:00
|
|
|
|
2007-07-13 18:17:35 +04:00
|
|
|
// Ignore the disabled attribute in editable contentEditable/designMode
|
|
|
|
// roots.
|
2007-06-28 06:48:16 +04:00
|
|
|
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) {
|
2007-07-13 18:17:35 +04:00
|
|
|
// The default value for tabindex should be 0 for editable
|
|
|
|
// contentEditable roots.
|
2007-06-28 06:48:16 +04:00
|
|
|
tabIndex = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2016-03-18 08:47:50 +03:00
|
|
|
disallowOverridingFocusability = false;
|
2008-04-15 22:40:38 +04: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 22:00:39 +04:00
|
|
|
// Just check for disabled attribute on form controls
|
2010-09-19 01:33:16 +04:00
|
|
|
disabled = IsDisabled();
|
2007-06-28 06:48:16 +04:00
|
|
|
if (disabled) {
|
|
|
|
tabIndex = -1;
|
|
|
|
}
|
2004-07-25 01:12:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (aTabIndex) {
|
|
|
|
*aTabIndex = tabIndex;
|
|
|
|
}
|
2004-07-07 04:58:57 +04:00
|
|
|
|
2004-07-30 17:00:36 +04:00
|
|
|
// If a tabindex is specified at all, or the default tabindex is 0, we're focusable
|
2016-03-18 08:47:50 +03:00
|
|
|
*aIsFocusable =
|
2010-06-21 16:37:34 +04:00
|
|
|
(tabIndex >= 0 || (!disabled && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)));
|
2008-04-15 22:40:38 +04:00
|
|
|
|
2016-03-18 08:47:50 +03:00
|
|
|
return disallowOverridingFocusability;
|
2004-07-07 04:58:57 +04:00
|
|
|
}
|
|
|
|
|
2004-04-13 03:30:01 +04:00
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLElement::RegUnRegAccessKey(bool aDoReg)
|
2002-05-22 04:14:51 +04:00
|
|
|
{
|
|
|
|
// first check to see if we have an access key
|
|
|
|
nsAutoString accessKey;
|
2006-12-26 20:47:52 +03:00
|
|
|
GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accessKey);
|
2005-10-28 15:25:24 +04:00
|
|
|
if (accessKey.IsEmpty()) {
|
2004-04-13 03:30:01 +04:00
|
|
|
return;
|
2002-05-22 04:14:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// We have an access key, so get the ESM from the pres context.
|
2014-08-23 00:11:27 +04:00
|
|
|
nsPresContext* presContext = GetPresContext(eForUncomposedDoc);
|
2002-05-22 04:14:51 +04:00
|
|
|
|
2004-04-13 03:30:01 +04:00
|
|
|
if (presContext) {
|
2014-04-01 08:09:23 +04:00
|
|
|
EventStateManager* esm = presContext->EventStateManager();
|
2002-05-22 04:14:51 +04:00
|
|
|
|
2004-04-13 03:30:01 +04:00
|
|
|
// Register or unregister as appropriate.
|
|
|
|
if (aDoReg) {
|
2012-08-22 19:56:38 +04:00
|
|
|
esm->RegisterAccessKey(this, (uint32_t)accessKey.First());
|
2004-04-13 03:30:01 +04:00
|
|
|
} else {
|
2012-08-22 19:56:38 +04:00
|
|
|
esm->UnregisterAccessKey(this, (uint32_t)accessKey.First());
|
2004-04-13 03:30:01 +04:00
|
|
|
}
|
2002-05-22 04:14:51 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-18 15:18:42 +03:00
|
|
|
bool
|
2011-09-29 10:19:26 +04:00
|
|
|
nsGenericHTMLElement::PerformAccesskey(bool aKeyCausesActivation,
|
|
|
|
bool aIsTrustedEvent)
|
2007-02-13 18:02:57 +03:00
|
|
|
{
|
2014-08-23 00:11:27 +04:00
|
|
|
nsPresContext* presContext = GetPresContext(eForUncomposedDoc);
|
2015-09-18 15:18:42 +03:00
|
|
|
if (!presContext) {
|
|
|
|
return false;
|
|
|
|
}
|
2007-02-13 18:02:57 +03:00
|
|
|
|
|
|
|
// It's hard to say what HTML4 wants us to do in all cases.
|
2015-09-18 15:18:42 +03:00
|
|
|
bool focused = true;
|
|
|
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
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 22:00:39 +04:00
|
|
|
if (fm) {
|
2013-08-08 00:23:08 +04:00
|
|
|
fm->SetFocus(this, nsIFocusManager::FLAG_BYKEY);
|
2015-09-18 15:18:42 +03:00
|
|
|
|
|
|
|
// Return true if the element became the current focus within its window.
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowOuter* window = OwnerDoc()->GetWindow();
|
2015-09-18 15:18:42 +03:00
|
|
|
focused = (window && window->GetFocusedNode());
|
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 22:00:39 +04:00
|
|
|
}
|
2007-02-13 18:02:57 +03:00
|
|
|
|
|
|
|
if (aKeyCausesActivation) {
|
|
|
|
// Click on it if the users prefs indicate to do so.
|
|
|
|
nsAutoPopupStatePusher popupStatePusher(aIsTrustedEvent ?
|
|
|
|
openAllowed : openAbused);
|
2016-03-19 15:37:09 +03:00
|
|
|
DispatchSimulatedClick(this, aIsTrustedEvent, presContext);
|
2007-02-13 18:02:57 +03:00
|
|
|
}
|
2015-09-18 15:18:42 +03:00
|
|
|
|
|
|
|
return focused;
|
2007-02-13 18:02:57 +03:00
|
|
|
}
|
|
|
|
|
2016-03-19 15:37:09 +03:00
|
|
|
nsresult
|
|
|
|
nsGenericHTMLElement::DispatchSimulatedClick(nsGenericHTMLElement* aElement,
|
|
|
|
bool aIsTrusted,
|
|
|
|
nsPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
WidgetMouseEvent event(aIsTrusted, eMouseClick, nullptr,
|
|
|
|
WidgetMouseEvent::eReal);
|
|
|
|
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
|
|
|
|
return EventDispatcher::Dispatch(ToSupports(aElement), aPresContext, &event);
|
|
|
|
}
|
|
|
|
|
2004-01-15 20:07:27 +03:00
|
|
|
const nsAttrName*
|
|
|
|
nsGenericHTMLElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
|
|
|
|
{
|
2009-06-09 11:41:19 +04:00
|
|
|
if (IsInHTMLDocument()) {
|
2004-01-26 22:22:05 +03:00
|
|
|
nsAutoString lower;
|
2010-02-23 20:38:10 +03:00
|
|
|
nsContentUtils::ASCIIToLower(aStr, lower);
|
2010-03-08 18:45:00 +03:00
|
|
|
return mAttrsAndChildren.GetExistingAttrNameFromQName(lower);
|
2004-01-15 20:07:27 +03:00
|
|
|
}
|
2004-02-10 12:08:06 +03:00
|
|
|
|
2010-03-08 18:45:00 +03:00
|
|
|
return mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
|
2004-01-15 20:07:27 +03:00
|
|
|
}
|
2005-09-07 22:19:26 +04:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericHTMLElement::GetEditor(nsIEditor** aEditor)
|
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
*aEditor = nullptr;
|
2005-09-07 22:19:26 +04:00
|
|
|
|
2014-09-25 13:04:45 +04:00
|
|
|
// See also HTMLTextFieldAccessible::GetEditor.
|
|
|
|
if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
|
2005-09-07 22:19:26 +04:00
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
2011-11-16 11:50:19 +04:00
|
|
|
}
|
2005-09-07 22:19:26 +04:00
|
|
|
|
2012-12-24 06:38:41 +04:00
|
|
|
NS_IF_ADDREF(*aEditor = GetEditorInternal());
|
2005-09-07 22:19:26 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2006-07-29 04:04:40 +04:00
|
|
|
|
|
|
|
already_AddRefed<nsIEditor>
|
|
|
|
nsGenericHTMLElement::GetAssociatedEditor()
|
|
|
|
{
|
|
|
|
// If contenteditable is ever implemented, it might need to do something different here?
|
|
|
|
|
2012-12-24 06:38:41 +04:00
|
|
|
nsCOMPtr<nsIEditor> editor = GetEditorInternal();
|
|
|
|
return editor.forget();
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2006-07-29 04:04:40 +04:00
|
|
|
nsGenericHTMLElement::IsCurrentBodyElement()
|
|
|
|
{
|
2011-11-16 11:50:19 +04:00
|
|
|
// TODO Bug 698498: Should this handle the case where GetBody returns a
|
|
|
|
// frameset?
|
2015-03-03 14:08:59 +03:00
|
|
|
if (!IsHTMLElement(nsGkAtoms::body)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLDocument> htmlDocument =
|
2014-10-02 23:07:24 +04:00
|
|
|
do_QueryInterface(GetUncomposedDoc());
|
2006-07-29 04:04:40 +04:00
|
|
|
if (!htmlDocument) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLElement> htmlElement;
|
|
|
|
htmlDocument->GetBody(getter_AddRefs(htmlElement));
|
2013-01-13 01:53:01 +04:00
|
|
|
return htmlElement == static_cast<HTMLBodyElement*>(this);
|
2006-07-29 04:04:40 +04:00
|
|
|
}
|
2006-08-25 04:15:14 +04:00
|
|
|
|
|
|
|
// static
|
|
|
|
void
|
|
|
|
nsGenericHTMLElement::SyncEditorsOnSubtree(nsIContent* content)
|
|
|
|
{
|
|
|
|
/* Sync this node */
|
|
|
|
nsGenericHTMLElement* element = FromContent(content);
|
|
|
|
if (element) {
|
|
|
|
nsCOMPtr<nsIEditor> editor = element->GetAssociatedEditor();
|
|
|
|
if (editor) {
|
|
|
|
editor->SyncRealTimeSpell();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sync all children */
|
2011-09-27 11:54:58 +04:00
|
|
|
for (nsIContent* child = content->GetFirstChild();
|
|
|
|
child;
|
|
|
|
child = child->GetNextSibling()) {
|
|
|
|
SyncEditorsOnSubtree(child);
|
2006-08-25 04:15:14 +04:00
|
|
|
}
|
|
|
|
}
|
2006-10-07 14:27:45 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLElement::RecompileScriptEventListeners()
|
|
|
|
{
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t i, count = mAttrsAndChildren.AttrCount();
|
2006-10-07 14:27:45 +04:00
|
|
|
for (i = 0; i < count; ++i) {
|
|
|
|
const nsAttrName *name = mAttrsAndChildren.AttrNameAt(i);
|
|
|
|
|
|
|
|
// Eventlistenener-attributes are always in the null namespace
|
|
|
|
if (!name->IsAtom()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIAtom *attr = name->Atom();
|
2013-01-03 00:24:07 +04:00
|
|
|
if (!IsEventAttributeName(attr)) {
|
2006-10-07 14:27:45 +04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
GetAttr(kNameSpaceID_None, attr, value);
|
2012-08-30 20:25:10 +04:00
|
|
|
SetEventHandler(attr, value, true);
|
2006-10-07 14:27:45 +04:00
|
|
|
}
|
|
|
|
}
|
2007-06-28 06:48:16 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2007-06-28 06:48:16 +04:00
|
|
|
nsGenericHTMLElement::IsEditableRoot() const
|
|
|
|
{
|
2014-10-02 23:07:24 +04:00
|
|
|
nsIDocument *document = GetComposedDoc();
|
2007-06-28 06:48:16 +04:00
|
|
|
if (!document) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (document->HasFlag(NODE_IS_EDITABLE)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
2007-07-13 18:17:35 +04:00
|
|
|
if (GetContentEditableValue() != eTrue) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsIContent *parent = GetParent();
|
|
|
|
|
|
|
|
return !parent || !parent->HasFlag(NODE_IS_EDITABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
MakeContentDescendantsEditable(nsIContent *aContent, nsIDocument *aDocument)
|
|
|
|
{
|
2011-06-01 05:46:56 +04:00
|
|
|
// If aContent is not an element, we just need to update its
|
|
|
|
// internal editable state and don't need to notify anyone about
|
|
|
|
// that. For elements, we need to send a ContentStateChanged
|
|
|
|
// notification.
|
|
|
|
if (!aContent->IsElement()) {
|
2011-10-17 18:59:28 +04:00
|
|
|
aContent->UpdateEditableState(false);
|
2011-06-01 05:46:56 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Element *element = aContent->AsElement();
|
2007-06-28 06:48:16 +04:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
element->UpdateEditableState(true);
|
2007-06-28 06:48:16 +04:00
|
|
|
|
2011-06-01 05:46:56 +04:00
|
|
|
for (nsIContent *child = aContent->GetFirstChild();
|
|
|
|
child;
|
|
|
|
child = child->GetNextSibling()) {
|
2007-06-28 06:48:16 +04:00
|
|
|
if (!child->HasAttr(kNameSpaceID_None, nsGkAtoms::contenteditable)) {
|
|
|
|
MakeContentDescendantsEditable(child, aDocument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-08-22 19:56:38 +04:00
|
|
|
nsGenericHTMLElement::ChangeEditableState(int32_t aChange)
|
2007-06-28 06:48:16 +04:00
|
|
|
{
|
2014-10-02 23:07:24 +04:00
|
|
|
//XXXsmaug Fix this for Shadow DOM, bug 1066965.
|
|
|
|
nsIDocument* document = GetUncomposedDoc();
|
2007-06-28 06:48:16 +04:00
|
|
|
if (!document) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aChange != 0) {
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDocument =
|
|
|
|
do_QueryInterface(document);
|
|
|
|
if (htmlDocument) {
|
|
|
|
htmlDocument->ChangeContentEditableCount(this, aChange);
|
|
|
|
}
|
2015-08-14 20:52:38 +03:00
|
|
|
|
|
|
|
nsIContent* parent = GetParent();
|
|
|
|
while (parent) {
|
|
|
|
parent->ChangeEditableDescendantCount(aChange);
|
|
|
|
parent = parent->GetParent();
|
|
|
|
}
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (document->HasFlag(NODE_IS_EDITABLE)) {
|
2012-07-30 18:20:58 +04:00
|
|
|
document = nullptr;
|
2007-06-28 06:48:16 +04:00
|
|
|
}
|
|
|
|
|
2011-03-29 07:32:11 +04:00
|
|
|
// MakeContentDescendantsEditable is going to call ContentStateChanged for
|
2010-09-08 21:43:28 +04:00
|
|
|
// this element and all descendants if editable state has changed.
|
2011-06-01 01:38:25 +04:00
|
|
|
// We might as well wrap it all in one script blocker.
|
|
|
|
nsAutoScriptBlocker scriptBlocker;
|
2007-06-28 06:48:16 +04:00
|
|
|
MakeContentDescendantsEditable(this, document);
|
|
|
|
}
|
2012-06-05 03:49:57 +04:00
|
|
|
|
2013-08-02 05:21:31 +04:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
nsGenericHTMLFormElementWithState::nsGenericHTMLFormElementWithState(
|
2014-06-20 06:01:40 +04:00
|
|
|
already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo
|
2013-08-02 05:21:31 +04:00
|
|
|
)
|
|
|
|
: nsGenericHTMLFormElement(aNodeInfo)
|
|
|
|
{
|
|
|
|
mStateKey.SetIsVoid(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericHTMLFormElementWithState::GenerateStateKey()
|
|
|
|
{
|
|
|
|
// Keep the key if already computed
|
|
|
|
if (!mStateKey.IsVoid()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-08-23 00:11:27 +04:00
|
|
|
nsIDocument* doc = GetUncomposedDoc();
|
2013-08-02 05:21:31 +04:00
|
|
|
if (!doc) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate the state key
|
|
|
|
nsresult rv = nsContentUtils::GenerateStateKey(this, doc, mStateKey);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
mStateKey.SetIsVoid(true);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the state key is blank, this is anonymous content or for whatever
|
|
|
|
// reason we are not supposed to save/restore state: keep it as such.
|
|
|
|
if (!mStateKey.IsEmpty()) {
|
|
|
|
// Add something unique to content so layout doesn't muck us up.
|
|
|
|
mStateKey += "-C";
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPresState*
|
|
|
|
nsGenericHTMLFormElementWithState::GetPrimaryPresState()
|
|
|
|
{
|
|
|
|
if (mStateKey.IsEmpty()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsILayoutHistoryState> history = GetLayoutHistory(false);
|
|
|
|
|
|
|
|
if (!history) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the pres state for this key, if it doesn't exist, create one.
|
|
|
|
nsPresState* result = history->GetState(mStateKey);
|
|
|
|
if (!result) {
|
|
|
|
result = new nsPresState();
|
|
|
|
history->AddState(mStateKey, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsILayoutHistoryState>
|
|
|
|
nsGenericHTMLFormElementWithState::GetLayoutHistory(bool aRead)
|
|
|
|
{
|
2014-08-23 00:11:27 +04:00
|
|
|
nsCOMPtr<nsIDocument> doc = GetUncomposedDoc();
|
2013-08-02 05:21:31 +04:00
|
|
|
if (!doc) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get the history
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsILayoutHistoryState> history = doc->GetLayoutHistoryState();
|
|
|
|
if (!history) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aRead && !history->HasStates()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return history.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
nsGenericHTMLFormElementWithState::RestoreFormControlState()
|
|
|
|
{
|
|
|
|
if (mStateKey.IsEmpty()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsILayoutHistoryState> history =
|
|
|
|
GetLayoutHistory(true);
|
|
|
|
if (!history) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPresState *state;
|
|
|
|
// Get the pres state for this key
|
|
|
|
state = history->GetState(mStateKey);
|
|
|
|
if (state) {
|
|
|
|
bool result = RestoreState(state);
|
|
|
|
history->RemoveState(mStateKey);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-06-20 06:01:40 +04:00
|
|
|
nsGenericHTMLFormElementWithState::NodeInfoChanged(mozilla::dom::NodeInfo* aOldNodeInfo)
|
2013-08-02 05:21:31 +04:00
|
|
|
{
|
|
|
|
mStateKey.SetIsVoid(true);
|
|
|
|
}
|
|
|
|
|
2014-06-12 00:26:52 +04:00
|
|
|
void
|
2012-09-06 00:49:53 +04:00
|
|
|
nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope,
|
2014-06-12 00:26:52 +04:00
|
|
|
JS::MutableHandle<JS::Value> aRetval,
|
2012-11-11 03:30:15 +04:00
|
|
|
ErrorResult& aError)
|
2012-09-06 00:49:53 +04:00
|
|
|
{
|
2013-04-30 01:33:42 +04:00
|
|
|
JS::Rooted<JSObject*> scope(aCx, aScope);
|
2012-09-06 00:49:53 +04:00
|
|
|
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
|
2014-06-12 00:26:52 +04:00
|
|
|
aRetval.setNull();
|
|
|
|
return;
|
2012-09-06 00:49:53 +04:00
|
|
|
}
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
if (ItemScope()) {
|
2013-05-13 21:43:53 +04:00
|
|
|
JS::Rooted<JS::Value> v(aCx);
|
2014-04-10 08:58:43 +04:00
|
|
|
JSAutoCompartment ac(aCx, scope);
|
2014-06-12 00:26:52 +04:00
|
|
|
if (!mozilla::dom::WrapObject(aCx, this, aRetval)) {
|
2012-11-11 03:30:15 +04:00
|
|
|
aError.Throw(NS_ERROR_FAILURE);
|
2012-09-06 00:49:53 +04:00
|
|
|
}
|
2014-06-12 00:26:52 +04:00
|
|
|
return;
|
2012-09-06 00:49:53 +04:00
|
|
|
}
|
|
|
|
|
2015-02-13 04:27:39 +03:00
|
|
|
DOMString string;
|
2012-09-06 00:49:53 +04:00
|
|
|
GetItemValueText(string);
|
2014-06-12 00:26:52 +04:00
|
|
|
if (!xpc::NonVoidStringToJsval(aCx, string, aRetval)) {
|
2012-11-11 03:30:15 +04:00
|
|
|
aError.Throw(NS_ERROR_FAILURE);
|
2012-09-06 00:49:53 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-05 03:49:57 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsGenericHTMLElement::GetItemValue(nsIVariant** aValue)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIWritableVariant> out = new nsVariant();
|
|
|
|
|
|
|
|
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
|
|
|
|
out->SetAsEmpty();
|
|
|
|
out.forget(aValue);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
if (ItemScope()) {
|
2013-08-08 00:23:08 +04:00
|
|
|
out->SetAsISupports(static_cast<nsIContent*>(this));
|
2012-06-05 03:49:57 +04:00
|
|
|
} else {
|
2015-02-13 04:27:39 +03:00
|
|
|
DOMString string;
|
2012-06-05 03:49:57 +04:00
|
|
|
GetItemValueText(string);
|
2015-02-13 04:27:39 +03:00
|
|
|
nsString xpcomString;
|
|
|
|
string.ToString(xpcomString);
|
|
|
|
out->SetAsAString(xpcomString);
|
2012-06-05 03:49:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
out.forget(aValue);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
void
|
|
|
|
nsGenericHTMLElement::SetItemValue(JSContext* aCx, JS::Value aValue,
|
|
|
|
ErrorResult& aError)
|
|
|
|
{
|
|
|
|
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) ||
|
|
|
|
HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope)) {
|
|
|
|
aError.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-07-03 12:03:56 +04:00
|
|
|
nsAutoString string;
|
2013-05-24 17:16:00 +04:00
|
|
|
JS::Rooted<JS::Value> value(aCx, aValue);
|
2014-07-03 15:05:03 +04:00
|
|
|
if (!ConvertJSValueToString(aCx, value, eStringify, eStringify, string)) {
|
2012-11-11 03:30:15 +04:00
|
|
|
aError.Throw(NS_ERROR_UNEXPECTED);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SetItemValueText(string);
|
|
|
|
}
|
|
|
|
|
2012-06-05 03:49:57 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsGenericHTMLElement::SetItemValue(nsIVariant* aValue)
|
|
|
|
{
|
|
|
|
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) ||
|
|
|
|
HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope)) {
|
|
|
|
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString string;
|
|
|
|
aValue->GetAsAString(string);
|
|
|
|
SetItemValueText(string);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-02-13 04:27:39 +03:00
|
|
|
nsGenericHTMLElement::GetItemValueText(DOMString& text)
|
2012-06-05 03:49:57 +04:00
|
|
|
{
|
2014-08-05 14:10:00 +04:00
|
|
|
ErrorResult rv;
|
|
|
|
GetTextContentInternal(text, rv);
|
2012-06-05 03:49:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLElement::SetItemValueText(const nsAString& text)
|
|
|
|
{
|
2012-10-09 16:31:24 +04:00
|
|
|
mozilla::ErrorResult rv;
|
|
|
|
SetTextContentInternal(text, rv);
|
2012-06-05 03:49:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-09-06 00:49:53 +04:00
|
|
|
HTMLPropertiesCollectionDestructor(void *aObject, nsIAtom *aProperty,
|
|
|
|
void *aPropertyValue, void *aData)
|
2012-06-05 03:49:57 +04:00
|
|
|
{
|
2013-01-15 12:35:59 +04:00
|
|
|
HTMLPropertiesCollection* properties =
|
2012-09-06 00:49:53 +04:00
|
|
|
static_cast<HTMLPropertiesCollection*>(aPropertyValue);
|
2012-06-05 03:49:57 +04:00
|
|
|
NS_IF_RELEASE(properties);
|
|
|
|
}
|
|
|
|
|
2012-11-11 03:30:15 +04:00
|
|
|
HTMLPropertiesCollection*
|
|
|
|
nsGenericHTMLElement::Properties()
|
2012-06-05 03:49:57 +04:00
|
|
|
{
|
2013-01-15 12:35:59 +04:00
|
|
|
HTMLPropertiesCollection* properties =
|
2012-09-06 00:49:53 +04:00
|
|
|
static_cast<HTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
|
2012-06-05 03:49:57 +04:00
|
|
|
if (!properties) {
|
|
|
|
properties = new HTMLPropertiesCollection(this);
|
|
|
|
NS_ADDREF(properties);
|
2012-09-06 00:49:53 +04:00
|
|
|
SetProperty(nsGkAtoms::microdataProperties, properties, HTMLPropertiesCollectionDestructor);
|
2012-06-05 03:49:57 +04:00
|
|
|
}
|
2012-11-11 03:30:15 +04:00
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
|
2013-08-08 00:23:08 +04:00
|
|
|
NS_IMETHODIMP
|
2012-12-09 02:06:42 +04:00
|
|
|
nsGenericHTMLElement::GetProperties(nsISupports** aProperties)
|
2012-11-11 03:30:15 +04:00
|
|
|
{
|
2012-12-09 02:06:42 +04:00
|
|
|
NS_ADDREF(*aProperties = static_cast<nsIHTMLCollection*>(Properties()));
|
2013-08-08 00:23:08 +04:00
|
|
|
return NS_OK;
|
2012-06-05 03:49:57 +04:00
|
|
|
}
|
|
|
|
|
2012-06-27 09:17:31 +04:00
|
|
|
nsSize
|
2015-10-18 08:24:48 +03:00
|
|
|
nsGenericHTMLElement::GetWidthHeightForImage(RefPtr<imgRequestProxy>& aImageRequest)
|
2012-06-27 09:17:31 +04:00
|
|
|
{
|
|
|
|
nsSize size(0,0);
|
|
|
|
|
|
|
|
nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
|
|
|
|
|
|
|
|
if (frame) {
|
|
|
|
size = frame->GetContentRect().Size();
|
|
|
|
|
|
|
|
size.width = nsPresContext::AppUnitsToIntCSSPixels(size.width);
|
|
|
|
size.height = nsPresContext::AppUnitsToIntCSSPixels(size.height);
|
|
|
|
} else {
|
|
|
|
const nsAttrValue* value;
|
|
|
|
nsCOMPtr<imgIContainer> image;
|
|
|
|
if (aImageRequest) {
|
|
|
|
aImageRequest->GetImage(getter_AddRefs(image));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((value = GetParsedAttr(nsGkAtoms::width)) &&
|
|
|
|
value->Type() == nsAttrValue::eInteger) {
|
|
|
|
size.width = value->GetIntegerValue();
|
|
|
|
} else if (image) {
|
|
|
|
image->GetWidth(&size.width);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((value = GetParsedAttr(nsGkAtoms::height)) &&
|
|
|
|
value->Type() == nsAttrValue::eInteger) {
|
|
|
|
size.height = value->GetIntegerValue();
|
|
|
|
} else if (image) {
|
|
|
|
image->GetHeight(&size.height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ASSERTION(size.width >= 0, "negative width");
|
|
|
|
NS_ASSERTION(size.height >= 0, "negative height");
|
|
|
|
return size;
|
|
|
|
}
|
2013-01-03 00:24:07 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
nsGenericHTMLElement::IsEventAttributeName(nsIAtom *aName)
|
|
|
|
{
|
|
|
|
return nsContentUtils::IsEventAttributeName(aName, EventNameType_HTML);
|
|
|
|
}
|
2013-05-21 20:14:00 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Construct a URI from a string, as an element.src attribute
|
|
|
|
* would be set to. Helper for the media elements.
|
|
|
|
*/
|
|
|
|
nsresult
|
2015-05-22 08:12:13 +03:00
|
|
|
nsGenericHTMLElement::NewURIFromString(const nsAString& aURISpec,
|
2013-05-21 20:14:00 +04:00
|
|
|
nsIURI** aURI)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aURI);
|
|
|
|
|
|
|
|
*aURI = nullptr;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> doc = OwnerDoc();
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
|
|
|
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(aURI, aURISpec,
|
|
|
|
doc, baseURI);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
bool equal;
|
|
|
|
if (aURISpec.IsEmpty() &&
|
|
|
|
doc->GetDocumentURI() &&
|
|
|
|
NS_SUCCEEDED(doc->GetDocumentURI()->Equals(*aURI, &equal)) &&
|
|
|
|
equal) {
|
|
|
|
// Assume an element can't point to a fragment of its embedding
|
|
|
|
// document. Fail here instead of returning the recursive URI
|
|
|
|
// and waiting for the subsequent load to fail.
|
|
|
|
NS_RELEASE(*aURI);
|
|
|
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2015-10-30 08:37:03 +03:00
|
|
|
|
2015-11-20 07:14:57 +03:00
|
|
|
static bool
|
|
|
|
IsOrHasAncestorWithDisplayNone(Element* aElement, nsIPresShell* aPresShell)
|
|
|
|
{
|
|
|
|
nsTArray<Element*> elementsToCheck;
|
|
|
|
for (Element* e = aElement; e; e = e->GetParentElement()) {
|
|
|
|
if (e->GetPrimaryFrame()) {
|
|
|
|
// e definitely isn't display:none and doesn't have a display:none
|
|
|
|
// ancestor.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
elementsToCheck.AppendElement(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (elementsToCheck.IsEmpty()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:11 +03:00
|
|
|
StyleSetHandle styleSet = aPresShell->StyleSet();
|
2015-11-20 07:14:57 +03:00
|
|
|
RefPtr<nsStyleContext> sc;
|
|
|
|
for (int32_t i = elementsToCheck.Length() - 1; i >= 0; --i) {
|
|
|
|
if (sc) {
|
|
|
|
sc = styleSet->ResolveStyleFor(elementsToCheck[i], sc);
|
|
|
|
} else {
|
|
|
|
sc = nsComputedDOMStyle::GetStyleContextForElementNoFlush(elementsToCheck[i],
|
|
|
|
nullptr, aPresShell);
|
|
|
|
}
|
|
|
|
if (sc->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_NONE) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-10-30 08:37:03 +03:00
|
|
|
void
|
|
|
|
nsGenericHTMLElement::GetInnerText(mozilla::dom::DOMString& aValue,
|
|
|
|
mozilla::ErrorResult& aError)
|
|
|
|
{
|
|
|
|
if (!GetPrimaryFrame(Flush_Layout)) {
|
2015-11-20 07:14:57 +03:00
|
|
|
nsIPresShell* presShell = nsComputedDOMStyle::GetPresShellForContent(this);
|
2015-11-23 08:09:39 +03:00
|
|
|
if (!presShell || IsOrHasAncestorWithDisplayNone(this, presShell)) {
|
2015-10-30 08:37:03 +03:00
|
|
|
GetTextContentInternal(aValue, aError);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsRange::GetInnerTextNoFlush(aValue, aError, this, 0, this, GetChildCount());
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericHTMLElement::SetInnerText(const nsAString& aValue)
|
|
|
|
{
|
|
|
|
// Fire DOMNodeRemoved mutation events before we do anything else.
|
|
|
|
nsCOMPtr<nsIContent> kungFuDeathGrip;
|
|
|
|
|
|
|
|
// Batch possible DOMSubtreeModified events.
|
|
|
|
mozAutoSubtreeModified subtree(OwnerDoc(), nullptr);
|
|
|
|
FireNodeRemovedForChildren();
|
|
|
|
|
|
|
|
// Might as well stick a batch around this since we're performing several
|
|
|
|
// mutations.
|
|
|
|
mozAutoDocUpdate updateBatch(GetComposedDoc(),
|
|
|
|
UPDATE_CONTENT_MODEL, true);
|
|
|
|
nsAutoMutationBatch mb;
|
|
|
|
|
|
|
|
uint32_t childCount = GetChildCount();
|
|
|
|
|
|
|
|
mb.Init(this, true, false);
|
|
|
|
for (uint32_t i = 0; i < childCount; ++i) {
|
|
|
|
RemoveChildAt(0, true);
|
|
|
|
}
|
|
|
|
mb.RemovalDone();
|
|
|
|
|
|
|
|
nsString str;
|
|
|
|
const char16_t* s = aValue.BeginReading();
|
|
|
|
const char16_t* end = aValue.EndReading();
|
|
|
|
while (true) {
|
|
|
|
if (s != end && *s == '\r' && s + 1 != end && s[1] == '\n') {
|
|
|
|
// a \r\n pair should only generate one <br>, so just skip the \r
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
if (s == end || *s == '\r' || *s == '\n') {
|
|
|
|
if (!str.IsEmpty()) {
|
|
|
|
RefPtr<nsTextNode> textContent =
|
|
|
|
new nsTextNode(NodeInfo()->NodeInfoManager());
|
|
|
|
textContent->SetText(str, true);
|
|
|
|
AppendChildTo(textContent, true);
|
|
|
|
}
|
|
|
|
if (s == end) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
str.Truncate();
|
|
|
|
already_AddRefed<mozilla::dom::NodeInfo> ni =
|
|
|
|
NodeInfo()->NodeInfoManager()->GetNodeInfo(nsGkAtoms::br,
|
|
|
|
nullptr, kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE);
|
|
|
|
RefPtr<HTMLBRElement> br = new HTMLBRElement(ni);
|
|
|
|
AppendChildTo(br, true);
|
|
|
|
} else {
|
|
|
|
str.Append(*s);
|
|
|
|
}
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
|
|
|
|
mb.NodesAdded();
|
|
|
|
}
|