summaryrefslogtreecommitdiffstats
path: root/dom/svg/SVGAttrTearoffTable.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/svg/SVGAttrTearoffTable.h98
1 files changed, 98 insertions, 0 deletions
diff --git a/dom/svg/SVGAttrTearoffTable.h b/dom/svg/SVGAttrTearoffTable.h
new file mode 100644
index 0000000000..14c5d07466
--- /dev/null
+++ b/dom/svg/SVGAttrTearoffTable.h
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef DOM_SVG_SVGATTRTEAROFFTABLE_H_
+#define DOM_SVG_SVGATTRTEAROFFTABLE_H_
+
+#include "mozilla/DebugOnly.h"
+#include "mozilla/StaticPtr.h"
+#include "nsTHashMap.h"
+#include "nsDebug.h"
+#include "nsHashKeys.h"
+
+namespace mozilla {
+
+/**
+ * Global hashmap to associate internal SVG data types (e.g. SVGAnimatedLength)
+ * with DOM tear-off objects (e.g. DOMSVGLength). This allows us to always
+ * return the same object for subsequent requests for DOM objects.
+ *
+ * We don't keep an owning reference to the tear-off objects so they are
+ * responsible for removing themselves from this table when they die.
+ */
+template <class SimpleType, class TearoffType>
+class SVGAttrTearoffTable {
+ public:
+#ifdef DEBUG
+ ~SVGAttrTearoffTable() {
+ NS_ASSERTION(!mTable, "Tear-off objects remain in hashtable at shutdown.");
+ }
+#endif
+
+ TearoffType* GetTearoff(SimpleType* aSimple);
+
+ void AddTearoff(SimpleType* aSimple, TearoffType* aTearoff);
+
+ void RemoveTearoff(SimpleType* aSimple);
+
+ private:
+ using SimpleTypePtrKey = nsPtrHashKey<SimpleType>;
+ using TearoffTable = nsTHashMap<SimpleTypePtrKey, TearoffType*>;
+
+ StaticAutoPtr<TearoffTable> mTable;
+};
+
+template <class SimpleType, class TearoffType>
+TearoffType* SVGAttrTearoffTable<SimpleType, TearoffType>::GetTearoff(
+ SimpleType* aSimple) {
+ if (!mTable) {
+ return nullptr;
+ }
+
+ TearoffType* tearoff = nullptr;
+
+ DebugOnly<bool> found = mTable->Get(aSimple, &tearoff);
+ MOZ_ASSERT(!found || tearoff,
+ "null pointer stored in attribute tear-off map");
+
+ return tearoff;
+}
+
+template <class SimpleType, class TearoffType>
+void SVGAttrTearoffTable<SimpleType, TearoffType>::AddTearoff(
+ SimpleType* aSimple, TearoffType* aTearoff) {
+ if (!mTable) {
+ mTable = new TearoffTable();
+ }
+
+ // We shouldn't be adding a tear-off if there already is one. If that happens,
+ // something is wrong.
+ if (mTable->Get(aSimple, nullptr)) {
+ MOZ_ASSERT(false, "There is already a tear-off for this object.");
+ return;
+ }
+
+ mTable->InsertOrUpdate(aSimple, aTearoff);
+}
+
+template <class SimpleType, class TearoffType>
+void SVGAttrTearoffTable<SimpleType, TearoffType>::RemoveTearoff(
+ SimpleType* aSimple) {
+ if (!mTable) {
+ // Perhaps something happened in between creating the SimpleType object and
+ // registering it
+ return;
+ }
+
+ mTable->Remove(aSimple);
+ if (mTable->Count() == 0) {
+ mTable = nullptr;
+ }
+}
+
+} // namespace mozilla
+
+#endif // DOM_SVG_SVGATTRTEAROFFTABLE_H_