nsXULContentUtils.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. A package of routines shared by the XUL content code.
  22. */
  23. #include "mozilla/ArrayUtils.h"
  24. #include "nsCOMPtr.h"
  25. #include "nsIContent.h"
  26. #include "nsIDocument.h"
  27. #include "nsIDOMElement.h"
  28. #include "nsIDOMXULCommandDispatcher.h"
  29. #include "nsIDOMXULDocument.h"
  30. #include "nsIRDFNode.h"
  31. #include "nsIRDFService.h"
  32. #include "nsIServiceManager.h"
  33. #include "nsIURL.h"
  34. #include "nsXULContentUtils.h"
  35. #include "nsLayoutCID.h"
  36. #include "nsNameSpaceManager.h"
  37. #include "nsRDFCID.h"
  38. #include "nsString.h"
  39. #include "nsXPIDLString.h"
  40. #include "nsGkAtoms.h"
  41. #include "mozilla/Logging.h"
  42. #include "prtime.h"
  43. #include "rdf.h"
  44. #include "nsContentUtils.h"
  45. #include "nsIDateTimeFormat.h"
  46. #include "nsIScriptableDateFormat.h"
  47. #include "nsICollation.h"
  48. #include "nsCollationCID.h"
  49. #include "nsILocale.h"
  50. #include "nsILocaleService.h"
  51. #include "nsIConsoleService.h"
  52. #include "nsEscape.h"
  53. using namespace mozilla;
  54. //------------------------------------------------------------------------
  55. nsIRDFService* nsXULContentUtils::gRDF;
  56. nsIDateTimeFormat* nsXULContentUtils::gFormat;
  57. nsICollation *nsXULContentUtils::gCollation;
  58. extern LazyLogModule gXULTemplateLog;
  59. #define XUL_RESOURCE(ident, uri) nsIRDFResource* nsXULContentUtils::ident
  60. #define XUL_LITERAL(ident, val) nsIRDFLiteral* nsXULContentUtils::ident
  61. #include "nsXULResourceList.h"
  62. #undef XUL_RESOURCE
  63. #undef XUL_LITERAL
  64. //------------------------------------------------------------------------
  65. // Constructors n' stuff
  66. //
  67. nsresult
  68. nsXULContentUtils::Init()
  69. {
  70. static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
  71. nsresult rv = CallGetService(kRDFServiceCID, &gRDF);
  72. if (NS_FAILED(rv)) {
  73. return rv;
  74. }
  75. #define XUL_RESOURCE(ident, uri) \
  76. PR_BEGIN_MACRO \
  77. rv = gRDF->GetResource(NS_LITERAL_CSTRING(uri), &(ident)); \
  78. if (NS_FAILED(rv)) return rv; \
  79. PR_END_MACRO
  80. #define XUL_LITERAL(ident, val) \
  81. PR_BEGIN_MACRO \
  82. rv = gRDF->GetLiteral(val, &(ident)); \
  83. if (NS_FAILED(rv)) return rv; \
  84. PR_END_MACRO
  85. #include "nsXULResourceList.h"
  86. #undef XUL_RESOURCE
  87. #undef XUL_LITERAL
  88. gFormat = nsIDateTimeFormat::Create().take();
  89. if (!gFormat) {
  90. return NS_ERROR_FAILURE;
  91. }
  92. return NS_OK;
  93. }
  94. nsresult
  95. nsXULContentUtils::Finish()
  96. {
  97. NS_IF_RELEASE(gRDF);
  98. #define XUL_RESOURCE(ident, uri) NS_IF_RELEASE(ident)
  99. #define XUL_LITERAL(ident, val) NS_IF_RELEASE(ident)
  100. #include "nsXULResourceList.h"
  101. #undef XUL_RESOURCE
  102. #undef XUL_LITERAL
  103. NS_IF_RELEASE(gFormat);
  104. NS_IF_RELEASE(gCollation);
  105. return NS_OK;
  106. }
  107. nsICollation*
  108. nsXULContentUtils::GetCollation()
  109. {
  110. if (!gCollation) {
  111. nsresult rv;
  112. // get a locale service
  113. nsCOMPtr<nsILocaleService> localeService =
  114. do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
  115. if (NS_SUCCEEDED(rv)) {
  116. nsCOMPtr<nsILocale> locale;
  117. rv = localeService->GetApplicationLocale(getter_AddRefs(locale));
  118. if (NS_SUCCEEDED(rv) && locale) {
  119. nsCOMPtr<nsICollationFactory> colFactory =
  120. do_CreateInstance(NS_COLLATIONFACTORY_CONTRACTID);
  121. if (colFactory) {
  122. rv = colFactory->CreateCollation(locale, &gCollation);
  123. NS_ASSERTION(NS_SUCCEEDED(rv),
  124. "couldn't create collation instance");
  125. } else
  126. NS_ERROR("couldn't create instance of collation factory");
  127. } else
  128. NS_ERROR("unable to get application locale");
  129. } else
  130. NS_ERROR("couldn't get locale factory");
  131. }
  132. return gCollation;
  133. }
  134. //------------------------------------------------------------------------
  135. nsresult
  136. nsXULContentUtils::FindChildByTag(nsIContent* aElement,
  137. int32_t aNameSpaceID,
  138. nsIAtom* aTag,
  139. nsIContent** aResult)
  140. {
  141. for (nsIContent* child = aElement->GetFirstChild();
  142. child;
  143. child = child->GetNextSibling()) {
  144. if (child->NodeInfo()->Equals(aTag, aNameSpaceID)) {
  145. NS_ADDREF(*aResult = child);
  146. return NS_OK;
  147. }
  148. }
  149. *aResult = nullptr;
  150. return NS_RDF_NO_VALUE; // not found
  151. }
  152. /*
  153. Note: this routine is similar, yet distinctly different from, nsBookmarksService::GetTextForNode
  154. */
  155. nsresult
  156. nsXULContentUtils::GetTextForNode(nsIRDFNode* aNode, nsAString& aResult)
  157. {
  158. if (! aNode) {
  159. aResult.Truncate();
  160. return NS_OK;
  161. }
  162. nsresult rv;
  163. // Literals are the most common, so try these first.
  164. nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(aNode);
  165. if (literal) {
  166. const char16_t* p;
  167. rv = literal->GetValueConst(&p);
  168. if (NS_FAILED(rv)) return rv;
  169. aResult = p;
  170. return NS_OK;
  171. }
  172. nsCOMPtr<nsIRDFDate> dateLiteral = do_QueryInterface(aNode);
  173. if (dateLiteral) {
  174. PRTime value;
  175. rv = dateLiteral->GetValue(&value);
  176. if (NS_FAILED(rv)) return rv;
  177. nsAutoString str;
  178. rv = gFormat->FormatPRTime(nullptr /* nsILocale* locale */,
  179. kDateFormatShort,
  180. kTimeFormatSeconds,
  181. value,
  182. str);
  183. aResult.Assign(str);
  184. if (NS_FAILED(rv)) return rv;
  185. return NS_OK;
  186. }
  187. nsCOMPtr<nsIRDFInt> intLiteral = do_QueryInterface(aNode);
  188. if (intLiteral) {
  189. int32_t value;
  190. rv = intLiteral->GetValue(&value);
  191. if (NS_FAILED(rv)) return rv;
  192. aResult.Truncate();
  193. nsAutoString intStr;
  194. intStr.AppendInt(value, 10);
  195. aResult.Append(intStr);
  196. return NS_OK;
  197. }
  198. nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(aNode);
  199. if (resource) {
  200. const char* p;
  201. rv = resource->GetValueConst(&p);
  202. if (NS_FAILED(rv)) return rv;
  203. CopyUTF8toUTF16(p, aResult);
  204. return NS_OK;
  205. }
  206. NS_ERROR("not a resource or a literal");
  207. return NS_ERROR_UNEXPECTED;
  208. }
  209. nsresult
  210. nsXULContentUtils::GetResource(int32_t aNameSpaceID, nsIAtom* aAttribute, nsIRDFResource** aResult)
  211. {
  212. // construct a fully-qualified URI from the namespace/tag pair.
  213. NS_PRECONDITION(aAttribute != nullptr, "null ptr");
  214. if (! aAttribute)
  215. return NS_ERROR_NULL_POINTER;
  216. return GetResource(aNameSpaceID, nsDependentAtomString(aAttribute),
  217. aResult);
  218. }
  219. nsresult
  220. nsXULContentUtils::GetResource(int32_t aNameSpaceID, const nsAString& aAttribute, nsIRDFResource** aResult)
  221. {
  222. // construct a fully-qualified URI from the namespace/tag pair.
  223. // XXX should we allow nodes with no namespace???
  224. //NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "no namespace");
  225. //if (aNameSpaceID == kNameSpaceID_Unknown)
  226. // return NS_ERROR_UNEXPECTED;
  227. nsresult rv;
  228. char16_t buf[256];
  229. nsFixedString uri(buf, ArrayLength(buf), 0);
  230. if (aNameSpaceID != kNameSpaceID_Unknown && aNameSpaceID != kNameSpaceID_None) {
  231. rv = nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, uri);
  232. // XXX ignore failure; treat as "no namespace"
  233. }
  234. // XXX check to see if we need to insert a '/' or a '#'. Oy.
  235. if (!uri.IsEmpty() && uri.Last() != '#' && uri.Last() != '/' && aAttribute.First() != '#')
  236. uri.Append(char16_t('#'));
  237. uri.Append(aAttribute);
  238. rv = gRDF->GetUnicodeResource(uri, aResult);
  239. NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
  240. if (NS_FAILED(rv)) return rv;
  241. return NS_OK;
  242. }
  243. nsresult
  244. nsXULContentUtils::SetCommandUpdater(nsIDocument* aDocument, nsIContent* aElement)
  245. {
  246. // Deal with setting up a 'commandupdater'. Pulls the 'events' and
  247. // 'targets' attributes off of aElement, and adds it to the
  248. // document's command dispatcher.
  249. NS_PRECONDITION(aDocument != nullptr, "null ptr");
  250. if (! aDocument)
  251. return NS_ERROR_NULL_POINTER;
  252. NS_PRECONDITION(aElement != nullptr, "null ptr");
  253. if (! aElement)
  254. return NS_ERROR_NULL_POINTER;
  255. nsresult rv;
  256. nsCOMPtr<nsIDOMXULDocument> xuldoc = do_QueryInterface(aDocument);
  257. NS_ASSERTION(xuldoc != nullptr, "not a xul document");
  258. if (! xuldoc)
  259. return NS_ERROR_UNEXPECTED;
  260. nsCOMPtr<nsIDOMXULCommandDispatcher> dispatcher;
  261. rv = xuldoc->GetCommandDispatcher(getter_AddRefs(dispatcher));
  262. NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get dispatcher");
  263. if (NS_FAILED(rv)) return rv;
  264. NS_ASSERTION(dispatcher != nullptr, "no dispatcher");
  265. if (! dispatcher)
  266. return NS_ERROR_UNEXPECTED;
  267. nsAutoString events;
  268. aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::events, events);
  269. if (events.IsEmpty())
  270. events.Assign('*');
  271. nsAutoString targets;
  272. aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::targets, targets);
  273. if (targets.IsEmpty())
  274. targets.Assign('*');
  275. nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
  276. NS_ASSERTION(domelement != nullptr, "not a DOM element");
  277. if (! domelement)
  278. return NS_ERROR_UNEXPECTED;
  279. rv = dispatcher->AddCommandUpdater(domelement, events, targets);
  280. if (NS_FAILED(rv)) return rv;
  281. return NS_OK;
  282. }
  283. void
  284. nsXULContentUtils::LogTemplateError(const char* aStr)
  285. {
  286. nsAutoString message;
  287. message.AssignLiteral("Error parsing template: ");
  288. message.Append(NS_ConvertUTF8toUTF16(aStr).get());
  289. nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
  290. if (cs) {
  291. cs->LogStringMessage(message.get());
  292. MOZ_LOG(gXULTemplateLog, LogLevel::Info, ("Error parsing template: %s", aStr));
  293. }
  294. }