AK+Everywhere: Remove the null state of DeprecatedString

This commit removes DeprecatedString's "null" state, and replaces all
its users with one of the following:
- A normal, empty DeprecatedString
- Optional<DeprecatedString>

Note that null states of DeprecatedFlyString/StringView/etc are *not*
affected by this commit. However, DeprecatedString::empty() is now
considered equal to a null StringView.
This commit is contained in:
Ali Mohammad Pur 2023-10-10 15:00:58 +03:30 committed by Ali Mohammad Pur
parent daf6d8173c
commit aeee98b3a1
189 changed files with 597 additions and 652 deletions

View file

@ -38,8 +38,6 @@ void DeprecatedFlyString::did_destroy_impl(Badge<StringImpl>, StringImpl& impl)
DeprecatedFlyString::DeprecatedFlyString(DeprecatedString const& string)
{
if (string.is_null())
return;
if (string.impl()->is_fly()) {
m_impl = string.impl();
return;
@ -60,7 +58,7 @@ DeprecatedFlyString::DeprecatedFlyString(StringView string)
if (string.is_null())
return;
auto it = fly_impls().find(string.hash(), [&](auto& candidate) {
return string == candidate;
return string == *candidate;
});
if (it == fly_impls().end()) {
auto new_string = string.to_deprecated_string();

View file

@ -28,6 +28,9 @@ bool DeprecatedString::operator==(DeprecatedString const& other) const
bool DeprecatedString::operator==(StringView other) const
{
if (other.is_null())
return is_empty();
return view() == other;
}
@ -55,9 +58,7 @@ bool DeprecatedString::copy_characters_to_buffer(char* buffer, size_t buffer_siz
DeprecatedString DeprecatedString::isolated_copy() const
{
if (!m_impl)
return {};
if (!m_impl->length())
if (m_impl->length() == 0)
return empty();
char* buffer;
auto impl = StringImpl::create_uninitialized(length(), buffer);
@ -69,7 +70,6 @@ DeprecatedString DeprecatedString::substring(size_t start, size_t length) const
{
if (!length)
return DeprecatedString::empty();
VERIFY(m_impl);
VERIFY(!Checked<size_t>::addition_would_overflow(start, length));
VERIFY(start + length <= m_impl->length());
return { characters() + start, length };
@ -77,14 +77,12 @@ DeprecatedString DeprecatedString::substring(size_t start, size_t length) const
DeprecatedString DeprecatedString::substring(size_t start) const
{
VERIFY(m_impl);
VERIFY(start <= length());
return { characters() + start, length() - start };
}
StringView DeprecatedString::substring_view(size_t start, size_t length) const
{
VERIFY(m_impl);
VERIFY(!Checked<size_t>::addition_would_overflow(start, length));
VERIFY(start + length <= m_impl->length());
return { characters() + start, length };
@ -92,7 +90,6 @@ StringView DeprecatedString::substring_view(size_t start, size_t length) const
StringView DeprecatedString::substring_view(size_t start) const
{
VERIFY(m_impl);
VERIFY(start <= length());
return { characters() + start, length() - start };
}
@ -157,8 +154,6 @@ Vector<StringView> DeprecatedString::split_view(char const separator, SplitBehav
ByteBuffer DeprecatedString::to_byte_buffer() const
{
if (!m_impl)
return {};
// FIXME: Handle OOM failure.
return ByteBuffer::copy(bytes()).release_value_but_fixme_should_propagate_errors();
}
@ -379,21 +374,17 @@ DeprecatedString escape_html_entities(StringView html)
}
DeprecatedString::DeprecatedString(DeprecatedFlyString const& string)
: m_impl(string.impl())
: m_impl(*string.impl())
{
}
DeprecatedString DeprecatedString::to_lowercase() const
{
if (!m_impl)
return {};
return m_impl->to_lowercase();
}
DeprecatedString DeprecatedString::to_uppercase() const
{
if (!m_impl)
return {};
return m_impl->to_uppercase();
}
@ -414,6 +405,9 @@ DeprecatedString DeprecatedString::invert_case() const
bool DeprecatedString::operator==(char const* cstring) const
{
if (!cstring)
return is_empty();
return view() == cstring;
}
@ -438,7 +432,7 @@ ErrorOr<DeprecatedString> DeprecatedString::from_utf8(ReadonlyBytes bytes)
{
if (!Utf8View(bytes).validate())
return Error::from_string_literal("DeprecatedString::from_utf8: Input was not valid UTF-8");
return DeprecatedString { StringImpl::create(bytes) };
return DeprecatedString { *StringImpl::create(bytes) };
}
}

View file

@ -40,10 +40,13 @@ class DeprecatedString {
public:
~DeprecatedString() = default;
DeprecatedString() = default;
DeprecatedString()
: m_impl(StringImpl::the_empty_stringimpl())
{
}
DeprecatedString(StringView view)
: m_impl(StringImpl::create(view.characters_without_null_termination(), view.length()))
: m_impl(*StringImpl::create(view.characters_without_null_termination(), view.length()))
{
}
@ -55,20 +58,21 @@ public:
DeprecatedString(DeprecatedString&& other)
: m_impl(move(other.m_impl))
{
other.m_impl = StringImpl::the_empty_stringimpl();
}
DeprecatedString(char const* cstring, ShouldChomp shouldChomp = NoChomp)
: m_impl(StringImpl::create(cstring, shouldChomp))
: m_impl(*StringImpl::create(cstring, shouldChomp))
{
}
DeprecatedString(char const* cstring, size_t length, ShouldChomp shouldChomp = NoChomp)
: m_impl(StringImpl::create(cstring, length, shouldChomp))
: m_impl(*StringImpl::create(cstring, length, shouldChomp))
{
}
explicit DeprecatedString(ReadonlyBytes bytes, ShouldChomp shouldChomp = NoChomp)
: m_impl(StringImpl::create(bytes, shouldChomp))
: m_impl(*StringImpl::create(bytes, shouldChomp))
{
}
@ -77,18 +81,8 @@ public:
{
}
DeprecatedString(StringImpl const* impl)
: m_impl(impl)
{
}
DeprecatedString(RefPtr<StringImpl const>&& impl)
: m_impl(move(impl))
{
}
DeprecatedString(NonnullRefPtr<StringImpl const>&& impl)
: m_impl(move(impl))
: m_impl(*move(impl))
{
}
@ -174,31 +168,25 @@ public:
[[nodiscard]] StringView substring_view(size_t start, size_t length) const;
[[nodiscard]] StringView substring_view(size_t start) const;
[[nodiscard]] bool is_null() const { return !m_impl; }
[[nodiscard]] ALWAYS_INLINE bool is_empty() const { return length() == 0; }
[[nodiscard]] ALWAYS_INLINE size_t length() const { return m_impl ? m_impl->length() : 0; }
// Includes NUL-terminator, if non-nullptr.
[[nodiscard]] ALWAYS_INLINE char const* characters() const { return m_impl ? m_impl->characters() : nullptr; }
[[nodiscard]] ALWAYS_INLINE size_t length() const { return m_impl->length(); }
// Includes NUL-terminator.
[[nodiscard]] ALWAYS_INLINE char const* characters() const { return m_impl->characters(); }
[[nodiscard]] bool copy_characters_to_buffer(char* buffer, size_t buffer_size) const;
[[nodiscard]] ALWAYS_INLINE ReadonlyBytes bytes() const
{
if (m_impl) {
return m_impl->bytes();
}
return {};
return m_impl->bytes();
}
[[nodiscard]] ALWAYS_INLINE char const& operator[](size_t i) const
{
VERIFY(!is_null());
return (*m_impl)[i];
}
[[nodiscard]] ALWAYS_INLINE u8 byte_at(size_t i) const
{
VERIFY(!is_null());
return bit_cast<u8>((*m_impl)[i]);
}
@ -251,22 +239,15 @@ public:
return *this;
}
DeprecatedString& operator=(nullptr_t)
template<OneOf<ReadonlyBytes, Bytes> T>
DeprecatedString& operator=(T bytes)
{
m_impl = nullptr;
return *this;
}
DeprecatedString& operator=(ReadonlyBytes bytes)
{
m_impl = StringImpl::create(bytes);
m_impl = *StringImpl::create(bytes);
return *this;
}
[[nodiscard]] u32 hash() const
{
if (!m_impl)
return 0;
return m_impl->hash();
}
@ -323,7 +304,7 @@ public:
}
private:
RefPtr<StringImpl const> m_impl;
NonnullRefPtr<StringImpl const> m_impl;
};
template<>

View file

@ -129,7 +129,7 @@ StringView GenericLexer::consume_quoted_string(char escape_char)
}
#ifndef KERNEL
DeprecatedString GenericLexer::consume_and_unescape_string(char escape_char)
Optional<DeprecatedString> GenericLexer::consume_and_unescape_string(char escape_char)
{
auto view = consume_quoted_string(escape_char);
if (view.is_null())

View file

@ -119,7 +119,7 @@ public:
StringView consume_until(StringView);
StringView consume_quoted_string(char escape_char = 0);
#ifndef KERNEL
DeprecatedString consume_and_unescape_string(char escape_char = '\\');
Optional<DeprecatedString> consume_and_unescape_string(char escape_char = '\\');
#endif
enum class UnicodeEscapeError {

View file

@ -132,8 +132,6 @@ ErrorOr<JsonValue> JsonParser::parse_object()
break;
ignore_while(is_space);
auto name = TRY(consume_and_unescape_string());
if (name.is_null())
return Error::from_string_literal("JsonParser: Expected object property name");
ignore_while(is_space);
if (!consume_specific(':'))
return Error::from_string_literal("JsonParser: Expected ':'");

View file

@ -174,13 +174,9 @@ JsonValue::JsonValue(double value)
JsonValue::JsonValue(DeprecatedString const& value)
{
if (value.is_null()) {
m_type = Type::Null;
} else {
m_type = Type::String;
m_value.as_string = const_cast<StringImpl*>(value.impl());
m_value.as_string->ref();
}
m_type = Type::String;
m_value.as_string = const_cast<StringImpl*>(value.impl());
m_value.as_string->ref();
}
JsonValue::JsonValue(StringView value)

View file

@ -90,9 +90,6 @@ bool LexicalPath::is_child_of(LexicalPath const& possible_parent) const
DeprecatedString LexicalPath::canonicalized_path(DeprecatedString path)
{
if (path.is_null())
return {};
// NOTE: We never allow an empty m_string, if it's empty, we just set it to '.'.
if (path.is_empty())
return ".";

View file

@ -47,9 +47,6 @@ NonnullRefPtr<StringImpl const> StringImpl::create_uninitialized(size_t length,
RefPtr<StringImpl const> StringImpl::create(char const* cstring, size_t length, ShouldChomp should_chomp)
{
if (!cstring)
return nullptr;
if (should_chomp) {
while (length) {
char last_ch = cstring[length - 1];
@ -72,10 +69,7 @@ RefPtr<StringImpl const> StringImpl::create(char const* cstring, size_t length,
RefPtr<StringImpl const> StringImpl::create(char const* cstring, ShouldChomp shouldChomp)
{
if (!cstring)
return nullptr;
if (!*cstring)
if (!cstring || !*cstring)
return the_empty_stringimpl();
return create(cstring, strlen(cstring), shouldChomp);
@ -88,8 +82,6 @@ RefPtr<StringImpl const> StringImpl::create(ReadonlyBytes bytes, ShouldChomp sho
RefPtr<StringImpl const> StringImpl::create_lowercased(char const* cstring, size_t length)
{
if (!cstring)
return nullptr;
if (!length)
return the_empty_stringimpl();
char* buffer;
@ -101,8 +93,6 @@ RefPtr<StringImpl const> StringImpl::create_lowercased(char const* cstring, size
RefPtr<StringImpl const> StringImpl::create_uppercased(char const* cstring, size_t length)
{
if (!cstring)
return nullptr;
if (!length)
return the_empty_stringimpl();
char* buffer;

View file

@ -178,12 +178,12 @@ bool StringView::equals_ignoring_ascii_case(StringView other) const
#ifndef KERNEL
DeprecatedString StringView::to_lowercase_string() const
{
return StringImpl::create_lowercased(characters_without_null_termination(), length());
return StringImpl::create_lowercased(characters_without_null_termination(), length()).release_nonnull();
}
DeprecatedString StringView::to_uppercase_string() const
{
return StringImpl::create_uppercased(characters_without_null_termination(), length());
return StringImpl::create_uppercased(characters_without_null_termination(), length()).release_nonnull();
}
DeprecatedString StringView::to_titlecase_string() const

View file

@ -191,13 +191,11 @@ URL URL::create_with_file_scheme(DeprecatedString const& path, DeprecatedString
URL url;
url.set_scheme("file"_string);
// NOTE: If the hostname is localhost (or null, which implies localhost), it should be set to the empty string.
// This is because a file URL always needs a non-null hostname.
url.set_host(hostname.is_null() || hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
url.set_host(hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
url.set_paths(lexical_path.parts());
if (path.ends_with('/'))
url.append_slash();
if (!fragment.is_null())
if (!fragment.is_empty())
url.set_fragment(String::from_deprecated_string(fragment).release_value_but_fixme_should_propagate_errors());
return url;
}
@ -208,14 +206,12 @@ URL URL::create_with_help_scheme(DeprecatedString const& path, DeprecatedString
URL url;
url.set_scheme("help"_string);
// NOTE: If the hostname is localhost (or null, which implies localhost), it should be set to the empty string.
// This is because a file URL always needs a non-null hostname.
url.set_host(hostname.is_null() || hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
url.set_host(hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
url.set_paths(lexical_path.parts());
if (path.ends_with('/'))
url.append_slash();
if (!fragment.is_null())
if (!fragment.is_empty())
url.set_fragment(String::from_deprecated_string(fragment).release_value_but_fixme_should_propagate_errors());
return url;
}

View file

@ -311,7 +311,7 @@ void do_message(SourceGenerator message_generator, DeprecatedString const& name,
class @message.pascal_name@ final : public IPC::Message {
public:)~~~");
if (!response_type.is_null())
if (!response_type.is_empty())
message_generator.appendln(R"~~~(
typedef class @message.response_type@ ResponseType;)~~~");

View file

@ -785,7 +785,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
}
i++;
}
if (current_dictionary->parent_name.is_null())
if (current_dictionary->parent_name.is_empty())
break;
VERIFY(interface.dictionaries.contains(current_dictionary->parent_name));
current_dictionary = &interface.dictionaries.find(current_dictionary->parent_name)->value;
@ -1755,7 +1755,7 @@ static void generate_wrap_statement(SourceGenerator& generator, DeprecatedString
)~~~");
}
if (current_dictionary->parent_name.is_null())
if (current_dictionary->parent_name.is_empty())
break;
VERIFY(interface.dictionaries.contains(current_dictionary->parent_name));
current_dictionary = &interface.dictionaries.find(current_dictionary->parent_name)->value;
@ -2352,7 +2352,7 @@ static void collect_attribute_values_of_an_inheritance_stack(SourceGenerator& fu
if (attribute.extended_attributes.contains("Reflect")) {
auto attribute_name = attribute.extended_attributes.get("Reflect").value();
if (attribute_name.is_null())
if (attribute_name.is_empty())
attribute_name = attribute.name;
attribute_name = make_input_acceptable_cpp(attribute_name);
@ -2837,7 +2837,7 @@ static JS::ThrowCompletionOr<@fully_qualified_name@*> impl_from(JS::VM& vm)
if (attribute.extended_attributes.contains("Reflect")) {
auto attribute_name = attribute.extended_attributes.get("Reflect").value();
if (attribute_name.is_null())
if (attribute_name.is_empty())
attribute_name = attribute.name;
attribute_name = make_input_acceptable_cpp(attribute_name);

View file

@ -52,7 +52,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!line.starts_with("endpoint "sv))
continue;
auto line_endpoint_name = line.substring_view("endpoint "sv.length());
if (!endpoint_name.is_null()) {
if (!endpoint_name.is_empty()) {
// Note: If there are three or more endpoints defined in a file, these errors will look a bit wonky.
// However, that's fine, because it shouldn't happen in the first place.
warnln("Error: Multiple endpoints in file '{}': Found {} and {}", filename, endpoint_name, line_endpoint_name);
@ -72,7 +72,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
had_errors = true;
continue; // next file
}
if (endpoint_name.is_null()) {
if (endpoint_name.is_empty()) {
// If this happens, this file probably needs to parse the endpoint name more carefully.
warnln("Error: Could not detect endpoint name in file '{}'", filename);
had_errors = true;

View file

@ -41,7 +41,7 @@ TEST_CASE(enqueue_begin_being_moved_from)
DeprecatedString str { "test" };
strings.enqueue_begin(move(str));
EXPECT(str.is_null());
EXPECT(str.is_empty());
}
TEST_CASE(deque_end)

View file

@ -14,11 +14,9 @@
TEST_CASE(construct_empty)
{
EXPECT(DeprecatedString().is_null());
EXPECT(DeprecatedString().is_empty());
EXPECT(!DeprecatedString().characters());
EXPECT(DeprecatedString().characters() != nullptr);
EXPECT(!DeprecatedString("").is_null());
EXPECT(DeprecatedString("").is_empty());
EXPECT(DeprecatedString("").characters() != nullptr);
@ -29,7 +27,6 @@ TEST_CASE(construct_contents)
{
DeprecatedString test_string = "ABCDEF";
EXPECT(!test_string.is_empty());
EXPECT(!test_string.is_null());
EXPECT_EQ(test_string.length(), 6u);
EXPECT_EQ(test_string.length(), strlen(test_string.characters()));
EXPECT(test_string.characters() != nullptr);
@ -42,7 +39,7 @@ TEST_CASE(construct_contents)
TEST_CASE(equal)
{
EXPECT_NE(DeprecatedString::empty(), DeprecatedString {});
EXPECT_EQ(DeprecatedString::empty(), DeprecatedString {});
}
TEST_CASE(compare)
@ -116,7 +113,7 @@ TEST_CASE(move_string)
auto test_string_copy = test_string;
auto test_string_move = move(test_string_copy);
EXPECT_EQ(test_string, test_string_move);
EXPECT(test_string_copy.is_null());
EXPECT(test_string_copy.is_empty());
}
TEST_CASE(repeated)
@ -253,7 +250,6 @@ TEST_CASE(builder_zero_initial_capacity)
StringBuilder builder(0);
builder.append(""sv);
auto built = builder.to_deprecated_string();
EXPECT_EQ(built.is_null(), false);
EXPECT_EQ(built.length(), 0u);
}

View file

@ -49,7 +49,7 @@ TEST_CASE(range_loop)
int loop_counter = 0;
for (auto& it : number_to_string) {
EXPECT_EQ(it.value.is_null(), false);
EXPECT_EQ(it.value.is_empty(), false);
++loop_counter;
}
EXPECT_EQ(loop_counter, 3);

View file

@ -64,7 +64,7 @@ TEST_CASE(range_loop)
int loop_counter = 0;
for (auto& it : strings) {
EXPECT_EQ(it.is_null(), false);
EXPECT_EQ(it.is_empty(), false);
++loop_counter;
}
EXPECT_EQ(loop_counter, 3);

View file

@ -60,7 +60,6 @@ TEST_CASE(json_empty_string)
{
auto json = JsonValue::from_string("\"\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().is_null(), false);
EXPECT_EQ(json.as_string().is_empty(), true);
}
@ -68,7 +67,6 @@ TEST_CASE(json_string)
{
auto json = JsonValue::from_string("\"A\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().is_null(), false);
EXPECT_EQ(json.as_string().length(), size_t { 1 });
EXPECT_EQ(json.as_string() == "A", true);
}
@ -77,7 +75,6 @@ TEST_CASE(json_utf8_character)
{
auto json = JsonValue::from_string("\"\\u0041\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().is_null(), false);
EXPECT_EQ(json.as_string().length(), size_t { 1 });
EXPECT_EQ(json.as_string() == "A", true);
}
@ -92,7 +89,6 @@ TEST_CASE(json_utf8_multibyte)
auto& json = json_or_error.value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().is_null(), false);
EXPECT_EQ(json.as_string().length(), size_t { 2 });
EXPECT_EQ(json.as_string() == "š", true);
EXPECT_EQ(json.as_string() == "\xc5\xa1", true);

View file

@ -44,14 +44,12 @@ TEST_CASE(strings)
int loop_counter = 0;
for (DeprecatedString const& string : strings) {
EXPECT(!string.is_null());
EXPECT(!string.is_empty());
++loop_counter;
}
loop_counter = 0;
for (auto& string : (const_cast<Vector<DeprecatedString> const&>(strings))) {
EXPECT(!string.is_null());
EXPECT(!string.is_empty());
++loop_counter;
}

View file

@ -21,7 +21,7 @@ static constexpr char PATH_LOREM_250[] = "This-is-an-annoyingly-long-name-that-s
static constexpr size_t ITERATION_DEPTH = 17;
static void check_result(char const* what, DeprecatedString const& expected, char const* actual)
static void check_result(char const* what, StringView expected, char const* actual)
{
if (expected != actual)
FAIL(DeprecatedString::formatted("Expected {} to be \"{}\" ({} characters)", what, actual, actual ? strlen(actual) : 0));

View file

@ -337,7 +337,7 @@ static Result<TestMetadata, DeprecatedString> extract_metadata(StringView source
failed_message = "Failed to find phase in negative attributes";
break;
}
if (metadata.type.is_null()) {
if (metadata.type.is_empty()) {
failed_message = "Failed to find type in negative attributes";
break;
}
@ -640,7 +640,7 @@ int main(int argc, char** argv)
auto collect_output = [&] {
fflush(stdout);
auto nread = read(stdout_pipe[0], buffer, BUFFER_SIZE);
DeprecatedString value;
Optional<DeprecatedString> value;
if (nread > 0) {
value = DeprecatedString { buffer, static_cast<size_t>(nread) };
@ -743,15 +743,16 @@ int main(int argc, char** argv)
auto result = run_test(original_contents, path, metadata);
DISARM_TIMER();
DeprecatedString first_output = collect_output();
if (!first_output.is_null())
result_object.set("output", first_output);
auto first_output = collect_output();
if (first_output.has_value())
result_object.set("output", *first_output);
passed = verify_test(result, metadata, result_object);
auto output = first_output.value_or("");
if (metadata.is_async && !s_parse_only) {
if (!first_output.contains("Test262:AsyncTestComplete"sv) || first_output.contains("Test262:AsyncTestFailure"sv)) {
if (!output.contains("Test262:AsyncTestComplete"sv) || output.contains("Test262:AsyncTestFailure"sv)) {
result_object.set("async_fail", true);
if (first_output.is_null())
if (!first_output.has_value())
result_object.set("output", JsonValue { AK::JsonValue::Type::Null });
passed = false;
@ -766,15 +767,17 @@ int main(int argc, char** argv)
auto result = run_test(with_strict, path, metadata);
DISARM_TIMER();
DeprecatedString first_output = collect_output();
if (!first_output.is_null())
result_object.set("strict_output", first_output);
auto first_output = collect_output();
if (first_output.has_value())
result_object.set("strict_output", *first_output);
passed = verify_test(result, metadata, result_object);
auto output = first_output.value_or("");
if (metadata.is_async && !s_parse_only) {
if (!first_output.contains("Test262:AsyncTestComplete"sv) || first_output.contains("Test262:AsyncTestFailure"sv)) {
if (!output.contains("Test262:AsyncTestComplete"sv) || output.contains("Test262:AsyncTestFailure"sv)) {
result_object.set("async_fail", true);
if (first_output.is_null())
if (!first_output.has_value())
result_object.set("output", JsonValue { AK::JsonValue::Type::Null });
passed = false;

View file

@ -141,7 +141,7 @@ static ErrorOr<String> display_name_from_edid(EDID::Parser const& edid)
auto product_name = edid.display_product_name();
auto build_manufacturer_product_name = [&]() -> ErrorOr<String> {
if (product_name.is_null() || product_name.is_empty())
if (product_name.is_empty())
return TRY(String::from_deprecated_string(manufacturer_name));
return String::formatted("{} {}", manufacturer_name, product_name);
};

View file

@ -319,7 +319,7 @@ void MailWidget::selected_mailbox(GUI::ModelIndex const& index)
DeprecatedString date = internal_date.to_deprecated_string();
DeprecatedString subject = envelope.subject.value_or("(No subject)");
if (subject.contains("=?"sv) && subject.contains("?="sv)) {
subject = MUST(IMAP::decode_rfc2047_encoded_words(subject));
subject = MUST(IMAP::decode_rfc2047_encoded_words(subject)).span();
}
StringBuilder sender_builder;
@ -491,9 +491,9 @@ void MailWidget::selected_email_to_load(GUI::ModelIndex const& index)
} else if (selected_alternative_encoding.equals_ignoring_ascii_case("base64"sv)) {
auto decoded_base64 = decode_base64(encoded_data);
if (!decoded_base64.is_error())
decoded_data = decoded_base64.release_value();
decoded_data = decoded_base64.release_value().span();
} else if (selected_alternative_encoding.equals_ignoring_ascii_case("quoted-printable"sv)) {
decoded_data = IMAP::decode_quoted_printable(encoded_data).release_value_but_fixme_should_propagate_errors();
decoded_data = IMAP::decode_quoted_printable(encoded_data).release_value_but_fixme_should_propagate_errors().span();
} else {
dbgln("Mail: Unimplemented decoder for encoding: {}", selected_alternative_encoding);
GUI::MessageBox::show(window(), DeprecatedString::formatted("The e-mail encoding '{}' is currently unsupported.", selected_alternative_encoding), "Unsupported"sv, GUI::MessageBox::Type::Information);

View file

@ -24,7 +24,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
TRY(Core::System::unveil("/tmp/portal/window", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
DeprecatedString adapter;
StringView adapter;
Core::ArgsParser parser;
parser.add_positional_argument(adapter, "Adapter to display settings for", "adapter", Core::ArgsParser::Required::No);

View file

@ -26,7 +26,7 @@ NonnullOwnPtr<M3UParser> M3UParser::from_file(StringView path)
NonnullOwnPtr<M3UParser> M3UParser::from_memory(DeprecatedString const& m3u_contents, bool utf8)
{
auto parser = make<M3UParser>();
VERIFY(!m3u_contents.is_null() && !m3u_contents.is_empty() && !m3u_contents.is_whitespace());
VERIFY(!m3u_contents.is_empty() && !m3u_contents.is_whitespace());
parser->m_m3u_raw_data = m3u_contents;
parser->m_use_utf8 = utf8;
return parser;

View file

@ -40,9 +40,6 @@ Player::Player(Audio::ConnectionToServer& audio_client_connection)
void Player::play_file_path(DeprecatedString const& path)
{
if (path.is_null())
return;
if (!FileSystem::exists(path)) {
audio_load_error(path, "File does not exist"sv);
return;

View file

@ -22,7 +22,7 @@ namespace Spreadsheet {
void SpreadsheetView::EditingDelegate::set_value(GUI::Variant const& value, GUI::ModelEditingDelegate::SelectionBehavior selection_behavior)
{
if (value.as_string().is_null()) {
if (!value.is_valid()) {
StringModelEditingDelegate::set_value("", selection_behavior);
commit();
return;

View file

@ -74,7 +74,7 @@ void MemoryStatsWidget::set_graph_widget(GraphWidget& graph)
void MemoryStatsWidget::set_graph_widget_via_name(DeprecatedString name)
{
m_graph_widget_name = move(name);
if (!m_graph_widget_name.is_null()) {
if (!m_graph_widget_name.is_empty()) {
// FIXME: We assume here that the graph widget is a sibling or descendant of a sibling. This prevents more complex hierarchies.
auto* maybe_graph = parent_widget()->find_descendant_of_type_named<GraphWidget>(m_graph_widget_name);
if (maybe_graph) {

View file

@ -279,7 +279,7 @@ MainWidget::MainWidget()
m_save_as_action = GUI::CommonActions::make_save_as_action([&](auto&) {
auto extension = m_extension;
if (extension.is_null() && m_editor->syntax_highlighter())
if (extension.is_empty() && m_editor->syntax_highlighter())
extension = Syntax::common_language_extension(m_editor->syntax_highlighter()->language());
auto response = FileSystemAccessClient::Client::the().save_file(window(), m_name, extension);

View file

@ -47,7 +47,7 @@ Vector<BacktraceModel::FrameInfo> BacktraceModel::create_backtrace(Debug::Proces
if (frame_index > 0)
--current_instruction;
DeprecatedString name = lib->debug_info->elf().symbolicate(current_instruction - lib->base_address);
if (name.is_null()) {
if (name.is_empty()) {
dbgln("BacktraceModel: couldn't find containing function for address: {:p} (library={})", current_instruction, lib->name);
name = "<missing>";
}

View file

@ -134,7 +134,7 @@ void Debugger::start()
Debugger::CreateDebugSessionResult Debugger::create_debug_session()
{
if (!m_executable_path.is_null()) {
if (!m_executable_path.is_empty()) {
auto child_setup_callback = [this]() {
if (m_child_setup_callback)
return m_child_setup_callback();

View file

@ -113,7 +113,7 @@ void EditorWrapper::set_project_root(DeprecatedString const& project_root)
void EditorWrapper::update_title()
{
StringBuilder title;
if (m_filename.is_null())
if (m_filename.is_empty())
title.append(untitled_label);
else
title.append(m_filename);

View file

@ -24,7 +24,7 @@ GitRepo::CreateResult GitRepo::try_to_create(DeprecatedString const& repository_
RefPtr<GitRepo> GitRepo::initialize_repository(DeprecatedString const& repository_root)
{
auto res = command_wrapper({ "init" }, repository_root);
if (res.is_null())
if (!res.has_value())
return {};
VERIFY(git_repo_exists(repository_root));
@ -42,25 +42,25 @@ Vector<DeprecatedString> GitRepo::unstaged_files() const
Vector<DeprecatedString> GitRepo::staged_files() const
{
auto raw_result = command({ "diff", "--cached", "--name-only" });
if (raw_result.is_null())
if (!raw_result.has_value())
return {};
return parse_files_list(raw_result);
return parse_files_list(*raw_result);
}
Vector<DeprecatedString> GitRepo::modified_files() const
{
auto raw_result = command({ "ls-files", "--modified", "--exclude-standard" });
if (raw_result.is_null())
if (!raw_result.has_value())
return {};
return parse_files_list(raw_result);
return parse_files_list(*raw_result);
}
Vector<DeprecatedString> GitRepo::untracked_files() const
{
auto raw_result = command({ "ls-files", "--others", "--exclude-standard" });
if (raw_result.is_null())
if (!raw_result.has_value())
return {};
return parse_files_list(raw_result);
return parse_files_list(*raw_result);
}
Vector<DeprecatedString> GitRepo::parse_files_list(DeprecatedString const& raw_result)
@ -73,12 +73,12 @@ Vector<DeprecatedString> GitRepo::parse_files_list(DeprecatedString const& raw_r
return files;
}
DeprecatedString GitRepo::command(Vector<DeprecatedString> const& command_parts) const
Optional<DeprecatedString> GitRepo::command(Vector<DeprecatedString> const& command_parts) const
{
return command_wrapper(command_parts, m_repository_root);
}
DeprecatedString GitRepo::command_wrapper(Vector<DeprecatedString> const& command_parts, DeprecatedString const& chdir)
Optional<DeprecatedString> GitRepo::command_wrapper(Vector<DeprecatedString> const& command_parts, DeprecatedString const& chdir)
{
auto const result = Core::command("git", command_parts, LexicalPath(chdir));
if (result.is_error() || result.value().exit_code != 0)
@ -88,27 +88,27 @@ DeprecatedString GitRepo::command_wrapper(Vector<DeprecatedString> const& comman
bool GitRepo::git_is_installed()
{
return !command_wrapper({ "--help" }, "/").is_null();
return command_wrapper({ "--help" }, "/").has_value();
}
bool GitRepo::git_repo_exists(DeprecatedString const& repo_root)
{
return !command_wrapper({ "status" }, repo_root).is_null();
return command_wrapper({ "status" }, repo_root).has_value();
}
bool GitRepo::stage(DeprecatedString const& file)
{
return !command({ "add", file }).is_null();
return command({ "add", file }).has_value();
}
bool GitRepo::unstage(DeprecatedString const& file)
{
return !command({ "reset", "HEAD", "--", file }).is_null();
return command({ "reset", "HEAD", "--", file }).has_value();
}
bool GitRepo::commit(DeprecatedString const& message)
{
return !command({ "commit", "-m", message }).is_null();
return command({ "commit", "-m", message }).has_value();
}
Optional<DeprecatedString> GitRepo::original_file_content(DeprecatedString const& file) const
@ -124,10 +124,10 @@ Optional<DeprecatedString> GitRepo::unstaged_diff(DeprecatedString const& file)
bool GitRepo::is_tracked(DeprecatedString const& file) const
{
auto res = command({ "ls-files", file });
if (res.is_null())
if (!res.has_value())
return false;
return !res.is_empty();
return !res->is_empty();
}
}

View file

@ -45,7 +45,7 @@ private:
static bool git_is_installed();
static bool git_repo_exists(DeprecatedString const& repo_root);
static DeprecatedString command_wrapper(Vector<DeprecatedString> const& command_parts, DeprecatedString const& chdir);
static Optional<DeprecatedString> command_wrapper(Vector<DeprecatedString> const& command_parts, DeprecatedString const& chdir);
static Vector<DeprecatedString> parse_files_list(DeprecatedString const&);
explicit GitRepo(DeprecatedString const& repository_root)
@ -56,7 +56,7 @@ private:
Vector<DeprecatedString> modified_files() const;
Vector<DeprecatedString> untracked_files() const;
DeprecatedString command(Vector<DeprecatedString> const& command_parts) const;
Optional<DeprecatedString> command(Vector<DeprecatedString> const& command_parts) const;
DeprecatedString m_repository_root;
};

View file

@ -909,15 +909,15 @@ NonnullRefPtr<GUI::Action> HackStudioWidget::create_save_as_action()
auto suggested_path = FileSystem::absolute_path(old_path.string()).release_value_but_fixme_should_propagate_errors();
Optional<DeprecatedString> save_path = GUI::FilePicker::get_save_filepath(window(),
old_filename.is_null() ? "Untitled"sv : old_path.title(),
old_filename.is_null() ? "txt"sv : old_path.extension(),
old_filename.is_empty() ? "Untitled"sv : old_path.title(),
old_filename.is_empty() ? "txt"sv : old_path.extension(),
suggested_path);
if (!save_path.has_value()) {
return;
}
DeprecatedString const relative_file_path = LexicalPath::relative_path(save_path.value(), m_project->root_path());
if (current_editor_wrapper().filename().is_null()) {
if (current_editor_wrapper().filename().is_empty()) {
current_editor_wrapper().set_filename(relative_file_path);
} else {
for (auto& editor_wrapper : m_all_editor_wrappers) {
@ -1729,7 +1729,7 @@ void HackStudioWidget::update_current_editor_title()
void HackStudioWidget::on_cursor_change()
{
update_statusbar();
if (current_editor_wrapper().filename().is_null())
if (current_editor_wrapper().filename().is_empty())
return;
auto current_location = current_project_location();

View file

@ -68,9 +68,9 @@ DeprecatedString FileDB::to_absolute_path(DeprecatedString const& filename) cons
if (LexicalPath { filename }.is_absolute()) {
return filename;
}
if (m_project_root.is_null())
if (!m_project_root.has_value())
return filename;
return LexicalPath { DeprecatedString::formatted("{}/{}", m_project_root, filename) }.string();
return LexicalPath { DeprecatedString::formatted("{}/{}", *m_project_root, filename) }.string();
}
ErrorOr<NonnullRefPtr<GUI::TextDocument>> FileDB::create_from_filesystem(DeprecatedString const& filename) const

View file

@ -38,7 +38,7 @@ private:
private:
HashMap<DeprecatedString, NonnullRefPtr<GUI::TextDocument>> m_open_files;
DeprecatedString m_project_root;
Optional<DeprecatedString> m_project_root;
};
}

View file

@ -60,7 +60,7 @@ public:
}
if (suggestion.is_symbol_declaration()) {
if (index.column() == Column::Name) {
if (suggestion.as_symbol_declaration.value().scope.is_null())
if (!suggestion.as_symbol_declaration.value().scope.is_empty())
return suggestion.as_symbol_declaration.value().name;
return DeprecatedString::formatted("{}::{}", suggestion.as_symbol_declaration.value().scope, suggestion.as_symbol_declaration.value().name);
}

View file

@ -881,17 +881,17 @@ void sync()
syscall(SC_sync);
}
static DeprecatedString getlogin_buffer;
static Optional<DeprecatedString> getlogin_buffer {};
char* getlogin()
{
if (getlogin_buffer.is_null()) {
if (!getlogin_buffer.has_value()) {
if (auto* passwd = getpwuid(getuid())) {
getlogin_buffer = DeprecatedString(passwd->pw_name);
}
endpwent();
}
return const_cast<char*>(getlogin_buffer.characters());
return const_cast<char*>(getlogin_buffer->characters());
}
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html

View file

@ -210,7 +210,7 @@ Vector<CodeComprehension::AutocompleteResultEntry> CppComprehensionEngine::autoc
{
VERIFY(parent.object());
auto type = type_of(document, *parent.object());
if (type.is_null()) {
if (type.is_empty()) {
dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "Could not infer type of object");
return {};
}
@ -385,7 +385,7 @@ DeprecatedString CppComprehensionEngine::document_path_from_include_path(StringV
};
auto result = document_path_for_library_include(include_path);
if (result.is_null())
if (result.is_empty())
result = document_path_for_user_defined_include(include_path);
return result;
@ -703,7 +703,7 @@ Optional<Vector<CodeComprehension::AutocompleteResultEntry>> CppComprehensionEng
partial_include = partial_include.substring_view(0, partial_include.length() - 1).trim_whitespace();
}
} else if (partial_include.starts_with('"')) {
include_root = filedb().project_root();
include_root = filedb().project_root().value_or("");
if (partial_include.length() > 1 && partial_include.ends_with('\"')) {
already_has_suffix = true;
partial_include = partial_include.substring_view(0, partial_include.length() - 1).trim_whitespace();

View file

@ -52,8 +52,8 @@ public:
virtual Optional<DeprecatedString> get_or_read_from_filesystem(StringView filename) const override
{
DeprecatedString target_filename = filename;
if (!project_root().is_null() && filename.starts_with(project_root())) {
target_filename = LexicalPath::relative_path(filename, project_root());
if (project_root().has_value() && filename.starts_with(*project_root())) {
target_filename = LexicalPath::relative_path(filename, *project_root());
}
return m_map.get(target_filename);
}

View file

@ -14,9 +14,9 @@ DeprecatedString FileDB::to_absolute_path(StringView filename) const
if (LexicalPath { filename }.is_absolute()) {
return filename;
}
if (m_project_root.is_null())
if (!m_project_root.has_value())
return filename;
return LexicalPath { DeprecatedString::formatted("{}/{}", m_project_root, filename) }.string();
return LexicalPath { DeprecatedString::formatted("{}/{}", *m_project_root, filename) }.string();
}
}

View file

@ -19,15 +19,21 @@ public:
virtual ~FileDB() = default;
virtual Optional<DeprecatedString> get_or_read_from_filesystem(StringView filename) const = 0;
void set_project_root(StringView project_root) { m_project_root = project_root; }
DeprecatedString const& project_root() const { return m_project_root; }
void set_project_root(StringView project_root)
{
if (project_root.is_null())
m_project_root.clear();
else
m_project_root = project_root;
}
Optional<DeprecatedString> const& project_root() const { return m_project_root; }
DeprecatedString to_absolute_path(StringView filename) const;
protected:
FileDB() = default;
private:
DeprecatedString m_project_root;
Optional<DeprecatedString> m_project_root;
};
}

View file

@ -162,16 +162,17 @@ ErrorOr<Vector<Account>> Account::all([[maybe_unused]] Read options)
bool Account::authenticate(SecretString const& password) const
{
// If there was no shadow entry for this account, authentication always fails.
if (m_password_hash.is_null())
if (!m_password_hash.has_value())
return false;
// An empty passwd field indicates that no password is required to log in.
if (m_password_hash.is_empty())
if (m_password_hash->is_empty())
return true;
// FIXME: Use crypt_r if it can be built in lagom.
char* hash = crypt(password.characters(), m_password_hash.characters());
return hash != nullptr && AK::timing_safe_compare(hash, m_password_hash.characters(), m_password_hash.length());
auto const bytes = m_password_hash->characters();
char* hash = crypt(password.characters(), bytes);
return hash != nullptr && AK::timing_safe_compare(hash, bytes, m_password_hash->length());
}
ErrorOr<void> Account::login() const
@ -190,24 +191,25 @@ void Account::set_password(SecretString const& password)
void Account::set_password_enabled(bool enabled)
{
if (enabled && m_password_hash != "" && m_password_hash[0] == '!') {
m_password_hash = m_password_hash.substring(1, m_password_hash.length() - 1);
} else if (!enabled && (m_password_hash == "" || m_password_hash[0] != '!')) {
auto flattened_password_hash = m_password_hash.value_or(DeprecatedString::empty());
if (enabled && !flattened_password_hash.is_empty() && flattened_password_hash[0] == '!') {
m_password_hash = flattened_password_hash.substring(1, flattened_password_hash.length() - 1);
} else if (!enabled && (flattened_password_hash.is_empty() || flattened_password_hash[0] != '!')) {
StringBuilder builder;
builder.append('!');
builder.append(m_password_hash);
builder.append(flattened_password_hash);
m_password_hash = builder.to_deprecated_string();
}
}
void Account::delete_password()
{
m_password_hash = "";
m_password_hash = DeprecatedString::empty();
}
Account::Account(passwd const& pwd, spwd const& spwd, Vector<gid_t> extra_gids)
: m_username(pwd.pw_name)
, m_password_hash(spwd.sp_pwdp)
, m_password_hash(spwd.sp_pwdp ? Optional<DeprecatedString>(spwd.sp_pwdp) : OptionalNone {})
, m_uid(pwd.pw_uid)
, m_gid(pwd.pw_gid)
, m_gecos(pwd.pw_gecos)
@ -300,7 +302,7 @@ ErrorOr<DeprecatedString> Account::generate_shadow_file() const
if (p->sp_namp == m_username) {
if (m_deleted)
continue;
builder.appendff("{}:{}", m_username, m_password_hash);
builder.appendff("{}:{}", m_username, m_password_hash.value_or(DeprecatedString::empty()));
} else
builder.appendff("{}:{}", p->sp_namp, p->sp_pwdp);

View file

@ -41,7 +41,7 @@ public:
ErrorOr<void> login() const;
DeprecatedString username() const { return m_username; }
DeprecatedString password_hash() const { return m_password_hash; }
DeprecatedString password_hash() const { return m_password_hash.value_or(DeprecatedString::empty()); }
// Setters only affect in-memory copy of password.
// You must call sync to apply changes.
@ -56,9 +56,9 @@ public:
void set_extra_gids(Vector<gid_t> extra_gids) { m_extra_gids = move(extra_gids); }
void delete_password();
// A null password means that this account was missing from /etc/shadow.
// A nonexistent password means that this account was missing from /etc/shadow.
// It's considered to have a password in that case, and authentication will always fail.
bool has_password() const { return !m_password_hash.is_empty() || m_password_hash.is_null(); }
bool has_password() const { return !m_password_hash.has_value() || !m_password_hash->is_empty(); }
uid_t uid() const { return m_uid; }
gid_t gid() const { return m_gid; }
@ -82,7 +82,7 @@ private:
DeprecatedString m_username;
DeprecatedString m_password_hash;
Optional<DeprecatedString> m_password_hash;
uid_t m_uid { 0 };
gid_t m_gid { 0 };
DeprecatedString m_gecos;

View file

@ -140,11 +140,10 @@ ErrorOr<void> ConfigFile::reparse()
return {};
}
DeprecatedString ConfigFile::read_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& default_value) const
Optional<DeprecatedString> ConfigFile::read_entry_optional(const AK::DeprecatedString& group, const AK::DeprecatedString& key) const
{
if (!has_key(group, key)) {
return default_value;
}
if (!has_key(group, key))
return {};
auto it = m_groups.find(group);
auto jt = it->value.find(key);
return jt->value;

View file

@ -42,7 +42,11 @@ public:
size_t num_groups() const { return m_groups.size(); }
DeprecatedString read_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& default_value = DeprecatedString()) const;
DeprecatedString read_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& default_value = {}) const
{
return read_entry_optional(group, key).value_or(default_value);
}
Optional<DeprecatedString> read_entry_optional(DeprecatedString const& group, DeprecatedString const& key) const;
bool read_bool_entry(DeprecatedString const& group, DeprecatedString const& key, bool default_value = false) const;
template<Integral T = int>
@ -52,9 +56,9 @@ public:
return default_value;
if constexpr (IsSigned<T>)
return read_entry(group, key).to_int<T>().value_or(default_value);
return read_entry(group, key, "").to_int<T>().value_or(default_value);
else
return read_entry(group, key).to_uint<T>().value_or(default_value);
return read_entry(group, key, "").to_uint<T>().value_or(default_value);
}
void write_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& value);

View file

@ -189,29 +189,40 @@ static ErrorOr<void> unveil_dynamic_loader()
ErrorOr<void> unveil(StringView path, StringView permissions)
{
auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
if (permissions.contains('x'))
TRY(unveil_dynamic_loader());
Syscall::SC_unveil_params params {
static_cast<int>(UnveilFlags::CurrentProgram),
{ parsed_path.characters(), parsed_path.length() },
{ permissions.characters_without_null_termination(), permissions.length() },
{ nullptr, 0 },
{ nullptr, 0 },
};
DeprecatedString parsed_path;
if (!path.is_null()) {
parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
params.path = { parsed_path.characters(), parsed_path.length() };
params.permissions = { permissions.characters_without_null_termination(), permissions.length() };
}
int rc = syscall(SC_unveil, &params);
HANDLE_SYSCALL_RETURN_VALUE("unveil", rc, {});
}
ErrorOr<void> unveil_after_exec(StringView path, StringView permissions)
{
auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
DeprecatedString parsed_path;
Syscall::SC_unveil_params params {
static_cast<int>(UnveilFlags::AfterExec),
{ parsed_path.characters(), parsed_path.length() },
{ nullptr, 0 },
{ permissions.characters_without_null_termination(), permissions.length() },
};
if (!path.is_null()) {
parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
params.path = { parsed_path.characters(), parsed_path.length() };
}
int rc = syscall(SC_unveil, &params);
HANDLE_SYSCALL_RETURN_VALUE("unveil", rc, {});
}

View file

@ -41,7 +41,7 @@ ErrorOr<NonnullOwnPtr<Core::LocalSocket>> take_over_socket_from_system_server(De
parse_sockets_from_system_server();
int fd;
if (socket_path.is_null()) {
if (socket_path.is_empty()) {
// We want the first (and only) socket.
VERIFY(s_overtaken_sockets.size() == 1);
fd = s_overtaken_sockets.begin()->value;

View file

@ -102,7 +102,7 @@ void Preprocessor::handle_preprocessor_statement(StringView line)
consume_whitespace(lexer);
auto keyword = lexer.consume_until(' ');
lexer.ignore();
if (keyword.is_empty() || keyword.is_null() || keyword.is_whitespace())
if (keyword.is_empty() || keyword.is_whitespace())
return;
handle_preprocessor_keyword(keyword, lexer);
@ -243,7 +243,7 @@ void Preprocessor::handle_preprocessor_keyword(StringView keyword, GenericLexer&
size_t Preprocessor::do_substitution(Vector<Token> const& tokens, size_t token_index, Definition const& defined_value)
{
if (defined_value.value.is_null())
if (defined_value.value.is_empty())
return token_index;
Substitution sub;

View file

@ -161,7 +161,7 @@ Optional<Packet> Packet::from_raw_packet(u8 const* raw_data, size_t raw_size)
case RecordType::AAAA:
// Fall through
case RecordType::SRV:
data = { record.data(), record.data_length() };
data = ReadonlyBytes { record.data(), record.data_length() };
break;
default:
// FIXME: Parse some other record types perhaps?

View file

@ -95,7 +95,7 @@ ErrorOr<void> DebugInfo::prepare_lines()
auto compute_full_path = [&](DeprecatedFlyString const& file_path) -> Optional<DeprecatedString> {
if (file_path.view().contains("Toolchain/"sv) || file_path.view().contains("libgcc"sv))
return {};
if (file_path.view().starts_with("./"sv) && !m_source_root.is_null())
if (file_path.view().starts_with("./"sv) && !m_source_root.is_empty())
return LexicalPath::join(m_source_root, file_path).string();
if (auto index_of_serenity_slash = file_path.view().find("serenity/"sv); index_of_serenity_slash.has_value()) {
auto start_index = index_of_serenity_slash.value() + "serenity/"sv.length();

View file

@ -455,7 +455,7 @@ DeprecatedString Image::symbolicate(FlatPtr address, u32* out_offset) const
}
auto& demangled_name = symbol->demangled_name;
if (demangled_name.is_null())
if (demangled_name.is_empty())
demangled_name = demangle(symbol->name);
if (out_offset) {

View file

@ -98,7 +98,7 @@ Result Client::save_file(GUI::Window* parent_window, DeprecatedString const& nam
GUI::ConnectionToWindowServer::the().remove_window_stealing_for_client(child_window_server_client_id, parent_window_id);
});
async_prompt_save_file(id, parent_window_server_client_id, parent_window_id, name.is_null() ? "Untitled" : name, ext.is_null() ? "txt" : ext, Core::StandardPaths::home_directory(), requested_access);
async_prompt_save_file(id, parent_window_server_client_id, parent_window_id, name.is_empty() ? "Untitled" : name, ext.is_empty() ? "txt" : ext, Core::StandardPaths::home_directory(), requested_access);
return handle_promise(id);
}

View file

@ -89,9 +89,11 @@ void AbstractView::model_did_update(unsigned int flags)
m_drop_candidate_index = {};
selection().remove_all_matching([this](auto& index) { return !model()->is_within_range(index); });
auto index = find_next_search_match(m_highlighted_search.view());
if (index.is_valid())
highlight_search(index);
if (m_highlighted_search.has_value()) {
auto index = find_next_search_match(m_highlighted_search->view());
if (index.is_valid())
highlight_search(index);
}
}
m_selection_start_index = {};
}
@ -592,11 +594,11 @@ void AbstractView::keydown_event(KeyEvent& event)
if (is_searchable()) {
if (event.key() == KeyCode::Key_Backspace) {
if (!m_highlighted_search.is_null()) {
if (m_highlighted_search.has_value()) {
// if (event.modifiers() == Mod_Ctrl) {
// TODO: delete last word
// }
Utf8View view(m_highlighted_search);
Utf8View view(*m_highlighted_search);
size_t n_code_points = view.length();
if (n_code_points > 1) {
n_code_points--;
@ -621,7 +623,7 @@ void AbstractView::keydown_event(KeyEvent& event)
return;
}
} else if (event.key() == KeyCode::Key_Escape) {
if (!m_highlighted_search.is_null()) {
if (m_highlighted_search.has_value()) {
stop_highlighted_search_timer();
event.accept();
@ -629,7 +631,8 @@ void AbstractView::keydown_event(KeyEvent& event)
}
} else if (event.key() != KeyCode::Key_Tab && !event.ctrl() && !event.alt() && event.code_point() != 0) {
StringBuilder sb;
sb.append(m_highlighted_search);
if (m_highlighted_search.has_value())
sb.append(*m_highlighted_search);
sb.append_code_point(event.code_point());
auto index = find_next_search_match(sb.string_view());
@ -650,7 +653,7 @@ void AbstractView::keydown_event(KeyEvent& event)
void AbstractView::stop_highlighted_search_timer()
{
m_highlighted_search = nullptr;
m_highlighted_search.clear();
if (m_highlighted_search_timer)
m_highlighted_search_timer->stop();
if (m_highlighted_search_index.is_valid()) {
@ -723,8 +726,8 @@ void AbstractView::draw_item_text(Gfx::Painter& painter, ModelIndex const& index
text_color = index.data(ModelRole::ForegroundColor).to_color(palette().color(foreground_role()));
if (index == m_highlighted_search_index) {
auto const byte_offset = search_highlighting_offset < m_highlighted_search.length() ? 0 : item_text.length();
auto const byte_length = min(item_text.length() - byte_offset, m_highlighted_search.length() - search_highlighting_offset);
auto const byte_offset = search_highlighting_offset < m_highlighted_search.value_or("").length() ? 0 : item_text.length();
auto const byte_length = min(item_text.length() - byte_offset, m_highlighted_search.value_or("").length() - search_highlighting_offset);
Utf8View const searching_text(item_text.substring_view(byte_offset, byte_length));
// Highlight the text background first

View file

@ -199,7 +199,7 @@ private:
RefPtr<Model> m_model;
ModelSelection m_selection;
DeprecatedString m_highlighted_search;
Optional<DeprecatedString> m_highlighted_search;
RefPtr<Core::Timer> m_highlighted_search_timer;
SelectionBehavior m_selection_behavior { SelectionBehavior::SelectItems };
SelectionMode m_selection_mode { SelectionMode::SingleSelection };

View file

@ -48,9 +48,10 @@ ErrorOr<Optional<String>> FilePicker::get_filepath(Badge<FileSystemAccessServer:
ConnectionToWindowServer::the().set_window_parent_from_client(window_server_client_id, parent_window_id, picker->window_id());
if (picker->exec() == ExecResult::OK) {
auto file_path = TRY(String::from_deprecated_string(picker->selected_file()));
if (file_path.is_empty())
auto file_path = TRY(picker->selected_file().map([](auto& v) { return String::from_deprecated_string(v); }));
if (file_path.has_value() && file_path->is_empty())
return Optional<String> {};
return file_path;
}
return Optional<String> {};
@ -60,17 +61,12 @@ Optional<DeprecatedString> FilePicker::get_open_filepath(Window* parent_window,
{
auto picker = FilePicker::construct(parent_window, folder ? Mode::OpenFolder : Mode::Open, ""sv, path, screen_position, move(allowed_file_types));
if (!window_title.is_null())
if (!window_title.is_empty())
picker->set_title(window_title);
if (picker->exec() == ExecResult::OK) {
DeprecatedString file_path = picker->selected_file();
if (picker->exec() == ExecResult::OK)
return picker->selected_file();
if (file_path.is_null())
return {};
return file_path;
}
return {};
}
@ -78,14 +74,8 @@ Optional<DeprecatedString> FilePicker::get_save_filepath(Window* parent_window,
{
auto picker = FilePicker::construct(parent_window, Mode::Save, DeprecatedString::formatted("{}.{}", title, extension), path, screen_position);
if (picker->exec() == ExecResult::OK) {
DeprecatedString file_path = picker->selected_file();
if (file_path.is_null())
return {};
return file_path;
}
if (picker->exec() == ExecResult::OK)
return picker->selected_file();
return {};
}

View file

@ -44,7 +44,7 @@ public:
virtual ~FilePicker() override;
DeprecatedString const& selected_file() const { return m_selected_file; }
Optional<DeprecatedString> const& selected_file() const { return m_selected_file; }
private:
void on_file_return();
@ -77,7 +77,7 @@ private:
RefPtr<MultiView> m_view;
NonnullRefPtr<FileSystemModel> m_model;
DeprecatedString m_selected_file;
Optional<DeprecatedString> m_selected_file;
Vector<DeprecatedString> m_allowed_file_types_names;
Optional<Vector<FileTypeFilter>> m_allowed_file_types;

View file

@ -68,7 +68,7 @@ bool FileSystemModel::Node::fetch_data(DeprecatedString const& full_path, bool i
perror("readlink");
else {
symlink_target = sym_link_target_or_error.release_value().to_deprecated_string();
if (symlink_target.is_null())
if (symlink_target.is_empty())
perror("readlink");
}
}
@ -364,7 +364,7 @@ void FileSystemModel::update_node_on_selection(ModelIndex const& index, bool con
void FileSystemModel::set_root_path(DeprecatedString root_path)
{
if (root_path.is_null())
if (root_path.is_empty())
m_root_path = {};
else
m_root_path = LexicalPath::canonicalized_path(move(root_path));
@ -382,7 +382,7 @@ void FileSystemModel::invalidate()
{
m_root = adopt_own(*new Node(*this));
if (m_root_path.is_null())
if (m_root_path.is_empty())
m_root->m_parent_of_root = true;
m_root->reify_if_needed();

View file

@ -96,7 +96,10 @@ public:
virtual void set_value(Variant const& value, SelectionBehavior selection_behavior) override
{
auto& textbox = static_cast<TextBox&>(*widget());
textbox.set_text(value.to_deprecated_string());
if (value.is_valid())
textbox.set_text(value.to_deprecated_string());
else
textbox.clear();
if (selection_behavior == SelectionBehavior::SelectAll)
textbox.select_all();
}

View file

@ -202,10 +202,10 @@ void TableView::keydown_event(KeyEvent& event)
if (selection().size() > 1) {
selection().for_each_index([&](GUI::ModelIndex& index) {
begin_editing(index);
m_editing_delegate->set_value(DeprecatedString {});
m_editing_delegate->set_value(GUI::Variant {});
});
} else {
m_editing_delegate->set_value(DeprecatedString {});
m_editing_delegate->set_value(GUI::Variant {});
}
} else if (is_backspace) {
m_editing_delegate->set_value(DeprecatedString::empty());

View file

@ -98,7 +98,6 @@ public:
return visit(
[](Empty) { return false; },
[](Detail::Boolean v) { return v.value; },
[](DeprecatedString const& v) { return !v.is_null(); },
[](Integral auto v) { return v != 0; },
[](Gfx::IntPoint const& v) { return !v.is_zero(); },
[](OneOf<Gfx::IntRect, Gfx::IntSize> auto const& v) { return !v.is_empty(); },

View file

@ -69,7 +69,7 @@ Link::Link(DeprecatedString text, Document const& document)
m_name = url_string.substring_view(offset, url_string.length() - offset);
}
m_url = document.url().complete_url(url);
if (m_name.is_null())
if (m_name.is_empty())
m_name = m_url.to_deprecated_string();
}

View file

@ -249,10 +249,6 @@ void Job::on_socket_connected()
auto line = maybe_line.release_value();
dbgln_if(JOB_DEBUG, "Job {} read line of length {}", m_request.url(), line.length());
if (line.is_null()) {
dbgln("Job: Expected HTTP status");
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::TransmissionFailed); });
}
auto parts = line.split_view(' ');
if (parts.size() < 2) {
dbgln("Job: Expected 2-part or 3-part HTTP status line, got '{}'", line);
@ -302,16 +298,6 @@ void Job::on_socket_connected()
}
auto line = maybe_line.release_value();
if (line.is_null()) {
if (m_state == State::Trailers) {
// Some servers like to send two ending chunks
// use this fact as an excuse to ignore anything after the last chunk
// that is not a valid trailing header.
return finish_up();
}
dbgln("Job: Expected HTTP header");
return did_fail(Core::NetworkJob::Error::ProtocolFailed);
}
if (line.is_empty()) {
if (m_state == State::Trailers) {
return finish_up();

View file

@ -45,7 +45,7 @@ void JSONObject::initialize(Realm& realm)
}
// 25.5.2 JSON.stringify ( value [ , replacer [ , space ] ] ), https://tc39.es/ecma262/#sec-json.stringify
ThrowCompletionOr<DeprecatedString> JSONObject::stringify_impl(VM& vm, Value value, Value replacer, Value space)
ThrowCompletionOr<Optional<DeprecatedString>> JSONObject::stringify_impl(VM& vm, Value value, Value replacer, Value space)
{
auto& realm = *vm.current_realm();
@ -62,7 +62,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::stringify_impl(VM& vm, Value val
Vector<DeprecatedString> list;
for (size_t i = 0; i < replacer_length; ++i) {
auto replacer_value = TRY(replacer_object.get(i));
DeprecatedString item;
Optional<DeprecatedString> item;
if (replacer_value.is_string()) {
item = replacer_value.as_string().deprecated_string();
} else if (replacer_value.is_number()) {
@ -72,8 +72,8 @@ ThrowCompletionOr<DeprecatedString> JSONObject::stringify_impl(VM& vm, Value val
if (is<StringObject>(value_object) || is<NumberObject>(value_object))
item = TRY(replacer_value.to_deprecated_string(vm));
}
if (!item.is_null() && !list.contains_slow(item)) {
list.append(item);
if (item.has_value() && !list.contains_slow(*item)) {
list.append(*item);
}
}
state.property_list = list;
@ -118,15 +118,15 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::stringify)
auto replacer = vm.argument(1);
auto space = vm.argument(2);
auto string = TRY(stringify_impl(vm, value, replacer, space));
if (string.is_null())
auto maybe_string = TRY(stringify_impl(vm, value, replacer, space));
if (!maybe_string.has_value())
return js_undefined();
return PrimitiveString::create(vm, string);
return PrimitiveString::create(vm, maybe_string.release_value());
}
// 25.5.2.1 SerializeJSONProperty ( state, key, holder ), https://tc39.es/ecma262/#sec-serializejsonproperty
ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_property(VM& vm, StringifyState& state, PropertyKey const& key, Object* holder)
ThrowCompletionOr<Optional<DeprecatedString>> JSONObject::serialize_json_property(VM& vm, StringifyState& state, PropertyKey const& key, Object* holder)
{
// 1. Let value be ? Get(holder, key).
auto value = TRY(holder->get(key));
@ -209,14 +209,14 @@ ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_property(VM& vm,
// b. If isArray is true, return ? SerializeJSONArray(state, value).
if (is_array)
return serialize_json_array(vm, state, value.as_object());
return TRY(serialize_json_array(vm, state, value.as_object()));
// c. Return ? SerializeJSONObject(state, value).
return serialize_json_object(vm, state, value.as_object());
return TRY(serialize_json_object(vm, state, value.as_object()));
}
// 12. Return undefined.
return DeprecatedString {};
return Optional<DeprecatedString> {};
}
// 25.5.2.4 SerializeJSONObject ( state, value ), https://tc39.es/ecma262/#sec-serializejsonobject
@ -234,7 +234,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_object(VM& vm, St
if (key.is_symbol())
return {};
auto serialized_property_string = TRY(serialize_json_property(vm, state, key, &object));
if (!serialized_property_string.is_null()) {
if (serialized_property_string.has_value()) {
property_strings.append(DeprecatedString::formatted(
"{}:{}{}",
quote_json_string(key.to_string()),
@ -305,10 +305,10 @@ ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_array(VM& vm, Str
for (size_t i = 0; i < length; ++i) {
auto serialized_property_string = TRY(serialize_json_property(vm, state, i, &object));
if (serialized_property_string.is_null()) {
if (!serialized_property_string.has_value()) {
property_strings.append("null"sv);
} else {
property_strings.append(serialized_property_string);
property_strings.append(serialized_property_string.release_value());
}
}

View file

@ -19,7 +19,7 @@ public:
// The base implementation of stringify is exposed because it is used by
// test-js to communicate between the JS tests and the C++ test runner.
static ThrowCompletionOr<DeprecatedString> stringify_impl(VM&, Value value, Value replacer, Value space);
static ThrowCompletionOr<Optional<DeprecatedString>> stringify_impl(VM&, Value value, Value replacer, Value space);
static Value parse_json_value(VM&, JsonValue const&);
@ -35,7 +35,7 @@ private:
};
// Stringify helpers
static ThrowCompletionOr<DeprecatedString> serialize_json_property(VM&, StringifyState&, PropertyKey const& key, Object* holder);
static ThrowCompletionOr<Optional<DeprecatedString>> serialize_json_property(VM&, StringifyState&, PropertyKey const& key, Object* holder);
static ThrowCompletionOr<DeprecatedString> serialize_json_object(VM&, StringifyState&, Object&);
static ThrowCompletionOr<DeprecatedString> serialize_json_array(VM&, StringifyState&, Object&);
static DeprecatedString quote_json_string(DeprecatedString);

View file

@ -221,7 +221,7 @@ NonnullGCPtr<PrimitiveString> PrimitiveString::create(VM& vm, DeprecatedString s
NonnullGCPtr<PrimitiveString> PrimitiveString::create(VM& vm, DeprecatedFlyString const& string)
{
return create(vm, string.impl());
return create(vm, *string.impl());
}
NonnullGCPtr<PrimitiveString> PrimitiveString::create(VM& vm, PrimitiveString& lhs, PrimitiveString& rhs)

View file

@ -910,7 +910,7 @@ ThrowCompletionOr<NonnullGCPtr<Module>> VM::resolve_imported_module(ScriptOrModu
VERIFY(module_request.assertions.is_empty() || (module_request.assertions.size() == 1 && module_request.assertions.first().key == "type"));
auto module_type = module_request.assertions.is_empty() ? DeprecatedString {} : module_request.assertions.first().value;
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] module at {} has type {} [is_null={}]", module_request.module_specifier, module_type, module_type.is_null());
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] module at {} has type {}", module_request.module_specifier, module_type);
StringView base_filename = referencing_script_or_module.visit(
[&](Empty) {

View file

@ -174,7 +174,7 @@ DeprecatedString Token::string_value(StringValueStatus& status) const
// In non-strict mode LegacyOctalEscapeSequence is allowed in strings:
// https://tc39.es/ecma262/#sec-additional-syntax-string-literals
DeprecatedString octal_str;
Optional<DeprecatedString> octal_str;
auto is_octal_digit = [](char ch) { return ch >= '0' && ch <= '7'; };
auto is_zero_to_three = [](char ch) { return ch >= '0' && ch <= '3'; };
@ -193,9 +193,9 @@ DeprecatedString Token::string_value(StringValueStatus& status) const
else if (is_zero_to_three(lexer.peek()) && is_octal_digit(lexer.peek(1)) && is_octal_digit(lexer.peek(2)))
octal_str = lexer.consume(3);
if (!octal_str.is_null()) {
if (octal_str.has_value()) {
status = StringValueStatus::LegacyOctalEscapeSequence;
auto code_point = strtoul(octal_str.characters(), nullptr, 8);
auto code_point = strtoul(octal_str->characters(), nullptr, 8);
VERIFY(code_point <= 255);
builder.append_code_point(code_point);
continue;

View file

@ -256,8 +256,6 @@ NonnullRefPtr<StringObject> Parser::parse_string()
is_binary_string = true;
}
VERIFY(!string.is_null());
auto string_object = make_object<StringObject>(string, is_binary_string);
if (m_document->security_handler() && m_enable_encryption)

View file

@ -186,8 +186,8 @@ public:
ResultType type() const { return m_type; }
bool select_from_table() const { return !m_table_name.is_null(); }
DeprecatedString const& table_name() const { return m_table_name; }
bool select_from_table() const { return m_table_name.has_value(); }
Optional<DeprecatedString> const& table_name() const { return m_table_name; }
bool select_from_expression() const { return !m_expression.is_null(); }
RefPtr<Expression> const& expression() const { return m_expression; }
@ -196,7 +196,7 @@ public:
private:
ResultType m_type { ResultType::All };
DeprecatedString m_table_name {};
Optional<DeprecatedString> m_table_name {};
RefPtr<Expression> m_expression {};
DeprecatedString m_column_alias {};

View file

@ -566,16 +566,16 @@ RefPtr<Expression> Parser::parse_bind_parameter_expression()
return {};
}
RefPtr<Expression> Parser::parse_column_name_expression(DeprecatedString with_parsed_identifier, bool with_parsed_period)
RefPtr<Expression> Parser::parse_column_name_expression(Optional<DeprecatedString> with_parsed_identifier, bool with_parsed_period)
{
if (with_parsed_identifier.is_null() && !match(TokenType::Identifier))
if (!with_parsed_identifier.has_value() && !match(TokenType::Identifier))
return {};
DeprecatedString first_identifier;
if (with_parsed_identifier.is_null())
if (!with_parsed_identifier.has_value())
first_identifier = consume(TokenType::Identifier).value();
else
first_identifier = move(with_parsed_identifier);
first_identifier = with_parsed_identifier.release_value();
DeprecatedString schema_name;
DeprecatedString table_name;
@ -1010,17 +1010,17 @@ NonnullRefPtr<ResultColumn> Parser::parse_result_column()
// If we match an identifier now, we don't know whether it is a table-name of the form "table-name.*", or if it is the start of a
// column-name-expression, until we try to parse the asterisk. So if we consume an identifier and a period, but don't find an
// asterisk, hold onto that information to form a column-name-expression later.
DeprecatedString table_name;
Optional<DeprecatedString> table_name;
bool parsed_period = false;
if (match(TokenType::Identifier)) {
table_name = consume().value();
parsed_period = consume_if(TokenType::Period);
if (parsed_period && consume_if(TokenType::Asterisk))
return create_ast_node<ResultColumn>(move(table_name));
return create_ast_node<ResultColumn>(table_name.release_value());
}
auto expression = table_name.is_null()
auto expression = !table_name.has_value()
? parse_expression()
: static_cast<NonnullRefPtr<Expression>>(*parse_column_name_expression(move(table_name), parsed_period));

View file

@ -74,7 +74,7 @@ private:
bool match_secondary_expression() const;
RefPtr<Expression> parse_literal_value_expression();
RefPtr<Expression> parse_bind_parameter_expression();
RefPtr<Expression> parse_column_name_expression(DeprecatedString with_parsed_identifier = {}, bool with_parsed_period = false);
RefPtr<Expression> parse_column_name_expression(Optional<DeprecatedString> with_parsed_identifier = {}, bool with_parsed_period = false);
RefPtr<Expression> parse_unary_operator_expression();
RefPtr<Expression> parse_binary_operator_expression(NonnullRefPtr<Expression> lhs);
RefPtr<Expression> parse_chained_expression(bool surrounded_by_parentheses = true);

View file

@ -44,7 +44,7 @@ ByteBuffer TLSv12::build_hello()
size_t alpn_negotiated_length = 0;
// ALPN
if (!m_context.negotiated_alpn.is_null()) {
if (!m_context.negotiated_alpn.is_empty()) {
alpn_negotiated_length = m_context.negotiated_alpn.length();
alpn_length = alpn_negotiated_length + 1;
extension_length += alpn_length + 6;
@ -69,7 +69,7 @@ ByteBuffer TLSv12::build_hello()
// set SNI if we have one, and the user hasn't explicitly asked us to omit it.
auto sni_length = 0;
if (!m_context.extensions.SNI.is_null() && m_context.options.use_sni)
if (!m_context.extensions.SNI.is_empty() && m_context.options.use_sni)
sni_length = m_context.extensions.SNI.length();
auto elliptic_curves_length = 2 * m_context.options.elliptic_curves.size();

View file

@ -247,9 +247,10 @@ inline AK::Result<JS::NonnullGCPtr<JS::SourceTextModule>, ParserError> parse_mod
inline ErrorOr<JsonValue> get_test_results(JS::Realm& realm)
{
auto results = MUST(realm.global_object().get("__TestResults__"));
auto json_string = MUST(JS::JSONObject::stringify_impl(*g_vm, results, JS::js_undefined(), JS::js_undefined()));
return JsonValue::from_string(json_string);
auto maybe_json_string = MUST(JS::JSONObject::stringify_impl(*g_vm, results, JS::js_undefined(), JS::js_undefined()));
if (maybe_json_string.has_value())
return JsonValue::from_string(*maybe_json_string);
return JsonValue();
}
inline void TestRunner::do_run_single_test(DeprecatedString const& test_path, size_t, size_t)

View file

@ -38,7 +38,7 @@ struct Attribute {
#ifndef KERNEL
DeprecatedString href;
DeprecatedString href_id;
Optional<DeprecatedString> href_id;
#endif
enum class Flags : u8 {

View file

@ -292,7 +292,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
// Pass: Compute the rect(s) of the currently hovered link, if any.
Vector<Gfx::IntRect> hovered_href_rects;
if (!m_hovered_href_id.is_null()) {
if (m_hovered_href_id.has_value()) {
for (u16 visual_row = 0; visual_row < m_terminal.rows(); ++visual_row) {
auto& line = m_terminal.line(first_row_from_history + visual_row);
for (size_t column = 0; column < line.length(); ++column) {
@ -415,7 +415,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
auto character_rect = glyph_rect(visual_row, column);
if (!m_hovered_href_id.is_null() && attribute.href_id == m_hovered_href_id) {
if (m_hovered_href_id.has_value() && attribute.href_id == m_hovered_href_id) {
text_color = palette().base_text();
}
@ -754,7 +754,7 @@ void TerminalWidget::doubleclick_event(GUI::MouseEvent& event)
{
if (event.button() == GUI::MouseButton::Primary) {
auto attribute = m_terminal.attribute_at(buffer_position_at(event.position()));
if (!attribute.href_id.is_null()) {
if (attribute.href_id.has_value()) {
dbgln("Open hyperlinked URL: '{}'", attribute.href);
Desktop::Launcher::open(attribute.href);
return;
@ -806,7 +806,7 @@ void TerminalWidget::copy()
void TerminalWidget::mouseup_event(GUI::MouseEvent& event)
{
if (event.button() == GUI::MouseButton::Primary) {
if (!m_active_href_id.is_null()) {
if (m_active_href_id.has_value()) {
m_active_href = {};
m_active_href_id = {};
update();
@ -862,7 +862,7 @@ void TerminalWidget::mousemove_event(GUI::MouseEvent& event)
auto attribute = m_terminal.attribute_at(position);
if (attribute.href_id != m_hovered_href_id) {
if (!attribute.href_id.is_null()) {
if (attribute.href_id.has_value()) {
m_hovered_href_id = attribute.href_id;
m_hovered_href = attribute.href;
@ -902,7 +902,7 @@ void TerminalWidget::mousemove_event(GUI::MouseEvent& event)
if (!(event.buttons() & GUI::MouseButton::Primary))
return;
if (!m_active_href_id.is_null()) {
if (m_active_href_id.has_value()) {
auto diff = event.position() - m_left_mousedown_position;
auto distance_travelled_squared = diff.x() * diff.x() + diff.y() * diff.y();
constexpr int drag_distance_threshold = 5;
@ -1111,7 +1111,7 @@ void TerminalWidget::set_cursor_shape(CursorShape shape)
void TerminalWidget::context_menu_event(GUI::ContextMenuEvent& event)
{
if (m_hovered_href_id.is_null()) {
if (!m_hovered_href_id.has_value()) {
m_context_menu->popup(event.screen_position());
} else {
m_context_menu_href = m_hovered_href;

View file

@ -168,10 +168,10 @@ private:
VT::Range m_selection;
DeprecatedString m_hovered_href;
DeprecatedString m_hovered_href_id;
Optional<DeprecatedString> m_hovered_href_id;
DeprecatedString m_active_href;
DeprecatedString m_active_href_id;
Optional<DeprecatedString> m_active_href_id;
// Snapshot of m_hovered_href when opening a context menu for a hyperlink.
DeprecatedString m_context_menu_href;

View file

@ -40,7 +40,7 @@ DeprecatedString CSSNamespaceRule::serialized() const
builder.append("@namespace "sv);
// followed by the serialization as an identifier of the prefix attribute (if any),
if (!m_prefix.is_empty() && !m_prefix.is_null()) {
if (!m_prefix.is_empty()) {
serialize_an_identifier(builder, m_prefix);
// followed by a single SPACE (U+0020) if there is a prefix,
builder.append(" "sv);

View file

@ -53,23 +53,23 @@ DeprecatedString CSSStyleRule::serialized() const
builder.append(" {"sv);
// 2. Let decls be the result of performing serialize a CSS declaration block on the rules associated declarations, or null if there are no such declarations.
auto decls = declaration().serialized();
auto decls = declaration().length() > 0 ? declaration().serialized() : Optional<DeprecatedString>();
// FIXME: 3. Let rules be the result of performing serialize a CSS rule on each rule in the rules cssRules list, or null if there are no such rules.
DeprecatedString rules;
Optional<DeprecatedString> rules;
// 4. If decls and rules are both null, append " }" to s (i.e. a single SPACE (U+0020) followed by RIGHT CURLY BRACKET (U+007D)) and return s.
if (decls.is_null() && rules.is_null()) {
if (!decls.has_value() && !rules.has_value()) {
builder.append(" }"sv);
return builder.to_deprecated_string();
}
// 5. If rules is null:
if (rules.is_null()) {
if (!rules.has_value()) {
// 1. Append a single SPACE (U+0020) to s
builder.append(' ');
// 2. Append decls to s
builder.append(decls);
builder.append(*decls);
// 3. Append " }" to s (i.e. a single SPACE (U+0020) followed by RIGHT CURLY BRACKET (U+007D)).
builder.append(" }"sv);
// 4. Return s.

View file

@ -36,9 +36,9 @@ static inline bool matches_lang_pseudo_class(DOM::Element const& element, Vector
{
FlyString element_language;
for (auto const* e = &element; e; e = e->parent_element()) {
auto lang = e->deprecated_attribute(HTML::AttributeNames::lang);
if (!lang.is_null()) {
element_language = FlyString::from_deprecated_fly_string(lang).release_value_but_fixme_should_propagate_errors();
auto lang = e->attribute(HTML::AttributeNames::lang);
if (lang.has_value()) {
element_language = lang.release_value();
break;
}
}

View file

@ -92,7 +92,7 @@ void Attr::change_attribute(String value)
}
// https://dom.spec.whatwg.org/#handle-attribute-changes
void Attr::handle_attribute_changes(Element& element, DeprecatedString const& old_value, DeprecatedString const& new_value)
void Attr::handle_attribute_changes(Element& element, Optional<DeprecatedString> old_value, Optional<DeprecatedString> new_value)
{
DeprecatedString deprecated_namespace_uri;
if (namespace_uri().has_value())
@ -107,8 +107,8 @@ void Attr::handle_attribute_changes(Element& element, DeprecatedString const& ol
JS::MarkedVector<JS::Value> arguments { vm.heap() };
arguments.append(JS::PrimitiveString::create(vm, local_name()));
arguments.append(old_value.is_null() ? JS::js_null() : JS::PrimitiveString::create(vm, old_value));
arguments.append(new_value.is_null() ? JS::js_null() : JS::PrimitiveString::create(vm, new_value));
arguments.append(!old_value.has_value() ? JS::js_null() : JS::PrimitiveString::create(vm, old_value.release_value()));
arguments.append(!new_value.has_value() ? JS::js_null() : JS::PrimitiveString::create(vm, new_value.release_value()));
arguments.append(!namespace_uri().has_value() ? JS::js_null() : JS::PrimitiveString::create(vm, namespace_uri().value()));
element.enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::attributeChangedCallback, move(arguments));

View file

@ -41,7 +41,7 @@ public:
// Always returns true: https://dom.spec.whatwg.org/#dom-attr-specified
constexpr bool specified() const { return true; }
void handle_attribute_changes(Element&, DeprecatedString const& old_value, DeprecatedString const& new_value);
void handle_attribute_changes(Element&, Optional<DeprecatedString> old_value, Optional<DeprecatedString> new_value);
private:
Attr(Document&, QualifiedName, String value, Element*);

View file

@ -82,19 +82,19 @@ Element::Element(Document& document, DOM::QualifiedName qualified_name)
return;
// 2. If value is null and oldValue is the empty string, then return.
if (value.is_null() && old_value == DeprecatedString::empty())
if (!value.has_value() && old_value == DeprecatedString::empty())
return;
// 3. If value is the empty string and oldValue is null, then return.
if (value == DeprecatedString::empty() && old_value.is_null())
if (value == DeprecatedString::empty() && !old_value.has_value())
return;
// 4. If value is null or the empty string, then set elements name to the empty string.
if (value.is_empty())
if (!value.has_value() || value->is_empty())
set_slottable_name({});
// 5. Otherwise, set elements name to value.
else
set_slottable_name(MUST(String::from_deprecated_string(value)));
set_slottable_name(MUST(String::from_deprecated_string(*value)));
// 6. If element is assigned, then run assign slottables for elements assigned slot.
if (auto assigned_slot = assigned_slot_internal())
@ -468,7 +468,7 @@ void Element::add_attribute_change_steps(AttributeChangeSteps steps)
m_attribute_change_steps.append(move(steps));
}
void Element::run_attribute_change_steps(FlyString const& local_name, DeprecatedString const& old_value, DeprecatedString const& value, DeprecatedFlyString const& namespace_)
void Element::run_attribute_change_steps(FlyString const& local_name, Optional<DeprecatedString> const& old_value, Optional<DeprecatedString> const& value, DeprecatedFlyString const& namespace_)
{
for (auto const& attribute_change_steps : m_attribute_change_steps)
attribute_change_steps(local_name, old_value, value, namespace_);
@ -478,19 +478,21 @@ void Element::run_attribute_change_steps(FlyString const& local_name, Deprecated
invalidate_style_after_attribute_change(local_name);
}
void Element::attribute_changed(FlyString const& name, DeprecatedString const& value)
void Element::attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value)
{
auto value_or_empty = value.value_or("");
if (name == HTML::AttributeNames::class_) {
auto new_classes = value.split_view(Infra::is_ascii_whitespace);
auto new_classes = value_or_empty.split_view(Infra::is_ascii_whitespace);
m_classes.clear();
m_classes.ensure_capacity(new_classes.size());
for (auto& new_class : new_classes) {
m_classes.unchecked_append(FlyString::from_utf8(new_class).release_value_but_fixme_should_propagate_errors());
}
if (m_class_list)
m_class_list->associated_attribute_changed(value);
m_class_list->associated_attribute_changed(value_or_empty);
} else if (name == HTML::AttributeNames::style) {
if (value.is_null()) {
if (!value.has_value()) {
if (!m_inline_style) {
m_inline_style = nullptr;
set_needs_style_update(true);
@ -499,16 +501,16 @@ void Element::attribute_changed(FlyString const& name, DeprecatedString const& v
// https://drafts.csswg.org/cssom/#ref-for-cssstyledeclaration-updating-flag
if (m_inline_style && m_inline_style->is_updating())
return;
m_inline_style = parse_css_style_attribute(CSS::Parser::ParsingContext(document()), value, *this);
m_inline_style = parse_css_style_attribute(CSS::Parser::ParsingContext(document()), *value, *this);
set_needs_style_update(true);
}
} else if (name == HTML::AttributeNames::dir) {
// https://html.spec.whatwg.org/multipage/dom.html#attr-dir
if (value.equals_ignoring_ascii_case("ltr"sv))
if (value_or_empty.equals_ignoring_ascii_case("ltr"sv))
m_dir = Dir::Ltr;
else if (value.equals_ignoring_ascii_case("rtl"sv))
else if (value_or_empty.equals_ignoring_ascii_case("rtl"sv))
m_dir = Dir::Rtl;
else if (value.equals_ignoring_ascii_case("auto"sv))
else if (value_or_empty.equals_ignoring_ascii_case("auto"sv))
m_dir = Dir::Auto;
else
m_dir = {};

View file

@ -153,11 +153,11 @@ public:
virtual void apply_presentational_hints(CSS::StyleProperties&) const { }
// https://dom.spec.whatwg.org/#concept-element-attributes-change-ext
using AttributeChangeSteps = Function<void(FlyString const& /*local_name*/, DeprecatedString const& /*old_value*/, DeprecatedString const& /*value*/, DeprecatedFlyString const& /*namespace_*/)>;
using AttributeChangeSteps = Function<void(FlyString const& /*local_name*/, Optional<DeprecatedString> const& /*old_value*/, Optional<DeprecatedString> const& /*value*/, DeprecatedFlyString const& /*namespace_*/)>;
void add_attribute_change_steps(AttributeChangeSteps steps);
void run_attribute_change_steps(FlyString const& local_name, DeprecatedString const& old_value, DeprecatedString const& value, DeprecatedFlyString const& namespace_);
virtual void attribute_changed(FlyString const& name, DeprecatedString const& value);
void run_attribute_change_steps(FlyString const& local_name, Optional<DeprecatedString> const& old_value, Optional<DeprecatedString> const& value, DeprecatedFlyString const& namespace_);
virtual void attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value);
struct [[nodiscard]] RequiredInvalidationAfterStyleChange {
bool repaint { false };

View file

@ -1533,7 +1533,7 @@ Painting::PaintableBox* Node::paintable_box()
}
// https://dom.spec.whatwg.org/#queue-a-mutation-record
void Node::queue_mutation_record(FlyString const& type, DeprecatedString attribute_name, DeprecatedString attribute_namespace, DeprecatedString old_value, Vector<JS::Handle<Node>> added_nodes, Vector<JS::Handle<Node>> removed_nodes, Node* previous_sibling, Node* next_sibling) const
void Node::queue_mutation_record(FlyString const& type, Optional<DeprecatedString> attribute_name, Optional<DeprecatedString> attribute_namespace, Optional<DeprecatedString> old_value, Vector<JS::Handle<Node>> added_nodes, Vector<JS::Handle<Node>> removed_nodes, Node* previous_sibling, Node* next_sibling) const
{
// NOTE: We defer garbage collection until the end of the scope, since we can't safely use MutationObserver* as a hashmap key otherwise.
// FIXME: This is a total hack.
@ -1541,7 +1541,7 @@ void Node::queue_mutation_record(FlyString const& type, DeprecatedString attribu
// 1. Let interestedObservers be an empty map.
// mutationObserver -> mappedOldValue
OrderedHashMap<MutationObserver*, DeprecatedString> interested_observers;
OrderedHashMap<MutationObserver*, Optional<DeprecatedString>> interested_observers;
// 2. Let nodes be the inclusive ancestors of target.
Vector<JS::Handle<Node const>> nodes;
@ -1565,7 +1565,7 @@ void Node::queue_mutation_record(FlyString const& type, DeprecatedString attribu
// then:
if (!(node.ptr() != this && !options.subtree)
&& !(type == MutationType::attributes && (!options.attributes.has_value() || !options.attributes.value()))
&& !(type == MutationType::attributes && options.attribute_filter.has_value() && (!attribute_namespace.is_null() || !options.attribute_filter->contains_slow(attribute_name.view())))
&& !(type == MutationType::attributes && options.attribute_filter.has_value() && (attribute_namespace.has_value() || !options.attribute_filter->contains_slow(attribute_name.value_or("").view())))
&& !(type == MutationType::characterData && (!options.character_data.has_value() || !options.character_data.value()))
&& !(type == MutationType::childList && !options.child_list)) {
// 1. Let mo be registereds observer.
@ -1593,17 +1593,9 @@ void Node::queue_mutation_record(FlyString const& type, DeprecatedString attribu
for (auto& interested_observer : interested_observers) {
// 1. Let record be a new MutationRecord object with its type set to type, target set to target, attributeName set to name, attributeNamespace set to namespace, oldValue set to mappedOldValue,
// addedNodes set to addedNodes, removedNodes set to removedNodes, previousSibling set to previousSibling, and nextSibling set to nextSibling.
Optional<String> maybe_attribute_name;
if (!attribute_name.is_null())
maybe_attribute_name = MUST(String::from_deprecated_string(attribute_name));
Optional<String> maybe_attribute_namespace;
if (!attribute_namespace.is_null())
maybe_attribute_namespace = MUST(String::from_deprecated_string(attribute_namespace));
Optional<String> maybe_interested_observer;
if (!interested_observer.value.is_null())
maybe_interested_observer = MUST(String::from_deprecated_string(interested_observer.value));
auto maybe_attribute_name = attribute_name.map([](auto& name) { return MUST(String::from_deprecated_string(name)); });
auto maybe_attribute_namespace = attribute_namespace.map([](auto& ns) { return MUST(String::from_deprecated_string(ns)); });
auto maybe_interested_observer = interested_observer.value.map([](auto& value) { return MUST(String::from_deprecated_string(value)); });
auto record = MutationRecord::create(realm(), type, *this, added_nodes_list, removed_nodes_list, previous_sibling, next_sibling, maybe_attribute_name, maybe_attribute_namespace, /* mappedOldValue */ maybe_interested_observer);
@ -1888,8 +1880,8 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
if (is<HTML::HTMLElement>(this)) {
auto const* element = static_cast<HTML::HTMLElement const*>(this);
auto tooltip = element->title();
if (!tooltip.is_empty() && !tooltip.is_null())
return String::from_deprecated_string(tooltip);
if (!tooltip.has_value() && !tooltip->is_empty())
return tooltip.release_value();
}
// Append the result of each step above, with a space, to the total accumulated text.
//

View file

@ -259,7 +259,7 @@ public:
void add_registered_observer(RegisteredObserver& registered_observer) { m_registered_observer_list.append(registered_observer); }
void queue_mutation_record(FlyString const& type, DeprecatedString attribute_name, DeprecatedString attribute_namespace, DeprecatedString old_value, Vector<JS::Handle<Node>> added_nodes, Vector<JS::Handle<Node>> removed_nodes, Node* previous_sibling, Node* next_sibling) const;
void queue_mutation_record(FlyString const& type, Optional<DeprecatedString> attribute_name, Optional<DeprecatedString> attribute_namespace, Optional<DeprecatedString> old_value, Vector<JS::Handle<Node>> added_nodes, Vector<JS::Handle<Node>> removed_nodes, Node* previous_sibling, Node* next_sibling) const;
// https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant
template<typename Callback>

View file

@ -43,8 +43,8 @@ void StyleElementUtils::update_a_style_block(DOM::Element& style_element)
return;
// 4. If element's type attribute is present and its value is neither the empty string nor an ASCII case-insensitive match for "text/css", then return.
auto type_attribute = style_element.deprecated_attribute(HTML::AttributeNames::type);
if (!type_attribute.is_null() && !type_attribute.is_empty() && !Infra::is_ascii_case_insensitive_match(type_attribute, "text/css"sv))
auto type_attribute = style_element.attribute(HTML::AttributeNames::type);
if (type_attribute.has_value() && !type_attribute->is_empty() && !Infra::is_ascii_case_insensitive_match(type_attribute->bytes_as_string_view(), "text/css"sv))
return;
// FIXME: 5. If the Should element's inline behavior be blocked by Content Security Policy? algorithm returns "Blocked" when executed upon the style element, "style", and the style element's child text content, then return. [CSP]
@ -86,7 +86,7 @@ void StyleElementUtils::remove_a_css_style_sheet(DOM::Document& document, CSS::C
}
// https://www.w3.org/TR/cssom/#create-a-css-style-sheet
void StyleElementUtils::create_a_css_style_sheet(DOM::Document& document, DeprecatedString type, DOM::Element* owner_node, DeprecatedString media, DeprecatedString title, bool alternate, bool origin_clean, DeprecatedString location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet)
void StyleElementUtils::create_a_css_style_sheet(DOM::Document& document, DeprecatedString type, DOM::Element* owner_node, DeprecatedString media, DeprecatedString title, bool alternate, bool origin_clean, Optional<DeprecatedString> location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet)
{
// 1. Create a new CSS style sheet object and set its properties as specified.
// FIXME: We receive `sheet` from the caller already. This is weird.
@ -96,16 +96,13 @@ void StyleElementUtils::create_a_css_style_sheet(DOM::Document& document, Deprec
sheet.set_owner_node(owner_node);
sheet.set_type(MUST(String::from_deprecated_string(type)));
sheet.set_media(move(media));
if (title.is_null())
sheet.set_title({});
else
sheet.set_title(MUST(String::from_deprecated_string(title)));
sheet.set_title(MUST(String::from_deprecated_string(title)));
sheet.set_alternate(alternate);
sheet.set_origin_clean(origin_clean);
if (location.is_null())
if (!location.has_value())
sheet.set_location({});
else
sheet.set_location(MUST(String::from_deprecated_string(location)));
sheet.set_location(MUST(String::from_deprecated_string(*location)));
// 2. Then run the add a CSS style sheet steps for the newly created CSS style sheet.
add_a_css_style_sheet(document, sheet);

View file

@ -20,7 +20,7 @@ public:
private:
void remove_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet);
void create_a_css_style_sheet(DOM::Document& document, DeprecatedString type, DOM::Element* owner_node, DeprecatedString media, DeprecatedString title, bool alternate, bool origin_clean, DeprecatedString location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet);
void create_a_css_style_sheet(DOM::Document& document, DeprecatedString type, DOM::Element* owner_node, DeprecatedString media, DeprecatedString title, bool alternate, bool origin_clean, Optional<DeprecatedString> location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet);
void add_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet);
// https://www.w3.org/TR/cssom/#associated-css-style-sheet

View file

@ -257,14 +257,14 @@ static Optional<DeprecatedString> record_namespace_information(DOM::Element cons
auto const& prefix_definition = attribute->local_name().to_deprecated_fly_string();
// 2. Let namespace definition be the value of attr's value.
auto namespace_definition = attribute->value().to_deprecated_string();
DeprecatedFlyString namespace_definition = attribute->value().to_deprecated_string();
// 3. If namespace definition is the XML namespace, then stop running these steps, and return to Main to visit the next attribute.
if (namespace_definition == Namespace::XML)
continue;
// 4. If namespace definition is the empty string (the declarative form of having no namespace), then let namespace definition be null instead.
if (namespace_definition.is_empty())
if (namespace_definition == ""sv)
namespace_definition = {};
// 5. If prefix definition is found in map given the namespace namespace definition, then stop running these steps, and return to Main to visit the next attribute.
@ -284,17 +284,19 @@ static Optional<DeprecatedString> record_namespace_information(DOM::Element cons
}
// https://w3c.github.io/DOM-Parsing/#dfn-serializing-an-attribute-value
static WebIDL::ExceptionOr<DeprecatedString> serialize_an_attribute_value(DeprecatedString const& attribute_value, [[maybe_unused]] RequireWellFormed require_well_formed)
static WebIDL::ExceptionOr<DeprecatedString> serialize_an_attribute_value(OneOf<DeprecatedString, DeprecatedFlyString> auto const& attribute_value, [[maybe_unused]] RequireWellFormed require_well_formed)
{
// FIXME: 1. If the require well-formed flag is set (its value is true), and attribute value contains characters that are not matched by the XML Char production,
// then throw an exception; the serialization of this attribute value would fail to produce a well-formed element serialization.
// 2. If attribute value is null, then return the empty string.
if (attribute_value.is_null())
return DeprecatedString::empty();
if constexpr (requires { attribute_value.is_null(); }) {
if (attribute_value.is_null())
return DeprecatedString::empty();
}
// 3. Otherwise, attribute value is a string. Return the value of attribute value, first replacing any occurrences of the following:
auto final_attribute_value = attribute_value;
DeprecatedString final_attribute_value = attribute_value;
// 1. "&" with "&amp;"
final_attribute_value = final_attribute_value.replace("&"sv, "&amp;"sv, ReplaceMode::All);

View file

@ -821,7 +821,7 @@ ErrorOr<void> dump_namespace_rule(StringBuilder& builder, CSS::CSSNamespaceRule
{
indent(builder, indent_levels);
TRY(builder.try_appendff(" Namespace: {}\n", namespace_.namespace_uri()));
if (!namespace_.prefix().is_null() && !namespace_.prefix().is_empty())
if (!namespace_.prefix().is_empty())
TRY(builder.try_appendff(" Prefix: {}\n", namespace_.prefix()));
return {};

View file

@ -27,7 +27,7 @@ void HTMLAnchorElement::initialize(JS::Realm& realm)
set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLAnchorElementPrototype>(realm, "HTMLAnchorElement"));
}
void HTMLAnchorElement::attribute_changed(FlyString const& name, DeprecatedString const& value)
void HTMLAnchorElement::attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value)
{
HTMLElement::attribute_changed(name, value);
if (name == HTML::AttributeNames::href) {
@ -35,9 +35,9 @@ void HTMLAnchorElement::attribute_changed(FlyString const& name, DeprecatedStrin
}
}
DeprecatedString HTMLAnchorElement::hyperlink_element_utils_href() const
Optional<String> HTMLAnchorElement::hyperlink_element_utils_href() const
{
return deprecated_attribute(HTML::AttributeNames::href);
return attribute(HTML::AttributeNames::href);
}
WebIDL::ExceptionOr<void> HTMLAnchorElement::set_hyperlink_element_utils_href(String href)
@ -98,7 +98,7 @@ i32 HTMLAnchorElement::default_tab_index_value() const
Optional<ARIA::Role> HTMLAnchorElement::default_role() const
{
// https://www.w3.org/TR/html-aria/#el-a-no-href
if (!href().is_null())
if (!href().is_empty())
return ARIA::Role::link;
// https://www.w3.org/TR/html-aria/#el-a
return ARIA::Role::generic;

View file

@ -43,12 +43,12 @@ private:
void run_activation_behavior(Web::DOM::Event const&);
// ^DOM::Element
virtual void attribute_changed(FlyString const& name, DeprecatedString const& value) override;
virtual void attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value) override;
virtual i32 default_tab_index_value() const override;
// ^HTML::HTMLHyperlinkElementUtils
virtual DOM::Document& hyperlink_element_utils_document() override { return document(); }
virtual DeprecatedString hyperlink_element_utils_href() const override;
virtual Optional<String> hyperlink_element_utils_href() const override;
virtual WebIDL::ExceptionOr<void> set_hyperlink_element_utils_href(String) override;
virtual bool hyperlink_element_utils_is_html_anchor_element() const final { return true; }
virtual bool hyperlink_element_utils_is_connected() const final { return is_connected(); }

View file

@ -23,7 +23,7 @@ void HTMLAreaElement::initialize(JS::Realm& realm)
set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLAreaElementPrototype>(realm, "HTMLAreaElement"));
}
void HTMLAreaElement::attribute_changed(FlyString const& name, DeprecatedString const& value)
void HTMLAreaElement::attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value)
{
HTMLElement::attribute_changed(name, value);
if (name == HTML::AttributeNames::href) {
@ -31,9 +31,9 @@ void HTMLAreaElement::attribute_changed(FlyString const& name, DeprecatedString
}
}
DeprecatedString HTMLAreaElement::hyperlink_element_utils_href() const
Optional<String> HTMLAreaElement::hyperlink_element_utils_href() const
{
return deprecated_attribute(HTML::AttributeNames::href);
return attribute(HTML::AttributeNames::href);
}
WebIDL::ExceptionOr<void> HTMLAreaElement::set_hyperlink_element_utils_href(String href)
@ -51,7 +51,7 @@ i32 HTMLAreaElement::default_tab_index_value() const
Optional<ARIA::Role> HTMLAreaElement::default_role() const
{
// https://www.w3.org/TR/html-aria/#el-area-no-href
if (!href().is_null())
if (!href().is_empty())
return ARIA::Role::link;
// https://www.w3.org/TR/html-aria/#el-area
return ARIA::Role::generic;

View file

@ -26,12 +26,12 @@ private:
virtual void initialize(JS::Realm&) override;
// ^DOM::Element
virtual void attribute_changed(FlyString const& name, DeprecatedString const& value) override;
virtual void attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value) override;
virtual i32 default_tab_index_value() const override;
// ^HTML::HTMLHyperlinkElementUtils
virtual DOM::Document& hyperlink_element_utils_document() override { return document(); }
virtual DeprecatedString hyperlink_element_utils_href() const override;
virtual Optional<String> hyperlink_element_utils_href() const override;
virtual WebIDL::ExceptionOr<void> set_hyperlink_element_utils_href(String) override;
virtual bool hyperlink_element_utils_is_html_anchor_element() const override { return false; }
virtual bool hyperlink_element_utils_is_connected() const override { return is_connected(); }

View file

@ -43,7 +43,7 @@ void HTMLBaseElement::removed_from(Node* parent)
document().update_base_element({});
}
void HTMLBaseElement::attribute_changed(FlyString const& name, DeprecatedString const& value)
void HTMLBaseElement::attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value)
{
HTMLElement::attribute_changed(name, value);

View file

@ -23,7 +23,7 @@ public:
virtual void inserted() override;
virtual void removed_from(Node*) override;
virtual void attribute_changed(FlyString const& name, DeprecatedString const& value) override;
virtual void attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value) override;
private:
HTMLBaseElement(DOM::Document&, DOM::QualifiedName);

View file

@ -55,26 +55,26 @@ void HTMLBodyElement::apply_presentational_hints(CSS::StyleProperties& style) co
});
}
void HTMLBodyElement::attribute_changed(FlyString const& name, DeprecatedString const& value)
void HTMLBodyElement::attribute_changed(FlyString const& name, Optional<DeprecatedString> const& value)
{
HTMLElement::attribute_changed(name, value);
if (name.equals_ignoring_ascii_case("link"sv)) {
// https://html.spec.whatwg.org/multipage/rendering.html#the-page:rules-for-parsing-a-legacy-colour-value-3
auto color = parse_legacy_color_value(value);
auto color = parse_legacy_color_value(value.value_or(""));
if (color.has_value())
document().set_link_color(color.value());
} else if (name.equals_ignoring_ascii_case("alink"sv)) {
// https://html.spec.whatwg.org/multipage/rendering.html#the-page:rules-for-parsing-a-legacy-colour-value-5
auto color = parse_legacy_color_value(value);
auto color = parse_legacy_color_value(value.value_or(""));
if (color.has_value())
document().set_active_link_color(color.value());
} else if (name.equals_ignoring_ascii_case("vlink"sv)) {
// https://html.spec.whatwg.org/multipage/rendering.html#the-page:rules-for-parsing-a-legacy-colour-value-4
auto color = parse_legacy_color_value(value);
auto color = parse_legacy_color_value(value.value_or(""));
if (color.has_value())
document().set_visited_link_color(color.value());
} else if (name.equals_ignoring_ascii_case("background"sv)) {
m_background_style_value = CSS::ImageStyleValue::create(document().parse_url(value));
m_background_style_value = CSS::ImageStyleValue::create(document().parse_url(value.value_or("")));
m_background_style_value->on_animate = [this] {
if (layout_node()) {
layout_node()->set_needs_display();
@ -83,9 +83,9 @@ void HTMLBodyElement::attribute_changed(FlyString const& name, DeprecatedString
}
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
if (name == HTML::AttributeNames::attribute_name) { \
element_event_handler_attribute_changed(event_name, String::from_deprecated_string(value).release_value()); \
#define __ENUMERATE(attribute_name, event_name) \
if (name == HTML::AttributeNames::attribute_name) { \
element_event_handler_attribute_changed(event_name, value.map([](auto& v) { return MUST(String::from_deprecated_string(v)); })); \
}
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE

View file

@ -20,7 +20,7 @@ class HTMLBodyElement final
public:
virtual ~HTMLBodyElement() override;
virtual void attribute_changed(FlyString const&, DeprecatedString const&) override;
virtual void attribute_changed(FlyString const&, Optional<DeprecatedString> const&) override;
virtual void apply_presentational_hints(CSS::StyleProperties&) const override;
// https://www.w3.org/TR/html-aria/#el-body

Some files were not shown because too many files have changed in this diff Show more