michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsContentSupportMap_h__ michael@0: #define nsContentSupportMap_h__ michael@0: michael@0: #include "pldhash.h" michael@0: #include "nsTemplateMatch.h" michael@0: michael@0: /** michael@0: * The nsContentSupportMap maintains a mapping from a "resource element" michael@0: * in the content tree to the nsTemplateMatch that was used to instantiate it. This michael@0: * is necessary to allow the XUL content to be built lazily. Specifically, michael@0: * when building "resumes" on a partially-built content element, the builder michael@0: * will walk upwards in the content tree to find the first element with an michael@0: * 'id' attribute. This element is assumed to be the "resource element", michael@0: * and allows the content builder to access the nsTemplateMatch (variable assignments michael@0: * and rule information). michael@0: */ michael@0: class nsContentSupportMap { michael@0: public: michael@0: nsContentSupportMap() { Init(); } michael@0: ~nsContentSupportMap() { Finish(); } michael@0: michael@0: nsresult Put(nsIContent* aElement, nsTemplateMatch* aMatch) { michael@0: if (!mMap.ops) michael@0: return NS_ERROR_NOT_INITIALIZED; michael@0: michael@0: PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mMap, aElement, PL_DHASH_ADD); michael@0: if (!hdr) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: Entry* entry = reinterpret_cast(hdr); michael@0: NS_ASSERTION(entry->mMatch == nullptr, "over-writing entry"); michael@0: entry->mContent = aElement; michael@0: entry->mMatch = aMatch; michael@0: return NS_OK; } michael@0: michael@0: bool Get(nsIContent* aElement, nsTemplateMatch** aMatch) { michael@0: if (!mMap.ops) michael@0: return false; michael@0: michael@0: PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mMap, aElement, PL_DHASH_LOOKUP); michael@0: if (PL_DHASH_ENTRY_IS_FREE(hdr)) michael@0: return false; michael@0: michael@0: Entry* entry = reinterpret_cast(hdr); michael@0: *aMatch = entry->mMatch; michael@0: return true; } michael@0: michael@0: nsresult Remove(nsIContent* aElement); michael@0: michael@0: void Clear() { Finish(); Init(); } michael@0: michael@0: protected: michael@0: PLDHashTable mMap; michael@0: michael@0: void Init(); michael@0: void Finish(); michael@0: michael@0: struct Entry { michael@0: PLDHashEntryHdr mHdr; michael@0: nsIContent* mContent; michael@0: nsTemplateMatch* mMatch; michael@0: }; michael@0: }; michael@0: michael@0: #endif