From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- parser/htmlparser/nsHTMLTags.cpp | 167 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 parser/htmlparser/nsHTMLTags.cpp (limited to 'parser/htmlparser/nsHTMLTags.cpp') diff --git a/parser/htmlparser/nsHTMLTags.cpp b/parser/htmlparser/nsHTMLTags.cpp new file mode 100644 index 0000000000..ec3c4f322d --- /dev/null +++ b/parser/htmlparser/nsHTMLTags.cpp @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 2; 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 "nsHTMLTags.h" +#include "nsCRT.h" +#include "nsElementTable.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsUnicharUtils.h" +#include "mozilla/HashFunctions.h" +#include + +using namespace mozilla; + +// static array of unicode tag names +#define HTML_TAG(_tag, _classname, _interfacename) (u"" #_tag), +#define HTML_OTHER(_tag) +const char16_t* const nsHTMLTags::sTagNames[] = { +#include "nsHTMLTagList.h" +}; +#undef HTML_TAG +#undef HTML_OTHER + +int32_t nsHTMLTags::gTableRefCount; +nsHTMLTags::TagStringHash* nsHTMLTags::gTagTable; +nsHTMLTags::TagAtomHash* nsHTMLTags::gTagAtomTable; + +#define NS_HTMLTAG_NAME_MAX_LENGTH 10 + +// static +nsresult nsHTMLTags::AddRefTable(void) { + if (gTableRefCount++ == 0) { + NS_ASSERTION(!gTagTable && !gTagAtomTable, "pre existing hash!"); + + gTagTable = new TagStringHash(64); + gTagAtomTable = new TagAtomHash(64); + + // Fill in gTagTable with the above static char16_t strings as + // keys and the value of the corresponding enum as the value in + // the table. + + for (int32_t i = 0; i < NS_HTML_TAG_MAX; ++i) { + const char16_t* tagName = sTagNames[i]; + const nsHTMLTag tagValue = static_cast(i + 1); + + // We use AssignLiteral here to avoid a string copy. This is okay + // because this is truly static data. + nsString tmp; + tmp.AssignLiteral(tagName, nsString::char_traits::length(tagName)); + gTagTable->InsertOrUpdate(tmp, tagValue); + + // All the HTML tag names are static atoms within nsGkAtoms, and they are + // registered before this code is reached. + nsStaticAtom* atom = NS_GetStaticAtom(tmp); + MOZ_ASSERT(atom); + gTagAtomTable->InsertOrUpdate(atom, tagValue); + } + +#ifdef DEBUG + // Check all tagNames are lowercase, and that NS_HTMLTAG_NAME_MAX_LENGTH is + // correct. + uint32_t maxTagNameLength = 0; + for (int i = 0; i < NS_HTML_TAG_MAX; ++i) { + const char16_t* tagName = sTagNames[i]; + + nsAutoString lowerTagName(tagName); + ToLowerCase(lowerTagName); + MOZ_ASSERT(lowerTagName.Equals(tagName)); + + maxTagNameLength = std::max(NS_strlen(tagName), maxTagNameLength); + } + + MOZ_ASSERT(maxTagNameLength == NS_HTMLTAG_NAME_MAX_LENGTH); + + CheckElementTable(); + TestTagTable(); +#endif + } + + return NS_OK; +} + +// static +void nsHTMLTags::ReleaseTable(void) { + if (0 == --gTableRefCount) { + delete gTagTable; + delete gTagAtomTable; + gTagTable = nullptr; + gTagAtomTable = nullptr; + } +} + +// static +nsHTMLTag nsHTMLTags::StringTagToId(const nsAString& aTagName) { + uint32_t length = aTagName.Length(); + + if (length > NS_HTMLTAG_NAME_MAX_LENGTH) { + return eHTMLTag_userdefined; + } + + // Setup a stack allocated string buffer with the appropriate length. + nsAutoString lowerCase; + lowerCase.SetLength(length); + + // Operate on the raw buffers to avoid bounds checks. + auto src = aTagName.BeginReading(); + auto dst = lowerCase.BeginWriting(); + + // Fast lowercasing-while-copying of ASCII characters into a + // nsString buffer. + + for (uint32_t i = 0; i < length; i++) { + char16_t c = src[i]; + + if (c <= 'Z' && c >= 'A') { + c |= 0x20; // Lowercase the ASCII character. + } + + dst[i] = c; // Copy ASCII character. + } + + return CaseSensitiveStringTagToId(lowerCase); +} + +#ifdef DEBUG +void nsHTMLTags::TestTagTable() { + const char16_t* tag; + nsHTMLTag id; + RefPtr atom; + + nsHTMLTags::AddRefTable(); + // Make sure we can find everything we are supposed to + for (int i = 0; i < NS_HTML_TAG_MAX; ++i) { + tag = sTagNames[i]; + const nsAString& tagString = nsDependentString(tag); + id = StringTagToId(tagString); + NS_ASSERTION(id != eHTMLTag_userdefined, "can't find tag id"); + + nsAutoString uname(tagString); + ToUpperCase(uname); + NS_ASSERTION(id == StringTagToId(uname), "wrong id"); + + NS_ASSERTION(id == CaseSensitiveStringTagToId(tagString), "wrong id"); + + atom = NS_Atomize(tag); + NS_ASSERTION(id == CaseSensitiveAtomTagToId(atom), "wrong id"); + } + + // Make sure we don't find things that aren't there + id = StringTagToId(u"@"_ns); + NS_ASSERTION(id == eHTMLTag_userdefined, "found @"); + id = StringTagToId(u"zzzzz"_ns); + NS_ASSERTION(id == eHTMLTag_userdefined, "found zzzzz"); + + atom = NS_Atomize("@"); + id = CaseSensitiveAtomTagToId(atom); + NS_ASSERTION(id == eHTMLTag_userdefined, "found @"); + atom = NS_Atomize("zzzzz"); + id = CaseSensitiveAtomTagToId(atom); + NS_ASSERTION(id == eHTMLTag_userdefined, "found zzzzz"); + + ReleaseTable(); +} + +#endif // DEBUG -- cgit v1.2.3