Bug 454821. Better signature for GetChildArray. r+sr=sicking
[mozilla-central.git] / content / base / src / nsGenericElement.h
blob41d95e6e2222c3a16676699e73f01e608d6655bc
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
13 * License.
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.
22 * Contributor(s):
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___
47 #include "nsCOMPtr.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"
68 class nsIDOMAttr;
69 class nsIDOMEventListener;
70 class nsIFrame;
71 class nsIDOMNamedNodeMap;
72 class nsDOMCSSDeclaration;
73 class nsIDOMCSSStyleDeclaration;
74 class nsIURI;
75 class nsVoidArray;
76 class nsINodeInfo;
77 class nsIControllers;
78 class nsIDOMNSFeatureFactory;
79 class nsIEventListenerManager;
80 class nsIScrollableView;
81 class nsContentList;
82 struct nsRect;
84 typedef unsigned long PtrBits;
86 /**
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.
90 * @see nsIDOMNodeList
92 class nsChildContentList : public nsINodeList,
93 public nsWrapperCache
95 public:
96 nsChildContentList(nsINode* aNode)
97 : mNode(aNode)
101 NS_DECL_ISUPPORTS
103 // nsIDOMNodeList interface
104 NS_DECL_NSIDOMNODELIST
106 // nsINodeList interface
107 virtual nsINode* GetNodeAt(PRUint32 aIndex);
109 void DropReference()
111 mNode = nsnull;
114 nsISupports* GetParentObject()
116 return mNode;
119 static nsChildContentList* FromSupports(nsISupports* aSupports)
121 nsINodeList* list = static_cast<nsINodeList*>(aSupports);
122 #ifdef DEBUG
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!");
131 #endif
132 return static_cast<nsChildContentList*>(list);
135 private:
136 // The node whose children make up the list (weak reference)
137 nsINode* mNode;
141 * A tearoff class for nsGenericElement to implement additional interfaces
143 class nsNode3Tearoff : public nsIDOM3Node
145 public:
146 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
148 NS_DECL_NSIDOM3NODE
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);
167 protected:
168 virtual ~nsNode3Tearoff() {}
170 private:
171 nsCOMPtr<nsIContent> mContent;
175 * A class that implements nsIWeakReference
178 class nsNodeWeakReference : public nsIWeakReference
180 public:
181 nsNodeWeakReference(nsINode* aNode)
182 : mNode(aNode)
186 ~nsNodeWeakReference();
188 // nsISupports
189 NS_DECL_ISUPPORTS
191 // nsIWeakReference
192 NS_DECL_NSIWEAKREFERENCE
194 void NoticeNodeDestruction()
196 mNode = nsnull;
199 private:
200 nsINode* mNode;
204 * Tearoff to use for nodes to implement nsISupportsWeakReference
206 class nsNodeSupportsWeakRefTearoff : public nsISupportsWeakReference
208 public:
209 nsNodeSupportsWeakRefTearoff(nsINode* aNode)
210 : mNode(aNode)
214 // nsISupports
215 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
217 // nsISupportsWeakReference
218 NS_DECL_NSISUPPORTSWEAKREFERENCE
220 NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
222 private:
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
241 private:
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.
258 void LastRelease();
260 nsresult GetDOM3EventTarget(nsIDOM3EventTarget **aTarget);
262 public:
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();
276 // nsISupports
277 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
279 // nsIDOMEventTarget
280 NS_DECL_NSIDOMEVENTTARGET
282 // nsIDOM3EventTarget
283 NS_DECL_NSIDOM3EVENTTARGET
285 // nsIDOMNSEventTarget
286 NS_DECL_NSIDOMNSEVENTTARGET
288 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMEventRTTearoff,
289 nsIDOMEventTarget)
291 private:
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
304 public:
305 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
307 NS_DECL_NSIDOMNODESELECTOR
309 NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSelectorTearoff)
311 nsNodeSelectorTearoff(nsIContent *aContent) : mContent(aContent)
315 private:
316 ~nsNodeSelectorTearoff() {}
318 private:
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
331 public:
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,
351 PRBool aNotify);
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,
361 const nsIID& aIID);
362 virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
363 const nsIID& aIID);
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,
393 nsIAtom* aValue,
394 nsCaseTreatment aCaseSensitive) const;
395 virtual PRInt32 FindAttrValueIn(PRInt32 aNameSpaceID,
396 nsIAtom* aName,
397 AttrValuesArray* aValues,
398 nsCaseTreatment aCaseSensitive) const;
399 virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
400 PRBool aNotify);
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,
406 PRBool aNotify);
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,
413 PRBool aNotify);
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();
430 #ifdef DEBUG
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;
438 #endif
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);
445 NS_IMETHOD_(PRBool)
446 IsAttributeMapped(const nsIAtom* aAttribute) const;
447 virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
448 PRInt32 aModType) const;
450 * Attribute Mapping Helpers
452 struct MappedAttributeEntry {
453 nsIAtom** attribute;
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
460 * handler.
462 static PRBool
463 FindAttributeDependence(const nsIAtom* aAttribute,
464 const MappedAttributeEntry* const aMaps[],
465 PRUint32 aMapCount);
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,
502 nsAString& aReturn);
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,
514 nsAString& aReturn);
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,
530 PRBool* aReturn);
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,
573 PRBool* aReturn);
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,
682 nsIContent* aTarget,
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
690 * event.
691 * If aPresContext is nsnull, this does nothing.
693 static nsresult DispatchEvent(nsPresContext* aPresContext,
694 nsEvent* aEvent,
695 nsIContent* aTarget,
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
712 * Flush_Layout
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.
731 struct nsAttrInfo {
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)
759 protected:
761 * Set attribute and (if needed) notify documentobservers and fire off
762 * mutation events.
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,
778 nsIAtom* aName,
779 nsIAtom* aPrefix,
780 const nsAString& aOldValue,
781 nsAttrValue& aParsedValue,
782 PRBool aModification,
783 PRBool aFireMutation,
784 PRBool aNotify,
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,
799 nsIAtom* aAttribute,
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,
817 nsIAtom* aName,
818 nsAttrValue& aValue,
819 nsresult* aRetval);
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
830 * removed.
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)
838 return NS_OK;
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
849 * removed.
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)
857 return NS_OK;
861 * Hook to allow subclasses to produce a different nsIEventListenerManager if
862 * needed for attachment of attribute-defined handlers
864 virtual nsresult
865 GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
866 nsISupports** aTarget,
867 PRBool* aDefer);
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();
901 public:
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
914 public:
915 nsDOMSlots(PtrBits aFlags);
916 virtual ~nsDOMSlots();
919 * The .style attribute (an interface that forwards to the actual
920 * style rules)
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;
930 union {
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;
954 protected:
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
1013 * (e.g. _blank).
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
1025 * Clone.
1027 #define NS_IMPL_ELEMENT_CLONE(_elementName) \
1028 nsresult \
1029 _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
1031 *aResult = nsnull; \
1033 _elementName *it = new _elementName(aNodeInfo); \
1034 if (!it) { \
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); \
1044 return rv; \
1047 #define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName) \
1048 nsresult \
1049 _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
1051 *aResult = nsnull; \
1053 _elementName *it = new _elementName(aNodeInfo); \
1054 if (!it) { \
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); \
1065 return rv; \
1069 * Yet another tearoff class for nsGenericElement
1070 * to implement additional interfaces
1072 class nsNSElementTearoff : public nsIDOMNSElement
1074 public:
1075 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
1077 NS_DECL_NSIDOMNSELEMENT
1079 NS_DECL_CYCLE_COLLECTION_CLASS(nsNSElementTearoff)
1081 nsNSElementTearoff(nsGenericElement *aContent) : mContent(aContent)
1085 private:
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();
1096 private:
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)) \
1112 return 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; \
1125 return NS_OK; \
1128 #endif /* nsGenericElement_h___ */