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 : * David Hyatt <hyatt@netscape.com>
25 : * Brendan Eich <brendan@mozilla.org>
26 : * Mark Hammond <mhammond@skippinet.com.au>
27 : *
28 : * Alternatively, the contents of this file may be used under the terms of
29 : * either of the GNU General Public License Version 2 or later (the "GPL"),
30 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 : * in which case the provisions of the GPL or the LGPL are applicable instead
32 : * of those above. If you wish to allow use of your version of this file only
33 : * under the terms of either the GPL or the LGPL, and not to allow others to
34 : * use your version of this file under the terms of the MPL, indicate your
35 : * decision by deleting the provisions above and replace them with the notice
36 : * and other provisions required by the GPL or the LGPL. If you do not delete
37 : * the provisions above, a recipient may use your version of this file under
38 : * the terms of any one of the MPL, the GPL or the LGPL.
39 : *
40 : * ***** END LICENSE BLOCK ***** */
41 :
42 : #ifndef nsXULContentSink_h__
43 : #define nsXULContentSink_h__
44 :
45 : #include "nsIExpatSink.h"
46 : #include "nsIXMLContentSink.h"
47 : #include "nsAutoPtr.h"
48 : #include "nsNodeInfoManager.h"
49 : #include "nsWeakPtr.h"
50 : #include "nsXULElement.h"
51 : #include "nsIDTD.h"
52 :
53 : class nsIDocument;
54 : class nsIScriptSecurityManager;
55 : class nsAttrName;
56 : class nsXULPrototypeDocument;
57 : class nsXULPrototypeElement;
58 : class nsXULPrototypeNode;
59 :
60 : class XULContentSinkImpl : public nsIXMLContentSink,
61 : public nsIExpatSink
62 : {
63 : public:
64 : XULContentSinkImpl();
65 : virtual ~XULContentSinkImpl();
66 :
67 : // nsISupports
68 : NS_DECL_ISUPPORTS
69 : NS_DECL_NSIEXPATSINK
70 :
71 : // nsIContentSink
72 0 : NS_IMETHOD WillParse(void) { return NS_OK; }
73 : NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode);
74 : NS_IMETHOD DidBuildModel(bool aTerminated);
75 : NS_IMETHOD WillInterrupt(void);
76 : NS_IMETHOD WillResume(void);
77 : NS_IMETHOD SetParser(nsParserBase* aParser);
78 0 : virtual void FlushPendingNotifications(mozFlushType aType) { }
79 : NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
80 : virtual nsISupports *GetTarget();
81 :
82 : /**
83 : * Initialize the content sink, giving it an nsIDocument object
84 : * with which to communicate with the outside world, and an
85 : * nsXULPrototypeDocument to build.
86 : */
87 : nsresult Init(nsIDocument* aDocument, nsXULPrototypeDocument* aPrototype);
88 :
89 : protected:
90 : // pseudo-constants
91 : PRUnichar* mText;
92 : PRInt32 mTextLength;
93 : PRInt32 mTextSize;
94 : bool mConstrainSize;
95 :
96 : nsresult AddAttributes(const PRUnichar** aAttributes,
97 : const PRUint32 aAttrLen,
98 : nsXULPrototypeElement* aElement);
99 :
100 : nsresult OpenRoot(const PRUnichar** aAttributes,
101 : const PRUint32 aAttrLen,
102 : nsINodeInfo *aNodeInfo);
103 :
104 : nsresult OpenTag(const PRUnichar** aAttributes,
105 : const PRUint32 aAttrLen,
106 : const PRUint32 aLineNumber,
107 : nsINodeInfo *aNodeInfo);
108 :
109 : // If OpenScript returns NS_OK and after it returns our state is eInScript,
110 : // that means that we created a prototype script and stuck it on
111 : // mContextStack. If NS_OK is returned but the state is still
112 : // eInDocumentElement then we didn't create a prototype script (e.g. the
113 : // script had an unknown type), and the caller should create a prototype
114 : // element.
115 : nsresult OpenScript(const PRUnichar** aAttributes,
116 : const PRUint32 aLineNumber);
117 :
118 : static bool IsDataInBuffer(PRUnichar* aBuffer, PRInt32 aLength);
119 :
120 : nsresult SetElementScriptType(nsXULPrototypeElement* element,
121 : const PRUnichar** aAttributes,
122 : const PRUint32 aAttrLen);
123 :
124 : // Text management
125 : nsresult FlushText(bool aCreateTextNode = true);
126 : nsresult AddText(const PRUnichar* aText, PRInt32 aLength);
127 :
128 :
129 : nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
130 :
131 : nsresult NormalizeAttributeString(const PRUnichar *aExpatName,
132 : nsAttrName &aName);
133 : nsresult CreateElement(nsINodeInfo *aNodeInfo,
134 : nsXULPrototypeElement** aResult);
135 :
136 :
137 : public:
138 : enum State { eInProlog, eInDocumentElement, eInScript, eInEpilog };
139 : protected:
140 :
141 : State mState;
142 :
143 : // content stack management
144 : class ContextStack {
145 : protected:
146 0 : struct Entry {
147 : nsRefPtr<nsXULPrototypeNode> mNode;
148 : // a LOT of nodes have children; preallocate for 8
149 : nsPrototypeArray mChildren;
150 : State mState;
151 : Entry* mNext;
152 0 : Entry() : mChildren(8) {}
153 : };
154 :
155 : Entry* mTop;
156 : PRInt32 mDepth;
157 :
158 : public:
159 : ContextStack();
160 : ~ContextStack();
161 :
162 0 : PRInt32 Depth() { return mDepth; }
163 :
164 : nsresult Push(nsXULPrototypeNode* aNode, State aState);
165 : nsresult Pop(State* aState);
166 :
167 : nsresult GetTopNode(nsRefPtr<nsXULPrototypeNode>& aNode);
168 : nsresult GetTopChildren(nsPrototypeArray** aChildren);
169 : nsresult GetTopNodeScriptType(PRUint32 *aScriptType);
170 :
171 : void Clear();
172 : };
173 :
174 : friend class ContextStack;
175 : ContextStack mContextStack;
176 :
177 : nsWeakPtr mDocument; // [OWNER]
178 : nsCOMPtr<nsIURI> mDocumentURL; // [OWNER]
179 :
180 : nsRefPtr<nsXULPrototypeDocument> mPrototype; // [OWNER]
181 :
182 : // We use regular pointer b/c of funky exports on nsIParser:
183 : nsParserBase* mParser; // [OWNER]
184 : nsCOMPtr<nsIScriptSecurityManager> mSecMan;
185 : };
186 :
187 : #endif /* nsXULContentSink_h__ */
|