tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGElementFactory.cpp (3848B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      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 #include "SVGElementFactory.h"
      8 
      9 #include "mozilla/StaticPtr.h"
     10 #include "mozilla/dom/Element.h"
     11 #include "mozilla/dom/FromParser.h"
     12 #include "mozilla/dom/NodeInfo.h"
     13 #include "nsGkAtoms.h"
     14 #include "nsHashKeys.h"
     15 #include "nsIContent.h"
     16 #include "nsTHashMap.h"
     17 
     18 using namespace mozilla;
     19 using namespace mozilla::dom;
     20 
     21 // Hash table that maps nsAtom* SVG tags to a SVGContentCreatorFunction.
     22 using TagAtomTable =
     23    nsTHashMap<nsPtrHashKey<nsAtom>, SVGContentCreatorFunction>;
     24 StaticAutoPtr<TagAtomTable> sTagAtomTable;
     25 
     26 #define SVG_TAG(_tag, _classname)                                         \
     27  nsresult NS_NewSVG##_classname##Element(                                \
     28      nsIContent** aResult,                                               \
     29      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);              \
     30                                                                          \
     31  nsresult NS_NewSVG##_classname##Element(                                \
     32      nsIContent** aResult,                                               \
     33      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,               \
     34      FromParser aFromParser) {                                           \
     35    return NS_NewSVG##_classname##Element(aResult, std::move(aNodeInfo)); \
     36  }
     37 
     38 #define SVG_FROM_PARSER_TAG(_tag, _classname)
     39 
     40 #include "SVGTagList.h"
     41 #undef SVG_TAG
     42 #undef SVG_FROM_PARSER_TAG
     43 
     44 nsresult NS_NewSVGElement(Element** aResult,
     45                          already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
     46 
     47 enum SVGTag {
     48 #define SVG_TAG(_tag, _classname) eSVGTag_##_tag,
     49 #define SVG_FROM_PARSER_TAG(_tag, _classname) eSVGTag_##_tag,
     50 #include "SVGTagList.h"
     51 #undef SVG_TAG
     52 #undef SVG_FROM_PARSER_TAG
     53  eSVGTag_Count
     54 };
     55 
     56 void SVGElementFactory::Init() {
     57  sTagAtomTable = new TagAtomTable(64);
     58 
     59 #define SVG_TAG(_tag, _classname) \
     60  sTagAtomTable->InsertOrUpdate(  \
     61      nsGkAtoms::_tag,            \
     62      SVGContentCreatorFunction(NS_NewSVG##_classname##Element));
     63 #define SVG_FROM_PARSER_TAG(_tag, _classname) \
     64  sTagAtomTable->InsertOrUpdate(              \
     65      nsGkAtoms::_tag,                        \
     66      SVGContentCreatorFunction(NS_NewSVG##_classname##Element));
     67 #include "SVGTagList.h"
     68 #undef SVG_TAG
     69 #undef SVG_FROM_PARSER_TAG
     70 }
     71 
     72 void SVGElementFactory::Shutdown() { sTagAtomTable = nullptr; }
     73 
     74 nsresult NS_NewSVGElement(Element** aResult,
     75                          already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     76                          FromParser aFromParser) {
     77  NS_ASSERTION(sTagAtomTable, "no lookup table, needs SVGElementFactory::Init");
     78 
     79  RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
     80  nsAtom* name = ni->NameAtom();
     81 
     82  NS_ASSERTION(
     83      ni->NamespaceEquals(kNameSpaceID_SVG),
     84      "Trying to create SVG elements that aren't in the SVG namespace");
     85 
     86  SVGContentCreatorFunction cb = sTagAtomTable->Get(name);
     87  if (cb) {
     88    nsCOMPtr<nsIContent> content;
     89    nsresult rv = cb(getter_AddRefs(content), ni.forget(), aFromParser);
     90    *aResult = content.forget().take()->AsElement();
     91    return rv;
     92  }
     93 
     94  // if we don't know what to create, just create a standard svg element:
     95  return NS_NewSVGElement(aResult, ni.forget());
     96 }
     97 
     98 nsresult NS_NewSVGUnknownElement(
     99    nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
    100    FromParser aFromParser) {
    101  RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
    102  nsCOMPtr<Element> element;
    103  nsresult rv = NS_NewSVGElement(getter_AddRefs(element), ni.forget());
    104  element.forget(aResult);
    105  return rv;
    106 }