mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-30 05:09:01 +00:00
LibWeb: Move window.open TokenizedFeature parsing into its own file
This commit is contained in:
parent
79143833b6
commit
e2d50dc5dd
Notes:
sideshowbarker
2024-07-16 23:55:09 +09:00
Author: https://github.com/ADKaster
Commit: e2d50dc5dd
Pull-request: https://github.com/SerenityOS/serenity/pull/24477
Reviewed-by: https://github.com/trflynn89
5 changed files with 216 additions and 177 deletions
|
@ -163,6 +163,7 @@ source_set("HTML") {
|
||||||
"TimeRanges.cpp",
|
"TimeRanges.cpp",
|
||||||
"Timer.cpp",
|
"Timer.cpp",
|
||||||
"ToggleEvent.cpp",
|
"ToggleEvent.cpp",
|
||||||
|
"TokenizedFeatures.cpp",
|
||||||
"TrackEvent.cpp",
|
"TrackEvent.cpp",
|
||||||
"TraversableNavigable.cpp",
|
"TraversableNavigable.cpp",
|
||||||
"UserActivation.cpp",
|
"UserActivation.cpp",
|
||||||
|
|
|
@ -430,6 +430,7 @@ set(SOURCES
|
||||||
HTML/Timer.cpp
|
HTML/Timer.cpp
|
||||||
HTML/TimeRanges.cpp
|
HTML/TimeRanges.cpp
|
||||||
HTML/ToggleEvent.cpp
|
HTML/ToggleEvent.cpp
|
||||||
|
HTML/TokenizedFeatures.cpp
|
||||||
HTML/TrackEvent.cpp
|
HTML/TrackEvent.cpp
|
||||||
HTML/TraversableNavigable.cpp
|
HTML/TraversableNavigable.cpp
|
||||||
HTML/UserActivation.cpp
|
HTML/UserActivation.cpp
|
||||||
|
|
199
Userland/Libraries/LibWeb/HTML/TokenizedFeatures.cpp
Normal file
199
Userland/Libraries/LibWeb/HTML/TokenizedFeatures.cpp
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/GenericLexer.h>
|
||||||
|
#include <LibWeb/HTML/TokenizedFeatures.h>
|
||||||
|
#include <LibWeb/Infra/CharacterTypes.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#normalizing-the-feature-name
|
||||||
|
static String normalize_feature_name(String const& name)
|
||||||
|
{
|
||||||
|
// For legacy reasons, there are some aliases of some feature names. To normalize a feature name name, switch on name:
|
||||||
|
|
||||||
|
// "screenx"
|
||||||
|
if (name == "screenx"sv) {
|
||||||
|
// Return "left".
|
||||||
|
return "left"_string;
|
||||||
|
}
|
||||||
|
// "screeny"
|
||||||
|
else if (name == "screeny"sv) {
|
||||||
|
// Return "top".
|
||||||
|
return "top"_string;
|
||||||
|
}
|
||||||
|
// "innerwidth"
|
||||||
|
else if (name == "innerwidth"sv) {
|
||||||
|
// Return "width".
|
||||||
|
return "width"_string;
|
||||||
|
}
|
||||||
|
// "innerheight"
|
||||||
|
else if (name == "innerheight") {
|
||||||
|
// Return "height".
|
||||||
|
return "height"_string;
|
||||||
|
}
|
||||||
|
// Anything else
|
||||||
|
else {
|
||||||
|
// Return name.
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-window-open-features-tokenize
|
||||||
|
TokenizedFeature::Map tokenize_open_features(StringView features)
|
||||||
|
{
|
||||||
|
// 1. Let tokenizedFeatures be a new ordered map.
|
||||||
|
TokenizedFeature::Map tokenized_features;
|
||||||
|
|
||||||
|
// 2. Let position point at the first code point of features.
|
||||||
|
GenericLexer lexer(features);
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#feature-separator
|
||||||
|
auto is_feature_separator = [](auto character) {
|
||||||
|
return Infra::is_ascii_whitespace(character) || character == '=' || character == ',';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3. While position is not past the end of features:
|
||||||
|
while (!lexer.is_eof()) {
|
||||||
|
// 1. Let name be the empty string.
|
||||||
|
String name;
|
||||||
|
|
||||||
|
// 2. Let value be the empty string.
|
||||||
|
String value;
|
||||||
|
|
||||||
|
// 3. Collect a sequence of code points that are feature separators from features given position. This skips past leading separators before the name.
|
||||||
|
lexer.ignore_while(is_feature_separator);
|
||||||
|
|
||||||
|
// 4. Collect a sequence of code points that are not feature separators from features given position. Set name to the collected characters, converted to ASCII lowercase.
|
||||||
|
name = MUST(String::from_byte_string(lexer.consume_until(is_feature_separator).to_lowercase_string()));
|
||||||
|
|
||||||
|
// 5. Set name to the result of normalizing the feature name name.
|
||||||
|
name = normalize_feature_name(name);
|
||||||
|
|
||||||
|
// 6. While position is not past the end of features and the code point at position in features is not U+003D (=):
|
||||||
|
// 1. If the code point at position in features is U+002C (,), or if it is not a feature separator, then break.
|
||||||
|
// 2. Advance position by 1.
|
||||||
|
lexer.ignore_while(Infra::is_ascii_whitespace);
|
||||||
|
|
||||||
|
// 7. If the code point at position in features is a feature separator:
|
||||||
|
// 1. While position is not past the end of features and the code point at position in features is a feature separator:
|
||||||
|
// 1. If the code point at position in features is U+002C (,), then break.
|
||||||
|
// 2. Advance position by 1.
|
||||||
|
lexer.ignore_while([](auto character) { return Infra::is_ascii_whitespace(character) || character == '='; });
|
||||||
|
|
||||||
|
// 2. Collect a sequence of code points that are not feature separators code points from features given position. Set value to the collected code points, converted to ASCII lowercase.
|
||||||
|
value = MUST(String::from_byte_string(lexer.consume_until(is_feature_separator).to_lowercase_string()));
|
||||||
|
|
||||||
|
// 8. If name is not the empty string, then set tokenizedFeatures[name] to value.
|
||||||
|
if (!name.is_empty())
|
||||||
|
tokenized_features.set(move(name), move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return tokenizedFeatures.
|
||||||
|
return tokenized_features;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-window-open-features-parse-boolean
|
||||||
|
template<Enum T>
|
||||||
|
T parse_boolean_feature(StringView value)
|
||||||
|
{
|
||||||
|
// 1. If value is the empty string, then return true.
|
||||||
|
if (value.is_empty())
|
||||||
|
return T::Yes;
|
||||||
|
|
||||||
|
// 2. If value is "yes", then return true.
|
||||||
|
if (value == "yes"sv)
|
||||||
|
return T::Yes;
|
||||||
|
|
||||||
|
// 3. If value is "true", then return true.
|
||||||
|
if (value == "true"sv)
|
||||||
|
return T::Yes;
|
||||||
|
|
||||||
|
// 4. Let parsed be the result of parsing value as an integer.
|
||||||
|
auto parsed = value.to_number<i64>();
|
||||||
|
|
||||||
|
// 5. If parsed is an error, then set it to 0.
|
||||||
|
if (!parsed.has_value())
|
||||||
|
parsed = 0;
|
||||||
|
|
||||||
|
// 6. Return false if parsed is 0, and true otherwise.
|
||||||
|
return parsed == 0 ? T::No : T::Yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
template TokenizedFeature::Location parse_boolean_feature<TokenizedFeature::Location>(StringView value);
|
||||||
|
template TokenizedFeature::Menubar parse_boolean_feature<TokenizedFeature::Menubar>(StringView value);
|
||||||
|
template TokenizedFeature::NoOpener parse_boolean_feature<TokenizedFeature::NoOpener>(StringView value);
|
||||||
|
template TokenizedFeature::NoReferrer parse_boolean_feature<TokenizedFeature::NoReferrer>(StringView value);
|
||||||
|
template TokenizedFeature::Popup parse_boolean_feature<TokenizedFeature::Popup>(StringView value);
|
||||||
|
template TokenizedFeature::Resizable parse_boolean_feature<TokenizedFeature::Resizable>(StringView value);
|
||||||
|
template TokenizedFeature::Scrollbars parse_boolean_feature<TokenizedFeature::Scrollbars>(StringView value);
|
||||||
|
template TokenizedFeature::Status parse_boolean_feature<TokenizedFeature::Status>(StringView value);
|
||||||
|
template TokenizedFeature::Toolbar parse_boolean_feature<TokenizedFeature::Toolbar>(StringView value);
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/window-object.html#popup-window-is-requested
|
||||||
|
TokenizedFeature::Popup check_if_a_popup_window_is_requested(TokenizedFeature::Map const& tokenized_features)
|
||||||
|
{
|
||||||
|
// 1. If tokenizedFeatures is empty, then return false.
|
||||||
|
if (tokenized_features.is_empty())
|
||||||
|
return TokenizedFeature::Popup::No;
|
||||||
|
|
||||||
|
// 2. If tokenizedFeatures["popup"] exists, then return the result of parsing tokenizedFeatures["popup"] as a boolean feature.
|
||||||
|
if (auto popup_feature = tokenized_features.get("popup"sv); popup_feature.has_value())
|
||||||
|
return parse_boolean_feature<TokenizedFeature::Popup>(*popup_feature);
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/window-object.html#window-feature-is-set
|
||||||
|
auto check_if_a_window_feature_is_set = [&]<Enum T>(StringView feature_name, T default_value) {
|
||||||
|
// 1. If tokenizedFeatures[featureName] exists, then return the result of parsing tokenizedFeatures[featureName] as a boolean feature.
|
||||||
|
if (auto feature = tokenized_features.get(feature_name); feature.has_value())
|
||||||
|
return parse_boolean_feature<T>(*feature);
|
||||||
|
|
||||||
|
// 2. Return defaultValue.
|
||||||
|
return default_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3. Let location be the result of checking if a window feature is set, given tokenizedFeatures, "location", and false.
|
||||||
|
auto location = check_if_a_window_feature_is_set("location"sv, TokenizedFeature::Location::No);
|
||||||
|
|
||||||
|
// 4. Let toolbar be the result of checking if a window feature is set, given tokenizedFeatures, "toolbar", and false.
|
||||||
|
auto toolbar = check_if_a_window_feature_is_set("toolbar"sv, TokenizedFeature::Toolbar::No);
|
||||||
|
|
||||||
|
// 5. If location and toolbar are both false, then return true.
|
||||||
|
if (location == TokenizedFeature::Location::No && toolbar == TokenizedFeature::Toolbar::No)
|
||||||
|
return TokenizedFeature::Popup::Yes;
|
||||||
|
|
||||||
|
// 6. Let menubar be the result of checking if a window feature is set, given tokenizedFeatures, menubar", and false.
|
||||||
|
auto menubar = check_if_a_window_feature_is_set("menubar"sv, TokenizedFeature::Menubar::No);
|
||||||
|
|
||||||
|
// 7. If menubar is false, then return true.
|
||||||
|
if (menubar == TokenizedFeature::Menubar::No)
|
||||||
|
return TokenizedFeature::Popup::Yes;
|
||||||
|
|
||||||
|
// 8. Let resizable be the result of checking if a window feature is set, given tokenizedFeatures, "resizable", and true.
|
||||||
|
auto resizable = check_if_a_window_feature_is_set("resizable"sv, TokenizedFeature::Resizable::Yes);
|
||||||
|
|
||||||
|
// 9. If resizable is false, then return true.
|
||||||
|
if (resizable == TokenizedFeature::Resizable::No)
|
||||||
|
return TokenizedFeature::Popup::Yes;
|
||||||
|
|
||||||
|
// 10. Let scrollbars be the result of checking if a window feature is set, given tokenizedFeatures, "scrollbars", and false.
|
||||||
|
auto scrollbars = check_if_a_window_feature_is_set("scrollbars"sv, TokenizedFeature::Scrollbars::No);
|
||||||
|
|
||||||
|
// 11. If scrollbars is false, then return true.
|
||||||
|
if (scrollbars == TokenizedFeature::Scrollbars::No)
|
||||||
|
return TokenizedFeature::Popup::Yes;
|
||||||
|
|
||||||
|
// 12. Let status be the result of checking if a window feature is set, given tokenizedFeatures, "status", and false.
|
||||||
|
auto status = check_if_a_window_feature_is_set("status"sv, TokenizedFeature::Status::No);
|
||||||
|
|
||||||
|
// 13. If status is false, then return true.
|
||||||
|
if (status == TokenizedFeature::Status::No)
|
||||||
|
return TokenizedFeature::Popup::Yes;
|
||||||
|
|
||||||
|
// 14. Return false.
|
||||||
|
return TokenizedFeature::Popup::No;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/HashMap.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
|
||||||
namespace Web::HTML::TokenizedFeature {
|
namespace Web::HTML::TokenizedFeature {
|
||||||
|
|
||||||
#define TOKENIZED_FEATURE(Feature) \
|
#define TOKENIZED_FEATURE(Feature) \
|
||||||
|
@ -24,4 +27,16 @@ TOKENIZED_FEATURE(Scrollbars);
|
||||||
TOKENIZED_FEATURE(Status);
|
TOKENIZED_FEATURE(Status);
|
||||||
TOKENIZED_FEATURE(Toolbar);
|
TOKENIZED_FEATURE(Toolbar);
|
||||||
|
|
||||||
|
using Map = OrderedHashMap<String, String>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
TokenizedFeature::Map tokenize_open_features(StringView features);
|
||||||
|
TokenizedFeature::Popup check_if_a_popup_window_is_requested(TokenizedFeature::Map const&);
|
||||||
|
|
||||||
|
template<Enum T>
|
||||||
|
T parse_boolean_feature(StringView value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Base64.h>
|
#include <AK/Base64.h>
|
||||||
#include <AK/GenericLexer.h>
|
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
#include <LibIPC/File.h>
|
#include <LibIPC/File.h>
|
||||||
#include <LibJS/Runtime/AbstractOperations.h>
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
|
@ -140,182 +139,6 @@ void Window::finalize()
|
||||||
|
|
||||||
Window::~Window() = default;
|
Window::~Window() = default;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#normalizing-the-feature-name
|
|
||||||
static String normalize_feature_name(String const& name)
|
|
||||||
{
|
|
||||||
// For legacy reasons, there are some aliases of some feature names. To normalize a feature name name, switch on name:
|
|
||||||
|
|
||||||
// "screenx"
|
|
||||||
if (name == "screenx"sv) {
|
|
||||||
// Return "left".
|
|
||||||
return "left"_string;
|
|
||||||
}
|
|
||||||
// "screeny"
|
|
||||||
else if (name == "screeny"sv) {
|
|
||||||
// Return "top".
|
|
||||||
return "top"_string;
|
|
||||||
}
|
|
||||||
// "innerwidth"
|
|
||||||
else if (name == "innerwidth"sv) {
|
|
||||||
// Return "width".
|
|
||||||
return "width"_string;
|
|
||||||
}
|
|
||||||
// "innerheight"
|
|
||||||
else if (name == "innerheight") {
|
|
||||||
// Return "height".
|
|
||||||
return "height"_string;
|
|
||||||
}
|
|
||||||
// Anything else
|
|
||||||
else {
|
|
||||||
// Return name.
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-window-open-features-tokenize
|
|
||||||
static OrderedHashMap<String, String> tokenize_open_features(StringView features)
|
|
||||||
{
|
|
||||||
// 1. Let tokenizedFeatures be a new ordered map.
|
|
||||||
OrderedHashMap<String, String> tokenized_features;
|
|
||||||
|
|
||||||
// 2. Let position point at the first code point of features.
|
|
||||||
GenericLexer lexer(features);
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#feature-separator
|
|
||||||
auto is_feature_separator = [](auto character) {
|
|
||||||
return Infra::is_ascii_whitespace(character) || character == '=' || character == ',';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 3. While position is not past the end of features:
|
|
||||||
while (!lexer.is_eof()) {
|
|
||||||
// 1. Let name be the empty string.
|
|
||||||
String name;
|
|
||||||
|
|
||||||
// 2. Let value be the empty string.
|
|
||||||
String value;
|
|
||||||
|
|
||||||
// 3. Collect a sequence of code points that are feature separators from features given position. This skips past leading separators before the name.
|
|
||||||
lexer.ignore_while(is_feature_separator);
|
|
||||||
|
|
||||||
// 4. Collect a sequence of code points that are not feature separators from features given position. Set name to the collected characters, converted to ASCII lowercase.
|
|
||||||
name = MUST(String::from_byte_string(lexer.consume_until(is_feature_separator).to_lowercase_string()));
|
|
||||||
|
|
||||||
// 5. Set name to the result of normalizing the feature name name.
|
|
||||||
name = normalize_feature_name(name);
|
|
||||||
|
|
||||||
// 6. While position is not past the end of features and the code point at position in features is not U+003D (=):
|
|
||||||
// 1. If the code point at position in features is U+002C (,), or if it is not a feature separator, then break.
|
|
||||||
// 2. Advance position by 1.
|
|
||||||
lexer.ignore_while(Infra::is_ascii_whitespace);
|
|
||||||
|
|
||||||
// 7. If the code point at position in features is a feature separator:
|
|
||||||
// 1. While position is not past the end of features and the code point at position in features is a feature separator:
|
|
||||||
// 1. If the code point at position in features is U+002C (,), then break.
|
|
||||||
// 2. Advance position by 1.
|
|
||||||
lexer.ignore_while([](auto character) { return Infra::is_ascii_whitespace(character) || character == '='; });
|
|
||||||
|
|
||||||
// 2. Collect a sequence of code points that are not feature separators code points from features given position. Set value to the collected code points, converted to ASCII lowercase.
|
|
||||||
value = MUST(String::from_byte_string(lexer.consume_until(is_feature_separator).to_lowercase_string()));
|
|
||||||
|
|
||||||
// 8. If name is not the empty string, then set tokenizedFeatures[name] to value.
|
|
||||||
if (!name.is_empty())
|
|
||||||
tokenized_features.set(move(name), move(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Return tokenizedFeatures.
|
|
||||||
return tokenized_features;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-window-open-features-parse-boolean
|
|
||||||
template<Enum T>
|
|
||||||
static T parse_boolean_feature(StringView value)
|
|
||||||
{
|
|
||||||
// 1. If value is the empty string, then return true.
|
|
||||||
if (value.is_empty())
|
|
||||||
return T::Yes;
|
|
||||||
|
|
||||||
// 2. If value is "yes", then return true.
|
|
||||||
if (value == "yes"sv)
|
|
||||||
return T::Yes;
|
|
||||||
|
|
||||||
// 3. If value is "true", then return true.
|
|
||||||
if (value == "true"sv)
|
|
||||||
return T::Yes;
|
|
||||||
|
|
||||||
// 4. Let parsed be the result of parsing value as an integer.
|
|
||||||
auto parsed = value.to_number<i64>();
|
|
||||||
|
|
||||||
// 5. If parsed is an error, then set it to 0.
|
|
||||||
if (!parsed.has_value())
|
|
||||||
parsed = 0;
|
|
||||||
|
|
||||||
// 6. Return false if parsed is 0, and true otherwise.
|
|
||||||
return parsed == 0 ? T::No : T::Yes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/window-object.html#popup-window-is-requested
|
|
||||||
static TokenizedFeature::Popup check_if_a_popup_window_is_requested(OrderedHashMap<String, String> const& tokenized_features)
|
|
||||||
{
|
|
||||||
// 1. If tokenizedFeatures is empty, then return false.
|
|
||||||
if (tokenized_features.is_empty())
|
|
||||||
return TokenizedFeature::Popup::No;
|
|
||||||
|
|
||||||
// 2. If tokenizedFeatures["popup"] exists, then return the result of parsing tokenizedFeatures["popup"] as a boolean feature.
|
|
||||||
if (auto popup_feature = tokenized_features.get("popup"sv); popup_feature.has_value())
|
|
||||||
return parse_boolean_feature<TokenizedFeature::Popup>(*popup_feature);
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/window-object.html#window-feature-is-set
|
|
||||||
auto check_if_a_window_feature_is_set = [&]<Enum T>(StringView feature_name, T default_value) {
|
|
||||||
// 1. If tokenizedFeatures[featureName] exists, then return the result of parsing tokenizedFeatures[featureName] as a boolean feature.
|
|
||||||
if (auto feature = tokenized_features.get(feature_name); feature.has_value())
|
|
||||||
return parse_boolean_feature<T>(*feature);
|
|
||||||
|
|
||||||
// 2. Return defaultValue.
|
|
||||||
return default_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 3. Let location be the result of checking if a window feature is set, given tokenizedFeatures, "location", and false.
|
|
||||||
auto location = check_if_a_window_feature_is_set("location"sv, TokenizedFeature::Location::No);
|
|
||||||
|
|
||||||
// 4. Let toolbar be the result of checking if a window feature is set, given tokenizedFeatures, "toolbar", and false.
|
|
||||||
auto toolbar = check_if_a_window_feature_is_set("toolbar"sv, TokenizedFeature::Toolbar::No);
|
|
||||||
|
|
||||||
// 5. If location and toolbar are both false, then return true.
|
|
||||||
if (location == TokenizedFeature::Location::No && toolbar == TokenizedFeature::Toolbar::No)
|
|
||||||
return TokenizedFeature::Popup::Yes;
|
|
||||||
|
|
||||||
// 6. Let menubar be the result of checking if a window feature is set, given tokenizedFeatures, menubar", and false.
|
|
||||||
auto menubar = check_if_a_window_feature_is_set("menubar"sv, TokenizedFeature::Menubar::No);
|
|
||||||
|
|
||||||
// 7. If menubar is false, then return true.
|
|
||||||
if (menubar == TokenizedFeature::Menubar::No)
|
|
||||||
return TokenizedFeature::Popup::Yes;
|
|
||||||
|
|
||||||
// 8. Let resizable be the result of checking if a window feature is set, given tokenizedFeatures, "resizable", and true.
|
|
||||||
auto resizable = check_if_a_window_feature_is_set("resizable"sv, TokenizedFeature::Resizable::Yes);
|
|
||||||
|
|
||||||
// 9. If resizable is false, then return true.
|
|
||||||
if (resizable == TokenizedFeature::Resizable::No)
|
|
||||||
return TokenizedFeature::Popup::Yes;
|
|
||||||
|
|
||||||
// 10. Let scrollbars be the result of checking if a window feature is set, given tokenizedFeatures, "scrollbars", and false.
|
|
||||||
auto scrollbars = check_if_a_window_feature_is_set("scrollbars"sv, TokenizedFeature::Scrollbars::No);
|
|
||||||
|
|
||||||
// 11. If scrollbars is false, then return true.
|
|
||||||
if (scrollbars == TokenizedFeature::Scrollbars::No)
|
|
||||||
return TokenizedFeature::Popup::Yes;
|
|
||||||
|
|
||||||
// 12. Let status be the result of checking if a window feature is set, given tokenizedFeatures, "status", and false.
|
|
||||||
auto status = check_if_a_window_feature_is_set("status"sv, TokenizedFeature::Status::No);
|
|
||||||
|
|
||||||
// 13. If status is false, then return true.
|
|
||||||
if (status == TokenizedFeature::Status::No)
|
|
||||||
return TokenizedFeature::Popup::Yes;
|
|
||||||
|
|
||||||
// 14. Return false.
|
|
||||||
return TokenizedFeature::Popup::No;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/window-object.html#window-open-steps
|
// https://html.spec.whatwg.org/multipage/window-object.html#window-open-steps
|
||||||
WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::open_impl(StringView url, StringView target, StringView features)
|
WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::open_impl(StringView url, StringView target, StringView features)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue