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