1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
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.
21 : *
22 : * Contributor(s):
23 : * Chris Waterson <waterson@netscape.com>
24 : * Peter Annema <disttsc@bart.nl>
25 : * Mike Shaver <shaver@mozilla.org>
26 : * Ben Goodger <ben@netscape.com>
27 : * Mark Hammond <mhammond@skippinet.com.au>
28 : *
29 : * Alternatively, the contents of this file may be used under the terms of
30 : * either of the GNU General Public License Version 2 or later (the "GPL"),
31 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32 : * in which case the provisions of the GPL or the LGPL are applicable instead
33 : * of those above. If you wish to allow use of your version of this file only
34 : * under the terms of either the GPL or the LGPL, and not to allow others to
35 : * use your version of this file under the terms of the MPL, indicate your
36 : * decision by deleting the provisions above and replace them with the notice
37 : * and other provisions required by the GPL or the LGPL. If you do not delete
38 : * the provisions above, a recipient may use your version of this file under
39 : * the terms of any one of the MPL, the GPL or the LGPL.
40 : *
41 : * ***** END LICENSE BLOCK ***** */
42 :
43 : /*
44 :
45 : The base XUL element class and associates.
46 :
47 : */
48 :
49 : #ifndef nsXULElement_h__
50 : #define nsXULElement_h__
51 :
52 : // XXX because nsEventListenerManager has broken includes
53 : #include "nsIDOMEvent.h"
54 : #include "nsIServiceManager.h"
55 : #include "nsIAtom.h"
56 : #include "nsINodeInfo.h"
57 : #include "nsIControllers.h"
58 : #include "nsIDOMElement.h"
59 : #include "nsIDOMEventTarget.h"
60 : #include "nsIDOMXULElement.h"
61 : #include "nsIDOMXULMultSelectCntrlEl.h"
62 : #include "nsEventListenerManager.h"
63 : #include "nsIRDFCompositeDataSource.h"
64 : #include "nsIRDFResource.h"
65 : #include "nsIScriptObjectOwner.h"
66 : #include "nsBindingManager.h"
67 : #include "nsIURI.h"
68 : #include "nsIXULTemplateBuilder.h"
69 : #include "nsIBoxObject.h"
70 : #include "nsIXBLService.h"
71 : #include "nsLayoutCID.h"
72 : #include "nsAttrAndChildArray.h"
73 : #include "nsGkAtoms.h"
74 : #include "nsAutoPtr.h"
75 : #include "nsStyledElement.h"
76 : #include "nsDOMScriptObjectHolder.h"
77 : #include "nsIFrameLoader.h"
78 : #include "jspubtd.h"
79 :
80 : class nsIDocument;
81 : class nsString;
82 : class nsIDocShell;
83 :
84 : class nsIObjectInputStream;
85 : class nsIObjectOutputStream;
86 : class nsIScriptGlobalObjectOwner;
87 : class nsXULPrototypeNode;
88 : typedef nsTArray<nsRefPtr<nsXULPrototypeNode> > nsPrototypeArray;
89 :
90 : namespace mozilla {
91 : namespace css {
92 : class StyleRule;
93 : }
94 : }
95 :
96 : ////////////////////////////////////////////////////////////////////////
97 :
98 : #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
99 : #define XUL_PROTOTYPE_ATTRIBUTE_METER(counter) (nsXULPrototypeAttribute::counter++)
100 : #else
101 : #define XUL_PROTOTYPE_ATTRIBUTE_METER(counter) ((void) 0)
102 : #endif
103 :
104 :
105 : /**
106 :
107 : A prototype attribute for an nsXULPrototypeElement.
108 :
109 : */
110 :
111 : class nsXULPrototypeAttribute
112 : {
113 : public:
114 0 : nsXULPrototypeAttribute()
115 : : mName(nsGkAtoms::id), // XXX this is a hack, but names have to have a value
116 0 : mEventHandler(nsnull)
117 : {
118 : XUL_PROTOTYPE_ATTRIBUTE_METER(gNumAttributes);
119 0 : MOZ_COUNT_CTOR(nsXULPrototypeAttribute);
120 0 : }
121 :
122 : ~nsXULPrototypeAttribute();
123 :
124 : nsAttrName mName;
125 : nsAttrValue mValue;
126 : // mEventHandler is only valid for the language ID specified in the
127 : // containing nsXULPrototypeElement. We would ideally use
128 : // nsScriptObjectHolder, but want to avoid the extra lang ID.
129 : JSObject* mEventHandler;
130 :
131 : #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
132 : /**
133 : If enough attributes, on average, are event handlers, it pays to keep
134 : mEventHandler here, instead of maintaining a separate mapping in each
135 : nsXULElement associating those mName values with their mEventHandlers.
136 : Assume we don't need to keep mNameSpaceID along with mName in such an
137 : event-handler-only name-to-function-pointer mapping.
138 :
139 : Let
140 : minAttrSize = sizeof(mNodeInof) + sizeof(mValue)
141 : mappingSize = sizeof(mNodeInfo) + sizeof(mEventHandler)
142 : elemOverhead = nElems * sizeof(MappingPtr)
143 :
144 : Then
145 : nAttrs * minAttrSize + nEventHandlers * mappingSize + elemOverhead
146 : > nAttrs * (minAttrSize + mappingSize - sizeof(mNodeInfo))
147 : which simplifies to
148 : nEventHandlers * mappingSize + elemOverhead
149 : > nAttrs * (mappingSize - sizeof(mNodeInfo))
150 : or
151 : nEventHandlers + (nElems * sizeof(MappingPtr)) / mappingSize
152 : > nAttrs * (1 - sizeof(mNodeInfo) / mappingSize)
153 :
154 : If nsCOMPtr and all other pointers are the same size, this reduces to
155 : nEventHandlers + nElems / 2 > nAttrs / 2
156 :
157 : To measure how many attributes are event handlers, compile XUL source
158 : with XUL_PROTOTYPE_ATTRIBUTE_METERING and watch the counters below.
159 : Plug into the above relation -- if true, it pays to put mEventHandler
160 : in nsXULPrototypeAttribute rather than to keep a separate mapping.
161 :
162 : Recent numbers after opening four browser windows:
163 : nElems 3537, nAttrs 2528, nEventHandlers 1042
164 : giving 1042 + 3537/2 > 2528/2 or 2810 > 1264.
165 :
166 : As it happens, mEventHandler also makes this struct power-of-2 sized,
167 : 8 words on most architectures, which makes for strength-reduced array
168 : index-to-pointer calculations.
169 : */
170 : static PRUint32 gNumElements;
171 : static PRUint32 gNumAttributes;
172 : static PRUint32 gNumEventHandlers;
173 : static PRUint32 gNumCacheTests;
174 : static PRUint32 gNumCacheHits;
175 : static PRUint32 gNumCacheSets;
176 : static PRUint32 gNumCacheFills;
177 : #endif /* !XUL_PROTOTYPE_ATTRIBUTE_METERING */
178 : };
179 :
180 :
181 : /**
182 :
183 : A prototype content model element that holds the "primordial" values
184 : that have been parsed from the original XUL document. A
185 : 'lightweight' nsXULElement may delegate its representation to this
186 : structure, which is shared.
187 :
188 : */
189 :
190 : class nsXULPrototypeNode
191 : {
192 : public:
193 : enum Type { eType_Element, eType_Script, eType_Text, eType_PI };
194 :
195 : Type mType;
196 :
197 : nsAutoRefCnt mRefCnt;
198 :
199 0 : virtual ~nsXULPrototypeNode() {}
200 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
201 : nsIScriptGlobalObject* aGlobal,
202 : const nsCOMArray<nsINodeInfo> *aNodeInfos) = 0;
203 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
204 : nsIScriptGlobalObject* aGlobal,
205 : nsIURI* aDocumentURI,
206 : const nsCOMArray<nsINodeInfo> *aNodeInfos) = 0;
207 :
208 : #ifdef NS_BUILD_REFCNT_LOGGING
209 : virtual const char* ClassName() = 0;
210 : virtual PRUint32 ClassSize() = 0;
211 : #endif
212 :
213 0 : void AddRef() {
214 0 : ++mRefCnt;
215 0 : NS_LOG_ADDREF(this, mRefCnt, ClassName(), ClassSize());
216 0 : }
217 0 : void Release()
218 : {
219 0 : --mRefCnt;
220 0 : NS_LOG_RELEASE(this, mRefCnt, ClassName());
221 0 : if (mRefCnt == 0)
222 0 : delete this;
223 0 : }
224 : /**
225 : * The prototype document must call ReleaseSubtree when it is going
226 : * away. This makes the parents through the tree stop owning their
227 : * children, whether or not the parent's reference count is zero.
228 : * Individual elements may still own individual prototypes, but
229 : * those prototypes no longer remember their children to allow them
230 : * to be constructed.
231 : */
232 0 : virtual void ReleaseSubtree() { }
233 :
234 1396 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsXULPrototypeNode)
235 :
236 : protected:
237 0 : nsXULPrototypeNode(Type aType)
238 0 : : mType(aType) {}
239 : };
240 :
241 : class nsXULPrototypeElement : public nsXULPrototypeNode
242 : {
243 : public:
244 0 : nsXULPrototypeElement()
245 : : nsXULPrototypeNode(eType_Element),
246 : mNumAttributes(0),
247 : mAttributes(nsnull),
248 : mHasIdAttribute(false),
249 : mHasClassAttribute(false),
250 : mHasStyleAttribute(false),
251 : mHoldsScriptObject(false),
252 0 : mScriptTypeID(nsIProgrammingLanguage::UNKNOWN)
253 : {
254 0 : }
255 :
256 0 : virtual ~nsXULPrototypeElement()
257 0 : {
258 0 : Unlink();
259 0 : }
260 :
261 : #ifdef NS_BUILD_REFCNT_LOGGING
262 0 : virtual const char* ClassName() { return "nsXULPrototypeElement"; }
263 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
264 : #endif
265 :
266 0 : virtual void ReleaseSubtree()
267 : {
268 0 : for (PRInt32 i = mChildren.Length() - 1; i >= 0; i--) {
269 0 : if (mChildren[i].get())
270 0 : mChildren[i]->ReleaseSubtree();
271 : }
272 0 : mChildren.Clear();
273 0 : nsXULPrototypeNode::ReleaseSubtree();
274 0 : }
275 :
276 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
277 : nsIScriptGlobalObject* aGlobal,
278 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
279 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
280 : nsIScriptGlobalObject* aGlobal,
281 : nsIURI* aDocumentURI,
282 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
283 :
284 : nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI);
285 :
286 : void Unlink();
287 :
288 : nsPrototypeArray mChildren;
289 :
290 : nsCOMPtr<nsINodeInfo> mNodeInfo; // [OWNER]
291 :
292 : PRUint32 mNumAttributes;
293 : nsXULPrototypeAttribute* mAttributes; // [OWNER]
294 :
295 : bool mHasIdAttribute:1;
296 : bool mHasClassAttribute:1;
297 : bool mHasStyleAttribute:1;
298 : bool mHoldsScriptObject:1;
299 :
300 : // The language ID can not be set on a per-node basis, but is tracked
301 : // so that the language ID from the originating root can be used
302 : // (eg, when a node from an overlay ends up in our document, that node
303 : // must use its original script language, not our document's default.
304 : PRUint16 mScriptTypeID;
305 : };
306 :
307 : class nsXULDocument;
308 :
309 : class nsXULPrototypeScript : public nsXULPrototypeNode
310 : {
311 : public:
312 : nsXULPrototypeScript(PRUint32 aLangID, PRUint32 aLineNo, PRUint32 version);
313 : virtual ~nsXULPrototypeScript();
314 :
315 : #ifdef NS_BUILD_REFCNT_LOGGING
316 0 : virtual const char* ClassName() { return "nsXULPrototypeScript"; }
317 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
318 : #endif
319 :
320 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
321 : nsIScriptGlobalObject* aGlobal,
322 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
323 : nsresult SerializeOutOfLine(nsIObjectOutputStream* aStream,
324 : nsIScriptGlobalObject* aGlobal);
325 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
326 : nsIScriptGlobalObject* aGlobal,
327 : nsIURI* aDocumentURI,
328 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
329 : nsresult DeserializeOutOfLine(nsIObjectInputStream* aInput,
330 : nsIScriptGlobalObject* aGlobal);
331 :
332 : nsresult Compile(const PRUnichar* aText, PRInt32 aTextLength,
333 : nsIURI* aURI, PRUint32 aLineNo,
334 : nsIDocument* aDocument,
335 : nsIScriptGlobalObjectOwner* aGlobalOwner);
336 :
337 : void UnlinkJSObjects();
338 :
339 0 : void Set(nsScriptObjectHolder<JSScript>& aHolder)
340 : {
341 0 : NS_ASSERTION(mScriptObject.mLangID == aHolder.getScriptTypeID(),
342 : "Wrong language, this will leak the previous object.");
343 :
344 0 : mScriptObject.mLangID = aHolder.getScriptTypeID();
345 0 : Set(aHolder.get());
346 0 : }
347 : void Set(JSScript* aObject);
348 :
349 : struct ScriptObjectHolder
350 : {
351 0 : ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID),
352 0 : mObject(nsnull)
353 : {
354 0 : }
355 : PRUint32 mLangID;
356 : JSScript* mObject;
357 : };
358 : nsCOMPtr<nsIURI> mSrcURI;
359 : PRUint32 mLineNo;
360 : bool mSrcLoading;
361 : bool mOutOfLine;
362 : nsXULDocument* mSrcLoadWaiters; // [OWNER] but not COMPtr
363 : PRUint32 mLangVersion;
364 : ScriptObjectHolder mScriptObject;
365 : };
366 :
367 : class nsXULPrototypeText : public nsXULPrototypeNode
368 : {
369 : public:
370 0 : nsXULPrototypeText()
371 0 : : nsXULPrototypeNode(eType_Text)
372 : {
373 0 : }
374 :
375 0 : virtual ~nsXULPrototypeText()
376 0 : {
377 0 : }
378 :
379 : #ifdef NS_BUILD_REFCNT_LOGGING
380 0 : virtual const char* ClassName() { return "nsXULPrototypeText"; }
381 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
382 : #endif
383 :
384 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
385 : nsIScriptGlobalObject* aGlobal,
386 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
387 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
388 : nsIScriptGlobalObject* aGlobal,
389 : nsIURI* aDocumentURI,
390 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
391 :
392 : nsString mValue;
393 : };
394 :
395 : class nsXULPrototypePI : public nsXULPrototypeNode
396 : {
397 : public:
398 0 : nsXULPrototypePI()
399 0 : : nsXULPrototypeNode(eType_PI)
400 : {
401 0 : }
402 :
403 0 : virtual ~nsXULPrototypePI()
404 0 : {
405 0 : }
406 :
407 : #ifdef NS_BUILD_REFCNT_LOGGING
408 0 : virtual const char* ClassName() { return "nsXULPrototypePI"; }
409 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
410 : #endif
411 :
412 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
413 : nsIScriptGlobalObject* aGlobal,
414 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
415 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
416 : nsIScriptGlobalObject* aGlobal,
417 : nsIURI* aDocumentURI,
418 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
419 :
420 : nsString mTarget;
421 : nsString mData;
422 : };
423 :
424 : ////////////////////////////////////////////////////////////////////////
425 :
426 : /**
427 :
428 : The XUL element.
429 :
430 : */
431 :
432 : #define XUL_ELEMENT_TEMPLATE_GENERATED (1 << ELEMENT_TYPE_SPECIFIC_BITS_OFFSET)
433 :
434 : // Make sure we have space for our bit
435 : PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET < 32);
436 :
437 : class nsScriptEventHandlerOwnerTearoff;
438 :
439 : class nsXULElement : public nsStyledElement, public nsIDOMXULElement
440 576 : {
441 : public:
442 :
443 : /** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/
444 138385 : static nsXULElement* FromContent(nsIContent *aContent)
445 : {
446 138385 : if (aContent->IsXUL())
447 504 : return static_cast<nsXULElement*>(aContent);
448 137881 : return nsnull;
449 : }
450 :
451 : public:
452 : static nsIXBLService* GetXBLService() {
453 : if (!gXBLService)
454 : CallGetService("@mozilla.org/xbl;1", &gXBLService);
455 : return gXBLService;
456 : }
457 1364 : static void ReleaseGlobals() {
458 1364 : NS_IF_RELEASE(gXBLService);
459 1364 : }
460 :
461 : protected:
462 : // pseudo-constants
463 : static nsIXBLService* gXBLService;
464 :
465 : public:
466 : nsXULElement(already_AddRefed<nsINodeInfo> aNodeInfo);
467 :
468 : static nsresult
469 : Create(nsXULPrototypeElement* aPrototype, nsIDocument* aDocument,
470 : bool aIsScriptable, mozilla::dom::Element** aResult);
471 :
472 : // nsISupports
473 : NS_DECL_ISUPPORTS_INHERITED
474 1540 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXULElement,
475 : nsGenericElement)
476 :
477 : // nsINode
478 : virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
479 :
480 : // nsIContent
481 : virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
482 : nsIContent* aBindingParent,
483 : bool aCompileEventHandlers);
484 : virtual void UnbindFromTree(bool aDeep, bool aNullParent);
485 : virtual nsresult RemoveChildAt(PRUint32 aIndex, bool aNotify);
486 : virtual bool GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
487 : nsAString& aResult) const;
488 : virtual bool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const;
489 : virtual bool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
490 : const nsAString& aValue,
491 : nsCaseTreatment aCaseSensitive) const;
492 : virtual bool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
493 : nsIAtom* aValue,
494 : nsCaseTreatment aCaseSensitive) const;
495 : virtual PRInt32 FindAttrValueIn(PRInt32 aNameSpaceID,
496 : nsIAtom* aName,
497 : AttrValuesArray* aValues,
498 : nsCaseTreatment aCaseSensitive) const;
499 : virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
500 : bool aNotify);
501 : virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
502 : virtual PRUint32 GetAttrCount() const;
503 : virtual void DestroyContent();
504 :
505 : #ifdef DEBUG
506 : virtual void List(FILE* out, PRInt32 aIndent) const;
507 0 : virtual void DumpContent(FILE* out, PRInt32 aIndent,bool aDumpAll) const
508 : {
509 0 : }
510 : #endif
511 :
512 : virtual void PerformAccesskey(bool aKeyCausesActivation,
513 : bool aIsTrustedEvent);
514 : nsresult ClickWithInputSource(PRUint16 aInputSource);
515 :
516 : virtual nsIContent *GetBindingParent() const;
517 : virtual bool IsNodeOfType(PRUint32 aFlags) const;
518 : virtual bool IsFocusable(PRInt32 *aTabIndex = nsnull, bool aWithMouse = false);
519 : virtual nsIAtom* DoGetID() const;
520 : virtual const nsAttrValue* DoGetClasses() const;
521 :
522 : NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
523 : virtual mozilla::css::StyleRule* GetInlineStyleRule();
524 : virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
525 : PRInt32 aModType) const;
526 : NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
527 :
528 : // XUL element methods
529 : /**
530 : * The template-generated flag is used to indicate that a
531 : * template-generated element has already had its children generated.
532 : */
533 0 : void SetTemplateGenerated() { SetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
534 0 : void ClearTemplateGenerated() { UnsetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
535 0 : bool GetTemplateGenerated() { return HasFlag(XUL_ELEMENT_TEMPLATE_GENERATED); }
536 :
537 : // nsIDOMNode
538 0 : NS_FORWARD_NSIDOMNODE(nsGenericElement::)
539 :
540 : // nsIDOMElement
541 0 : NS_FORWARD_NSIDOMELEMENT(nsGenericElement::)
542 :
543 : // nsIDOMXULElement
544 : NS_DECL_NSIDOMXULELEMENT
545 :
546 : virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
547 : virtual nsEventStates IntrinsicState() const;
548 :
549 : nsresult EnsureLocalStyle();
550 :
551 : nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
552 : already_AddRefed<nsFrameLoader> GetFrameLoader();
553 : nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
554 :
555 : virtual void RecompileScriptEventListeners();
556 :
557 : // This function should ONLY be used by BindToTree implementations.
558 : // The function exists solely because XUL elements store the binding
559 : // parent as a member instead of in the slots, as nsGenericElement does.
560 504 : void SetXULBindingParent(nsIContent* aBindingParent)
561 : {
562 504 : mBindingParent = aBindingParent;
563 504 : }
564 :
565 : /**
566 : * Get the attr info for the given namespace ID and attribute name.
567 : * The namespace ID must not be kNameSpaceID_Unknown and the name
568 : * must not be null.
569 : */
570 : virtual nsAttrInfo GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const;
571 :
572 : virtual nsXPCClassInfo* GetClassInfo();
573 : protected:
574 : // XXX This can be removed when nsNodeUtils::CloneAndAdopt doesn't need
575 : // access to mPrototype anymore.
576 : friend class nsNodeUtils;
577 :
578 : // This can be removed if EnsureContentsGenerated dies.
579 : friend class nsNSElementTearoff;
580 :
581 : // Implementation methods
582 : nsresult EnsureContentsGenerated(void) const;
583 :
584 : nsresult ExecuteOnBroadcastHandler(nsIDOMElement* anElement, const nsAString& attrName);
585 :
586 : static nsresult
587 : ExecuteJSCode(nsIDOMElement* anElement, nsEvent* aEvent);
588 :
589 : // Helper routine that crawls a parent chain looking for a tree element.
590 : NS_IMETHOD GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement);
591 :
592 : nsresult AddPopupListener(nsIAtom* aName);
593 :
594 : class nsXULSlots : public nsGenericElement::nsDOMSlots
595 : {
596 : public:
597 : nsXULSlots();
598 : virtual ~nsXULSlots();
599 :
600 : void Traverse(nsCycleCollectionTraversalCallback &cb);
601 :
602 : nsRefPtr<nsFrameLoader> mFrameLoader;
603 : };
604 :
605 : virtual nsINode::nsSlots* CreateSlots();
606 :
607 : nsresult LoadSrc();
608 :
609 : // Required fields
610 : nsRefPtr<nsXULPrototypeElement> mPrototype;
611 :
612 : /**
613 : * The nearest enclosing content node with a binding
614 : * that created us. [Weak]
615 : */
616 : nsIContent* mBindingParent;
617 :
618 : /**
619 : * Abandon our prototype linkage, and copy all attributes locally
620 : */
621 : nsresult MakeHeavyweight();
622 :
623 1253 : const nsAttrValue* FindLocalOrProtoAttr(PRInt32 aNameSpaceID,
624 : nsIAtom *aName) const {
625 1253 : return nsXULElement::GetAttrInfo(aNameSpaceID, aName).mValue;
626 : }
627 :
628 : virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
629 : const nsAttrValueOrString* aValue,
630 : bool aNotify);
631 : virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
632 : const nsAttrValue* aValue, bool aNotify);
633 :
634 : virtual void UpdateEditableState(bool aNotify);
635 :
636 : virtual bool ParseAttribute(PRInt32 aNamespaceID,
637 : nsIAtom* aAttribute,
638 : const nsAString& aValue,
639 : nsAttrValue& aResult);
640 :
641 : virtual nsEventListenerManager*
642 : GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer);
643 :
644 : /**
645 : * Return our prototype's attribute, if one exists.
646 : */
647 : nsXULPrototypeAttribute *FindPrototypeAttribute(PRInt32 aNameSpaceID,
648 : nsIAtom *aName) const;
649 : /**
650 : * Add a listener for the specified attribute, if appropriate.
651 : */
652 : void AddListenerFor(const nsAttrName& aName,
653 : bool aCompileEventHandlers);
654 : void MaybeAddPopupListener(nsIAtom* aLocalName);
655 :
656 : nsIWidget* GetWindowWidget();
657 :
658 : // attribute setters for widget
659 : nsresult HideWindowChrome(bool aShouldHide);
660 : void SetChromeMargins(const nsAttrValue* aValue);
661 : void ResetChromeMargins();
662 : void SetTitlebarColor(nscolor aColor, bool aActive);
663 :
664 : void SetDrawsInTitlebar(bool aState);
665 :
666 : const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
667 :
668 : void RemoveBroadcaster(const nsAString & broadcasterId);
669 :
670 : protected:
671 : // Internal accessor. This shadows the 'Slots', and returns
672 : // appropriate value.
673 0 : nsIControllers *Controllers() {
674 0 : nsDOMSlots* slots = GetExistingDOMSlots();
675 0 : return slots ? slots->mControllers : nsnull;
676 : }
677 :
678 : void UnregisterAccessKey(const nsAString& aOldValue);
679 : bool BoolAttrIsTrue(nsIAtom* aName);
680 :
681 : friend nsresult
682 : NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
683 : friend void
684 : NS_TrustedNewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
685 :
686 : static already_AddRefed<nsXULElement>
687 : Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
688 : bool aIsScriptable);
689 :
690 : friend class nsScriptEventHandlerOwnerTearoff;
691 :
692 472 : bool IsReadWriteTextElement() const
693 : {
694 472 : const nsIAtom* tag = Tag();
695 : return
696 472 : GetNameSpaceID() == kNameSpaceID_XUL &&
697 : (tag == nsGkAtoms::textbox || tag == nsGkAtoms::textarea) &&
698 472 : !HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
699 : }
700 : };
701 :
702 : #endif // nsXULElement_h__
|