summaryrefslogtreecommitdiffstats
path: root/dom/xslt/base/txNamespaceMap.cpp
blob: f6b5b7bfb70576f45e322fda28ed984e05051858 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "txNamespaceMap.h"
#include "nsGkAtoms.h"
#include "txXPathNode.h"

txNamespaceMap::txNamespaceMap() = default;

txNamespaceMap::txNamespaceMap(const txNamespaceMap& aOther)
    : mPrefixes(aOther.mPrefixes.Clone()),
      mNamespaces(aOther.mNamespaces.Clone()) {}

nsresult txNamespaceMap::mapNamespace(nsAtom* aPrefix,
                                      const nsAString& aNamespaceURI) {
  nsAtom* prefix = aPrefix == nsGkAtoms::_empty ? nullptr : aPrefix;

  int32_t nsId;
  if (prefix && aNamespaceURI.IsEmpty()) {
    // Remove the mapping
    int32_t index = mPrefixes.IndexOf(prefix);
    if (index >= 0) {
      mPrefixes.RemoveElementAt(index);
      mNamespaces.RemoveElementAt(index);
    }

    return NS_OK;
  }

  if (aNamespaceURI.IsEmpty()) {
    // Set default to empty namespace
    nsId = kNameSpaceID_None;
  } else {
    nsId = txNamespaceManager::getNamespaceID(aNamespaceURI);
    NS_ENSURE_FALSE(nsId == kNameSpaceID_Unknown, NS_ERROR_FAILURE);
  }

  // Check if the mapping already exists
  int32_t index = mPrefixes.IndexOf(prefix);
  if (index >= 0) {
    mNamespaces.ElementAt(index) = nsId;

    return NS_OK;
  }

  // New mapping
  // XXX(Bug 1631371) Check if this should use a fallible operation as it
  // pretended earlier.
  mPrefixes.AppendElement(prefix);

  // XXX(Bug 1631371) Check if this should use a fallible operation as it
  // pretended earlier.
  mNamespaces.AppendElement(nsId);

  return NS_OK;
}

int32_t txNamespaceMap::lookupNamespace(nsAtom* aPrefix) {
  if (aPrefix == nsGkAtoms::xml) {
    return kNameSpaceID_XML;
  }

  nsAtom* prefix = aPrefix == nsGkAtoms::_empty ? 0 : aPrefix;

  int32_t index = mPrefixes.IndexOf(prefix);
  if (index >= 0) {
    return mNamespaces.SafeElementAt(index, kNameSpaceID_Unknown);
  }

  if (!prefix) {
    return kNameSpaceID_None;
  }

  return kNameSpaceID_Unknown;
}

int32_t txNamespaceMap::lookupNamespaceWithDefault(const nsAString& aPrefix) {
  RefPtr<nsAtom> prefix = NS_Atomize(aPrefix);
  if (prefix != nsGkAtoms::_poundDefault) {
    return lookupNamespace(prefix);
  }

  return lookupNamespace(nullptr);
}