1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 * Base class for all element classes; this provides an implementation
40 * of DOM Core's nsIDOMElement, implements nsIContent, provides
41 * utility methods for subclasses, and so forth.
44 #ifndef nsGenericElement_h___
45 #define nsGenericElement_h___
48 #include "nsAutoPtr.h"
49 #include "nsIContent.h"
50 #include "nsIDOMElement.h"
51 #include "nsIDOMDocumentFragment.h"
52 #include "nsIDOMEventTarget.h"
53 #include "nsIDOM3EventTarget.h"
54 #include "nsIDOM3Node.h"
55 #include "nsIDOMNSEventTarget.h"
56 #include "nsIDOMNSElement.h"
57 #include "nsILinkHandler.h"
58 #include "nsContentUtils.h"
59 #include "nsNodeUtils.h"
60 #include "nsAttrAndChildArray.h"
61 #include "mozFlushType.h"
62 #include "nsDOMAttributeMap.h"
63 #include "nsIWeakReference.h"
64 #include "nsCycleCollectionParticipant.h"
65 #include "nsIDocument.h"
66 #include "nsIDOMNodeSelector.h"
69 class nsIDOMEventListener
;
71 class nsIDOMNamedNodeMap
;
72 class nsDOMCSSDeclaration
;
73 class nsIDOMCSSStyleDeclaration
;
78 class nsIDOMNSFeatureFactory
;
79 class nsIEventListenerManager
;
80 class nsIScrollableView
;
84 typedef unsigned long PtrBits
;
87 * Class that implements the nsIDOMNodeList interface (a list of children of
88 * the content), by holding a reference to the content and delegating GetLength
89 * and Item to its existing child list.
92 class nsChildContentList
: public nsINodeList
,
96 nsChildContentList(nsINode
* aNode
)
103 // nsIDOMNodeList interface
104 NS_DECL_NSIDOMNODELIST
106 // nsINodeList interface
107 virtual nsINode
* GetNodeAt(PRUint32 aIndex
);
114 nsISupports
* GetParentObject()
119 static nsChildContentList
* FromSupports(nsISupports
* aSupports
)
121 nsINodeList
* list
= static_cast<nsINodeList
*>(aSupports
);
124 nsCOMPtr
<nsINodeList
> list_qi
= do_QueryInterface(aSupports
);
126 // If this assertion fires the QI implementation for the object in
127 // question doesn't use the nsINodeList pointer as the nsISupports
128 // pointer. That must be fixed, or we'll crash...
129 NS_ASSERTION(list_qi
== list
, "Uh, fix QI!");
132 return static_cast<nsChildContentList
*>(list
);
136 // The node whose children make up the list (weak reference)
141 * A tearoff class for nsGenericElement to implement additional interfaces
143 class nsNode3Tearoff
: public nsIDOM3Node
146 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
150 NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff
)
152 nsNode3Tearoff(nsIContent
*aContent
) : mContent(aContent
)
157 * Determines whether two nodes are equal.
159 * @param aContent1 The first node to compare.
160 * @param aContent2 The second node to compare.
162 * @return PR_TRUE if the nodes are equal.
164 static PRBool
AreNodesEqual(nsIContent
* aContent1
,
165 nsIContent
* aContent2
);
168 virtual ~nsNode3Tearoff() {}
171 nsCOMPtr
<nsIContent
> mContent
;
175 * A class that implements nsIWeakReference
178 class nsNodeWeakReference
: public nsIWeakReference
181 nsNodeWeakReference(nsINode
* aNode
)
186 ~nsNodeWeakReference();
192 NS_DECL_NSIWEAKREFERENCE
194 void NoticeNodeDestruction()
204 * Tearoff to use for nodes to implement nsISupportsWeakReference
206 class nsNodeSupportsWeakRefTearoff
: public nsISupportsWeakReference
209 nsNodeSupportsWeakRefTearoff(nsINode
* aNode
)
215 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
217 // nsISupportsWeakReference
218 NS_DECL_NSISUPPORTSWEAKREFERENCE
220 NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff
)
223 nsCOMPtr
<nsINode
> mNode
;
226 #define NS_EVENT_TEAROFF_CACHE_SIZE 4
229 * nsDOMEventRTTearoff is a tearoff class used by nsGenericElement and
230 * nsGenericDOMDataNode classes for implementing the interfaces
231 * nsIDOMEventTarget, nsIDOM3EventTarget and nsIDOMNSEventTarget.
233 * Use the method nsDOMEventRTTearoff::Create() to create one of these babies.
234 * @see nsDOMEventRTTearoff::Create
237 class nsDOMEventRTTearoff
: public nsIDOMEventTarget
,
238 public nsIDOM3EventTarget
,
239 public nsIDOMNSEventTarget
242 // This class uses a caching scheme so we don't let users of this
243 // class create new instances with 'new', in stead the callers
244 // should use the static method
245 // nsDOMEventRTTearoff::Create(). That's why the constructor and
246 // destrucor of this class is private.
248 nsDOMEventRTTearoff(nsIContent
*aContent
);
250 static nsDOMEventRTTearoff
*mCachedEventTearoff
[NS_EVENT_TEAROFF_CACHE_SIZE
];
251 static PRUint32 mCachedEventTearoffCount
;
254 * This method gets called by Release() when it's time to delete the
255 * this object, in stead of always deleting the object we'll put the
256 * object in the cache if unless the cache is already full.
260 nsresult
GetDOM3EventTarget(nsIDOM3EventTarget
**aTarget
);
263 virtual ~nsDOMEventRTTearoff();
266 * Use this static method to create instances of nsDOMEventRTTearoff.
267 * @param aContent the content to create a tearoff for
269 static nsDOMEventRTTearoff
*Create(nsIContent
*aContent
);
272 * Call before shutdown to clear the cache and free memory for this class.
274 static void Shutdown();
277 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
280 NS_DECL_NSIDOMEVENTTARGET
282 // nsIDOM3EventTarget
283 NS_DECL_NSIDOM3EVENTTARGET
285 // nsIDOMNSEventTarget
286 NS_DECL_NSIDOMNSEVENTTARGET
288 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMEventRTTearoff
,
293 * Strong reference back to the content object from where an instance of this
294 * class was 'torn off'
296 nsCOMPtr
<nsIContent
> mContent
;
300 * A tearoff class for nsGenericElement to implement NodeSelector
302 class nsNodeSelectorTearoff
: public nsIDOMNodeSelector
305 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
307 NS_DECL_NSIDOMNODESELECTOR
309 NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSelectorTearoff
)
311 nsNodeSelectorTearoff(nsIContent
*aContent
) : mContent(aContent
)
316 ~nsNodeSelectorTearoff() {}
319 nsCOMPtr
<nsIContent
> mContent
;
322 // Forward declare to allow being a friend
323 class nsNSElementTearoff
;
326 * A generic base class for DOM elements, implementing many nsIContent,
327 * nsIDOMNode and nsIDOMElement methods.
329 class nsGenericElement
: public nsIContent
332 nsGenericElement(nsINodeInfo
*aNodeInfo
);
333 virtual ~nsGenericElement();
335 friend class nsNSElementTearoff
;
337 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
340 * Called during QueryInterface to give the binding manager a chance to
341 * get an interface for this element.
343 nsresult
PostQueryInterface(REFNSIID aIID
, void** aInstancePtr
);
345 // nsINode interface methods
346 virtual PRUint32
GetChildCount() const;
347 virtual nsIContent
*GetChildAt(PRUint32 aIndex
) const;
348 virtual nsIContent
* const * GetChildArray(PRUint32
* aChildCount
) const;
349 virtual PRInt32
IndexOf(nsINode
* aPossibleChild
) const;
350 virtual nsresult
InsertChildAt(nsIContent
* aKid
, PRUint32 aIndex
,
352 virtual nsresult
RemoveChildAt(PRUint32 aIndex
, PRBool aNotify
);
353 virtual nsresult
PreHandleEvent(nsEventChainPreVisitor
& aVisitor
);
354 virtual nsresult
PostHandleEvent(nsEventChainPostVisitor
& aVisitor
);
355 virtual nsresult
DispatchDOMEvent(nsEvent
* aEvent
, nsIDOMEvent
* aDOMEvent
,
356 nsPresContext
* aPresContext
,
357 nsEventStatus
* aEventStatus
);
358 virtual nsresult
GetListenerManager(PRBool aCreateIfNotFound
,
359 nsIEventListenerManager
** aResult
);
360 virtual nsresult
AddEventListenerByIID(nsIDOMEventListener
*aListener
,
362 virtual nsresult
RemoveEventListenerByIID(nsIDOMEventListener
*aListener
,
364 virtual nsresult
GetSystemEventGroup(nsIDOMEventGroup
** aGroup
);
365 virtual nsresult
GetContextForEventHandlers(nsIScriptContext
** aContext
)
367 return nsContentUtils::GetContextForEventHandlers(this, aContext
);
370 // nsIContent interface methods
371 virtual nsresult
BindToTree(nsIDocument
* aDocument
, nsIContent
* aParent
,
372 nsIContent
* aBindingParent
,
373 PRBool aCompileEventHandlers
);
374 virtual void UnbindFromTree(PRBool aDeep
= PR_TRUE
,
375 PRBool aNullParent
= PR_TRUE
);
376 virtual nsIAtom
*GetIDAttributeName() const;
377 virtual nsIAtom
*GetClassAttributeName() const;
378 virtual already_AddRefed
<nsINodeInfo
> GetExistingAttrNameFromQName(const nsAString
& aStr
) const;
379 nsresult
SetAttr(PRInt32 aNameSpaceID
, nsIAtom
* aName
,
380 const nsAString
& aValue
, PRBool aNotify
)
382 return SetAttr(aNameSpaceID
, aName
, nsnull
, aValue
, aNotify
);
384 virtual nsresult
SetAttr(PRInt32 aNameSpaceID
, nsIAtom
* aName
, nsIAtom
* aPrefix
,
385 const nsAString
& aValue
, PRBool aNotify
);
386 virtual PRBool
GetAttr(PRInt32 aNameSpaceID
, nsIAtom
* aName
,
387 nsAString
& aResult
) const;
388 virtual PRBool
HasAttr(PRInt32 aNameSpaceID
, nsIAtom
* aName
) const;
389 virtual PRBool
AttrValueIs(PRInt32 aNameSpaceID
, nsIAtom
* aName
,
390 const nsAString
& aValue
,
391 nsCaseTreatment aCaseSensitive
) const;
392 virtual PRBool
AttrValueIs(PRInt32 aNameSpaceID
, nsIAtom
* aName
,
394 nsCaseTreatment aCaseSensitive
) const;
395 virtual PRInt32
FindAttrValueIn(PRInt32 aNameSpaceID
,
397 AttrValuesArray
* aValues
,
398 nsCaseTreatment aCaseSensitive
) const;
399 virtual nsresult
UnsetAttr(PRInt32 aNameSpaceID
, nsIAtom
* aAttribute
,
401 virtual const nsAttrName
* GetAttrNameAt(PRUint32 aIndex
) const;
402 virtual PRUint32
GetAttrCount() const;
403 virtual const nsTextFragment
*GetText();
404 virtual PRUint32
TextLength();
405 virtual nsresult
SetText(const PRUnichar
* aBuffer
, PRUint32 aLength
,
407 // Need to implement this here too to avoid hiding.
408 nsresult
SetText(const nsAString
& aStr
, PRBool aNotify
)
410 return SetText(aStr
.BeginReading(), aStr
.Length(), aNotify
);
412 virtual nsresult
AppendText(const PRUnichar
* aBuffer
, PRUint32 aLength
,
414 virtual PRBool
TextIsOnlyWhitespace();
415 virtual void AppendTextTo(nsAString
& aResult
);
416 virtual void SetFocus(nsPresContext
* aContext
);
417 virtual nsIContent
*GetBindingParent() const;
418 virtual PRBool
IsNodeOfType(PRUint32 aFlags
) const;
419 virtual already_AddRefed
<nsIURI
> GetBaseURI() const;
420 virtual PRBool
IsLink(nsIURI
** aURI
) const;
421 virtual void SetMayHaveFrame(PRBool aMayHaveFrame
);
422 virtual PRBool
MayHaveFrame() const;
424 virtual PRUint32
GetScriptTypeID() const;
425 virtual nsresult
SetScriptTypeID(PRUint32 aLang
);
427 virtual void DestroyContent();
428 virtual void SaveSubtreeState();
431 virtual void List(FILE* out
, PRInt32 aIndent
) const
433 List(out
, aIndent
, EmptyCString());
435 virtual void DumpContent(FILE* out
, PRInt32 aIndent
, PRBool aDumpAll
) const;
436 void List(FILE* out
, PRInt32 aIndent
, const nsCString
& aPrefix
) const;
437 void ListAttributes(FILE* out
) const;
440 virtual nsIAtom
* GetID() const;
441 virtual const nsAttrValue
* DoGetClasses() const;
442 NS_IMETHOD
WalkContentStyleRules(nsRuleWalker
* aRuleWalker
);
443 virtual nsICSSStyleRule
* GetInlineStyleRule();
444 NS_IMETHOD
SetInlineStyleRule(nsICSSStyleRule
* aStyleRule
, PRBool aNotify
);
446 IsAttributeMapped(const nsIAtom
* aAttribute
) const;
447 virtual nsChangeHint
GetAttributeChangeHint(const nsIAtom
* aAttribute
,
448 PRInt32 aModType
) const;
450 * Attribute Mapping Helpers
452 struct MappedAttributeEntry
{
457 * A common method where you can just pass in a list of maps to check
458 * for attribute dependence. Most implementations of
459 * IsAttributeMapped should use this function as a default
463 FindAttributeDependence(const nsIAtom
* aAttribute
,
464 const MappedAttributeEntry
* const aMaps
[],
467 // nsIDOMNode method implementation
468 NS_IMETHOD
GetNodeName(nsAString
& aNodeName
);
469 NS_IMETHOD
GetLocalName(nsAString
& aLocalName
);
470 NS_IMETHOD
GetNodeValue(nsAString
& aNodeValue
);
471 NS_IMETHOD
SetNodeValue(const nsAString
& aNodeValue
);
472 NS_IMETHOD
GetNodeType(PRUint16
* aNodeType
);
473 NS_IMETHOD
GetParentNode(nsIDOMNode
** aParentNode
);
474 NS_IMETHOD
GetAttributes(nsIDOMNamedNodeMap
** aAttributes
);
475 NS_IMETHOD
GetPreviousSibling(nsIDOMNode
** aPreviousSibling
);
476 NS_IMETHOD
GetNextSibling(nsIDOMNode
** aNextSibling
);
477 NS_IMETHOD
GetOwnerDocument(nsIDOMDocument
** aOwnerDocument
);
478 NS_IMETHOD
GetNamespaceURI(nsAString
& aNamespaceURI
);
479 NS_IMETHOD
GetPrefix(nsAString
& aPrefix
);
480 NS_IMETHOD
SetPrefix(const nsAString
& aPrefix
);
481 NS_IMETHOD
Normalize();
482 NS_IMETHOD
IsSupported(const nsAString
& aFeature
,
483 const nsAString
& aVersion
, PRBool
* aReturn
);
484 NS_IMETHOD
HasAttributes(PRBool
* aHasAttributes
);
485 NS_IMETHOD
GetChildNodes(nsIDOMNodeList
** aChildNodes
);
486 NS_IMETHOD
HasChildNodes(PRBool
* aHasChildNodes
);
487 NS_IMETHOD
GetFirstChild(nsIDOMNode
** aFirstChild
);
488 NS_IMETHOD
GetLastChild(nsIDOMNode
** aLastChild
);
489 NS_IMETHOD
InsertBefore(nsIDOMNode
* aNewChild
, nsIDOMNode
* aRefChild
,
490 nsIDOMNode
** aReturn
);
491 NS_IMETHOD
ReplaceChild(nsIDOMNode
* aNewChild
, nsIDOMNode
* aOldChild
,
492 nsIDOMNode
** aReturn
);
493 NS_IMETHOD
RemoveChild(nsIDOMNode
* aOldChild
, nsIDOMNode
** aReturn
);
494 NS_IMETHOD
AppendChild(nsIDOMNode
* aNewChild
, nsIDOMNode
** aReturn
)
496 return InsertBefore(aNewChild
, nsnull
, aReturn
);
499 // nsIDOMElement method implementation
500 NS_IMETHOD
GetTagName(nsAString
& aTagName
);
501 NS_IMETHOD
GetAttribute(const nsAString
& aName
,
503 NS_IMETHOD
SetAttribute(const nsAString
& aName
,
504 const nsAString
& aValue
);
505 NS_IMETHOD
RemoveAttribute(const nsAString
& aName
);
506 NS_IMETHOD
GetAttributeNode(const nsAString
& aName
,
507 nsIDOMAttr
** aReturn
);
508 NS_IMETHOD
SetAttributeNode(nsIDOMAttr
* aNewAttr
, nsIDOMAttr
** aReturn
);
509 NS_IMETHOD
RemoveAttributeNode(nsIDOMAttr
* aOldAttr
, nsIDOMAttr
** aReturn
);
510 NS_IMETHOD
GetElementsByTagName(const nsAString
& aTagname
,
511 nsIDOMNodeList
** aReturn
);
512 NS_IMETHOD
GetAttributeNS(const nsAString
& aNamespaceURI
,
513 const nsAString
& aLocalName
,
515 NS_IMETHOD
SetAttributeNS(const nsAString
& aNamespaceURI
,
516 const nsAString
& aQualifiedName
,
517 const nsAString
& aValue
);
518 NS_IMETHOD
RemoveAttributeNS(const nsAString
& aNamespaceURI
,
519 const nsAString
& aLocalName
);
520 NS_IMETHOD
GetAttributeNodeNS(const nsAString
& aNamespaceURI
,
521 const nsAString
& aLocalName
,
522 nsIDOMAttr
** aReturn
);
523 NS_IMETHOD
SetAttributeNodeNS(nsIDOMAttr
* aNewAttr
, nsIDOMAttr
** aReturn
);
524 NS_IMETHOD
GetElementsByTagNameNS(const nsAString
& aNamespaceURI
,
525 const nsAString
& aLocalName
,
526 nsIDOMNodeList
** aReturn
);
527 NS_IMETHOD
HasAttribute(const nsAString
& aName
, PRBool
* aReturn
);
528 NS_IMETHOD
HasAttributeNS(const nsAString
& aNamespaceURI
,
529 const nsAString
& aLocalName
,
531 nsresult
CloneNode(PRBool aDeep
, nsIDOMNode
**aResult
)
533 return nsNodeUtils::CloneNodeImpl(this, aDeep
, aResult
);
536 //----------------------------------------
539 * Add a script event listener with the given event handler name
540 * (like onclick) and with the value as JS
541 * @param aEventName the event listener name
542 * @param aValue the JS to attach
543 * @param aDefer indicates if deferred execution is allowed
545 nsresult
AddScriptEventListener(nsIAtom
* aEventName
,
546 const nsAString
& aValue
,
547 PRBool aDefer
= PR_TRUE
);
550 * Do whatever needs to be done when the mouse leaves a link
552 nsresult
LeaveLink(nsPresContext
* aPresContext
);
555 * Take two text nodes and append the second to the first.
556 * @param aFirst the node which will contain first + second [INOUT]
557 * @param aSecond the node which will be appended
559 nsresult
JoinTextNodes(nsIContent
* aFirst
,
560 nsIContent
* aSecond
);
563 * Check whether a spec feature/version is supported.
564 * @param aObject the object, which should support the feature,
565 * for example nsIDOMNode or nsIDOMDOMImplementation
566 * @param aFeature the feature ("Views", "Core", "HTML", "Range" ...)
567 * @param aVersion the version ("1.0", "2.0", ...)
568 * @param aReturn whether the feature is supported or not [OUT]
570 static nsresult
InternalIsSupported(nsISupports
* aObject
,
571 const nsAString
& aFeature
,
572 const nsAString
& aVersion
,
575 static nsresult
InternalGetFeature(nsISupports
* aObject
,
576 const nsAString
& aFeature
,
577 const nsAString
& aVersion
,
578 nsISupports
** aReturn
);
580 static already_AddRefed
<nsIDOMNSFeatureFactory
>
581 GetDOMFeatureFactory(const nsAString
& aFeature
, const nsAString
& aVersion
);
583 static PRBool
ShouldFocus(nsIContent
*aContent
);
585 static PRBool
ShouldBlur(nsIContent
*aContent
);
588 * Actual implementation of the DOM InsertBefore and ReplaceChild methods.
589 * Shared by nsDocument. When called from nsDocument, aParent will be null.
591 * @param aReplace True if aNewChild should replace aRefChild. False if
592 * aNewChild should be inserted before aRefChild.
593 * @param aNewChild The child to insert
594 * @param aRefChild The child to insert before or replace
595 * @param aParent The parent to use for the new child
596 * @param aDocument The document to use for the new child.
597 * Must be non-null, if aParent is null and must match
598 * aParent->GetCurrentDoc() if aParent is not null.
599 * @param aReturn [out] the child we insert
601 static nsresult
doReplaceOrInsertBefore(PRBool aReplace
, nsIDOMNode
* aNewChild
, nsIDOMNode
* aRefChild
,
602 nsIContent
* aParent
, nsIDocument
* aDocument
,
603 nsIDOMNode
** aReturn
);
606 * Actual implementation of the DOM RemoveChild method. Shared by
607 * nsDocument. When called from nsDocument, aParent will be null.
609 * @param aOldChild The child to remove
610 * @param aParent The parent to use for the new child
611 * @param aDocument The document to use for the new child.
612 * Must be non-null if aParent is null and must match
613 * aParent->GetCurrentDoc() if aParent is not null.
614 * @param aReturn [out] the child we remove
616 static nsresult
doRemoveChild(nsIDOMNode
* aOldChild
,
617 nsIContent
* aParent
, nsIDocument
* aDocument
,
618 nsIDOMNode
** aReturn
);
621 * Most of the implementation of the nsINode InsertChildAt method. Shared by
622 * nsDocument. When called from nsDocument, aParent will be null.
624 * @param aKid The child to insert.
625 * @param aIndex The index to insert at.
626 * @param aNotify Whether to notify.
627 * @param aParent The parent to use for the new child.
628 * @param aDocument The document to use for the notifications. Must be
629 * non-null if aParent is null (in which case aKid is being
630 * inserted as its child) and must match
631 * aParent->GetCurrentDoc() if aParent is not null.
632 * @param aChildArray The child array to work with
634 static nsresult
doInsertChildAt(nsIContent
* aKid
, PRUint32 aIndex
,
635 PRBool aNotify
, nsIContent
* aParent
,
636 nsIDocument
* aDocument
,
637 nsAttrAndChildArray
& aChildArray
);
640 * Most of the implementation of the nsINode RemoveChildAt method. Shared by
641 * nsDocument. When called from nsDocument, aParent will be null.
643 * @param aIndex The index to remove at.
644 * @param aNotify Whether to notify.
645 * @param aKid The kid at aIndex. Must not be null.
646 * @param aParent The parent we're removing from.
647 * @param aDocument The document to use for the notifications. Must be
648 * non-null if aParent is null (in which case aKid is being
649 * removed as its child) and must match
650 * aParent->GetCurrentDoc() if aParent is not null.
651 * @param aChildArray The child array to work with
653 static nsresult
doRemoveChildAt(PRUint32 aIndex
, PRBool aNotify
,
654 nsIContent
* aKid
, nsIContent
* aParent
,
655 nsIDocument
* aDocument
,
656 nsAttrAndChildArray
& aChildArray
);
659 * Helper methods for implementing querySelector/querySelectorAll
661 static nsresult
doQuerySelector(nsINode
* aRoot
, const nsAString
& aSelector
,
662 nsIDOMElement
**aReturn
);
663 static nsresult
doQuerySelectorAll(nsINode
* aRoot
,
664 const nsAString
& aSelector
,
665 nsIDOMNodeList
**aReturn
);
668 * Default event prehandling for content objects. Handles event retargeting.
670 static nsresult
doPreHandleEvent(nsIContent
* aContent
,
671 nsEventChainPreVisitor
& aVisitor
);
674 * Method to create and dispatch a left-click event loosely based on
675 * aSourceEvent. If aFullDispatch is true, the event will be dispatched
676 * through the full dispatching of the presshell of the aPresContext; if it's
677 * false the event will be dispatched only as a DOM event.
678 * If aPresContext is nsnull, this does nothing.
680 static nsresult
DispatchClickEvent(nsPresContext
* aPresContext
,
681 nsInputEvent
* aSourceEvent
,
683 PRBool aFullDispatch
,
684 nsEventStatus
* aStatus
);
687 * Method to dispatch aEvent to aTarget. If aFullDispatch is true, the event
688 * will be dispatched through the full dispatching of the presshell of the
689 * aPresContext; if it's false the event will be dispatched only as a DOM
691 * If aPresContext is nsnull, this does nothing.
693 static nsresult
DispatchEvent(nsPresContext
* aPresContext
,
696 PRBool aFullDispatch
,
697 nsEventStatus
* aStatus
);
700 * Get the primary frame for this content without flushing (see
701 * GetPrimaryFrameFor)
703 * @return the primary frame
705 nsIFrame
* GetPrimaryFrame();
708 * Get the primary frame for this content with flushing (see
709 * GetPrimaryFrameFor).
711 * @param aType the kind of flush to do, typically Flush_Frames or
713 * @return the primary frame
715 nsIFrame
* GetPrimaryFrame(mozFlushType aType
);
718 * Get the primary frame for a piece of content without flushing.
720 * @param aContent the content to get the primary frame for
721 * @param aDocument the document for this content
722 * @return the primary frame
724 static nsIFrame
* GetPrimaryFrameFor(nsIContent
* aContent
,
725 nsIDocument
* aDocument
);
728 * Struct that stores info on an attribute. The name and value must
729 * either both be null or both be non-null.
732 nsAttrInfo(const nsAttrName
* aName
, const nsAttrValue
* aValue
) :
733 mName(aName
), mValue(aValue
) {}
734 nsAttrInfo(const nsAttrInfo
& aOther
) :
735 mName(aOther
.mName
), mValue(aOther
.mValue
) {}
737 const nsAttrName
* mName
;
738 const nsAttrValue
* mValue
;
742 * Returns the attribute map, if there is one.
744 * @return existing attribute map or nsnull.
746 nsDOMAttributeMap
*GetAttributeMap()
748 nsDOMSlots
*slots
= GetExistingDOMSlots();
750 return slots
? slots
->mAttributeMap
.get() : nsnull
;
753 virtual void RecompileScriptEventListeners()
757 NS_DECL_CYCLE_COLLECTION_CLASS(nsGenericElement
)
761 * Set attribute and (if needed) notify documentobservers and fire off
764 * @param aNamespaceID namespace of attribute
765 * @param aAttribute local-name of attribute
766 * @param aPrefix aPrefix of attribute
767 * @param aOldValue previous value of attribute. Only needed if
768 * aFireMutation is true.
769 * @param aParsedValue parsed new value of attribute
770 * @param aModification is this a attribute-modification or addition. Only
771 * needed if aFireMutation or aNotify is true.
772 * @param aFireMutation should mutation-events be fired?
773 * @param aNotify should we notify document-observers?
774 * @param aValueForAfterSetAttr If not null, AfterSetAttr will be called
775 * with the value pointed by this parameter.
777 nsresult
SetAttrAndNotify(PRInt32 aNamespaceID
,
780 const nsAString
& aOldValue
,
781 nsAttrValue
& aParsedValue
,
782 PRBool aModification
,
783 PRBool aFireMutation
,
785 const nsAString
* aValueForAfterSetAttr
);
788 * Convert an attribute string value to attribute type based on the type of
789 * attribute. Called by SetAttr(). Note that at the moment we only do this
790 * for attributes in the null namespace (kNameSpaceID_None).
792 * @param aNamespaceID the namespace of the attribute to convert
793 * @param aAttribute the attribute to convert
794 * @param aValue the string value to convert
795 * @param aResult the nsAttrValue [OUT]
796 * @return PR_TRUE if the parsing was successful, PR_FALSE otherwise
798 virtual PRBool
ParseAttribute(PRInt32 aNamespaceID
,
800 const nsAString
& aValue
,
801 nsAttrValue
& aResult
);
804 * Try to set the attribute as a mapped attribute, if applicable. This will
805 * only be called for attributes that are in the null namespace and only on
806 * attributes that returned true when passed to IsAttributeMapped. The
807 * caller will not try to set the attr in any other way if this method
808 * returns PR_TRUE (the value of aRetval does not matter for that purpose).
810 * @param aDocument the current document of this node (an optimization)
811 * @param aName the name of the attribute
812 * @param aValue the nsAttrValue to set
813 * @param [out] aRetval the nsresult status of the operation, if any.
814 * @return PR_TRUE if the setting was attempted, PR_FALSE otherwise.
816 virtual PRBool
SetMappedAttribute(nsIDocument
* aDocument
,
822 * Hook that is called by nsGenericElement::SetAttr to allow subclasses to
823 * deal with attribute sets. This will only be called after we verify that
824 * we're actually doing an attr set and will be called before ParseAttribute
825 * and hence before we've set the new value.
827 * @param aNamespaceID the namespace of the attr being set
828 * @param aName the localname of the attribute being set
829 * @param aValue the value it's being set to. If null, the attr is being
831 * @param aNotify Whether we plan to notify document observers.
833 // Note that this is inlined so that when subclasses call it it gets
834 // inlined. Those calls don't go through a vtable.
835 virtual nsresult
BeforeSetAttr(PRInt32 aNamespaceID
, nsIAtom
* aName
,
836 const nsAString
* aValue
, PRBool aNotify
)
842 * Hook that is called by nsGenericElement::SetAttr to allow subclasses to
843 * deal with attribute sets. This will only be called after we have called
844 * SetAndTakeAttr (that is, after we have actually set the attr).
846 * @param aNamespaceID the namespace of the attr being set
847 * @param aName the localname of the attribute being set
848 * @param aValue the value it's being set to. If null, the attr is being
850 * @param aNotify Whether we plan to notify document observers.
852 // Note that this is inlined so that when subclasses call it it gets
853 // inlined. Those calls don't go through a vtable.
854 virtual nsresult
AfterSetAttr(PRInt32 aNamespaceID
, nsIAtom
* aName
,
855 const nsAString
* aValue
, PRBool aNotify
)
861 * Hook to allow subclasses to produce a different nsIEventListenerManager if
862 * needed for attachment of attribute-defined handlers
865 GetEventListenerManagerForAttr(nsIEventListenerManager
** aManager
,
866 nsISupports
** aTarget
,
870 * Get the attr info for the given namespace ID and attribute name. The
871 * namespace ID must not be kNameSpaceID_Unknown and the name must not be
872 * null. Note that this can only return info on attributes that actually
873 * live on this element (and is only virtual to handle XUL prototypes). That
874 * is, this should only be called from methods that only care about attrs
875 * that effectively live in mAttrsAndChildren.
877 virtual nsAttrInfo
GetAttrInfo(PRInt32 aNamespaceID
, nsIAtom
* aName
) const;
880 * Copy attributes and state to another element
881 * @param aDest the object to copy to
883 nsresult
CopyInnerTo(nsGenericElement
* aDest
) const;
886 * Internal hook for converting an attribute name-string to an atomized name
888 virtual const nsAttrName
* InternalGetExistingAttrNameFromQName(const nsAString
& aStr
) const;
891 * Retrieve the rectangle for the offsetX properties, which
892 * are coordinates relative to the returned aOffsetParent.
894 * @param aRect offset rectangle
895 * @param aOffsetParent offset parent
897 virtual void GetOffsetRect(nsRect
& aRect
, nsIContent
** aOffsetParent
);
899 nsIFrame
* GetStyledFrame();
902 // Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
903 // otherwise nsXULElement::nsXULSlots doesn't compile.
905 * There are a set of DOM- and scripting-specific instance variables
906 * that may only be instantiated when a content object is accessed
907 * through the DOM. Rather than burn actual slots in the content
908 * objects for each of these instance variables, we put them off
909 * in a side structure that's only allocated when the content is
910 * accessed through the DOM.
912 class nsDOMSlots
: public nsINode::nsSlots
915 nsDOMSlots(PtrBits aFlags
);
916 virtual ~nsDOMSlots();
919 * The .style attribute (an interface that forwards to the actual
921 * @see nsGenericHTMLElement::GetStyle */
922 nsRefPtr
<nsDOMCSSDeclaration
> mStyle
;
925 * An object implementing nsIDOMNamedNodeMap for this content (attributes)
926 * @see nsGenericElement::GetAttributes
928 nsRefPtr
<nsDOMAttributeMap
> mAttributeMap
;
932 * The nearest enclosing content node with a binding that created us.
933 * @see nsGenericElement::GetBindingParent
935 nsIContent
* mBindingParent
; // [Weak]
938 * The controllers of the XUL Element.
940 nsIControllers
* mControllers
; // [OWNER]
944 * Weak reference to this node
946 nsNodeWeakReference
* mWeakReference
;
949 * An object implementing the .children property for this element.
951 nsRefPtr
<nsContentList
> mChildrenList
;
955 // Override from nsINode
956 virtual nsINode::nsSlots
* CreateSlots();
958 nsDOMSlots
*GetDOMSlots()
960 return static_cast<nsDOMSlots
*>(GetSlots());
963 nsDOMSlots
*GetExistingDOMSlots() const
965 return static_cast<nsDOMSlots
*>(GetExistingSlots());
969 * GetContentsAsText will take all the textnodes that are children
970 * of |this| and concatenate the text in them into aText. It
971 * completely ignores any non-text-node children of |this|; in
972 * particular it does not descend into any children of |this| that
973 * happen to be container elements.
975 * @param aText the resulting text [OUT]
977 void GetContentsAsText(nsAString
& aText
);
980 * Functions to carry out event default actions for links of all types
981 * (HTML links, XLinks, SVG "XLinks", etc.)
985 * Check that we meet the conditions to handle a link event
986 * and that we are actually on a link.
988 * @param aVisitor event visitor
989 * @param aURI the uri of the link, set only if the return value is PR_TRUE [OUT]
990 * @return PR_TRUE if we can handle the link event, PR_FALSE otherwise
992 PRBool
CheckHandleEventForLinksPrecondition(nsEventChainVisitor
& aVisitor
,
993 nsIURI
** aURI
) const;
996 * Handle status bar updates before they can be cancelled.
998 nsresult
PreHandleEventForLinks(nsEventChainPreVisitor
& aVisitor
);
1001 * Handle default actions for link event if the event isn't consumed yet.
1003 nsresult
PostHandleEventForLinks(nsEventChainPostVisitor
& aVisitor
);
1006 * Get the target of this link element. Consumers should established that
1007 * this element is a link (probably using IsLink) before calling this
1008 * function (or else why call it?)
1010 * Note: for HTML this gets the value of the 'target' attribute; for XLink
1011 * this gets the value of the xlink:_moz_target attribute, or failing that,
1012 * the value of xlink:show, converted to a suitably equivalent named target
1015 virtual void GetLinkTarget(nsAString
& aTarget
);
1018 * Array containing all attributes and children for this element
1020 nsAttrAndChildArray mAttrsAndChildren
;
1024 * Macros to implement Clone(). _elementName is the class for which to implement
1027 #define NS_IMPL_ELEMENT_CLONE(_elementName) \
1029 _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
1031 *aResult = nsnull; \
1033 _elementName *it = new _elementName(aNodeInfo); \
1035 return NS_ERROR_OUT_OF_MEMORY; \
1038 nsCOMPtr<nsINode> kungFuDeathGrip = it; \
1039 nsresult rv = CopyInnerTo(it); \
1040 if (NS_SUCCEEDED(rv)) { \
1041 kungFuDeathGrip.swap(*aResult); \
1047 #define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName) \
1049 _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
1051 *aResult = nsnull; \
1053 _elementName *it = new _elementName(aNodeInfo); \
1055 return NS_ERROR_OUT_OF_MEMORY; \
1058 nsCOMPtr<nsINode> kungFuDeathGrip = it; \
1059 nsresult rv = it->Init(); \
1060 rv |= CopyInnerTo(it); \
1061 if (NS_SUCCEEDED(rv)) { \
1062 kungFuDeathGrip.swap(*aResult); \
1069 * Yet another tearoff class for nsGenericElement
1070 * to implement additional interfaces
1072 class nsNSElementTearoff
: public nsIDOMNSElement
1075 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
1077 NS_DECL_NSIDOMNSELEMENT
1079 NS_DECL_CYCLE_COLLECTION_CLASS(nsNSElementTearoff
)
1081 nsNSElementTearoff(nsGenericElement
*aContent
) : mContent(aContent
)
1086 nsContentList
* GetChildrenList();
1088 nsRefPtr
<nsGenericElement
> mContent
;
1091 * Get this element's client area rect in app units.
1092 * @return the frame's client area
1094 nsRect
GetClientAreaRect();
1099 * Get the element's styled frame (the primary frame or, for tables, the inner
1100 * table frame) and closest scrollable view.
1101 * @note This method flushes pending notifications (Flush_Layout).
1102 * @param aScrollableView the scrollable view [OUT]
1103 * @param aFrame (optional) the frame [OUT]
1105 void GetScrollInfo(nsIScrollableView
**aScrollableView
,
1106 nsIFrame
**aFrame
= nsnull
);
1109 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE \
1110 rv = nsGenericElement::QueryInterface(aIID, aInstancePtr); \
1111 if (NS_SUCCEEDED(rv)) \
1114 NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
1116 #define NS_ELEMENT_INTERFACE_MAP_END \
1118 return PostQueryInterface(aIID, aInstancePtr); \
1121 NS_ADDREF(foundInterface); \
1123 *aInstancePtr = foundInterface; \
1128 #endif /* nsGenericElement_h___ */