content/xul/templates/src/nsXULContentUtils.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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  */
    22 /*
    24   A package of routines shared by the XUL content code.
    26  */
    28 #include "mozilla/ArrayUtils.h"
    30 #include "nsCOMPtr.h"
    31 #include "nsIContent.h"
    32 #include "nsIDocument.h"
    33 #include "nsIDOMElement.h"
    34 #include "nsIDOMXULCommandDispatcher.h"
    35 #include "nsIDOMXULDocument.h"
    36 #include "nsIRDFNode.h"
    37 #include "nsIRDFService.h"
    38 #include "nsIServiceManager.h"
    39 #include "nsIURL.h"
    40 #include "nsXULContentUtils.h"
    41 #include "nsLayoutCID.h"
    42 #include "nsNameSpaceManager.h"
    43 #include "nsNetUtil.h"
    44 #include "nsRDFCID.h"
    45 #include "nsString.h"
    46 #include "nsXPIDLString.h"
    47 #include "nsGkAtoms.h"
    48 #include "prlog.h"
    49 #include "prtime.h"
    50 #include "rdf.h"
    51 #include "nsContentUtils.h"
    52 #include "nsIDateTimeFormat.h"
    53 #include "nsDateTimeFormatCID.h"
    54 #include "nsIScriptableDateFormat.h"
    55 #include "nsICollation.h"
    56 #include "nsCollationCID.h"
    57 #include "nsILocale.h"
    58 #include "nsILocaleService.h"
    59 #include "nsIConsoleService.h"
    60 #include "nsEscape.h"
    62 using namespace mozilla;
    64 //------------------------------------------------------------------------
    66 nsIRDFService* nsXULContentUtils::gRDF;
    67 nsIDateTimeFormat* nsXULContentUtils::gFormat;
    68 nsICollation *nsXULContentUtils::gCollation;
    70 #ifdef PR_LOGGING
    71 extern PRLogModuleInfo* gXULTemplateLog;
    72 #endif
    74 #define XUL_RESOURCE(ident, uri) nsIRDFResource* nsXULContentUtils::ident
    75 #define XUL_LITERAL(ident, val) nsIRDFLiteral* nsXULContentUtils::ident
    76 #include "nsXULResourceList.h"
    77 #undef XUL_RESOURCE
    78 #undef XUL_LITERAL
    80 //------------------------------------------------------------------------
    81 // Constructors n' stuff
    82 //
    84 nsresult
    85 nsXULContentUtils::Init()
    86 {
    87     static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
    88     nsresult rv = CallGetService(kRDFServiceCID, &gRDF);
    89     if (NS_FAILED(rv)) {
    90         return rv;
    91     }
    93 #define XUL_RESOURCE(ident, uri)                              \
    94   PR_BEGIN_MACRO                                              \
    95    rv = gRDF->GetResource(NS_LITERAL_CSTRING(uri), &(ident)); \
    96    if (NS_FAILED(rv)) return rv;                              \
    97   PR_END_MACRO
    99 #define XUL_LITERAL(ident, val)                                   \
   100   PR_BEGIN_MACRO                                                  \
   101    rv = gRDF->GetLiteral(NS_LITERAL_STRING(val).get(), &(ident)); \
   102    if (NS_FAILED(rv)) return rv;                                  \
   103   PR_END_MACRO
   105 #include "nsXULResourceList.h"
   106 #undef XUL_RESOURCE
   107 #undef XUL_LITERAL
   109     rv = CallCreateInstance(NS_DATETIMEFORMAT_CONTRACTID, &gFormat);
   110     if (NS_FAILED(rv)) {
   111         return rv;
   112     }
   114     return NS_OK;
   115 }
   118 nsresult
   119 nsXULContentUtils::Finish()
   120 {
   121     NS_IF_RELEASE(gRDF);
   123 #define XUL_RESOURCE(ident, uri) NS_IF_RELEASE(ident)
   124 #define XUL_LITERAL(ident, val) NS_IF_RELEASE(ident)
   125 #include "nsXULResourceList.h"
   126 #undef XUL_RESOURCE
   127 #undef XUL_LITERAL
   129     NS_IF_RELEASE(gFormat);
   130     NS_IF_RELEASE(gCollation);
   132     return NS_OK;
   133 }
   135 nsICollation*
   136 nsXULContentUtils::GetCollation()
   137 {
   138     if (!gCollation) {
   139         nsresult rv;
   141         // get a locale service 
   142         nsCOMPtr<nsILocaleService> localeService =
   143             do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
   144         if (NS_SUCCEEDED(rv)) {
   145             nsCOMPtr<nsILocale> locale;
   146             rv = localeService->GetApplicationLocale(getter_AddRefs(locale));
   147             if (NS_SUCCEEDED(rv) && locale) {
   148                 nsCOMPtr<nsICollationFactory> colFactory =
   149                     do_CreateInstance(NS_COLLATIONFACTORY_CONTRACTID);
   150                 if (colFactory) {
   151                     rv = colFactory->CreateCollation(locale, &gCollation);
   152                     NS_ASSERTION(NS_SUCCEEDED(rv),
   153                                  "couldn't create collation instance");
   154                 } else
   155                     NS_ERROR("couldn't create instance of collation factory");
   156             } else
   157                 NS_ERROR("unable to get application locale");
   158         } else
   159             NS_ERROR("couldn't get locale factory");
   160     }
   162     return gCollation;
   163 }
   165 //------------------------------------------------------------------------
   167 nsresult
   168 nsXULContentUtils::FindChildByTag(nsIContent* aElement,
   169                                   int32_t aNameSpaceID,
   170                                   nsIAtom* aTag,
   171                                   nsIContent** aResult)
   172 {
   173     for (nsIContent* child = aElement->GetFirstChild();
   174          child;
   175          child = child->GetNextSibling()) {
   177         if (child->NodeInfo()->Equals(aTag, aNameSpaceID)) {
   178             NS_ADDREF(*aResult = child);
   180             return NS_OK;
   181         }
   182     }
   184     *aResult = nullptr;
   185     return NS_RDF_NO_VALUE; // not found
   186 }
   189 nsresult
   190 nsXULContentUtils::GetElementResource(nsIContent* aElement, nsIRDFResource** aResult)
   191 {
   192     // Perform a reverse mapping from an element in the content model
   193     // to an RDF resource.
   194     nsresult rv;
   196     char16_t buf[128];
   197     nsFixedString id(buf, ArrayLength(buf), 0);
   199     // Whoa.  Why the "id" attribute?  What if it's not even a XUL
   200     // element?  This is totally bogus!
   201     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
   202     if (id.IsEmpty())
   203         return NS_ERROR_FAILURE;
   205     // Since the element will store its ID attribute as a document-relative value,
   206     // we may need to qualify it first...
   207     nsCOMPtr<nsIDocument> doc = aElement->GetDocument();
   208     NS_ASSERTION(doc, "element is not in any document");
   209     if (! doc)
   210         return NS_ERROR_FAILURE;
   212     rv = nsXULContentUtils::MakeElementResource(doc, id, aResult);
   213     if (NS_FAILED(rv)) return rv;
   215     return NS_OK;
   216 }
   219 /*
   220 	Note: this routine is similar, yet distinctly different from, nsBookmarksService::GetTextForNode
   221 */
   223 nsresult
   224 nsXULContentUtils::GetTextForNode(nsIRDFNode* aNode, nsAString& aResult)
   225 {
   226     if (! aNode) {
   227         aResult.Truncate();
   228         return NS_OK;
   229     }
   231     nsresult rv;
   233     // Literals are the most common, so try these first.
   234     nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(aNode);
   235     if (literal) {
   236         const char16_t* p;
   237         rv = literal->GetValueConst(&p);
   238         if (NS_FAILED(rv)) return rv;
   240         aResult = p;
   241         return NS_OK;
   242     }
   244     nsCOMPtr<nsIRDFDate> dateLiteral = do_QueryInterface(aNode);
   245     if (dateLiteral) {
   246         PRTime value;
   247         rv = dateLiteral->GetValue(&value);
   248         if (NS_FAILED(rv)) return rv;
   250         nsAutoString str;
   251         rv = gFormat->FormatPRTime(nullptr /* nsILocale* locale */,
   252                                   kDateFormatShort,
   253                                   kTimeFormatSeconds,
   254                                   value,
   255                                   str);
   256         aResult.Assign(str);
   258         if (NS_FAILED(rv)) return rv;
   260         return NS_OK;
   261     }
   263     nsCOMPtr<nsIRDFInt> intLiteral = do_QueryInterface(aNode);
   264     if (intLiteral) {
   265         int32_t	value;
   266         rv = intLiteral->GetValue(&value);
   267         if (NS_FAILED(rv)) return rv;
   269         aResult.Truncate();
   270         nsAutoString intStr;
   271         intStr.AppendInt(value, 10);
   272         aResult.Append(intStr);
   273         return NS_OK;
   274     }
   277     nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(aNode);
   278     if (resource) {
   279         const char* p;
   280         rv = resource->GetValueConst(&p);
   281         if (NS_FAILED(rv)) return rv;
   282         CopyUTF8toUTF16(p, aResult);
   283         return NS_OK;
   284     }
   286     NS_ERROR("not a resource or a literal");
   287     return NS_ERROR_UNEXPECTED;
   288 }
   290 nsresult
   291 nsXULContentUtils::MakeElementURI(nsIDocument* aDocument,
   292                                   const nsAString& aElementID,
   293                                   nsCString& aURI)
   294 {
   295     // Convert an element's ID to a URI that can be used to refer to
   296     // the element in the XUL graph.
   298     nsIURI *docURI = aDocument->GetDocumentURI();
   299     NS_ENSURE_TRUE(docURI, NS_ERROR_UNEXPECTED);
   301     nsRefPtr<nsIURI> docURIClone;
   302     nsresult rv = docURI->Clone(getter_AddRefs(docURIClone));
   303     NS_ENSURE_SUCCESS(rv, rv);
   305     rv = docURIClone->SetRef(NS_ConvertUTF16toUTF8(aElementID));
   306     if (NS_SUCCEEDED(rv)) {
   307         return docURIClone->GetSpec(aURI);
   308     }
   310     // docURIClone is apparently immutable. Fine - we can append ref manually.
   311     rv = docURI->GetSpec(aURI);
   312     NS_ENSURE_SUCCESS(rv, rv);
   314     nsAutoCString ref;
   315     NS_EscapeURL(NS_ConvertUTF16toUTF8(aElementID), esc_FilePath | esc_AlwaysCopy, ref);
   317     aURI.Append('#');
   318     aURI.Append(ref);
   320     return NS_OK;
   321 }
   324 nsresult
   325 nsXULContentUtils::MakeElementResource(nsIDocument* aDocument, const nsAString& aID, nsIRDFResource** aResult)
   326 {
   327     nsresult rv;
   329     char buf[256];
   330     nsFixedCString uri(buf, sizeof(buf), 0);
   331     rv = MakeElementURI(aDocument, aID, uri);
   332     if (NS_FAILED(rv)) return rv;
   334     rv = gRDF->GetResource(uri, aResult);
   335     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create resource");
   336     if (NS_FAILED(rv)) return rv;
   338     return NS_OK;
   339 }
   343 nsresult
   344 nsXULContentUtils::MakeElementID(nsIDocument* aDocument,
   345                                  const nsACString& aURI,
   346                                  nsAString& aElementID)
   347 {
   348     // Convert a URI into an element ID that can be accessed from the
   349     // DOM APIs.
   350     nsCOMPtr<nsIURI> uri;
   351     nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI,
   352                             aDocument->GetDocumentCharacterSet().get());
   353     NS_ENSURE_SUCCESS(rv, rv);
   355     nsAutoCString ref;
   356     uri->GetRef(ref);
   357     CopyUTF8toUTF16(ref, aElementID);
   359     return NS_OK;
   360 }
   362 nsresult
   363 nsXULContentUtils::GetResource(int32_t aNameSpaceID, nsIAtom* aAttribute, nsIRDFResource** aResult)
   364 {
   365     // construct a fully-qualified URI from the namespace/tag pair.
   366     NS_PRECONDITION(aAttribute != nullptr, "null ptr");
   367     if (! aAttribute)
   368         return NS_ERROR_NULL_POINTER;
   370     return GetResource(aNameSpaceID, nsDependentAtomString(aAttribute),
   371                        aResult);
   372 }
   375 nsresult
   376 nsXULContentUtils::GetResource(int32_t aNameSpaceID, const nsAString& aAttribute, nsIRDFResource** aResult)
   377 {
   378     // construct a fully-qualified URI from the namespace/tag pair.
   380     // XXX should we allow nodes with no namespace???
   381     //NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "no namespace");
   382     //if (aNameSpaceID == kNameSpaceID_Unknown)
   383     //    return NS_ERROR_UNEXPECTED;
   385     nsresult rv;
   387     char16_t buf[256];
   388     nsFixedString uri(buf, ArrayLength(buf), 0);
   389     if (aNameSpaceID != kNameSpaceID_Unknown && aNameSpaceID != kNameSpaceID_None) {
   390         rv = nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, uri);
   391         // XXX ignore failure; treat as "no namespace"
   392     }
   394     // XXX check to see if we need to insert a '/' or a '#'. Oy.
   395     if (!uri.IsEmpty()  && uri.Last() != '#' && uri.Last() != '/' && aAttribute.First() != '#')
   396         uri.Append(char16_t('#'));
   398     uri.Append(aAttribute);
   400     rv = gRDF->GetUnicodeResource(uri, aResult);
   401     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
   402     if (NS_FAILED(rv)) return rv;
   404     return NS_OK;
   405 }
   408 nsresult
   409 nsXULContentUtils::SetCommandUpdater(nsIDocument* aDocument, nsIContent* aElement)
   410 {
   411     // Deal with setting up a 'commandupdater'. Pulls the 'events' and
   412     // 'targets' attributes off of aElement, and adds it to the
   413     // document's command dispatcher.
   414     NS_PRECONDITION(aDocument != nullptr, "null ptr");
   415     if (! aDocument)
   416         return NS_ERROR_NULL_POINTER;
   418     NS_PRECONDITION(aElement != nullptr, "null ptr");
   419     if (! aElement)
   420         return NS_ERROR_NULL_POINTER;
   422     nsresult rv;
   424     nsCOMPtr<nsIDOMXULDocument> xuldoc = do_QueryInterface(aDocument);
   425     NS_ASSERTION(xuldoc != nullptr, "not a xul document");
   426     if (! xuldoc)
   427         return NS_ERROR_UNEXPECTED;
   429     nsCOMPtr<nsIDOMXULCommandDispatcher> dispatcher;
   430     rv = xuldoc->GetCommandDispatcher(getter_AddRefs(dispatcher));
   431     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get dispatcher");
   432     if (NS_FAILED(rv)) return rv;
   434     NS_ASSERTION(dispatcher != nullptr, "no dispatcher");
   435     if (! dispatcher)
   436         return NS_ERROR_UNEXPECTED;
   438     nsAutoString events;
   439     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::events, events);
   440     if (events.IsEmpty())
   441         events.AssignLiteral("*");
   443     nsAutoString targets;
   444     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::targets, targets);
   446     if (targets.IsEmpty())
   447         targets.AssignLiteral("*");
   449     nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
   450     NS_ASSERTION(domelement != nullptr, "not a DOM element");
   451     if (! domelement)
   452         return NS_ERROR_UNEXPECTED;
   454     rv = dispatcher->AddCommandUpdater(domelement, events, targets);
   455     if (NS_FAILED(rv)) return rv;
   457     return NS_OK;
   458 }
   460 void
   461 nsXULContentUtils::LogTemplateError(const char* aStr)
   462 {
   463   nsAutoString message;
   464   message.AssignLiteral("Error parsing template: ");
   465   message.Append(NS_ConvertUTF8toUTF16(aStr).get());
   467   nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
   468   if (cs) {
   469     cs->LogStringMessage(message.get());
   470     PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS, ("Error parsing template: %s", aStr));
   471   }
   472 }

mercurial