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 : public nsISupports
191 : {
192 : public:
193 : enum Type { eType_Element, eType_Script, eType_Text, eType_PI };
194 :
195 : Type mType;
196 :
197 0 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
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 : /**
214 : * The prototype document must call ReleaseSubtree when it is going
215 : * away. This makes the parents through the tree stop owning their
216 : * children, whether or not the parent's reference count is zero.
217 : * Individual elements may still own individual prototypes, but
218 : * those prototypes no longer remember their children to allow them
219 : * to be constructed.
220 : */
221 0 : virtual void ReleaseSubtree() { }
222 :
223 1464 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsXULPrototypeNode)
224 :
225 : protected:
226 0 : nsXULPrototypeNode(Type aType)
227 0 : : mType(aType) {}
228 : };
229 :
230 : class nsXULPrototypeElement : public nsXULPrototypeNode
231 : {
232 : public:
233 0 : nsXULPrototypeElement()
234 : : nsXULPrototypeNode(eType_Element),
235 : mNumAttributes(0),
236 : mAttributes(nsnull),
237 : mHasIdAttribute(false),
238 : mHasClassAttribute(false),
239 : mHasStyleAttribute(false),
240 : mHoldsScriptObject(false),
241 0 : mScriptTypeID(nsIProgrammingLanguage::UNKNOWN)
242 : {
243 0 : }
244 :
245 0 : virtual ~nsXULPrototypeElement()
246 0 : {
247 0 : Unlink();
248 0 : }
249 :
250 : #ifdef NS_BUILD_REFCNT_LOGGING
251 0 : virtual const char* ClassName() { return "nsXULPrototypeElement"; }
252 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
253 : #endif
254 :
255 0 : virtual void ReleaseSubtree()
256 : {
257 0 : for (PRInt32 i = mChildren.Length() - 1; i >= 0; i--) {
258 0 : if (mChildren[i].get())
259 0 : mChildren[i]->ReleaseSubtree();
260 : }
261 0 : mChildren.Clear();
262 0 : nsXULPrototypeNode::ReleaseSubtree();
263 0 : }
264 :
265 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
266 : nsIScriptGlobalObject* aGlobal,
267 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
268 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
269 : nsIScriptGlobalObject* aGlobal,
270 : nsIURI* aDocumentURI,
271 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
272 :
273 : nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI);
274 :
275 : void Unlink();
276 :
277 : nsPrototypeArray mChildren;
278 :
279 : nsCOMPtr<nsINodeInfo> mNodeInfo; // [OWNER]
280 :
281 : PRUint32 mNumAttributes;
282 : nsXULPrototypeAttribute* mAttributes; // [OWNER]
283 :
284 : bool mHasIdAttribute:1;
285 : bool mHasClassAttribute:1;
286 : bool mHasStyleAttribute:1;
287 : bool mHoldsScriptObject:1;
288 :
289 : // The language ID can not be set on a per-node basis, but is tracked
290 : // so that the language ID from the originating root can be used
291 : // (eg, when a node from an overlay ends up in our document, that node
292 : // must use its original script language, not our document's default.
293 : PRUint16 mScriptTypeID;
294 : };
295 :
296 : class nsXULDocument;
297 :
298 : class nsXULPrototypeScript : public nsXULPrototypeNode
299 : {
300 : public:
301 : nsXULPrototypeScript(PRUint32 aLangID, PRUint32 aLineNo, PRUint32 version);
302 : virtual ~nsXULPrototypeScript();
303 :
304 : #ifdef NS_BUILD_REFCNT_LOGGING
305 0 : virtual const char* ClassName() { return "nsXULPrototypeScript"; }
306 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
307 : #endif
308 :
309 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
310 : nsIScriptGlobalObject* aGlobal,
311 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
312 : nsresult SerializeOutOfLine(nsIObjectOutputStream* aStream,
313 : nsIScriptGlobalObject* aGlobal);
314 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
315 : nsIScriptGlobalObject* aGlobal,
316 : nsIURI* aDocumentURI,
317 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
318 : nsresult DeserializeOutOfLine(nsIObjectInputStream* aInput,
319 : nsIScriptGlobalObject* aGlobal);
320 :
321 : nsresult Compile(const PRUnichar* aText, PRInt32 aTextLength,
322 : nsIURI* aURI, PRUint32 aLineNo,
323 : nsIDocument* aDocument,
324 : nsIScriptGlobalObjectOwner* aGlobalOwner);
325 :
326 : void UnlinkJSObjects();
327 :
328 0 : void Set(nsScriptObjectHolder<JSScript>& aHolder)
329 : {
330 0 : NS_ASSERTION(mScriptObject.mLangID == aHolder.getScriptTypeID(),
331 : "Wrong language, this will leak the previous object.");
332 :
333 0 : mScriptObject.mLangID = aHolder.getScriptTypeID();
334 0 : Set(aHolder.get());
335 0 : }
336 : void Set(JSScript* aObject);
337 :
338 : struct ScriptObjectHolder
339 : {
340 0 : ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID),
341 0 : mObject(nsnull)
342 : {
343 0 : }
344 : PRUint32 mLangID;
345 : JSScript* mObject;
346 : };
347 : nsCOMPtr<nsIURI> mSrcURI;
348 : PRUint32 mLineNo;
349 : bool mSrcLoading;
350 : bool mOutOfLine;
351 : nsXULDocument* mSrcLoadWaiters; // [OWNER] but not COMPtr
352 : PRUint32 mLangVersion;
353 : ScriptObjectHolder mScriptObject;
354 : };
355 :
356 : class nsXULPrototypeText : public nsXULPrototypeNode
357 : {
358 : public:
359 0 : nsXULPrototypeText()
360 0 : : nsXULPrototypeNode(eType_Text)
361 : {
362 0 : }
363 :
364 0 : virtual ~nsXULPrototypeText()
365 0 : {
366 0 : }
367 :
368 : #ifdef NS_BUILD_REFCNT_LOGGING
369 0 : virtual const char* ClassName() { return "nsXULPrototypeText"; }
370 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
371 : #endif
372 :
373 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
374 : nsIScriptGlobalObject* aGlobal,
375 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
376 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
377 : nsIScriptGlobalObject* aGlobal,
378 : nsIURI* aDocumentURI,
379 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
380 :
381 : nsString mValue;
382 : };
383 :
384 : class nsXULPrototypePI : public nsXULPrototypeNode
385 : {
386 : public:
387 0 : nsXULPrototypePI()
388 0 : : nsXULPrototypeNode(eType_PI)
389 : {
390 0 : }
391 :
392 0 : virtual ~nsXULPrototypePI()
393 0 : {
394 0 : }
395 :
396 : #ifdef NS_BUILD_REFCNT_LOGGING
397 0 : virtual const char* ClassName() { return "nsXULPrototypePI"; }
398 0 : virtual PRUint32 ClassSize() { return sizeof(*this); }
399 : #endif
400 :
401 : virtual nsresult Serialize(nsIObjectOutputStream* aStream,
402 : nsIScriptGlobalObject* aGlobal,
403 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
404 : virtual nsresult Deserialize(nsIObjectInputStream* aStream,
405 : nsIScriptGlobalObject* aGlobal,
406 : nsIURI* aDocumentURI,
407 : const nsCOMArray<nsINodeInfo> *aNodeInfos);
408 :
409 : nsString mTarget;
410 : nsString mData;
411 : };
412 :
413 : ////////////////////////////////////////////////////////////////////////
414 :
415 : /**
416 :
417 : The XUL element.
418 :
419 : */
420 :
421 : #define XUL_ELEMENT_TEMPLATE_GENERATED (1 << ELEMENT_TYPE_SPECIFIC_BITS_OFFSET)
422 :
423 : // Make sure we have space for our bit
424 : PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET < 32);
425 :
426 : class nsScriptEventHandlerOwnerTearoff;
427 :
428 : class nsXULElement : public nsStyledElement, public nsIDOMXULElement
429 576 : {
430 : public:
431 :
432 : /** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/
433 156681 : static nsXULElement* FromContent(nsIContent *aContent)
434 : {
435 156681 : if (aContent->IsXUL())
436 579 : return static_cast<nsXULElement*>(aContent);
437 156102 : return nsnull;
438 : }
439 :
440 : public:
441 : static nsIXBLService* GetXBLService() {
442 : if (!gXBLService)
443 : CallGetService("@mozilla.org/xbl;1", &gXBLService);
444 : return gXBLService;
445 : }
446 1403 : static void ReleaseGlobals() {
447 1403 : NS_IF_RELEASE(gXBLService);
448 1403 : }
449 :
450 : protected:
451 : // pseudo-constants
452 : static nsIXBLService* gXBLService;
453 :
454 : public:
455 : nsXULElement(already_AddRefed<nsINodeInfo> aNodeInfo);
456 :
457 : static nsresult
458 : Create(nsXULPrototypeElement* aPrototype, nsIDocument* aDocument,
459 : bool aIsScriptable, mozilla::dom::Element** aResult);
460 :
461 : // nsISupports
462 : NS_DECL_ISUPPORTS_INHERITED
463 1608 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXULElement,
464 : nsGenericElement)
465 :
466 : // nsINode
467 : virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
468 :
469 : // nsIContent
470 : virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
471 : nsIContent* aBindingParent,
472 : bool aCompileEventHandlers);
473 : virtual void UnbindFromTree(bool aDeep, bool aNullParent);
474 : virtual nsresult RemoveChildAt(PRUint32 aIndex, bool aNotify);
475 : virtual bool GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
476 : nsAString& aResult) const;
477 : virtual bool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const;
478 : virtual bool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
479 : const nsAString& aValue,
480 : nsCaseTreatment aCaseSensitive) const;
481 : virtual bool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
482 : nsIAtom* aValue,
483 : nsCaseTreatment aCaseSensitive) const;
484 : virtual PRInt32 FindAttrValueIn(PRInt32 aNameSpaceID,
485 : nsIAtom* aName,
486 : AttrValuesArray* aValues,
487 : nsCaseTreatment aCaseSensitive) const;
488 : virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
489 : bool aNotify);
490 : virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
491 : virtual PRUint32 GetAttrCount() const;
492 : virtual void DestroyContent();
493 :
494 : #ifdef DEBUG
495 : virtual void List(FILE* out, PRInt32 aIndent) const;
496 0 : virtual void DumpContent(FILE* out, PRInt32 aIndent,bool aDumpAll) const
497 : {
498 0 : }
499 : #endif
500 :
501 : virtual void PerformAccesskey(bool aKeyCausesActivation,
502 : bool aIsTrustedEvent);
503 : nsresult ClickWithInputSource(PRUint16 aInputSource);
504 :
505 : virtual nsIContent *GetBindingParent() const;
506 : virtual bool IsNodeOfType(PRUint32 aFlags) const;
507 : virtual bool IsFocusable(PRInt32 *aTabIndex = nsnull, bool aWithMouse = false);
508 : virtual nsIAtom* DoGetID() const;
509 : virtual const nsAttrValue* DoGetClasses() const;
510 :
511 : NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
512 : virtual mozilla::css::StyleRule* GetInlineStyleRule();
513 : virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
514 : PRInt32 aModType) const;
515 : NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
516 :
517 : // XUL element methods
518 : /**
519 : * The template-generated flag is used to indicate that a
520 : * template-generated element has already had its children generated.
521 : */
522 0 : void SetTemplateGenerated() { SetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
523 0 : void ClearTemplateGenerated() { UnsetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
524 0 : bool GetTemplateGenerated() { return HasFlag(XUL_ELEMENT_TEMPLATE_GENERATED); }
525 :
526 : // nsIDOMNode
527 0 : NS_FORWARD_NSIDOMNODE(nsGenericElement::)
528 :
529 : // nsIDOMElement
530 0 : NS_FORWARD_NSIDOMELEMENT(nsGenericElement::)
531 :
532 : // nsIDOMXULElement
533 : NS_DECL_NSIDOMXULELEMENT
534 :
535 : virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
536 : virtual nsEventStates IntrinsicState() const;
537 :
538 : nsresult EnsureLocalStyle();
539 :
540 : nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
541 : already_AddRefed<nsFrameLoader> GetFrameLoader();
542 : nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
543 :
544 : virtual void RecompileScriptEventListeners();
545 :
546 : // This function should ONLY be used by BindToTree implementations.
547 : // The function exists solely because XUL elements store the binding
548 : // parent as a member instead of in the slots, as nsGenericElement does.
549 579 : void SetXULBindingParent(nsIContent* aBindingParent)
550 : {
551 579 : mBindingParent = aBindingParent;
552 579 : }
553 :
554 : /**
555 : * Get the attr info for the given namespace ID and attribute name.
556 : * The namespace ID must not be kNameSpaceID_Unknown and the name
557 : * must not be null.
558 : */
559 : virtual nsAttrInfo GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const;
560 :
561 : virtual nsXPCClassInfo* GetClassInfo();
562 : protected:
563 : // XXX This can be removed when nsNodeUtils::CloneAndAdopt doesn't need
564 : // access to mPrototype anymore.
565 : friend class nsNodeUtils;
566 :
567 : // This can be removed if EnsureContentsGenerated dies.
568 : friend class nsNSElementTearoff;
569 :
570 : // Implementation methods
571 : nsresult EnsureContentsGenerated(void) const;
572 :
573 : nsresult ExecuteOnBroadcastHandler(nsIDOMElement* anElement, const nsAString& attrName);
574 :
575 : static nsresult
576 : ExecuteJSCode(nsIDOMElement* anElement, nsEvent* aEvent);
577 :
578 : // Helper routine that crawls a parent chain looking for a tree element.
579 : NS_IMETHOD GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement);
580 :
581 : nsresult AddPopupListener(nsIAtom* aName);
582 :
583 : class nsXULSlots : public nsGenericElement::nsDOMSlots
584 : {
585 : public:
586 : nsXULSlots();
587 : virtual ~nsXULSlots();
588 :
589 : void Traverse(nsCycleCollectionTraversalCallback &cb);
590 :
591 : nsRefPtr<nsFrameLoader> mFrameLoader;
592 : };
593 :
594 : virtual nsINode::nsSlots* CreateSlots();
595 :
596 : nsresult LoadSrc();
597 :
598 : // Required fields
599 : nsRefPtr<nsXULPrototypeElement> mPrototype;
600 :
601 : /**
602 : * The nearest enclosing content node with a binding
603 : * that created us. [Weak]
604 : */
605 : nsIContent* mBindingParent;
606 :
607 : /**
608 : * Abandon our prototype linkage, and copy all attributes locally
609 : */
610 : nsresult MakeHeavyweight();
611 :
612 1253 : const nsAttrValue* FindLocalOrProtoAttr(PRInt32 aNameSpaceID,
613 : nsIAtom *aName) const {
614 1253 : return nsXULElement::GetAttrInfo(aNameSpaceID, aName).mValue;
615 : }
616 :
617 : virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
618 : const nsAttrValueOrString* aValue,
619 : bool aNotify);
620 : virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
621 : const nsAttrValue* aValue, bool aNotify);
622 :
623 : virtual void UpdateEditableState(bool aNotify);
624 :
625 : virtual bool ParseAttribute(PRInt32 aNamespaceID,
626 : nsIAtom* aAttribute,
627 : const nsAString& aValue,
628 : nsAttrValue& aResult);
629 :
630 : virtual nsEventListenerManager*
631 : GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer);
632 :
633 : /**
634 : * Return our prototype's attribute, if one exists.
635 : */
636 : nsXULPrototypeAttribute *FindPrototypeAttribute(PRInt32 aNameSpaceID,
637 : nsIAtom *aName) const;
638 : /**
639 : * Add a listener for the specified attribute, if appropriate.
640 : */
641 : void AddListenerFor(const nsAttrName& aName,
642 : bool aCompileEventHandlers);
643 : void MaybeAddPopupListener(nsIAtom* aLocalName);
644 :
645 : nsIWidget* GetWindowWidget();
646 :
647 : // attribute setters for widget
648 : nsresult HideWindowChrome(bool aShouldHide);
649 : void SetChromeMargins(const nsAttrValue* aValue);
650 : void ResetChromeMargins();
651 : void SetTitlebarColor(nscolor aColor, bool aActive);
652 :
653 : void SetDrawsInTitlebar(bool aState);
654 :
655 : const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
656 :
657 : void RemoveBroadcaster(const nsAString & broadcasterId);
658 :
659 : protected:
660 : // Internal accessor. This shadows the 'Slots', and returns
661 : // appropriate value.
662 0 : nsIControllers *Controllers() {
663 0 : nsDOMSlots* slots = GetExistingDOMSlots();
664 0 : return slots ? slots->mControllers : nsnull;
665 : }
666 :
667 : void UnregisterAccessKey(const nsAString& aOldValue);
668 : bool BoolAttrIsTrue(nsIAtom* aName);
669 :
670 : friend nsresult
671 : NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
672 : friend void
673 : NS_TrustedNewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
674 :
675 : static already_AddRefed<nsXULElement>
676 : Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
677 : bool aIsScriptable);
678 :
679 : friend class nsScriptEventHandlerOwnerTearoff;
680 :
681 472 : bool IsReadWriteTextElement() const
682 : {
683 472 : const nsIAtom* tag = Tag();
684 : return
685 472 : GetNameSpaceID() == kNameSpaceID_XUL &&
686 : (tag == nsGkAtoms::textbox || tag == nsGkAtoms::textarea) &&
687 472 : !HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
688 : }
689 : };
690 :
691 : #endif // nsXULElement_h__
|