Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 : *
7 : *
8 : * This Original Code has been modified by IBM Corporation.
9 : * Modifications made by IBM described herein are
10 : * Copyright (c) International Business Machines
11 : * Corporation, 2000
12 : *
13 : * Modifications to Mozilla code or documentation
14 : * identified per MPL Section 3.3
15 : *
16 : * Date Modified by Description of modification
17 : * 03/27/2000 IBM Corp. Added PR_CALLBACK for Optlink
18 : * use in OS2
19 : */
20 :
21 :
22 : /*
23 :
24 : A package of routines shared by the XUL content code.
25 :
26 : */
27 :
28 : #include "mozilla/ArrayUtils.h"
29 :
30 : #include "DateTimeFormat.h"
31 : #include "nsCOMPtr.h"
32 : #include "nsIContent.h"
33 : #include "nsIDocument.h"
34 : #include "nsIDOMElement.h"
35 : #include "nsIDOMXULCommandDispatcher.h"
36 : #include "nsIDOMXULDocument.h"
37 : #include "nsIRDFNode.h"
38 : #include "nsIRDFService.h"
39 : #include "nsIServiceManager.h"
40 : #include "nsIURL.h"
41 : #include "nsXULContentUtils.h"
42 : #include "nsLayoutCID.h"
43 : #include "nsNameSpaceManager.h"
44 : #include "nsRDFCID.h"
45 : #include "nsString.h"
46 : #include "nsXPIDLString.h"
47 : #include "nsGkAtoms.h"
48 : #include "mozilla/Logging.h"
49 : #include "prtime.h"
50 : #include "rdf.h"
51 : #include "nsContentUtils.h"
52 : #include "nsIScriptableDateFormat.h"
53 : #include "nsICollation.h"
54 : #include "nsCollationCID.h"
55 : #include "nsIConsoleService.h"
56 : #include "nsEscape.h"
57 :
58 : using namespace mozilla;
59 :
60 : //------------------------------------------------------------------------
61 :
62 : nsIRDFService* nsXULContentUtils::gRDF;
63 : nsICollation *nsXULContentUtils::gCollation;
64 :
65 : extern LazyLogModule gXULTemplateLog;
66 :
67 : #define XUL_RESOURCE(ident, uri) nsIRDFResource* nsXULContentUtils::ident
68 : #define XUL_LITERAL(ident, val) nsIRDFLiteral* nsXULContentUtils::ident
69 : #include "nsXULResourceList.h"
70 : #undef XUL_RESOURCE
71 : #undef XUL_LITERAL
72 :
73 : //------------------------------------------------------------------------
74 : // Constructors n' stuff
75 : //
76 :
77 : nsresult
78 3 : nsXULContentUtils::Init()
79 : {
80 : static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
81 3 : nsresult rv = CallGetService(kRDFServiceCID, &gRDF);
82 3 : if (NS_FAILED(rv)) {
83 0 : return rv;
84 : }
85 :
86 : #define XUL_RESOURCE(ident, uri) \
87 : PR_BEGIN_MACRO \
88 : rv = gRDF->GetResource(NS_LITERAL_CSTRING(uri), &(ident)); \
89 : if (NS_FAILED(rv)) return rv; \
90 : PR_END_MACRO
91 :
92 : #define XUL_LITERAL(ident, val) \
93 : PR_BEGIN_MACRO \
94 : rv = gRDF->GetLiteral(val, &(ident)); \
95 : if (NS_FAILED(rv)) return rv; \
96 : PR_END_MACRO
97 :
98 : #include "nsXULResourceList.h"
99 : #undef XUL_RESOURCE
100 : #undef XUL_LITERAL
101 :
102 3 : return NS_OK;
103 : }
104 :
105 :
106 : nsresult
107 0 : nsXULContentUtils::Finish()
108 : {
109 0 : NS_IF_RELEASE(gRDF);
110 :
111 : #define XUL_RESOURCE(ident, uri) NS_IF_RELEASE(ident)
112 : #define XUL_LITERAL(ident, val) NS_IF_RELEASE(ident)
113 : #include "nsXULResourceList.h"
114 : #undef XUL_RESOURCE
115 : #undef XUL_LITERAL
116 :
117 0 : NS_IF_RELEASE(gCollation);
118 :
119 0 : return NS_OK;
120 : }
121 :
122 : nsICollation*
123 0 : nsXULContentUtils::GetCollation()
124 : {
125 0 : if (!gCollation) {
126 : nsCOMPtr<nsICollationFactory> colFactory =
127 0 : do_CreateInstance(NS_COLLATIONFACTORY_CONTRACTID);
128 0 : if (colFactory) {
129 0 : DebugOnly<nsresult> rv = colFactory->CreateCollation(&gCollation);
130 0 : NS_ASSERTION(NS_SUCCEEDED(rv),
131 : "couldn't create collation instance");
132 : } else
133 0 : NS_ERROR("couldn't create instance of collation factory");
134 : }
135 :
136 0 : return gCollation;
137 : }
138 :
139 : //------------------------------------------------------------------------
140 :
141 : nsresult
142 0 : nsXULContentUtils::FindChildByTag(nsIContent* aElement,
143 : int32_t aNameSpaceID,
144 : nsIAtom* aTag,
145 : nsIContent** aResult)
146 : {
147 0 : for (nsIContent* child = aElement->GetFirstChild();
148 0 : child;
149 0 : child = child->GetNextSibling()) {
150 :
151 0 : if (child->NodeInfo()->Equals(aTag, aNameSpaceID)) {
152 0 : NS_ADDREF(*aResult = child);
153 :
154 0 : return NS_OK;
155 : }
156 : }
157 :
158 0 : *aResult = nullptr;
159 0 : return NS_RDF_NO_VALUE; // not found
160 : }
161 :
162 :
163 : /*
164 : Note: this routine is similar, yet distinctly different from, nsBookmarksService::GetTextForNode
165 : */
166 :
167 : nsresult
168 0 : nsXULContentUtils::GetTextForNode(nsIRDFNode* aNode, nsAString& aResult)
169 : {
170 0 : if (! aNode) {
171 0 : aResult.Truncate();
172 0 : return NS_OK;
173 : }
174 :
175 : nsresult rv;
176 :
177 : // Literals are the most common, so try these first.
178 0 : nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(aNode);
179 0 : if (literal) {
180 : const char16_t* p;
181 0 : rv = literal->GetValueConst(&p);
182 0 : if (NS_FAILED(rv)) return rv;
183 :
184 0 : aResult = p;
185 0 : return NS_OK;
186 : }
187 :
188 0 : nsCOMPtr<nsIRDFDate> dateLiteral = do_QueryInterface(aNode);
189 0 : if (dateLiteral) {
190 : PRTime value;
191 0 : rv = dateLiteral->GetValue(&value);
192 0 : if (NS_FAILED(rv)) return rv;
193 :
194 0 : nsAutoString str;
195 0 : rv = DateTimeFormat::FormatPRTime(kDateFormatShort,
196 : kTimeFormatSeconds,
197 : value,
198 0 : str);
199 :
200 0 : aResult.Assign(str);
201 :
202 0 : if (NS_FAILED(rv)) return rv;
203 :
204 0 : return NS_OK;
205 : }
206 :
207 0 : nsCOMPtr<nsIRDFInt> intLiteral = do_QueryInterface(aNode);
208 0 : if (intLiteral) {
209 : int32_t value;
210 0 : rv = intLiteral->GetValue(&value);
211 0 : if (NS_FAILED(rv)) return rv;
212 :
213 0 : aResult.Truncate();
214 0 : nsAutoString intStr;
215 0 : intStr.AppendInt(value, 10);
216 0 : aResult.Append(intStr);
217 0 : return NS_OK;
218 : }
219 :
220 :
221 0 : nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(aNode);
222 0 : if (resource) {
223 : const char* p;
224 0 : rv = resource->GetValueConst(&p);
225 0 : if (NS_FAILED(rv)) return rv;
226 0 : CopyUTF8toUTF16(p, aResult);
227 0 : return NS_OK;
228 : }
229 :
230 0 : NS_ERROR("not a resource or a literal");
231 0 : return NS_ERROR_UNEXPECTED;
232 : }
233 :
234 : nsresult
235 0 : nsXULContentUtils::GetResource(int32_t aNameSpaceID, nsIAtom* aAttribute, nsIRDFResource** aResult)
236 : {
237 : // construct a fully-qualified URI from the namespace/tag pair.
238 0 : NS_PRECONDITION(aAttribute != nullptr, "null ptr");
239 0 : if (! aAttribute)
240 0 : return NS_ERROR_NULL_POINTER;
241 :
242 0 : return GetResource(aNameSpaceID, nsDependentAtomString(aAttribute),
243 0 : aResult);
244 : }
245 :
246 :
247 : nsresult
248 0 : nsXULContentUtils::GetResource(int32_t aNameSpaceID, const nsAString& aAttribute, nsIRDFResource** aResult)
249 : {
250 : // construct a fully-qualified URI from the namespace/tag pair.
251 :
252 : // XXX should we allow nodes with no namespace???
253 : //NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "no namespace");
254 : //if (aNameSpaceID == kNameSpaceID_Unknown)
255 : // return NS_ERROR_UNEXPECTED;
256 :
257 : nsresult rv;
258 :
259 : char16_t buf[256];
260 0 : nsFixedString uri(buf, ArrayLength(buf), 0);
261 0 : if (aNameSpaceID != kNameSpaceID_Unknown && aNameSpaceID != kNameSpaceID_None) {
262 0 : rv = nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, uri);
263 : // XXX ignore failure; treat as "no namespace"
264 : }
265 :
266 : // XXX check to see if we need to insert a '/' or a '#'. Oy.
267 0 : if (!uri.IsEmpty() && uri.Last() != '#' && uri.Last() != '/' && aAttribute.First() != '#')
268 0 : uri.Append(char16_t('#'));
269 :
270 0 : uri.Append(aAttribute);
271 :
272 0 : rv = gRDF->GetUnicodeResource(uri, aResult);
273 0 : NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
274 0 : if (NS_FAILED(rv)) return rv;
275 :
276 0 : return NS_OK;
277 : }
278 :
279 :
280 : nsresult
281 4 : nsXULContentUtils::SetCommandUpdater(nsIDocument* aDocument, nsIContent* aElement)
282 : {
283 : // Deal with setting up a 'commandupdater'. Pulls the 'events' and
284 : // 'targets' attributes off of aElement, and adds it to the
285 : // document's command dispatcher.
286 4 : NS_PRECONDITION(aDocument != nullptr, "null ptr");
287 4 : if (! aDocument)
288 0 : return NS_ERROR_NULL_POINTER;
289 :
290 4 : NS_PRECONDITION(aElement != nullptr, "null ptr");
291 4 : if (! aElement)
292 0 : return NS_ERROR_NULL_POINTER;
293 :
294 : nsresult rv;
295 :
296 8 : nsCOMPtr<nsIDOMXULDocument> xuldoc = do_QueryInterface(aDocument);
297 4 : NS_ASSERTION(xuldoc != nullptr, "not a xul document");
298 4 : if (! xuldoc)
299 0 : return NS_ERROR_UNEXPECTED;
300 :
301 8 : nsCOMPtr<nsIDOMXULCommandDispatcher> dispatcher;
302 4 : rv = xuldoc->GetCommandDispatcher(getter_AddRefs(dispatcher));
303 4 : NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get dispatcher");
304 4 : if (NS_FAILED(rv)) return rv;
305 :
306 4 : NS_ASSERTION(dispatcher != nullptr, "no dispatcher");
307 4 : if (! dispatcher)
308 0 : return NS_ERROR_UNEXPECTED;
309 :
310 8 : nsAutoString events;
311 4 : aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::events, events);
312 4 : if (events.IsEmpty())
313 0 : events.Assign('*');
314 :
315 8 : nsAutoString targets;
316 4 : aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::targets, targets);
317 :
318 4 : if (targets.IsEmpty())
319 4 : targets.Assign('*');
320 :
321 8 : nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
322 4 : NS_ASSERTION(domelement != nullptr, "not a DOM element");
323 4 : if (! domelement)
324 0 : return NS_ERROR_UNEXPECTED;
325 :
326 4 : rv = dispatcher->AddCommandUpdater(domelement, events, targets);
327 4 : if (NS_FAILED(rv)) return rv;
328 :
329 4 : return NS_OK;
330 : }
331 :
332 : void
333 0 : nsXULContentUtils::LogTemplateError(const char* aStr)
334 : {
335 0 : nsAutoString message;
336 0 : message.AssignLiteral("Error parsing template: ");
337 0 : message.Append(NS_ConvertUTF8toUTF16(aStr).get());
338 :
339 0 : nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
340 0 : if (cs) {
341 0 : cs->LogStringMessage(message.get());
342 0 : MOZ_LOG(gXULTemplateLog, LogLevel::Info, ("Error parsing template: %s", aStr));
343 : }
344 0 : }
|