nsXMLBinding.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  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. #include "nsXULTemplateQueryProcessorXML.h"
  6. #include "nsXULTemplateResultXML.h"
  7. #include "nsXMLBinding.h"
  8. #include "mozilla/ErrorResult.h"
  9. #include "mozilla/dom/XPathResult.h"
  10. using namespace mozilla;
  11. using namespace mozilla::dom;
  12. nsXMLBindingSet::~nsXMLBindingSet()
  13. {}
  14. void
  15. nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsAutoPtr<XPathExpression>&& aExpr)
  16. {
  17. nsAutoPtr<nsXMLBinding> newbinding(new nsXMLBinding(aVar, Move(aExpr)));
  18. if (mFirst) {
  19. nsXMLBinding* binding = mFirst;
  20. while (binding) {
  21. // if the target variable is already used in a binding, ignore it
  22. // since it won't be useful for anything
  23. if (binding->mVar == aVar)
  24. return;
  25. // add the binding at the end of the list
  26. if (!binding->mNext) {
  27. binding->mNext = newbinding;
  28. return;
  29. }
  30. binding = binding->mNext;
  31. }
  32. }
  33. else {
  34. mFirst = newbinding;
  35. }
  36. }
  37. int32_t
  38. nsXMLBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable,
  39. nsXMLBinding** aBinding)
  40. {
  41. int32_t idx = 0;
  42. nsXMLBinding* binding = mFirst;
  43. while (binding) {
  44. if (binding->mVar == aTargetVariable) {
  45. *aBinding = binding;
  46. return idx;
  47. }
  48. idx++;
  49. binding = binding->mNext;
  50. }
  51. *aBinding = nullptr;
  52. return -1;
  53. }
  54. XPathResult*
  55. nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult,
  56. nsXMLBinding* aBinding,
  57. int32_t aIndex,
  58. uint16_t aType)
  59. {
  60. XPathResult* value = mValues.SafeElementAt(aIndex);
  61. if (value) {
  62. return value;
  63. }
  64. nsINode* contextNode = aResult->Node();
  65. if (!contextNode) {
  66. return nullptr;
  67. }
  68. mValues.EnsureLengthAtLeast(aIndex + 1);
  69. ErrorResult ignored;
  70. mValues[aIndex] = aBinding->mExpr->Evaluate(*contextNode, aType, nullptr,
  71. ignored);
  72. return mValues[aIndex];
  73. }
  74. nsINode*
  75. nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
  76. nsXMLBinding* aBinding,
  77. int32_t aIndex)
  78. {
  79. XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
  80. XPathResult::FIRST_ORDERED_NODE_TYPE);
  81. ErrorResult rv;
  82. return result ? result->GetSingleNodeValue(rv) : nullptr;
  83. }
  84. void
  85. nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult,
  86. nsXMLBinding* aBinding,
  87. int32_t aIndex,
  88. nsAString& aValue)
  89. {
  90. XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
  91. XPathResult::STRING_TYPE);
  92. if (result) {
  93. ErrorResult rv;
  94. result->GetStringValue(aValue, rv);
  95. } else {
  96. aValue.Truncate();
  97. }
  98. }