WindowFeatures.h (4314B)
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 #ifndef mozilla_dom_WindowFeatures_h 8 #define mozilla_dom_WindowFeatures_h 9 10 #include "mozilla/Assertions.h" // MOZ_ASSERT 11 #include "mozilla/HashTable.h" // mozilla::HashMap 12 #include "nsString.h" 13 #include "nsStringFwd.h" // nsCString, nsACString, nsAutoCString, nsLiteralCString 14 #include "nsTStringHasher.h" // mozilla::DefaultHasher<nsCString> 15 16 namespace mozilla::dom { 17 18 // Represents `tokenizedFeatures` in 19 // https://html.spec.whatwg.org/multipage/window-object.html#concept-window-open-features-tokenize 20 // with accessor methods for values. 21 class WindowFeatures { 22 public: 23 WindowFeatures() = default; 24 25 WindowFeatures(const WindowFeatures& aOther) = delete; 26 WindowFeatures& operator=(const WindowFeatures& aOther) = delete; 27 28 WindowFeatures(WindowFeatures&& aOther) = delete; 29 WindowFeatures& operator=(WindowFeatures&& aOther) = delete; 30 31 // Tokenizes `aFeatures` and stores the result map in member field. 32 // This should be called at the begining, only once. 33 // 34 // Returns true if successfully tokenized, false otherwise. 35 bool Tokenize(const nsACString& aFeatures); 36 37 // Returns true if the `aName` feature is specified. 38 template <size_t N> 39 bool Exists(const char (&aName)[N]) const { 40 MOZ_ASSERT(IsLowerCase(aName)); 41 nsLiteralCString name(aName); 42 return tokenizedFeatures_.has(name); 43 } 44 45 // Returns string value of `aName` feature. 46 // The feature must exist. 47 template <size_t N> 48 const nsCString& Get(const char (&aName)[N]) const { 49 MOZ_ASSERT(IsLowerCase(aName)); 50 nsLiteralCString name(aName); 51 auto p = tokenizedFeatures_.lookup(name); 52 MOZ_ASSERT(p.found()); 53 54 return p->value(); 55 } 56 57 // Returns integer value of `aName` feature. 58 // The feature must exist. 59 template <size_t N> 60 int32_t GetInt(const char (&aName)[N]) const { 61 const nsCString& value = Get(aName); 62 return ParseIntegerWithFallback(value); 63 } 64 65 // Returns bool value of `aName` feature. 66 // The feature must exist. 67 template <size_t N> 68 bool GetBool(const char (&aName)[N]) const { 69 const nsCString& value = Get(aName); 70 return ParseBool(value); 71 } 72 73 // Returns bool value of `aName` feature. 74 // If the feature doesn't exist, returns `aDefault`. 75 // 76 // If `aPresenceFlag` is provided and the feature exists, it's set to `true`. 77 // (note that the value isn't overwritten if the feature doesn't exist) 78 template <size_t N> 79 bool GetBoolWithDefault(const char (&aName)[N], bool aDefault, 80 bool* aPresenceFlag = nullptr) const { 81 MOZ_ASSERT(IsLowerCase(aName)); 82 nsLiteralCString name(aName); 83 auto p = tokenizedFeatures_.lookup(name); 84 if (p.found()) { 85 if (aPresenceFlag) { 86 *aPresenceFlag = true; 87 } 88 return ParseBool(p->value()); 89 } 90 return aDefault; 91 } 92 93 // Remove the feature from the map. 94 template <size_t N> 95 void Remove(const char (&aName)[N]) { 96 MOZ_ASSERT(IsLowerCase(aName)); 97 nsLiteralCString name(aName); 98 tokenizedFeatures_.remove(name); 99 } 100 101 // Returns true if there was no feature specified, or all features are 102 // removed by `Remove`. 103 // 104 // Note that this can be true even if `aFeatures` parameter of `Tokenize` 105 // is not empty, in case it contains no feature with non-empty name. 106 bool IsEmpty() const { return tokenizedFeatures_.empty(); } 107 108 // Stringify the map into `aOutput`. 109 // The result can be parsed again with `Tokenize`. 110 void Stringify(nsAutoCString& aOutput); 111 112 private: 113 #ifdef DEBUG 114 // Returns true if `text` does not contain any character that gets modified by 115 // `ToLowerCase`. 116 static bool IsLowerCase(const char* text); 117 #endif 118 119 static int32_t ParseIntegerWithFallback(const nsCString& aValue); 120 static bool ParseBool(const nsCString& aValue); 121 122 // A map from feature name to feature value. 123 // If value is not provided, it's empty string. 124 mozilla::HashMap<nsCString, nsCString> tokenizedFeatures_; 125 }; 126 127 } // namespace mozilla::dom 128 129 #endif // #ifndef mozilla_dom_WindowFeatures_h