LCOV - code coverage report
Current view: top level - dom/xul/templates - nsXULTemplateQueryProcessorXML.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 219 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 25 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsCOMPtr.h"
       7             : #include "nsAutoPtr.h"
       8             : #include "nsIDOMDocument.h"
       9             : #include "nsIDOMNode.h"
      10             : #include "nsIDOMElement.h"
      11             : #include "nsIDOMEvent.h"
      12             : #include "nsIDocument.h"
      13             : #include "nsIContent.h"
      14             : #include "nsComponentManagerUtils.h"
      15             : #include "nsGkAtoms.h"
      16             : #include "nsIURI.h"
      17             : #include "nsIArray.h"
      18             : #include "nsIScriptContext.h"
      19             : #include "nsArrayUtils.h"
      20             : #include "nsPIDOMWindow.h"
      21             : #include "nsXULContentUtils.h"
      22             : #include "mozilla/dom/XPathEvaluator.h"
      23             : #include "nsXULTemplateQueryProcessorXML.h"
      24             : #include "nsXULTemplateResultXML.h"
      25             : #include "nsXULSortService.h"
      26             : #include "mozilla/dom/Element.h"
      27             : #include "mozilla/dom/XMLHttpRequest.h"
      28             : 
      29             : using namespace mozilla;
      30             : using namespace mozilla::dom;
      31             : 
      32           0 : NS_IMPL_ISUPPORTS(nsXMLQuery, nsXMLQuery)
      33             : 
      34             : //----------------------------------------------------------------------
      35             : //
      36             : // nsXULTemplateResultSetXML
      37             : //
      38             : 
      39           0 : NS_IMPL_ISUPPORTS(nsXULTemplateResultSetXML, nsISimpleEnumerator)
      40             : 
      41             : NS_IMETHODIMP
      42           0 : nsXULTemplateResultSetXML::HasMoreElements(bool *aResult)
      43             : {
      44             :     // if GetSnapshotLength failed, then the return type was not a set of
      45             :     // nodes, so just return false in this case.
      46           0 :     ErrorResult rv;
      47           0 :     uint32_t length = mResults->GetSnapshotLength(rv);
      48           0 :     if (NS_WARN_IF(rv.Failed())) {
      49           0 :       rv.SuppressException();
      50           0 :       *aResult = false;
      51           0 :       return NS_OK;
      52             :     }
      53             : 
      54           0 :     *aResult = mPosition < length;
      55           0 :     return NS_OK;
      56             : }
      57             : 
      58             : NS_IMETHODIMP
      59           0 : nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
      60             : {
      61           0 :     ErrorResult rv;
      62           0 :     nsINode* node = mResults->SnapshotItem(mPosition, rv);
      63           0 :     if (rv.Failed()) {
      64           0 :         return rv.StealNSResult();
      65             :     }
      66             : 
      67             :     nsXULTemplateResultXML* result =
      68           0 :         new nsXULTemplateResultXML(mQuery, node->AsContent(), mBindingSet);
      69             : 
      70           0 :     ++mPosition;
      71           0 :     *aResult = result;
      72           0 :     NS_ADDREF(result);
      73           0 :     return NS_OK;
      74             : }
      75             : 
      76             : 
      77             : //----------------------------------------------------------------------
      78             : //
      79             : // nsXULTemplateQueryProcessorXML
      80             : //
      81             : 
      82             : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateQueryProcessorXML)
      83             : 
      84           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateQueryProcessorXML)
      85           0 :     tmp->mRuleToBindingsMap.Clear();
      86           0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot)
      87           0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK(mEvaluator)
      88           0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateBuilder)
      89           0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK(mRequest)
      90           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      91           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorXML)
      92           0 :     for (auto it = tmp->mRuleToBindingsMap.Iter(); !it.Done(); it.Next()) {
      93           0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRuleToBindingsMap key");
      94           0 :         cb.NoteXPCOMChild(it.Key());
      95             :     }
      96           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
      97           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvaluator)
      98           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateBuilder)
      99           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
     100           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     101           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULTemplateQueryProcessorXML)
     102           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULTemplateQueryProcessorXML)
     103           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateQueryProcessorXML)
     104           0 :     NS_INTERFACE_MAP_ENTRY(nsIXULTemplateQueryProcessor)
     105           0 :     NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
     106           0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULTemplateQueryProcessor)
     107           0 : NS_INTERFACE_MAP_END
     108             : 
     109             : /*
     110             :  * Only the first datasource in aDataSource is used, which should be either an
     111             :  * nsIURI of an XML document, or a DOM node. If the former, GetDatasource will
     112             :  * load the document asynchronously and return null in aResult. Once the
     113             :  * document has loaded, the builder's datasource will be set to the XML
     114             :  * document. If the datasource is a DOM node, the node will be returned in
     115             :  * aResult.
     116             :  */
     117             : NS_IMETHODIMP
     118           0 : nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
     119             :                                               nsIDOMNode* aRootNode,
     120             :                                               bool aIsTrusted,
     121             :                                               nsIXULTemplateBuilder* aBuilder,
     122             :                                               bool* aShouldDelayBuilding,
     123             :                                               nsISupports** aResult)
     124             : {
     125           0 :     *aResult = nullptr;
     126           0 :     *aShouldDelayBuilding = false;
     127             : 
     128             :     nsresult rv;
     129             :     uint32_t length;
     130             : 
     131           0 :     aDataSources->GetLength(&length);
     132           0 :     if (length == 0)
     133           0 :         return NS_OK;
     134             : 
     135             :     // we get only the first item, because the query processor supports only
     136             :     // one document as a datasource
     137             : 
     138           0 :     nsCOMPtr<nsIDOMNode> node = do_QueryElementAt(aDataSources, 0);
     139           0 :     if (node) {
     140           0 :         return CallQueryInterface(node, aResult);
     141             :     }
     142             : 
     143           0 :     nsCOMPtr<nsIURI> uri = do_QueryElementAt(aDataSources, 0);
     144           0 :     if (!uri)
     145           0 :         return NS_ERROR_UNEXPECTED;
     146             : 
     147           0 :     nsAutoCString uriStr;
     148           0 :     rv = uri->GetSpec(uriStr);
     149           0 :     NS_ENSURE_SUCCESS(rv, rv);
     150             : 
     151           0 :     nsCOMPtr<nsIContent> root = do_QueryInterface(aRootNode);
     152           0 :     if (!root)
     153           0 :         return NS_ERROR_UNEXPECTED;
     154             : 
     155           0 :     nsCOMPtr<nsIDocument> doc = root->GetUncomposedDoc();
     156           0 :     if (!doc)
     157           0 :         return NS_ERROR_UNEXPECTED;
     158             : 
     159           0 :     nsIPrincipal *docPrincipal = doc->NodePrincipal();
     160             : 
     161           0 :     bool hasHadScriptObject = true;
     162             :     nsIScriptGlobalObject* scriptObject =
     163           0 :       doc->GetScriptHandlingObject(hasHadScriptObject);
     164           0 :     NS_ENSURE_STATE(scriptObject);
     165             : 
     166             :     nsCOMPtr<nsIXMLHttpRequest> req =
     167           0 :         do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
     168           0 :     NS_ENSURE_SUCCESS(rv, rv);
     169             : 
     170           0 :     rv = req->Init(docPrincipal, scriptObject, nullptr, nullptr);
     171           0 :     NS_ENSURE_SUCCESS(rv, rv);
     172             : 
     173           0 :     rv = req->Open(NS_LITERAL_CSTRING("GET"), uriStr, true,
     174           0 :                    EmptyString(), EmptyString());
     175           0 :     NS_ENSURE_SUCCESS(rv, rv);
     176             : 
     177           0 :     nsCOMPtr<EventTarget> target(do_QueryInterface(req));
     178           0 :     rv = target->AddEventListener(NS_LITERAL_STRING("load"), this, false);
     179           0 :     NS_ENSURE_SUCCESS(rv, rv);
     180             : 
     181           0 :     rv = target->AddEventListener(NS_LITERAL_STRING("error"), this, false);
     182           0 :     NS_ENSURE_SUCCESS(rv, rv);
     183             : 
     184           0 :     rv = req->Send(nullptr);
     185           0 :     NS_ENSURE_SUCCESS(rv, rv);
     186             : 
     187           0 :     mTemplateBuilder = aBuilder;
     188           0 :     mRequest = req;
     189             : 
     190           0 :     *aShouldDelayBuilding = true;
     191           0 :     return NS_OK;
     192             : }
     193             : 
     194             : NS_IMETHODIMP
     195           0 : nsXULTemplateQueryProcessorXML::InitializeForBuilding(nsISupports* aDatasource,
     196             :                                                       nsIXULTemplateBuilder* aBuilder,
     197             :                                                       nsIDOMNode* aRootNode)
     198             : {
     199           0 :     if (mGenerationStarted)
     200           0 :         return NS_ERROR_UNEXPECTED;
     201             : 
     202             :     // the datasource is either a document or a DOM element
     203           0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDatasource);
     204           0 :     if (doc)
     205           0 :         mRoot = doc->GetDocumentElement();
     206             :     else
     207           0 :       mRoot = do_QueryInterface(aDatasource);
     208           0 :     NS_ENSURE_STATE(mRoot);
     209             : 
     210           0 :     mEvaluator = new XPathEvaluator();
     211             : 
     212           0 :     return NS_OK;
     213             : }
     214             : 
     215             : NS_IMETHODIMP
     216           0 : nsXULTemplateQueryProcessorXML::Done()
     217             : {
     218           0 :     mGenerationStarted = false;
     219             : 
     220           0 :     mRuleToBindingsMap.Clear();
     221             : 
     222           0 :     return NS_OK;
     223             : }
     224             : 
     225             : NS_IMETHODIMP
     226           0 : nsXULTemplateQueryProcessorXML::CompileQuery(nsIXULTemplateBuilder* aBuilder,
     227             :                                              nsIDOMNode* aQueryNode,
     228             :                                              nsIAtom* aRefVariable,
     229             :                                              nsIAtom* aMemberVariable,
     230             :                                              nsISupports** _retval)
     231             : {
     232           0 :     *_retval = nullptr;
     233             : 
     234           0 :     nsCOMPtr<nsIContent> content = do_QueryInterface(aQueryNode);
     235             : 
     236           0 :     nsAutoString expr;
     237           0 :     content->GetAttr(kNameSpaceID_None, nsGkAtoms::expr, expr);
     238             : 
     239             :     // if an expression is not specified, then the default is to
     240             :     // just take all of the children
     241           0 :     if (expr.IsEmpty())
     242           0 :         expr.Assign('*');
     243             : 
     244           0 :     ErrorResult rv;
     245           0 :     nsAutoPtr<XPathExpression> compiledexpr;
     246           0 :     compiledexpr = CreateExpression(expr, content, rv);
     247           0 :     if (rv.Failed()) {
     248           0 :         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_XPATH);
     249           0 :         return rv.StealNSResult();
     250             :     }
     251             : 
     252             :     RefPtr<nsXMLQuery> query =
     253           0 :         new nsXMLQuery(this, aMemberVariable, Move(compiledexpr));
     254             : 
     255           0 :     for (nsIContent* condition = content->GetFirstChild();
     256           0 :          condition;
     257           0 :          condition = condition->GetNextSibling()) {
     258             : 
     259           0 :         if (condition->NodeInfo()->Equals(nsGkAtoms::assign,
     260             :                                           kNameSpaceID_XUL)) {
     261           0 :             nsAutoString var;
     262           0 :             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::var, var);
     263             : 
     264           0 :             nsAutoString expr;
     265           0 :             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::expr, expr);
     266             : 
     267             :             // ignore assignments without a variable or an expression
     268           0 :             if (!var.IsEmpty() && !expr.IsEmpty()) {
     269           0 :                 compiledexpr = CreateExpression(expr, condition, rv);
     270           0 :                 if (rv.Failed()) {
     271           0 :                     nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_ASSIGN_XPATH);
     272           0 :                     return rv.StealNSResult();
     273             :                 }
     274             : 
     275           0 :                 nsCOMPtr<nsIAtom> varatom = NS_Atomize(var);
     276             : 
     277           0 :                 query->AddBinding(varatom, Move(compiledexpr));
     278             :             }
     279             :         }
     280             :     }
     281             : 
     282           0 :     query.forget(_retval);
     283             : 
     284           0 :     return NS_OK;
     285             : }
     286             : 
     287             : NS_IMETHODIMP
     288           0 : nsXULTemplateQueryProcessorXML::GenerateResults(nsISupports* aDatasource,
     289             :                                                 nsIXULTemplateResult* aRef,
     290             :                                                 nsISupports* aQuery,
     291             :                                                 nsISimpleEnumerator** aResults)
     292             : {
     293           0 :     if (!aQuery)
     294           0 :         return NS_ERROR_INVALID_ARG;
     295             : 
     296           0 :     mGenerationStarted = true;
     297             : 
     298           0 :     nsCOMPtr<nsXMLQuery> xmlquery = do_QueryInterface(aQuery);
     299           0 :     if (!xmlquery)
     300           0 :         return NS_ERROR_INVALID_ARG;
     301             : 
     302           0 :     nsCOMPtr<nsISupports> supports;
     303           0 :     nsCOMPtr<nsINode> context;
     304           0 :     if (aRef)
     305           0 :       aRef->GetBindingObjectFor(xmlquery->GetMemberVariable(),
     306           0 :                                 getter_AddRefs(supports));
     307           0 :     context = do_QueryInterface(supports);
     308           0 :     if (!context)
     309           0 :         context = mRoot;
     310             : 
     311           0 :     XPathExpression* expr = xmlquery->GetResultsExpression();
     312           0 :     if (!expr)
     313           0 :         return NS_ERROR_FAILURE;
     314             : 
     315           0 :     ErrorResult rv;
     316             :     RefPtr<XPathResult> exprresults =
     317           0 :         expr->Evaluate(*context, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
     318           0 :                        nullptr, rv);
     319           0 :     if (rv.Failed()) {
     320           0 :         return rv.StealNSResult();
     321             :     }
     322             : 
     323             :     RefPtr<nsXULTemplateResultSetXML> results =
     324           0 :         new nsXULTemplateResultSetXML(xmlquery, exprresults.forget(),
     325           0 :                                       xmlquery->GetBindingSet());
     326             : 
     327           0 :     results.forget(aResults);
     328             : 
     329           0 :     return NS_OK;
     330             : }
     331             : 
     332             : NS_IMETHODIMP
     333           0 : nsXULTemplateQueryProcessorXML::AddBinding(nsIDOMNode* aRuleNode,
     334             :                                            nsIAtom* aVar,
     335             :                                            nsIAtom* aRef,
     336             :                                            const nsAString& aExpr)
     337             : {
     338           0 :     if (mGenerationStarted)
     339           0 :         return NS_ERROR_FAILURE;
     340             : 
     341           0 :     RefPtr<nsXMLBindingSet> bindings = mRuleToBindingsMap.GetWeak(aRuleNode);
     342           0 :     if (!bindings) {
     343           0 :         bindings = new nsXMLBindingSet();
     344           0 :         mRuleToBindingsMap.Put(aRuleNode, bindings);
     345             :     }
     346             : 
     347           0 :     nsCOMPtr<nsINode> ruleNode = do_QueryInterface(aRuleNode);
     348             : 
     349           0 :     ErrorResult rv;
     350           0 :     nsAutoPtr<XPathExpression> compiledexpr;
     351           0 :     compiledexpr = CreateExpression(aExpr, ruleNode, rv);
     352           0 :     if (rv.Failed()) {
     353           0 :         rv.SuppressException();
     354           0 :         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_BINDING_XPATH);
     355           0 :         return NS_OK;
     356             :     }
     357             : 
     358             :     // aRef isn't currently used for XML query processors
     359           0 :     bindings->AddBinding(aVar, Move(compiledexpr));
     360           0 :     return NS_OK;
     361             : }
     362             : 
     363             : NS_IMETHODIMP
     364           0 : nsXULTemplateQueryProcessorXML::TranslateRef(nsISupports* aDatasource,
     365             :                                              const nsAString& aRefString,
     366             :                                              nsIXULTemplateResult** aRef)
     367             : {
     368           0 :     *aRef = nullptr;
     369             : 
     370             :     // the datasource is either a document or a DOM element
     371           0 :     nsCOMPtr<Element> rootElement;
     372           0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDatasource);
     373           0 :     if (doc)
     374           0 :         rootElement = doc->GetRootElement();
     375             :     else
     376           0 :         rootElement = do_QueryInterface(aDatasource);
     377             : 
     378             :     // if no root element, just return. The document may not have loaded yet
     379           0 :     if (!rootElement)
     380           0 :         return NS_OK;
     381             : 
     382           0 :     RefPtr<nsXULTemplateResultXML> result = new nsXULTemplateResultXML(nullptr, rootElement, nullptr);
     383           0 :     result.forget(aRef);
     384             : 
     385           0 :     return NS_OK;
     386             : }
     387             : 
     388             : 
     389             : NS_IMETHODIMP
     390           0 : nsXULTemplateQueryProcessorXML::CompareResults(nsIXULTemplateResult* aLeft,
     391             :                                                nsIXULTemplateResult* aRight,
     392             :                                                nsIAtom* aVar,
     393             :                                                uint32_t aSortHints,
     394             :                                                int32_t* aResult)
     395             : {
     396           0 :     *aResult = 0;
     397           0 :     if (!aVar)
     398           0 :         return NS_OK;
     399             : 
     400           0 :     nsAutoString leftVal;
     401           0 :     if (aLeft)
     402           0 :         aLeft->GetBindingFor(aVar, leftVal);
     403             : 
     404           0 :     nsAutoString rightVal;
     405           0 :     if (aRight)
     406           0 :         aRight->GetBindingFor(aVar, rightVal);
     407             : 
     408           0 :     *aResult = XULSortServiceImpl::CompareValues(leftVal, rightVal, aSortHints);
     409           0 :     return NS_OK;
     410             : }
     411             : 
     412             : nsXMLBindingSet*
     413           0 : nsXULTemplateQueryProcessorXML::GetOptionalBindingsForRule(nsIDOMNode* aRuleNode)
     414             : {
     415           0 :     return mRuleToBindingsMap.GetWeak(aRuleNode);
     416             : }
     417             : 
     418             : XPathExpression*
     419           0 : nsXULTemplateQueryProcessorXML::CreateExpression(const nsAString& aExpr,
     420             :                                                  nsINode* aNode,
     421             :                                                  ErrorResult& aRv)
     422             : {
     423           0 :     return mEvaluator->CreateExpression(aExpr, aNode, aRv);
     424             : }
     425             : 
     426             : NS_IMETHODIMP
     427           0 : nsXULTemplateQueryProcessorXML::HandleEvent(nsIDOMEvent* aEvent)
     428             : {
     429           0 :     NS_PRECONDITION(aEvent, "aEvent null");
     430           0 :     nsAutoString eventType;
     431           0 :     aEvent->GetType(eventType);
     432             : 
     433           0 :     if (eventType.EqualsLiteral("load") && mTemplateBuilder) {
     434           0 :         NS_ASSERTION(mRequest, "request was not set");
     435           0 :         nsCOMPtr<nsIDOMDocument> doc;
     436           0 :         if (NS_SUCCEEDED(mRequest->GetResponseXML(getter_AddRefs(doc))))
     437           0 :             mTemplateBuilder->SetDatasource(doc);
     438             : 
     439             :         // to avoid leak. we don't need it after...
     440           0 :         mTemplateBuilder = nullptr;
     441           0 :         mRequest = nullptr;
     442             :     }
     443           0 :     else if (eventType.EqualsLiteral("error")) {
     444           0 :         mTemplateBuilder = nullptr;
     445           0 :         mRequest = nullptr;
     446             :     }
     447             : 
     448           0 :     return NS_OK;
     449             : }

Generated by: LCOV version 1.13