mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
Compare commits
29 commits
a7231f874a
...
fb8479b513
Author | SHA1 | Date | |
---|---|---|---|
|
fb8479b513 | ||
|
001df24935 | ||
|
b60cb699a9 | ||
|
8d13115d9a | ||
|
cd14b215d1 | ||
|
35764db0b7 | ||
|
caf7983039 | ||
|
cdb54fe504 | ||
|
7f989765f5 | ||
|
41c172c663 | ||
|
ac5699c8fc | ||
|
ce26e5d757 | ||
|
3a2cc1aa20 | ||
|
0448d4d609 | ||
|
a1687854ab | ||
|
d1120e1809 | ||
|
248e4bb517 | ||
|
b4ba65c6e5 | ||
|
009f328308 | ||
|
d55caff227 | ||
|
570c5f8df2 | ||
|
4c1d4aa678 | ||
|
5f42f1318a | ||
|
98183c7164 | ||
|
0a3193f0b6 | ||
|
164dd05467 | ||
|
0269bdbe60 | ||
|
2b316d16ce | ||
|
ce3ce607ae |
143 changed files with 4104 additions and 410 deletions
|
@ -8,5 +8,6 @@ Libraries/LibJS/Tests/modules/top-level-dispose.mjs
|
|||
Libraries/LibJS/Tests/using-declaration.js
|
||||
Libraries/LibJS/Tests/using-for-loops.js
|
||||
|
||||
Tests/LibWeb/Ref/data
|
||||
Tests/LibWeb/Ref/input/wpt-import
|
||||
Tests/LibWeb/Text/input/wpt-import
|
||||
|
|
|
@ -35,5 +35,5 @@ you are welcome to ask on [Discord](../README.md#get-in-touch-and-participate).
|
|||
* [LibWeb: From Loading to Painting](LibWebFromLoadingToPainting.md)
|
||||
* [LibWeb: Browsing Contexts and Navigables](BrowsingContextsAndNavigables.md)
|
||||
* [How to Add an IDL File](AddNewIDLFile.md)
|
||||
* [LibWeb Code Style & Patterns](Browser/Patterns.md)
|
||||
* [LibWeb Code Style & Patterns](LibWebPatterns.md)
|
||||
* [CSS Generated Files](CSSGeneratedFiles.md)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||
|
||||
namespace Crypto::ASN1 {
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/BitmapView.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibCrypto/ASN1/ASN1.h>
|
||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/Span.h>
|
||||
#include <LibCrypto/ASN1/ASN1.h>
|
||||
#include <LibCrypto/ASN1/DER.h>
|
||||
|
||||
namespace Crypto {
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <AK/ByteString.h>
|
||||
#include <AK/Endian.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibCrypto/Hash/HashFunction.h>
|
||||
|
||||
namespace Crypto::Authentication {
|
||||
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
*/
|
||||
|
||||
#include "UnsignedBigIntegerAlgorithms.h"
|
||||
#include <AK/BigIntBase.h>
|
||||
#include <AK/BuiltinWrappers.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||
|
||||
namespace Crypto {
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include "UnsignedBigIntegerAlgorithms.h"
|
||||
#include <AK/BigIntBase.h>
|
||||
#include <AK/BuiltinWrappers.h>
|
||||
|
||||
namespace Crypto {
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||
|
||||
namespace Crypto {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/BigIntBase.h>
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/Span.h>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibCrypto/Checksum/CRC32.h>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCrypto/Cipher/Cipher.h>
|
||||
#include <LibCrypto/Cipher/Mode/CBC.h>
|
||||
#include <LibCrypto/Cipher/Mode/CTR.h>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/Span.h>
|
||||
|
||||
namespace Crypto::Cipher {
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Random.h>
|
||||
|
||||
namespace Crypto::Curves {
|
||||
|
||||
class Curve25519 {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <LibCrypto/Curves/EllipticCurve.h>
|
||||
|
||||
namespace Crypto::Curves {
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <AK/ByteReader.h>
|
||||
#include <AK/Endian.h>
|
||||
#include <AK/Random.h>
|
||||
#include <LibCrypto/Curves/Curve25519.h>
|
||||
#include <LibCrypto/Curves/X25519.h>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/Random.h>
|
||||
#include <LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h>
|
||||
#include <LibCrypto/NumberTheory/ModularFunctions.h>
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Random.h>
|
||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||
|
||||
namespace Crypto::NumberTheory {
|
||||
|
|
|
@ -7,12 +7,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Base64.h>
|
||||
#include <AK/MaybeOwned.h>
|
||||
#include <AK/IPv4Address.h>
|
||||
#include <AK/IPv6Address.h>
|
||||
#include <AK/RedBlackTree.h>
|
||||
#include <AK/Time.h>
|
||||
#include <LibCore/Promise.h>
|
||||
#include <LibCore/SocketAddress.h>
|
||||
#include <LibURL/URL.h>
|
||||
|
||||
namespace DNS {
|
||||
namespace Messages {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/AtomicRefCounted.h>
|
||||
#include <AK/HashTable.h>
|
||||
#include <AK/MaybeOwned.h>
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <AK/Random.h>
|
||||
#include <AK/StringView.h>
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
# include <sys/disk.h>
|
||||
#elif defined(AK_OS_LINUX)
|
||||
# include <linux/fs.h>
|
||||
#elif defined(AK_OS_WINDOWS)
|
||||
# include <dirent.h>
|
||||
#endif
|
||||
|
||||
// On Linux distros that use glibc `basename` is defined as a macro that expands to `__xpg_basename`, so we undefine it
|
||||
|
|
|
@ -16,6 +16,7 @@ set(SOURCES
|
|||
Font/Font.cpp
|
||||
Font/FontData.cpp
|
||||
Font/FontDatabase.cpp
|
||||
Font/FontVariant.cpp
|
||||
Font/PathFontProvider.cpp
|
||||
Font/ScaledFont.cpp
|
||||
Font/ScaledFontSkia.cpp
|
||||
|
|
|
@ -400,7 +400,8 @@ public:
|
|||
|
||||
constexpr Color with_opacity(float opacity) const
|
||||
{
|
||||
return with_alpha(alpha() * opacity);
|
||||
VERIFY(opacity >= 0 && opacity <= 1);
|
||||
return with_alpha(static_cast<u8>(round(alpha() * opacity)));
|
||||
}
|
||||
|
||||
constexpr Color darkened(float amount = 0.5f) const
|
||||
|
@ -549,9 +550,9 @@ public:
|
|||
break;
|
||||
}
|
||||
|
||||
u8 out_r = (u8)(r * 255);
|
||||
u8 out_g = (u8)(g * 255);
|
||||
u8 out_b = (u8)(b * 255);
|
||||
auto out_r = static_cast<u8>(round(r * 255));
|
||||
auto out_g = static_cast<u8>(round(g * 255));
|
||||
auto out_b = static_cast<u8>(round(b * 255));
|
||||
return Color(out_r, out_g, out_b);
|
||||
}
|
||||
|
||||
|
|
176
Libraries/LibGfx/Font/FontVariant.cpp
Normal file
176
Libraries/LibGfx/Font/FontVariant.cpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Johan Dahlin <jdahlin@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibGfx/Font/FontVariant.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
StringView font_variant_alternates_to_string(FontVariantAlternates value)
|
||||
{
|
||||
if (value.normal && value.historical_forms)
|
||||
return "normal historical-forms"sv;
|
||||
if (value.normal)
|
||||
return "normal"sv;
|
||||
if (value.historical_forms)
|
||||
return "historical-forms"sv;
|
||||
return {};
|
||||
}
|
||||
|
||||
StringView font_variant_ligatures_to_string(FontVariantLigatures ligatures)
|
||||
{
|
||||
if (ligatures.normal)
|
||||
return "normal"sv;
|
||||
if (ligatures.none)
|
||||
return "none"sv;
|
||||
|
||||
Vector<StringView> values;
|
||||
switch (ligatures.common) {
|
||||
case FontVariantLigatures::Common::Common:
|
||||
values.append("common-ligatures"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Common::NoCommon:
|
||||
values.append("no-common-ligatures"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Common::Unset:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ligatures.discretionary) {
|
||||
case FontVariantLigatures::Discretionary::Discretionary:
|
||||
values.append("discretionary-ligatures"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Discretionary::NoDiscretionary:
|
||||
values.append("no-discretionary-ligatures"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Discretionary::Unset:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ligatures.historical) {
|
||||
case FontVariantLigatures::Historical::Historical:
|
||||
values.append("historical-ligatures"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Historical::NoHistorical:
|
||||
values.append("no-historical-ligatures"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Historical::Unset:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ligatures.contextual) {
|
||||
case FontVariantLigatures::Contextual::Contextual:
|
||||
values.append("contextual"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Contextual::NoContextual:
|
||||
values.append("no-contextual"sv);
|
||||
break;
|
||||
case FontVariantLigatures::Contextual::Unset:
|
||||
break;
|
||||
}
|
||||
|
||||
StringBuilder builder;
|
||||
builder.join(' ', values);
|
||||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
StringView font_variant_east_asian_to_string(FontVariantEastAsian value)
|
||||
{
|
||||
Vector<StringView> values;
|
||||
|
||||
switch (value.variant) {
|
||||
case FontVariantEastAsian::Variant::Unset:
|
||||
break;
|
||||
case FontVariantEastAsian::Variant::Jis78:
|
||||
values.append("jis78"sv);
|
||||
break;
|
||||
case FontVariantEastAsian::Variant::Jis83:
|
||||
values.append("jis83"sv);
|
||||
break;
|
||||
case FontVariantEastAsian::Variant::Jis90:
|
||||
values.append("jis90"sv);
|
||||
break;
|
||||
case FontVariantEastAsian::Variant::Jis04:
|
||||
values.append("jis04"sv);
|
||||
break;
|
||||
case FontVariantEastAsian::Variant::Simplified:
|
||||
values.append("simplified"sv);
|
||||
break;
|
||||
case FontVariantEastAsian::Variant::Traditional:
|
||||
values.append("traditional"sv);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (value.width) {
|
||||
case FontVariantEastAsian::Width::Unset:
|
||||
break;
|
||||
case FontVariantEastAsian::Width::FullWidth:
|
||||
values.append("full-width"sv);
|
||||
break;
|
||||
case FontVariantEastAsian::Width::Proportional:
|
||||
values.append("proportional-width"sv);
|
||||
break;
|
||||
}
|
||||
|
||||
if (value.ruby)
|
||||
values.append("ruby"sv);
|
||||
|
||||
StringBuilder builder;
|
||||
builder.join(' ', values);
|
||||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
StringView font_variant_numeric_to_string(FontVariantNumeric value)
|
||||
{
|
||||
Vector<StringView> values;
|
||||
|
||||
if (value.normal)
|
||||
values.append("normal"sv);
|
||||
if (value.ordinal)
|
||||
values.append("ordinal"sv);
|
||||
if (value.slashed_zero)
|
||||
values.append("slashed-zero"sv);
|
||||
|
||||
switch (value.figure) {
|
||||
case FontVariantNumeric::Figure::Unset:
|
||||
break;
|
||||
case FontVariantNumeric::Figure::Lining:
|
||||
values.append("lining-nums"sv);
|
||||
break;
|
||||
case FontVariantNumeric::Figure::Oldstyle:
|
||||
values.append("oldstyle-nums"sv);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (value.spacing) {
|
||||
case FontVariantNumeric::Spacing::Unset:
|
||||
break;
|
||||
case FontVariantNumeric::Spacing::Proportional:
|
||||
values.append("proportional-nums"sv);
|
||||
break;
|
||||
case FontVariantNumeric::Spacing::Tabular:
|
||||
values.append("tabular-nums"sv);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (value.fraction) {
|
||||
case FontVariantNumeric::Fraction::Unset:
|
||||
break;
|
||||
case FontVariantNumeric::Fraction::Diagonal:
|
||||
values.append("diagonal-fractions"sv);
|
||||
break;
|
||||
case FontVariantNumeric::Fraction::Stacked:
|
||||
values.append("stacked-fractions"sv);
|
||||
break;
|
||||
}
|
||||
|
||||
StringBuilder builder;
|
||||
builder.join(' ', values);
|
||||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
}
|
90
Libraries/LibGfx/Font/FontVariant.h
Normal file
90
Libraries/LibGfx/Font/FontVariant.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
using FontFeatureName = StringView;
|
||||
|
||||
class FontVariantAlternates {
|
||||
public:
|
||||
bool normal { false };
|
||||
bool historical_forms { false };
|
||||
};
|
||||
|
||||
class FontVariantEastAsian {
|
||||
public:
|
||||
enum class Variant { Unset,
|
||||
Jis78,
|
||||
Jis83,
|
||||
Jis90,
|
||||
Jis04,
|
||||
Simplified,
|
||||
Traditional };
|
||||
enum class Width { Unset,
|
||||
Proportional,
|
||||
FullWidth };
|
||||
|
||||
bool normal = false;
|
||||
bool ruby = false;
|
||||
Variant variant { Variant::Unset };
|
||||
Width width { Width::Unset };
|
||||
};
|
||||
|
||||
class FontVariantLigatures {
|
||||
public:
|
||||
enum class Common { Unset,
|
||||
Common,
|
||||
NoCommon };
|
||||
enum class Discretionary { Unset,
|
||||
Discretionary,
|
||||
NoDiscretionary };
|
||||
enum class Historical { Unset,
|
||||
Historical,
|
||||
NoHistorical };
|
||||
enum class Contextual { Unset,
|
||||
Contextual,
|
||||
NoContextual };
|
||||
|
||||
bool normal = false;
|
||||
bool none = false;
|
||||
Common common { Common::Unset };
|
||||
Discretionary discretionary { Discretionary::Unset };
|
||||
Historical historical { Historical::Unset };
|
||||
Contextual contextual { Contextual::Unset };
|
||||
};
|
||||
|
||||
class FontVariantNumeric {
|
||||
public:
|
||||
enum class Figure { Unset,
|
||||
Lining,
|
||||
Oldstyle };
|
||||
enum class Spacing { Unset,
|
||||
Proportional,
|
||||
Tabular };
|
||||
enum class Fraction { Unset,
|
||||
Diagonal,
|
||||
Stacked };
|
||||
|
||||
bool normal = false;
|
||||
bool ordinal = false;
|
||||
bool slashed_zero = false;
|
||||
Figure figure { Figure::Unset };
|
||||
Spacing spacing { Spacing::Unset };
|
||||
Fraction fraction { Fraction::Unset };
|
||||
};
|
||||
|
||||
extern StringView font_variant_alternates_to_string(FontVariantAlternates);
|
||||
extern StringView font_variant_east_asian_to_string(FontVariantEastAsian);
|
||||
extern StringView font_variant_ligatures_to_string(FontVariantLigatures);
|
||||
extern StringView font_variant_numeric_to_string(FontVariantNumeric);
|
||||
|
||||
}
|
|
@ -58,13 +58,13 @@ ScaledFontMetrics ScaledFont::metrics() const
|
|||
return metrics;
|
||||
}
|
||||
|
||||
float ScaledFont::width(StringView view) const { return measure_text_width(Utf8View(view), *this); }
|
||||
float ScaledFont::width(Utf8View const& view) const { return measure_text_width(view, *this); }
|
||||
float ScaledFont::width(StringView view) const { return measure_text_width(Utf8View(view), *this, {}); }
|
||||
float ScaledFont::width(Utf8View const& view) const { return measure_text_width(view, *this, {}); }
|
||||
|
||||
float ScaledFont::glyph_width(u32 code_point) const
|
||||
{
|
||||
auto string = String::from_code_point(code_point);
|
||||
return measure_text_width(Utf8View(string), *this);
|
||||
return measure_text_width(Utf8View(string), *this, {});
|
||||
}
|
||||
|
||||
NonnullRefPtr<ScaledFont> ScaledFont::scaled_with_size(float point_size) const
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
#include <initializer_list>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace Gfx {
|
||||
|
||||
RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType text_type)
|
||||
RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType text_type, ShapeFeatures const& features)
|
||||
{
|
||||
hb_buffer_t* buffer = hb_buffer_create();
|
||||
ScopeGuard destroy_buffer = [&]() { hb_buffer_destroy(buffer); };
|
||||
|
@ -24,7 +24,22 @@ RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf
|
|||
Vector<hb_glyph_info_t> const input_glyph_info({ glyph_info, glyph_count });
|
||||
|
||||
auto* hb_font = font.harfbuzz_font();
|
||||
hb_shape(hb_font, buffer, nullptr, 0);
|
||||
const hb_feature_t* hb_features_data = nullptr;
|
||||
Vector<hb_feature_t> hb_features;
|
||||
if (!features.is_empty()) {
|
||||
hb_features.ensure_capacity(features.size());
|
||||
for (auto const& feature : features) {
|
||||
hb_features.append({
|
||||
.tag = HB_TAG(feature.tag[0], feature.tag[1], feature.tag[2], feature.tag[3]),
|
||||
.value = feature.value,
|
||||
.start = 0,
|
||||
.end = static_cast<unsigned int>(-1),
|
||||
});
|
||||
}
|
||||
hb_features_data = hb_features.data();
|
||||
}
|
||||
|
||||
hb_shape(hb_font, buffer, hb_features_data, features.size());
|
||||
|
||||
glyph_info = hb_buffer_get_glyph_infos(buffer, &glyph_count);
|
||||
auto* positions = hb_buffer_get_glyph_positions(buffer, &glyph_count);
|
||||
|
@ -45,12 +60,14 @@ RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf
|
|||
point.translate_by(letter_spacing, 0);
|
||||
}
|
||||
|
||||
hb_buffer_reset(buffer);
|
||||
|
||||
return adopt_ref(*new Gfx::GlyphRun(move(glyph_run), font, text_type, point.x()));
|
||||
}
|
||||
|
||||
float measure_text_width(Utf8View const& string, Gfx::Font const& font)
|
||||
float measure_text_width(Utf8View const& string, Gfx::Font const& font, ShapeFeatures const& features)
|
||||
{
|
||||
auto glyph_run = shape_text({}, 0, string, font, GlyphRun::TextType::Common);
|
||||
auto glyph_run = shape_text({}, 0, string, font, GlyphRun::TextType::Common, features);
|
||||
return glyph_run->width();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,13 @@ struct DrawGlyph {
|
|||
}
|
||||
};
|
||||
|
||||
typedef struct ShapeFeature {
|
||||
char tag[4];
|
||||
u32 value;
|
||||
} ShapeFeature;
|
||||
|
||||
using ShapeFeatures = Vector<ShapeFeature, 4>;
|
||||
|
||||
class GlyphRun : public RefCounted<GlyphRun> {
|
||||
public:
|
||||
enum class TextType {
|
||||
|
@ -60,7 +67,7 @@ private:
|
|||
float m_width { 0 };
|
||||
};
|
||||
|
||||
RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType);
|
||||
float measure_text_width(Utf8View const& string, Gfx::Font const& font);
|
||||
RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType, ShapeFeatures const& features);
|
||||
float measure_text_width(Utf8View const& string, Gfx::Font const& font, ShapeFeatures const& features);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <AK/Base64.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibHTTP/HttpRequest.h>
|
||||
#include <LibURL/Parser.h>
|
||||
|
||||
namespace HTTP {
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <AK/ByteString.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibHTTP/HeaderMap.h>
|
||||
#include <LibURL/URL.h>
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <LibCore/NetworkResponse.h>
|
||||
#include <LibHTTP/HeaderMap.h>
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include "FFmpegLoader.h"
|
||||
#include <AK/BitStream.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <LibCore/System.h>
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
}
|
||||
|
||||
namespace Audio {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "PlaybackStream.h"
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <LibCore/ThreadedPromise.h>
|
||||
|
||||
#if defined(HAVE_PULSEAUDIO)
|
||||
# include "PlaybackStreamPulseAudio.h"
|
||||
|
|
|
@ -9,12 +9,9 @@
|
|||
#include "SampleFormats.h"
|
||||
#include <AK/AtomicRefCounted.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Queue.h>
|
||||
#include <AK/Time.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibThreading/ConditionVariable.h>
|
||||
#include <LibThreading/MutexProtected.h>
|
||||
#include <LibThreading/Thread.h>
|
||||
#include <LibCore/ThreadedPromise.h>
|
||||
|
||||
namespace Audio {
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
|
||||
#include "PlaybackStream.h"
|
||||
#include "PulseAudioWrappers.h"
|
||||
#include <AK/Queue.h>
|
||||
#include <LibThreading/ConditionVariable.h>
|
||||
#include <LibThreading/Mutex.h>
|
||||
|
||||
namespace Audio {
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "Forward.h"
|
||||
#include "PlaybackStream.h"
|
||||
#include "SampleFormats.h"
|
||||
#include <AK/AtomicRefCounted.h>
|
||||
#include <AK/Error.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include "SampleFormats.h"
|
||||
#include <AK/Assertions.h>
|
||||
|
||||
namespace Audio {
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace Audio {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Math.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <LibGfx/Matrix.h>
|
||||
#include <LibGfx/Matrix3x3.h>
|
||||
#include <LibGfx/Matrix4x4.h>
|
||||
#include <LibMedia/Color/ColorPrimaries.h>
|
||||
#include <LibMedia/Color/TransferCharacteristics.h>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/IntegralMath.h>
|
||||
#include <AK/Math.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Time.h>
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/IntegralMath.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <LibCore/MappedFile.h>
|
||||
#include <LibMedia/DecoderError.h>
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <AK/Time.h>
|
||||
#include <LibCore/SharedCircularQueue.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibMedia/Containers/Matroska/Document.h>
|
||||
#include <LibMedia/Demuxer.h>
|
||||
#include <LibThreading/ConditionVariable.h>
|
||||
#include <LibThreading/Mutex.h>
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/FixedArray.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <LibMedia/Color/ColorConverter.h>
|
||||
|
||||
#include "VideoFrame.h"
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/FixedArray.h>
|
||||
#include <AK/Time.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/Size.h>
|
||||
|
|
|
@ -8,15 +8,11 @@
|
|||
|
||||
#include "RegexBytecodeStreamOptimizer.h"
|
||||
#include "RegexMatch.h"
|
||||
#include "RegexOptions.h"
|
||||
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/DisjointChunks.h>
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Traits.h>
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <AK/Assertions.h>
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/Format.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace regex {
|
||||
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/GenericLexer.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Utf32View.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <AK/StringBuilder.h>
|
||||
#include <AK/StringUtils.h>
|
||||
#include <AK/TemporaryChange.h>
|
||||
#include <AK/Utf16View.h>
|
||||
#include <LibUnicode/CharacterTypes.h>
|
||||
|
||||
namespace regex {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "RegexOptions.h"
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibUnicode/Forward.h>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <AK/Debug.h>
|
||||
#include <AK/Endian.h>
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <AK/Random.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibTLS/TLSv12.h>
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
#include <AK/Function.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/HashTable.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/StackInfo.h>
|
||||
#include <AK/UFixedBigInt.h>
|
||||
#include <LibWasm/Types.h>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <AK/HashTable.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/SourceLocation.h>
|
||||
#include <AK/TemporaryChange.h>
|
||||
#include <AK/Try.h>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <AK/Endian.h>
|
||||
#include <AK/LEB128.h>
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/ScopeLogger.h>
|
||||
#include <AK/UFixedBigInt.h>
|
||||
#include <LibWasm/Types.h>
|
||||
|
|
|
@ -8,13 +8,10 @@
|
|||
#include <AK/Debug.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Random.h>
|
||||
#include <AK/SourceLocation.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/Tuple.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibWasm/AbstractMachine/Interpreter.h>
|
||||
#include <LibWasm/Printer/Printer.h>
|
||||
#include <LibWasm/AbstractMachine/Configuration.h>
|
||||
#include <LibWasm/Wasi.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
|
|
@ -102,8 +102,13 @@ Optional<StyleProperty> PropertyOwningCSSStyleDeclaration::property(PropertyID p
|
|||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-setproperty
|
||||
WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(PropertyID property_id, StringView value, StringView priority)
|
||||
WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(StringView property_name, StringView value, StringView priority)
|
||||
{
|
||||
auto maybe_property_id = property_id_from_string(property_name);
|
||||
if (!maybe_property_id.has_value())
|
||||
return {};
|
||||
auto property_id = maybe_property_id.value();
|
||||
|
||||
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
|
||||
// NOTE: This is handled by the virtual override in ResolvedCSSStyleDeclaration.
|
||||
|
||||
|
@ -114,7 +119,7 @@ WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(Proper
|
|||
|
||||
// 3. If value is the empty string, invoke removeProperty() with property as argument and return.
|
||||
if (value.is_empty()) {
|
||||
MUST(remove_property(property_id));
|
||||
MUST(remove_property(property_name));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -146,10 +151,22 @@ WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(Proper
|
|||
}
|
||||
// 9. Otherwise,
|
||||
else {
|
||||
// let updated be the result of set the CSS declaration property with value component value list,
|
||||
// with the important flag set if priority is not the empty string, and unset otherwise,
|
||||
// and with the list of declarations being the declarations.
|
||||
updated = set_a_css_declaration(property_id, *component_value_list, !priority.is_empty() ? Important::Yes : Important::No);
|
||||
if (property_id == PropertyID::Custom) {
|
||||
auto custom_name = FlyString::from_utf8_without_validation(property_name.bytes());
|
||||
StyleProperty style_property {
|
||||
.important = !priority.is_empty() ? Important::Yes : Important::No,
|
||||
.property_id = property_id,
|
||||
.value = component_value_list.release_nonnull(),
|
||||
.custom_name = custom_name,
|
||||
};
|
||||
m_custom_properties.set(custom_name, style_property);
|
||||
updated = true;
|
||||
} else {
|
||||
// let updated be the result of set the CSS declaration property with value component value list,
|
||||
// with the important flag set if priority is not the empty string, and unset otherwise,
|
||||
// and with the list of declarations being the declarations.
|
||||
updated = set_a_css_declaration(property_id, *component_value_list, !priority.is_empty() ? Important::Yes : Important::No);
|
||||
}
|
||||
}
|
||||
|
||||
// 10. If updated is true, update style attribute for the CSS declaration block.
|
||||
|
@ -160,8 +177,12 @@ WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(Proper
|
|||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty
|
||||
WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(PropertyID property_id)
|
||||
WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(StringView property_name)
|
||||
{
|
||||
auto property_id = property_id_from_string(property_name);
|
||||
if (!property_id.has_value())
|
||||
return String {};
|
||||
|
||||
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
|
||||
// NOTE: This is handled by the virtual override in ResolvedCSSStyleDeclaration.
|
||||
|
||||
|
@ -169,8 +190,7 @@ WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(P
|
|||
// NOTE: We've already converted it to a PropertyID enum value.
|
||||
|
||||
// 3. Let value be the return value of invoking getPropertyValue() with property as argument.
|
||||
// FIXME: The trip through string_from_property_id() here is silly.
|
||||
auto value = get_property_value(string_from_property_id(property_id));
|
||||
auto value = get_property_value(property_name);
|
||||
|
||||
// 4. Let removed be false.
|
||||
bool removed = false;
|
||||
|
@ -180,7 +200,12 @@ WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(P
|
|||
// 2. Remove that CSS declaration and let removed be true.
|
||||
|
||||
// 6. Otherwise, if property is a case-sensitive match for a property name of a CSS declaration in the declarations, remove that CSS declaration and let removed be true.
|
||||
removed = m_properties.remove_first_matching([&](auto& entry) { return entry.property_id == property_id; });
|
||||
if (property_id == PropertyID::Custom) {
|
||||
auto custom_name = FlyString::from_utf8_without_validation(property_name.bytes());
|
||||
removed = m_custom_properties.remove(custom_name);
|
||||
} else {
|
||||
removed = m_properties.remove_first_matching([&](auto& entry) { return entry.property_id == property_id; });
|
||||
}
|
||||
|
||||
// 7. If removed is true, Update style attribute for the CSS declaration block.
|
||||
if (removed)
|
||||
|
@ -241,6 +266,14 @@ String CSSStyleDeclaration::get_property_value(StringView property_name) const
|
|||
if (!property_id.has_value())
|
||||
return {};
|
||||
|
||||
if (property_id.value() == PropertyID::Custom) {
|
||||
auto maybe_custom_property = custom_property(FlyString::from_utf8_without_validation(property_name.bytes()));
|
||||
if (maybe_custom_property.has_value()) {
|
||||
return maybe_custom_property.value().value->to_string();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
// 2. If property is a shorthand property, then follow these substeps:
|
||||
if (property_is_shorthand(property_id.value())) {
|
||||
// 1. Let list be a new empty array.
|
||||
|
@ -285,26 +318,26 @@ StringView CSSStyleDeclaration::get_property_priority(StringView property_name)
|
|||
auto property_id = property_id_from_string(property_name);
|
||||
if (!property_id.has_value())
|
||||
return {};
|
||||
if (property_id.value() == PropertyID::Custom) {
|
||||
auto maybe_custom_property = custom_property(FlyString::from_utf8_without_validation(property_name.bytes()));
|
||||
if (!maybe_custom_property.has_value())
|
||||
return {};
|
||||
return maybe_custom_property.value().important == Important::Yes ? "important"sv : ""sv;
|
||||
}
|
||||
auto maybe_property = property(property_id.value());
|
||||
if (!maybe_property.has_value())
|
||||
return {};
|
||||
return maybe_property->important == Important::Yes ? "important"sv : ""sv;
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> CSSStyleDeclaration::set_property(StringView property_name, StringView css_text, StringView priority)
|
||||
WebIDL::ExceptionOr<void> CSSStyleDeclaration::set_property(PropertyID property_id, StringView css_text, StringView priority)
|
||||
{
|
||||
auto property_id = property_id_from_string(property_name);
|
||||
if (!property_id.has_value())
|
||||
return {};
|
||||
return set_property(property_id.value(), css_text, priority);
|
||||
return set_property(string_from_property_id(property_id), css_text, priority);
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<String> CSSStyleDeclaration::remove_property(StringView property_name)
|
||||
WebIDL::ExceptionOr<String> CSSStyleDeclaration::remove_property(PropertyID property_name)
|
||||
{
|
||||
auto property_id = property_id_from_string(property_name);
|
||||
if (!property_id.has_value())
|
||||
return String {};
|
||||
return remove_property(property_id.value());
|
||||
return remove_property(string_from_property_id(property_name));
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
|
||||
|
|
|
@ -29,12 +29,13 @@ public:
|
|||
virtual String item(size_t index) const = 0;
|
||||
|
||||
virtual Optional<StyleProperty> property(PropertyID) const = 0;
|
||||
virtual Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const = 0;
|
||||
|
||||
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority = ""sv) = 0;
|
||||
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID) = 0;
|
||||
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority = ""sv);
|
||||
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID);
|
||||
|
||||
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority);
|
||||
virtual WebIDL::ExceptionOr<String> remove_property(StringView property_name);
|
||||
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority) = 0;
|
||||
virtual WebIDL::ExceptionOr<String> remove_property(StringView property_name) = 0;
|
||||
|
||||
String get_property_value(StringView property) const;
|
||||
StringView get_property_priority(StringView property) const;
|
||||
|
@ -75,13 +76,13 @@ public:
|
|||
virtual String item(size_t index) const override;
|
||||
|
||||
virtual Optional<StyleProperty> property(PropertyID) const override;
|
||||
virtual Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const override { return m_custom_properties.get(custom_property_name); }
|
||||
|
||||
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority) override;
|
||||
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID) override;
|
||||
|
||||
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority) override;
|
||||
virtual WebIDL::ExceptionOr<String> remove_property(StringView property_name) override;
|
||||
Vector<StyleProperty> const& properties() const { return m_properties; }
|
||||
HashMap<FlyString, StyleProperty> const& custom_properties() const { return m_custom_properties; }
|
||||
Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const { return m_custom_properties.get(custom_property_name); }
|
||||
|
||||
size_t custom_property_count() const { return m_custom_properties.size(); }
|
||||
|
||||
virtual String serialized() const final override;
|
||||
|
|
|
@ -481,4 +481,165 @@ int CSSStyleValue::to_font_width() const
|
|||
return width;
|
||||
}
|
||||
|
||||
Gfx::FontVariantAlternates CSSStyleValue::to_font_variant_alternates() const
|
||||
{
|
||||
VERIFY(is_keyword());
|
||||
switch (as_keyword().keyword()) {
|
||||
case Keyword::Normal:
|
||||
return Gfx::FontVariantAlternates { .normal = true };
|
||||
case Keyword::HistoricalForms:
|
||||
return Gfx::FontVariantAlternates { .historical_forms = true };
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
Optional<FontVariantCaps> CSSStyleValue::to_font_variant_caps() const
|
||||
{
|
||||
VERIFY(is_keyword());
|
||||
return keyword_to_font_variant_caps(as_keyword().keyword());
|
||||
}
|
||||
|
||||
Gfx::FontVariantEastAsian CSSStyleValue::to_font_variant_east_asian() const
|
||||
{
|
||||
VERIFY(is_value_list());
|
||||
auto& list = as_value_list();
|
||||
Gfx::FontVariantEastAsian east_asian {};
|
||||
for (auto& value : list.values()) {
|
||||
VERIFY(value->is_keyword());
|
||||
switch (value->as_keyword().keyword()) {
|
||||
case Keyword::Normal:
|
||||
east_asian.normal = true;
|
||||
return east_asian;
|
||||
case Keyword::Jis78:
|
||||
east_asian.variant = Gfx::FontVariantEastAsian::Variant::Jis78;
|
||||
break;
|
||||
case Keyword::Jis83:
|
||||
east_asian.variant = Gfx::FontVariantEastAsian::Variant::Jis83;
|
||||
break;
|
||||
case Keyword::Jis90:
|
||||
east_asian.variant = Gfx::FontVariantEastAsian::Variant::Jis90;
|
||||
break;
|
||||
case Keyword::Jis04:
|
||||
east_asian.variant = Gfx::FontVariantEastAsian::Variant::Jis04;
|
||||
break;
|
||||
case Keyword::Simplified:
|
||||
east_asian.variant = Gfx::FontVariantEastAsian::Variant::Simplified;
|
||||
break;
|
||||
case Keyword::Traditional:
|
||||
east_asian.variant = Gfx::FontVariantEastAsian::Variant::Traditional;
|
||||
break;
|
||||
case Keyword::FullWidth:
|
||||
east_asian.width = Gfx::FontVariantEastAsian::Width::FullWidth;
|
||||
break;
|
||||
case Keyword::ProportionalWidth:
|
||||
east_asian.width = Gfx::FontVariantEastAsian::Width::Proportional;
|
||||
break;
|
||||
case Keyword::Ruby:
|
||||
east_asian.ruby = true;
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return east_asian;
|
||||
}
|
||||
|
||||
Gfx::FontVariantLigatures CSSStyleValue::to_font_variant_ligatures() const
|
||||
{
|
||||
VERIFY(is_value_list());
|
||||
auto& list = as_value_list();
|
||||
Gfx::FontVariantLigatures ligatures;
|
||||
|
||||
for (auto& value : list.values()) {
|
||||
VERIFY(value->is_keyword());
|
||||
switch (value->as_keyword().keyword()) {
|
||||
case Keyword::Normal:
|
||||
ligatures.normal = true;
|
||||
return ligatures;
|
||||
case Keyword::None:
|
||||
ligatures.none = true;
|
||||
return ligatures;
|
||||
case Keyword::CommonLigatures:
|
||||
ligatures.common = Gfx::FontVariantLigatures::Common::Common;
|
||||
break;
|
||||
case Keyword::NoCommonLigatures:
|
||||
ligatures.common = Gfx::FontVariantLigatures::Common::NoCommon;
|
||||
break;
|
||||
case Keyword::DiscretionaryLigatures:
|
||||
ligatures.discretionary = Gfx::FontVariantLigatures::Discretionary::Discretionary;
|
||||
break;
|
||||
case Keyword::NoDiscretionaryLigatures:
|
||||
ligatures.discretionary = Gfx::FontVariantLigatures::Discretionary::NoDiscretionary;
|
||||
break;
|
||||
case Keyword::HistoricalLigatures:
|
||||
ligatures.historical = Gfx::FontVariantLigatures::Historical::Historical;
|
||||
break;
|
||||
case Keyword::NoHistoricalLigatures:
|
||||
ligatures.historical = Gfx::FontVariantLigatures::Historical::NoHistorical;
|
||||
break;
|
||||
case Keyword::Contextual:
|
||||
ligatures.contextual = Gfx::FontVariantLigatures::Contextual::Contextual;
|
||||
break;
|
||||
case Keyword::NoContextual:
|
||||
ligatures.contextual = Gfx::FontVariantLigatures::Contextual::NoContextual;
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ligatures;
|
||||
}
|
||||
|
||||
Gfx::FontVariantNumeric CSSStyleValue::to_font_variant_numeric() const
|
||||
{
|
||||
VERIFY(is_value_list());
|
||||
auto& list = as_value_list();
|
||||
Gfx::FontVariantNumeric numeric {};
|
||||
for (auto& value : list.values()) {
|
||||
VERIFY(value->is_keyword());
|
||||
switch (value->as_keyword().keyword()) {
|
||||
case Keyword::Normal:
|
||||
numeric.normal = true;
|
||||
return numeric;
|
||||
case Keyword::Ordinal:
|
||||
numeric.ordinal = true;
|
||||
break;
|
||||
case Keyword::SlashedZero:
|
||||
numeric.slashed_zero = true;
|
||||
break;
|
||||
case Keyword::OldstyleNums:
|
||||
numeric.figure = Gfx::FontVariantNumeric::Figure::Oldstyle;
|
||||
break;
|
||||
case Keyword::LiningNums:
|
||||
numeric.figure = Gfx::FontVariantNumeric::Figure::Lining;
|
||||
break;
|
||||
case Keyword::ProportionalNums:
|
||||
numeric.spacing = Gfx::FontVariantNumeric::Spacing::Proportional;
|
||||
break;
|
||||
case Keyword::TabularNums:
|
||||
numeric.spacing = Gfx::FontVariantNumeric::Spacing::Tabular;
|
||||
break;
|
||||
case Keyword::DiagonalFractions:
|
||||
numeric.fraction = Gfx::FontVariantNumeric::Fraction::Diagonal;
|
||||
break;
|
||||
case Keyword::StackedFractions:
|
||||
numeric.fraction = Gfx::FontVariantNumeric::Fraction::Stacked;
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return numeric;
|
||||
}
|
||||
|
||||
Optional<FontVariantPosition> CSSStyleValue::to_font_variant_position() const
|
||||
{
|
||||
VERIFY(is_keyword());
|
||||
return keyword_to_font_variant_position(as_keyword().keyword());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <LibGfx/Color.h>
|
||||
#include <LibGfx/Font/FontVariant.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/CSS/Enums.h>
|
||||
#include <LibWeb/CSS/Keyword.h>
|
||||
|
@ -104,6 +105,7 @@ public:
|
|||
Edge,
|
||||
FilterValueList,
|
||||
Flex,
|
||||
FontVariant,
|
||||
Frequency,
|
||||
GridAutoFlow,
|
||||
GridTemplateArea,
|
||||
|
@ -355,6 +357,12 @@ public:
|
|||
[[nodiscard]] int to_font_weight() const;
|
||||
[[nodiscard]] int to_font_slope() const;
|
||||
[[nodiscard]] int to_font_width() const;
|
||||
[[nodiscard]] Gfx::FontVariantAlternates to_font_variant_alternates() const;
|
||||
[[nodiscard]] Optional<FontVariantCaps> to_font_variant_caps() const;
|
||||
[[nodiscard]] Gfx::FontVariantEastAsian to_font_variant_east_asian() const;
|
||||
[[nodiscard]] Gfx::FontVariantLigatures to_font_variant_ligatures() const;
|
||||
[[nodiscard]] Gfx::FontVariantNumeric to_font_variant_numeric() const;
|
||||
[[nodiscard]] Optional<FontVariantPosition> to_font_variant_position() const;
|
||||
|
||||
virtual bool equals(CSSStyleValue const& other) const = 0;
|
||||
|
||||
|
|
|
@ -97,7 +97,6 @@ public:
|
|||
static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; }
|
||||
static CSSPixels font_size() { return 16; }
|
||||
static int font_weight() { return 400; }
|
||||
static CSS::FontVariant font_variant() { return CSS::FontVariant::Normal; }
|
||||
static CSSPixels line_height() { return 0; }
|
||||
static CSS::Float float_() { return CSS::Float::None; }
|
||||
static CSS::Length border_spacing() { return CSS::Length::make_px(0); }
|
||||
|
@ -511,7 +510,12 @@ public:
|
|||
Gfx::FontCascadeList const& font_list() const { return *m_inherited.font_list; }
|
||||
CSSPixels font_size() const { return m_inherited.font_size; }
|
||||
int font_weight() const { return m_inherited.font_weight; }
|
||||
CSS::FontVariant font_variant() const { return m_inherited.font_variant; }
|
||||
Gfx::FontVariantAlternates font_variant_alternates() const { return m_inherited.font_variant_alternates; }
|
||||
FontVariantCaps font_variant_caps() const { return m_inherited.font_variant_caps; }
|
||||
Gfx::FontVariantEastAsian font_variant_east_asian() const { return m_inherited.font_variant_east_asian; }
|
||||
Gfx::FontVariantLigatures font_variant_ligatures() const { return m_inherited.font_variant_ligatures; }
|
||||
Gfx::FontVariantNumeric font_variant_numeric() const { return m_inherited.font_variant_numeric; }
|
||||
FontVariantPosition font_variant_position() const { return m_inherited.font_variant_position; }
|
||||
Optional<FlyString> font_language_override() const { return m_inherited.font_language_override; }
|
||||
Optional<HashMap<FlyString, IntegerOrCalculated>> font_feature_settings() const { return m_inherited.font_feature_settings; }
|
||||
Optional<HashMap<FlyString, NumberOrCalculated>> font_variation_settings() const { return m_inherited.font_variation_settings; }
|
||||
|
@ -545,7 +549,12 @@ protected:
|
|||
RefPtr<Gfx::FontCascadeList> font_list {};
|
||||
CSSPixels font_size { InitialValues::font_size() };
|
||||
int font_weight { InitialValues::font_weight() };
|
||||
CSS::FontVariant font_variant { InitialValues::font_variant() };
|
||||
Gfx::FontVariantAlternates font_variant_alternates { .normal = true };
|
||||
FontVariantCaps font_variant_caps { FontVariantCaps::Normal };
|
||||
Gfx::FontVariantEastAsian font_variant_east_asian { .normal = true };
|
||||
Gfx::FontVariantLigatures font_variant_ligatures { .normal = true };
|
||||
Gfx::FontVariantNumeric font_variant_numeric { .normal = true };
|
||||
FontVariantPosition font_variant_position { FontVariantPosition::Normal };
|
||||
Optional<FlyString> font_language_override;
|
||||
Optional<HashMap<FlyString, IntegerOrCalculated>> font_feature_settings;
|
||||
Optional<HashMap<FlyString, NumberOrCalculated>> font_variation_settings;
|
||||
|
@ -717,7 +726,12 @@ public:
|
|||
void set_font_list(NonnullRefPtr<Gfx::FontCascadeList> font_list) { m_inherited.font_list = move(font_list); }
|
||||
void set_font_size(CSSPixels font_size) { m_inherited.font_size = font_size; }
|
||||
void set_font_weight(int font_weight) { m_inherited.font_weight = font_weight; }
|
||||
void set_font_variant(CSS::FontVariant font_variant) { m_inherited.font_variant = font_variant; }
|
||||
void set_font_variant_alternates(Gfx::FontVariantAlternates font_variant_alternates) { m_inherited.font_variant_alternates = font_variant_alternates; }
|
||||
void set_font_variant_caps(FontVariantCaps font_variant_caps) { m_inherited.font_variant_caps = font_variant_caps; }
|
||||
void set_font_variant_east_asian(Gfx::FontVariantEastAsian font_variant_east_asian) { m_inherited.font_variant_east_asian = font_variant_east_asian; }
|
||||
void set_font_variant_ligatures(Gfx::FontVariantLigatures font_variant_ligatures) { m_inherited.font_variant_ligatures = font_variant_ligatures; }
|
||||
void set_font_variant_numeric(Gfx::FontVariantNumeric font_variant_numeric) { m_inherited.font_variant_numeric = font_variant_numeric; }
|
||||
void set_font_variant_position(FontVariantPosition font_variant_position) { m_inherited.font_variant_position = font_variant_position; }
|
||||
void set_font_language_override(Optional<FlyString> font_language_override) { m_inherited.font_language_override = font_language_override; }
|
||||
void set_font_feature_settings(Optional<HashMap<FlyString, IntegerOrCalculated>> value) { m_inherited.font_feature_settings = move(value); }
|
||||
void set_font_variation_settings(Optional<HashMap<FlyString, NumberOrCalculated>> value) { m_inherited.font_variation_settings = move(value); }
|
||||
|
|
|
@ -221,9 +221,64 @@
|
|||
"fallback",
|
||||
"optional"
|
||||
],
|
||||
"font-variant": [
|
||||
"font-variant-alternates": [
|
||||
"normal",
|
||||
"small-caps"
|
||||
"historical-forms"
|
||||
],
|
||||
"font-variant-caps": [
|
||||
"normal",
|
||||
"small-caps",
|
||||
"all-small-caps",
|
||||
"petite-caps",
|
||||
"all-petite-caps",
|
||||
"unicase",
|
||||
"titling-caps"
|
||||
],
|
||||
"font-variant-east-asian": [
|
||||
"normal",
|
||||
"ruby",
|
||||
"jis78",
|
||||
"jis83",
|
||||
"jis90",
|
||||
"jis04",
|
||||
"simplified",
|
||||
"traditional",
|
||||
"full-width",
|
||||
"proportional-width"
|
||||
],
|
||||
"font-variant-emoji": [
|
||||
"normal",
|
||||
"text",
|
||||
"emoji",
|
||||
"unicode"
|
||||
],
|
||||
"font-variant-ligatures": [
|
||||
"normal",
|
||||
"none",
|
||||
"common-ligatures",
|
||||
"no-common-ligatures",
|
||||
"discretionary-ligatures",
|
||||
"no-discretionary-ligatures",
|
||||
"historical-ligatures",
|
||||
"no-historical-ligatures",
|
||||
"contextual",
|
||||
"no-contextual"
|
||||
],
|
||||
"font-variant-numeric": [
|
||||
"normal",
|
||||
"ordinal",
|
||||
"slashed-zero",
|
||||
"lining-nums",
|
||||
"oldstyle-nums",
|
||||
"proportional-nums",
|
||||
"tabular-nums",
|
||||
"diagonal-fractions",
|
||||
"stacked-fractions"
|
||||
],
|
||||
"font-variant-position": [
|
||||
"normal",
|
||||
"sub",
|
||||
"super"
|
||||
],
|
||||
"font-width": [
|
||||
"ultra-condensed",
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Web::CSS {
|
|||
GC_DEFINE_ALLOCATOR(FontFaceSet);
|
||||
|
||||
// https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-fontfaceset
|
||||
GC::Ref<FontFaceSet> FontFaceSet::construct_impl(JS::Realm& realm, Vector<GC::Root<FontFace>> const& initial_faces)
|
||||
GC::Ref<FontFaceSet> FontFaceSet::construct_impl(Web::Page& page, JS::Realm& realm, Vector<GC::Root<FontFace>> const& initial_faces)
|
||||
{
|
||||
auto ready_promise = WebIDL::create_promise(realm);
|
||||
auto set_entries = JS::Set::create(realm);
|
||||
|
@ -37,16 +37,17 @@ GC::Ref<FontFaceSet> FontFaceSet::construct_impl(JS::Realm& realm, Vector<GC::Ro
|
|||
for (auto const& face : initial_faces)
|
||||
set_entries->set_add(face);
|
||||
|
||||
return realm.create<FontFaceSet>(realm, ready_promise, set_entries);
|
||||
return realm.create<FontFaceSet>(page, realm, ready_promise, set_entries);
|
||||
}
|
||||
|
||||
GC::Ref<FontFaceSet> FontFaceSet::create(JS::Realm& realm)
|
||||
GC::Ref<FontFaceSet> FontFaceSet::create(Web::Page& page, JS::Realm& realm)
|
||||
{
|
||||
return construct_impl(realm, {});
|
||||
return construct_impl(page, realm, {});
|
||||
}
|
||||
|
||||
FontFaceSet::FontFaceSet(JS::Realm& realm, GC::Ref<WebIDL::Promise> ready_promise, GC::Ref<JS::Set> set_entries)
|
||||
FontFaceSet::FontFaceSet(Web::Page& page, JS::Realm& realm, GC::Ref<WebIDL::Promise> ready_promise, GC::Ref<JS::Set> set_entries)
|
||||
: DOM::EventTarget(realm)
|
||||
, m_page(page)
|
||||
, m_set_entries(set_entries)
|
||||
, m_ready_promise(ready_promise)
|
||||
, m_status(Bindings::FontFaceSetLoadStatus::Loaded)
|
||||
|
@ -63,6 +64,7 @@ void FontFaceSet::initialize(JS::Realm& realm)
|
|||
void FontFaceSet::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_page);
|
||||
visitor.visit(m_set_entries);
|
||||
visitor.visit(m_ready_promise);
|
||||
visitor.visit(m_loading_fonts);
|
||||
|
@ -289,7 +291,10 @@ GC::Ref<WebIDL::Promise> FontFaceSet::ready() const
|
|||
|
||||
void FontFaceSet::resolve_ready_promise()
|
||||
{
|
||||
dbgln("FontFaceSet::resolve_ready_promise(): {}", m_page->url());
|
||||
WebIDL::resolve_promise(realm(), m_ready_promise);
|
||||
|
||||
m_page->client().page_did_finish_loading_page_and_fonts(m_page->url());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/CSS/FontFace.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
|
@ -21,8 +23,8 @@ class FontFaceSet final : public DOM::EventTarget {
|
|||
GC_DECLARE_ALLOCATOR(FontFaceSet);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<FontFaceSet> construct_impl(JS::Realm&, Vector<GC::Root<FontFace>> const& initial_faces);
|
||||
[[nodiscard]] static GC::Ref<FontFaceSet> create(JS::Realm&);
|
||||
[[nodiscard]] static GC::Ref<FontFaceSet> construct_impl(Web::Page&, JS::Realm&, Vector<GC::Root<FontFace>> const& initial_faces);
|
||||
[[nodiscard]] static GC::Ref<FontFaceSet> create(Web::Page&, JS::Realm&);
|
||||
virtual ~FontFaceSet() override = default;
|
||||
|
||||
GC::Ref<JS::Set> set_entries() const { return m_set_entries; }
|
||||
|
@ -46,11 +48,12 @@ public:
|
|||
void resolve_ready_promise();
|
||||
|
||||
private:
|
||||
FontFaceSet(JS::Realm&, GC::Ref<WebIDL::Promise> ready_promise, GC::Ref<JS::Set> set_entries);
|
||||
FontFaceSet(Web::Page&, JS::Realm&, GC::Ref<WebIDL::Promise> ready_promise, GC::Ref<JS::Set> set_entries);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
GC::Ref<Web::Page> m_page;
|
||||
GC::Ref<JS::Set> m_set_entries;
|
||||
GC::Ref<WebIDL::Promise> m_ready_promise; // [[ReadyPromise]]
|
||||
|
||||
|
|
|
@ -67,7 +67,9 @@
|
|||
"additive",
|
||||
"alias",
|
||||
"all",
|
||||
"all-petite-caps",
|
||||
"all-scroll",
|
||||
"all-small-caps",
|
||||
"alpha",
|
||||
"alternate",
|
||||
"alternate-reverse",
|
||||
|
@ -114,6 +116,7 @@
|
|||
"collapse",
|
||||
"column",
|
||||
"column-reverse",
|
||||
"common-ligatures",
|
||||
"compact",
|
||||
"condensed",
|
||||
"contain",
|
||||
|
@ -121,6 +124,7 @@
|
|||
"content-box",
|
||||
"contents",
|
||||
"context-menu",
|
||||
"contextual",
|
||||
"copy",
|
||||
"cover",
|
||||
"crisp-edges",
|
||||
|
@ -133,7 +137,9 @@
|
|||
"decimal",
|
||||
"decimal-leading-zero",
|
||||
"default",
|
||||
"diagonal-fractions",
|
||||
"disc",
|
||||
"discretionary-ligatures",
|
||||
"disclosure-closed",
|
||||
"disclosure-open",
|
||||
"distribute",
|
||||
|
@ -147,6 +153,7 @@
|
|||
"ease-out",
|
||||
"ellipsis",
|
||||
"embed",
|
||||
"emoji",
|
||||
"enabled",
|
||||
"end",
|
||||
"evenodd",
|
||||
|
@ -185,6 +192,8 @@
|
|||
"high-quality",
|
||||
"highlight",
|
||||
"highlighttext",
|
||||
"historical-forms",
|
||||
"historical-ligatures",
|
||||
"horizontal-tb",
|
||||
"hover",
|
||||
"inactiveborder",
|
||||
|
@ -213,6 +222,10 @@
|
|||
"isolate",
|
||||
"isolate-override",
|
||||
"italic",
|
||||
"jis04",
|
||||
"jis78",
|
||||
"jis83",
|
||||
"jis90",
|
||||
"jump-both",
|
||||
"jump-end",
|
||||
"jump-none",
|
||||
|
@ -229,6 +242,7 @@
|
|||
"lighter",
|
||||
"line-through",
|
||||
"linear",
|
||||
"lining-nums",
|
||||
"linktext",
|
||||
"list-item",
|
||||
"listbox",
|
||||
|
@ -262,8 +276,12 @@
|
|||
"nearest",
|
||||
"nesw-resize",
|
||||
"no-close-quote",
|
||||
"no-common-ligatures",
|
||||
"no-contextual",
|
||||
"no-discretionary-ligatures",
|
||||
"no-drop",
|
||||
"no-open-quote",
|
||||
"no-historical-ligatures",
|
||||
"no-preference",
|
||||
"no-repeat",
|
||||
"none",
|
||||
|
@ -276,12 +294,14 @@
|
|||
"nwse-resize",
|
||||
"oblique",
|
||||
"off",
|
||||
"oldstyle-nums",
|
||||
"on",
|
||||
"opaque",
|
||||
"open-quote",
|
||||
"optimizequality",
|
||||
"optimizespeed",
|
||||
"optional",
|
||||
"ordinal",
|
||||
"outset",
|
||||
"outside",
|
||||
"overline",
|
||||
|
@ -289,6 +309,7 @@
|
|||
"padding-box",
|
||||
"paged",
|
||||
"paused",
|
||||
"petite-caps",
|
||||
"pixelated",
|
||||
"plaintext",
|
||||
"pointer",
|
||||
|
@ -299,6 +320,8 @@
|
|||
"progress",
|
||||
"progress-bar",
|
||||
"progressive",
|
||||
"proportional-nums",
|
||||
"proportional-width",
|
||||
"push-button",
|
||||
"radio",
|
||||
"rec2020",
|
||||
|
@ -342,6 +365,8 @@
|
|||
"serif",
|
||||
"sideways-lr",
|
||||
"sideways-rl",
|
||||
"simplified",
|
||||
"slashed-zero",
|
||||
"slider-horizontal",
|
||||
"slow",
|
||||
"small",
|
||||
|
@ -357,6 +382,7 @@
|
|||
"square-button",
|
||||
"srgb",
|
||||
"stable",
|
||||
"stacked-fractions",
|
||||
"standalone",
|
||||
"standard",
|
||||
"start",
|
||||
|
@ -378,6 +404,7 @@
|
|||
"table-header-group",
|
||||
"table-row",
|
||||
"table-row-group",
|
||||
"tabular-nums",
|
||||
"text",
|
||||
"text-bottom",
|
||||
"text-top",
|
||||
|
@ -385,6 +412,8 @@
|
|||
"textfield",
|
||||
"thick",
|
||||
"thin",
|
||||
"titling-caps",
|
||||
"traditional",
|
||||
"threeddarkshadow",
|
||||
"threedface",
|
||||
"threedhighlight",
|
||||
|
@ -399,6 +428,8 @@
|
|||
"ultra-condensed",
|
||||
"ultra-expanded",
|
||||
"underline",
|
||||
"unicase",
|
||||
"unicode",
|
||||
"unsafe",
|
||||
"unset",
|
||||
"up",
|
||||
|
|
|
@ -5903,6 +5903,455 @@ RefPtr<CSSStyleValue> Parser::parse_font_variation_settings_value(TokenStream<Co
|
|||
return StyleValueList::create(move(axis_tags), StyleValueList::Separator::Comma);
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleValue> Parser::parse_font_variant(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// 6.11 https://drafts.csswg.org/css-fonts/#propdef-font-variant
|
||||
// normal | none |
|
||||
// [ [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]
|
||||
// || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] ||
|
||||
// [ FIXME: stylistic(<feature-value-name>) ||
|
||||
// historical-forms ||
|
||||
// FIXME: styleset(<feature-value-name>#) ||
|
||||
// FIXME: character-variant(<feature-value-name>#) ||
|
||||
// FIXME: swash(<feature-value-name>) ||
|
||||
// FIXME: ornaments(<feature-value-name>) ||
|
||||
// FIXME: annotation(<feature-value-name>) ] ||
|
||||
// [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> ||
|
||||
// ordinal || slashed-zero ] || [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] ||
|
||||
// [ sub | super ] || [ text | emoji | unicode ] ]
|
||||
|
||||
bool has_caps = false;
|
||||
bool has_alternates = false;
|
||||
bool has_common_ligatures = false;
|
||||
bool has_discretionary_ligatures = false;
|
||||
bool has_historical_ligatures = false;
|
||||
bool has_contextual = false;
|
||||
bool has_numeric_figures = false;
|
||||
bool has_numeric_spacing = false;
|
||||
bool has_numeric_fractions = false;
|
||||
bool has_numeric_ordinals = false;
|
||||
bool has_numeric_slashed_zero = false;
|
||||
bool has_east_asian_variant = false;
|
||||
bool has_east_asian_width = false;
|
||||
bool has_east_asian_ruby = false;
|
||||
bool has_position = false;
|
||||
Keyword alternates_value = Keyword::Normal;
|
||||
Keyword caps_value = Keyword::Normal;
|
||||
Keyword position_value = Keyword::Normal;
|
||||
StyleValueVector east_asian_values;
|
||||
StyleValueVector ligatures_values;
|
||||
StyleValueVector numeric_values;
|
||||
StyleValueVector position_values;
|
||||
|
||||
// normal
|
||||
if (auto parsed_value = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||
/* do nothing */
|
||||
// none
|
||||
} else if (auto parsed_value = parse_all_as_single_keyword_value(tokens, Keyword::None)) {
|
||||
// FIXME
|
||||
} else {
|
||||
|
||||
while (tokens.has_next_token()) {
|
||||
auto maybe_value = parse_keyword_value(tokens);
|
||||
if (!maybe_value)
|
||||
break;
|
||||
auto value = maybe_value.release_nonnull();
|
||||
if (!value->is_keyword()) {
|
||||
// FIXME: alternate functions such as stylistic()
|
||||
return nullptr;
|
||||
}
|
||||
auto keyword = value->to_keyword();
|
||||
|
||||
switch (keyword) {
|
||||
// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
|
||||
case Keyword::CommonLigatures:
|
||||
case Keyword::NoCommonLigatures:
|
||||
if (has_common_ligatures)
|
||||
return nullptr;
|
||||
ligatures_values.append(value);
|
||||
has_common_ligatures = true;
|
||||
break;
|
||||
// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
|
||||
case Keyword::DiscretionaryLigatures:
|
||||
case Keyword::NoDiscretionaryLigatures:
|
||||
if (has_discretionary_ligatures)
|
||||
return nullptr;
|
||||
ligatures_values.append(value);
|
||||
has_discretionary_ligatures = true;
|
||||
break;
|
||||
// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
|
||||
case Keyword::HistoricalLigatures:
|
||||
case Keyword::NoHistoricalLigatures:
|
||||
if (has_historical_ligatures)
|
||||
return nullptr;
|
||||
ligatures_values.append(value);
|
||||
has_historical_ligatures = true;
|
||||
break;
|
||||
// <contextual-alt-values> = [ contextual | no-contextual ]
|
||||
case Keyword::Contextual:
|
||||
case Keyword::NoContextual:
|
||||
if (has_contextual)
|
||||
return nullptr;
|
||||
ligatures_values.append(value);
|
||||
has_contextual = true;
|
||||
break;
|
||||
// historical-forms
|
||||
case Keyword::HistoricalForms:
|
||||
if (has_alternates)
|
||||
return nullptr;
|
||||
alternates_value = keyword;
|
||||
has_alternates = true;
|
||||
break;
|
||||
// [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ]
|
||||
case Keyword::SmallCaps:
|
||||
case Keyword::AllSmallCaps:
|
||||
case Keyword::PetiteCaps:
|
||||
case Keyword::AllPetiteCaps:
|
||||
case Keyword::Unicase:
|
||||
case Keyword::TitlingCaps:
|
||||
if (has_caps)
|
||||
return nullptr;
|
||||
caps_value = keyword;
|
||||
has_caps = true;
|
||||
break;
|
||||
// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
|
||||
case Keyword::LiningNums:
|
||||
case Keyword::OldstyleNums:
|
||||
if (has_numeric_figures)
|
||||
return nullptr;
|
||||
numeric_values.append(value);
|
||||
has_numeric_figures = true;
|
||||
break;
|
||||
// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
|
||||
case Keyword::ProportionalNums:
|
||||
case Keyword::TabularNums:
|
||||
if (has_numeric_spacing)
|
||||
return nullptr;
|
||||
numeric_values.append(value);
|
||||
has_numeric_spacing = true;
|
||||
break;
|
||||
// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions]
|
||||
case Keyword::DiagonalFractions:
|
||||
case Keyword::StackedFractions:
|
||||
if (has_numeric_fractions)
|
||||
return nullptr;
|
||||
numeric_values.append(value);
|
||||
has_numeric_fractions = true;
|
||||
break;
|
||||
// ordinal
|
||||
case Keyword::Ordinal:
|
||||
if (has_numeric_ordinals)
|
||||
return nullptr;
|
||||
numeric_values.append(value);
|
||||
has_numeric_ordinals = true;
|
||||
break;
|
||||
case Keyword::SlashedZero:
|
||||
if (has_numeric_slashed_zero)
|
||||
return nullptr;
|
||||
numeric_values.append(value);
|
||||
has_numeric_slashed_zero = true;
|
||||
break;
|
||||
// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
|
||||
case Keyword::Jis78:
|
||||
case Keyword::Jis83:
|
||||
case Keyword::Jis90:
|
||||
case Keyword::Jis04:
|
||||
case Keyword::Simplified:
|
||||
case Keyword::Traditional:
|
||||
if (has_east_asian_variant)
|
||||
return nullptr;
|
||||
east_asian_values.append(value);
|
||||
has_east_asian_variant = true;
|
||||
break;
|
||||
// <east-asian-width-values> = [ full-width | proportional-width ]
|
||||
case Keyword::FullWidth:
|
||||
case Keyword::ProportionalWidth:
|
||||
if (has_east_asian_width)
|
||||
return nullptr;
|
||||
east_asian_values.append(value);
|
||||
has_east_asian_width = true;
|
||||
break;
|
||||
// ruby
|
||||
case Keyword::Ruby:
|
||||
if (has_east_asian_ruby)
|
||||
return nullptr;
|
||||
east_asian_values.append(value);
|
||||
has_east_asian_ruby = true;
|
||||
break;
|
||||
// sub | super
|
||||
case Keyword::Sub:
|
||||
case Keyword::Super:
|
||||
if (has_position)
|
||||
return nullptr;
|
||||
position_value = keyword;
|
||||
has_position = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ligatures_values.is_empty())
|
||||
ligatures_values.append(CSSKeywordValue::create(Keyword::Normal));
|
||||
if (numeric_values.is_empty())
|
||||
numeric_values.append(CSSKeywordValue::create(Keyword::Normal));
|
||||
if (east_asian_values.is_empty())
|
||||
east_asian_values.append(CSSKeywordValue::create(Keyword::Normal));
|
||||
|
||||
return ShorthandStyleValue::create(PropertyID::FontVariant,
|
||||
{ PropertyID::FontVariantAlternates,
|
||||
PropertyID::FontVariantCaps,
|
||||
PropertyID::FontVariantEastAsian,
|
||||
PropertyID::FontVariantLigatures,
|
||||
PropertyID::FontVariantNumeric,
|
||||
PropertyID::FontVariantPosition },
|
||||
{
|
||||
CSSKeywordValue::create(alternates_value),
|
||||
CSSKeywordValue::create(caps_value),
|
||||
StyleValueList::create(move(east_asian_values), StyleValueList::Separator::Space),
|
||||
StyleValueList::create(move(ligatures_values), StyleValueList::Separator::Space),
|
||||
StyleValueList::create(move(numeric_values), StyleValueList::Separator::Space),
|
||||
CSSKeywordValue::create(position_value),
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleValue> Parser::parse_font_variant_alternates_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// 6.8 https://drafts.csswg.org/css-fonts/#font-variant-alternates-prop
|
||||
// normal |
|
||||
// [ FIXME: stylistic(<feature-value-name>) ||
|
||||
// historical-forms ||
|
||||
// FIXME: styleset(<feature-value-name>#) ||
|
||||
// FIXME: character-variant(<feature-value-name>#) ||
|
||||
// FIXME: swash(<feature-value-name>) ||
|
||||
// FIXME: ornaments(<feature-value-name>) ||
|
||||
// FIXME: annotation(<feature-value-name>) ]
|
||||
|
||||
// normal
|
||||
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal))
|
||||
return normal;
|
||||
|
||||
// historical-forms
|
||||
// FIXME: Support this together with other values when we parse them.
|
||||
if (auto historical_forms = parse_all_as_single_keyword_value(tokens, Keyword::HistoricalForms))
|
||||
return historical_forms;
|
||||
|
||||
dbgln_if(CSS_PARSER_DEBUG, "CSSParser: @font-variant-alternate: parsing {} not implemented.", tokens.next_token().to_debug_string());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleValue> Parser::parse_font_variant_caps_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps
|
||||
// normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps
|
||||
|
||||
bool has_token = false;
|
||||
while (tokens.has_next_token()) {
|
||||
if (has_token)
|
||||
return nullptr;
|
||||
auto maybe_value = parse_keyword_value(tokens);
|
||||
if (!maybe_value)
|
||||
break;
|
||||
auto value = maybe_value.release_nonnull();
|
||||
auto font_variant = keyword_to_font_variant_caps(value->to_keyword());
|
||||
if (font_variant.has_value()) {
|
||||
return value;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleValue> Parser::parse_font_variant_east_asian_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// 6.10 https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian
|
||||
// normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]
|
||||
// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
|
||||
// <east-asian-width-values> = [ full-width | proportional-width ]
|
||||
|
||||
StyleValueVector value_list;
|
||||
bool has_ruby = false;
|
||||
bool has_variant = false;
|
||||
bool has_width = false;
|
||||
|
||||
// normal | ...
|
||||
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||
value_list.append(normal.release_nonnull());
|
||||
} else {
|
||||
while (tokens.has_next_token()) {
|
||||
auto maybe_value = parse_keyword_value(tokens);
|
||||
if (!maybe_value)
|
||||
break;
|
||||
auto value = maybe_value.release_nonnull();
|
||||
auto font_variant = keyword_to_font_variant_east_asian(value->to_keyword());
|
||||
if (!font_variant.has_value()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto keyword = value->to_keyword();
|
||||
if (keyword == Keyword::Ruby) {
|
||||
if (has_ruby)
|
||||
return nullptr;
|
||||
has_ruby = true;
|
||||
} else if (keyword == Keyword::FullWidth || keyword == Keyword::ProportionalWidth) {
|
||||
if (has_width)
|
||||
return nullptr;
|
||||
has_width = true;
|
||||
} else {
|
||||
if (has_variant)
|
||||
return nullptr;
|
||||
has_variant = true;
|
||||
}
|
||||
value_list.append(value);
|
||||
}
|
||||
}
|
||||
if (value_list.is_empty())
|
||||
return nullptr;
|
||||
|
||||
return StyleValueList::create(move(value_list), StyleValueList::Separator::Space);
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleValue> Parser::parse_font_variant_ligatures_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// 6.4 https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures
|
||||
// normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]
|
||||
// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
|
||||
// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
|
||||
// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
|
||||
// <contextual-alt-values> = [ contextual | no-contextual ]
|
||||
|
||||
StyleValueVector value_list;
|
||||
bool has_common_ligatures = false;
|
||||
bool has_discretionary_ligatures = false;
|
||||
bool has_historical_ligatures = false;
|
||||
bool has_contextual = false;
|
||||
|
||||
// normal | ...
|
||||
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||
value_list.append(normal.release_nonnull());
|
||||
// none | ...
|
||||
} else if (auto none = parse_all_as_single_keyword_value(tokens, Keyword::None)) {
|
||||
value_list.append(none.release_nonnull());
|
||||
} else {
|
||||
while (tokens.has_next_token()) {
|
||||
auto maybe_value = parse_keyword_value(tokens);
|
||||
if (!maybe_value)
|
||||
break;
|
||||
auto value = maybe_value.release_nonnull();
|
||||
switch (value->to_keyword()) {
|
||||
// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
|
||||
case Keyword::CommonLigatures:
|
||||
case Keyword::NoCommonLigatures:
|
||||
if (has_common_ligatures)
|
||||
return nullptr;
|
||||
has_common_ligatures = true;
|
||||
break;
|
||||
// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
|
||||
case Keyword::DiscretionaryLigatures:
|
||||
case Keyword::NoDiscretionaryLigatures:
|
||||
if (has_discretionary_ligatures)
|
||||
return nullptr;
|
||||
has_discretionary_ligatures = true;
|
||||
break;
|
||||
// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
|
||||
case Keyword::HistoricalLigatures:
|
||||
case Keyword::NoHistoricalLigatures:
|
||||
if (has_historical_ligatures)
|
||||
return nullptr;
|
||||
has_historical_ligatures = true;
|
||||
break;
|
||||
// <contextual-alt-values> = [ contextual | no-contextual ]
|
||||
case Keyword::Contextual:
|
||||
case Keyword::NoContextual:
|
||||
if (has_contextual)
|
||||
return nullptr;
|
||||
has_contextual = true;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
value_list.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (value_list.is_empty())
|
||||
return nullptr;
|
||||
|
||||
return StyleValueList::create(move(value_list), StyleValueList::Separator::Space);
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleValue> Parser::parse_font_variant_numeric_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// 6.7 https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric
|
||||
// normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero]
|
||||
// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
|
||||
// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
|
||||
// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
|
||||
|
||||
StyleValueVector value_list;
|
||||
bool has_figures = false;
|
||||
bool has_spacing = false;
|
||||
bool has_fractions = false;
|
||||
bool has_ordinals = false;
|
||||
bool has_slashed_zero = false;
|
||||
|
||||
// normal | ...
|
||||
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||
value_list.append(normal.release_nonnull());
|
||||
} else {
|
||||
while (tokens.has_next_token()) {
|
||||
auto maybe_value = parse_keyword_value(tokens);
|
||||
if (!maybe_value)
|
||||
break;
|
||||
auto value = maybe_value.release_nonnull();
|
||||
switch (value->to_keyword()) {
|
||||
// ... || ordinal
|
||||
case Keyword::Ordinal:
|
||||
if (has_ordinals)
|
||||
return nullptr;
|
||||
has_ordinals = true;
|
||||
break;
|
||||
// ... || slashed-zero
|
||||
case Keyword::SlashedZero:
|
||||
if (has_slashed_zero)
|
||||
return nullptr;
|
||||
has_slashed_zero = true;
|
||||
break;
|
||||
// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
|
||||
case Keyword::LiningNums:
|
||||
case Keyword::OldstyleNums:
|
||||
if (has_figures)
|
||||
return nullptr;
|
||||
has_figures = true;
|
||||
break;
|
||||
// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
|
||||
case Keyword::ProportionalNums:
|
||||
case Keyword::TabularNums:
|
||||
if (has_spacing)
|
||||
return nullptr;
|
||||
has_spacing = true;
|
||||
break;
|
||||
// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
|
||||
case Keyword::DiagonalFractions:
|
||||
case Keyword::StackedFractions:
|
||||
if (has_fractions)
|
||||
return nullptr;
|
||||
has_fractions = true;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
value_list.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (value_list.is_empty())
|
||||
return nullptr;
|
||||
|
||||
return StyleValueList::create(move(value_list), StyleValueList::Separator::Space);
|
||||
}
|
||||
|
||||
Vector<ParsedFontFace::Source> Parser::parse_as_font_face_src()
|
||||
{
|
||||
return parse_font_face_src(m_token_stream);
|
||||
|
@ -7789,6 +8238,30 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue>> Parser::parse_css_value(Prope
|
|||
if (auto parsed_value = parse_font_variation_settings_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::FontVariant:
|
||||
if (auto parsed_value = parse_font_variant(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::FontVariantAlternates:
|
||||
if (auto parsed_value = parse_font_variant_alternates_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::FontVariantCaps:
|
||||
if (auto parsed_value = parse_font_variant_caps_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::FontVariantEastAsian:
|
||||
if (auto parsed_value = parse_font_variant_east_asian_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::FontVariantLigatures:
|
||||
if (auto parsed_value = parse_font_variant_ligatures_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::FontVariantNumeric:
|
||||
if (auto parsed_value = parse_font_variant_numeric_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::GridArea:
|
||||
if (auto parsed_value = parse_grid_area_shorthand_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
|
|
|
@ -322,6 +322,12 @@ private:
|
|||
RefPtr<CSSStyleValue> parse_font_language_override_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_feature_settings_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_variation_settings_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_variant(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_variant_alternates_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_variant_caps_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_variant_east_asian_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_variant_ligatures_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_font_variant_numeric_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_list_style_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_math_depth_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_overflow_value(TokenStream<ComponentValue>&);
|
||||
|
|
|
@ -1247,7 +1247,69 @@
|
|||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant"
|
||||
"font-variant-alternates",
|
||||
"font-variant-caps",
|
||||
"font-variant-east-asian",
|
||||
"font-variant-emoji",
|
||||
"font-variant-ligatures",
|
||||
"font-variant-numeric",
|
||||
"font-variant-position"
|
||||
]
|
||||
},
|
||||
"font-variant-alternates": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant-alternates"
|
||||
]
|
||||
},
|
||||
"font-variant-caps": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant-caps"
|
||||
]
|
||||
},
|
||||
"font-variant-east-asian": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant-east-asian"
|
||||
]
|
||||
},
|
||||
"font-variant-emoji": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant-emoji"
|
||||
]
|
||||
},
|
||||
"font-variant-ligatures": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant-ligatures"
|
||||
]
|
||||
},
|
||||
"font-variant-numeric": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant-numeric"
|
||||
]
|
||||
},
|
||||
"font-variant-position": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": true,
|
||||
"initial": "normal",
|
||||
"valid-types": [
|
||||
"font-variant-position"
|
||||
]
|
||||
},
|
||||
"font-variation-settings": {
|
||||
|
|
|
@ -601,6 +601,12 @@ Optional<StyleProperty> ResolvedCSSStyleDeclaration::property(PropertyID propert
|
|||
};
|
||||
}
|
||||
|
||||
Optional<StyleProperty> ResolvedCSSStyleDeclaration::custom_property(FlyString const&) const
|
||||
{
|
||||
dbgln("FIXME: ResolvedCSSStyleDeclaration::custom_property is not implemented");
|
||||
return {};
|
||||
}
|
||||
|
||||
static WebIDL::ExceptionOr<void> cannot_modify_computed_property_error(JS::Realm& realm)
|
||||
{
|
||||
return WebIDL::NoModificationAllowedError::create(realm, "Cannot modify properties in result of getComputedStyle()"_string);
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
virtual String item(size_t index) const override;
|
||||
|
||||
virtual Optional<StyleProperty> property(PropertyID) const override;
|
||||
virtual Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const override;
|
||||
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority) override;
|
||||
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority) override;
|
||||
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID) override;
|
||||
|
|
|
@ -260,7 +260,7 @@ ErrorOr<NonnullRefPtr<Gfx::Typeface>> FontLoader::try_load_font()
|
|||
mime_type = MimeSniff::Resource::sniff(resource()->encoded_data(), Web::MimeSniff::SniffingConfiguration { .sniffing_context = Web::MimeSniff::SniffingContext::Font });
|
||||
}
|
||||
if (mime_type.has_value()) {
|
||||
if (mime_type->essence() == "font/ttf"sv || mime_type->essence() == "application/x-font-ttf"sv) {
|
||||
if (mime_type->essence() == "font/ttf"sv || mime_type->essence() == "application/x-font-ttf"sv || mime_type->essence() == "font/otf"sv) {
|
||||
if (auto result = Gfx::Typeface::try_load_from_externally_owned_memory(resource()->encoded_data()); !result.is_error()) {
|
||||
return result;
|
||||
}
|
||||
|
@ -2111,6 +2111,13 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
|||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontStyle, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontWeight, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::LineHeight, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontVariant, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontVariantAlternates, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontVariantCaps, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontVariantEastAsian, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontVariantLigatures, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontVariantNumeric, pseudo_element);
|
||||
compute_defaulted_property_value(style, element, CSS::PropertyID::FontVariantPosition, pseudo_element);
|
||||
|
||||
auto const& font_family = style.property(CSS::PropertyID::FontFamily);
|
||||
auto const& font_size = style.property(CSS::PropertyID::FontSize);
|
||||
|
|
|
@ -1143,12 +1143,6 @@ Variant<CSS::VerticalAlign, CSS::LengthPercentage> StyleProperties::vertical_ali
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
Optional<CSS::FontVariant> StyleProperties::font_variant() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontVariant);
|
||||
return keyword_to_font_variant(value.to_keyword());
|
||||
}
|
||||
|
||||
Optional<FlyString> StyleProperties::font_language_override() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontLanguageOverride);
|
||||
|
@ -1157,6 +1151,42 @@ Optional<FlyString> StyleProperties::font_language_override() const
|
|||
return {};
|
||||
}
|
||||
|
||||
Gfx::FontVariantAlternates StyleProperties::font_variant_alternates() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontVariantAlternates);
|
||||
return value.to_font_variant_alternates();
|
||||
}
|
||||
|
||||
Optional<FontVariantCaps> StyleProperties::font_variant_caps() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontVariantCaps);
|
||||
return value.to_font_variant_caps();
|
||||
}
|
||||
|
||||
Gfx::FontVariantEastAsian StyleProperties::font_variant_east_asian() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontVariantEastAsian);
|
||||
return value.to_font_variant_east_asian();
|
||||
}
|
||||
|
||||
Gfx::FontVariantLigatures StyleProperties::font_variant_ligatures() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontVariantLigatures);
|
||||
return value.to_font_variant_ligatures();
|
||||
}
|
||||
|
||||
Gfx::FontVariantNumeric StyleProperties::font_variant_numeric() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontVariantNumeric);
|
||||
return value.to_font_variant_numeric();
|
||||
}
|
||||
|
||||
Optional<FontVariantPosition> StyleProperties::font_variant_position() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::FontVariantPosition);
|
||||
return value.to_font_variant_position();
|
||||
}
|
||||
|
||||
Optional<HashMap<FlyString, IntegerOrCalculated>> StyleProperties::font_feature_settings() const
|
||||
{
|
||||
auto const& value = property(PropertyID::FontFeatureSettings);
|
||||
|
|
|
@ -149,7 +149,12 @@ public:
|
|||
Optional<CSS::BoxSizing> box_sizing() const;
|
||||
Optional<CSS::PointerEvents> pointer_events() const;
|
||||
Variant<CSS::VerticalAlign, CSS::LengthPercentage> vertical_align() const;
|
||||
Optional<CSS::FontVariant> font_variant() const;
|
||||
Gfx::FontVariantAlternates font_variant_alternates() const;
|
||||
Optional<FontVariantCaps> font_variant_caps() const;
|
||||
Gfx::FontVariantEastAsian font_variant_east_asian() const;
|
||||
Gfx::FontVariantLigatures font_variant_ligatures() const;
|
||||
Gfx::FontVariantNumeric font_variant_numeric() const;
|
||||
Optional<FontVariantPosition> font_variant_position() const;
|
||||
Optional<FlyString> font_language_override() const;
|
||||
Optional<HashMap<FlyString, IntegerOrCalculated>> font_feature_settings() const;
|
||||
Optional<HashMap<FlyString, NumberOrCalculated>> font_variation_settings() const;
|
||||
|
|
|
@ -45,7 +45,7 @@ ValueComparingNonnullRefPtr<CSSColorValue> CSSColorValue::create_from_color(Colo
|
|||
return make_rgb_color(color);
|
||||
}
|
||||
|
||||
Optional<float> CSSColorValue::resolve_hue(CSSStyleValue const& style_value)
|
||||
Optional<double> CSSColorValue::resolve_hue(CSSStyleValue const& style_value)
|
||||
{
|
||||
// <number> | <angle> | none
|
||||
auto normalized = [](double number) {
|
||||
|
@ -67,11 +67,11 @@ Optional<float> CSSColorValue::resolve_hue(CSSStyleValue const& style_value)
|
|||
return {};
|
||||
}
|
||||
|
||||
Optional<float> CSSColorValue::resolve_with_reference_value(CSSStyleValue const& style_value, float one_hundred_percent_value)
|
||||
Optional<double> CSSColorValue::resolve_with_reference_value(CSSStyleValue const& style_value, float one_hundred_percent_value)
|
||||
{
|
||||
// <percentage> | <number> | none
|
||||
auto normalize_percentage = [one_hundred_percent_value](Percentage const& percentage) {
|
||||
return static_cast<float>(percentage.as_fraction()) * one_hundred_percent_value;
|
||||
return percentage.as_fraction() * one_hundred_percent_value;
|
||||
};
|
||||
|
||||
if (style_value.is_percentage())
|
||||
|
@ -94,7 +94,7 @@ Optional<float> CSSColorValue::resolve_with_reference_value(CSSStyleValue const&
|
|||
return {};
|
||||
}
|
||||
|
||||
Optional<float> CSSColorValue::resolve_alpha(CSSStyleValue const& style_value)
|
||||
Optional<double> CSSColorValue::resolve_alpha(CSSStyleValue const& style_value)
|
||||
{
|
||||
// <number> | <percentage> | none
|
||||
auto normalized = [](double number) {
|
||||
|
|
|
@ -48,9 +48,9 @@ protected:
|
|||
{
|
||||
}
|
||||
|
||||
static Optional<float> resolve_hue(CSSStyleValue const&);
|
||||
static Optional<float> resolve_with_reference_value(CSSStyleValue const&, float one_hundred_percent_value);
|
||||
static Optional<float> resolve_alpha(CSSStyleValue const&);
|
||||
static Optional<double> resolve_hue(CSSStyleValue const&);
|
||||
static Optional<double> resolve_with_reference_value(CSSStyleValue const&, float one_hundred_percent_value);
|
||||
static Optional<double> resolve_alpha(CSSStyleValue const&);
|
||||
|
||||
private:
|
||||
ColorType m_color_type;
|
||||
|
|
|
@ -25,8 +25,8 @@ Color CSSHWB::to_color(Optional<Layout::NodeWithStyle const&>) const
|
|||
return Color(gray, gray, gray, to_byte(alpha_val));
|
||||
}
|
||||
|
||||
float value = 1 - b_val;
|
||||
float saturation = 1 - (w_val / value);
|
||||
auto value = 1 - b_val;
|
||||
auto saturation = 1 - (w_val / value);
|
||||
return Color::from_hsv(h_val, saturation, value).with_opacity(alpha_val);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,60 @@ String ShorthandStyleValue::to_string() const
|
|||
longhand(PropertyID::FontSize)->to_string(),
|
||||
longhand(PropertyID::LineHeight)->to_string(),
|
||||
longhand(PropertyID::FontFamily)->to_string()));
|
||||
case PropertyID::FontVariant: {
|
||||
Vector<StringView> values;
|
||||
auto alternates = longhand(PropertyID::FontVariantAlternates)->to_font_variant_alternates();
|
||||
if (alternates.historical_forms)
|
||||
values.append("historical-forms"sv);
|
||||
auto caps_or_null = longhand(PropertyID::FontVariantCaps)->to_font_variant_caps();
|
||||
if (caps_or_null.has_value() && caps_or_null.value() != CSS::FontVariantCaps::Normal) {
|
||||
values.append(CSS::to_string(caps_or_null.release_value()));
|
||||
}
|
||||
auto east_asian = longhand(PropertyID::FontVariantEastAsian)->to_font_variant_east_asian();
|
||||
if (!east_asian.normal) {
|
||||
if (east_asian.variant != Gfx::FontVariantEastAsian::Variant::Unset)
|
||||
values.append(Gfx::font_variant_east_asian_to_string(east_asian));
|
||||
if (east_asian.width != Gfx::FontVariantEastAsian::Width::Unset)
|
||||
values.append(Gfx::font_variant_east_asian_to_string(east_asian));
|
||||
}
|
||||
auto ligatures = longhand(PropertyID::FontVariantLigatures)->to_font_variant_ligatures();
|
||||
if (!ligatures.normal && !ligatures.none) {
|
||||
if (ligatures.common != Gfx::FontVariantLigatures::Common::Unset)
|
||||
values.append(Gfx::font_variant_ligatures_to_string(ligatures));
|
||||
if (ligatures.discretionary != Gfx::FontVariantLigatures::Discretionary::Unset) {
|
||||
values.append(Gfx::font_variant_ligatures_to_string(ligatures));
|
||||
}
|
||||
if (ligatures.historical != Gfx::FontVariantLigatures::Historical::Unset) {
|
||||
values.append(Gfx::font_variant_ligatures_to_string(ligatures));
|
||||
}
|
||||
if (ligatures.contextual != Gfx::FontVariantLigatures::Contextual::Unset) {
|
||||
values.append(Gfx::font_variant_ligatures_to_string(ligatures));
|
||||
}
|
||||
}
|
||||
auto numeric = longhand(PropertyID::FontVariantNumeric)->to_font_variant_numeric();
|
||||
if (!numeric.normal) {
|
||||
if (numeric.ordinal)
|
||||
values.append("ordinal"sv);
|
||||
if (numeric.slashed_zero)
|
||||
values.append("slashed-zero"sv);
|
||||
if (numeric.figure != Gfx::FontVariantNumeric::Figure::Unset)
|
||||
values.append(Gfx::font_variant_numeric_to_string(numeric));
|
||||
if (numeric.spacing != Gfx::FontVariantNumeric::Spacing::Unset)
|
||||
values.append(Gfx::font_variant_numeric_to_string(numeric));
|
||||
if (numeric.fraction != Gfx::FontVariantNumeric::Fraction::Unset)
|
||||
values.append(Gfx::font_variant_numeric_to_string(numeric));
|
||||
}
|
||||
auto position_or_null = longhand(PropertyID::FontVariantPosition)->to_font_variant_position();
|
||||
if (position_or_null.has_value() && position_or_null.value() != CSS::FontVariantPosition::Normal) {
|
||||
values.append(CSS::to_string(position_or_null.release_value()));
|
||||
}
|
||||
StringBuilder builder;
|
||||
if (values.is_empty())
|
||||
builder.append("normal"sv);
|
||||
else
|
||||
builder.join(' ', values);
|
||||
return MUST(builder.to_string());
|
||||
}
|
||||
case PropertyID::GridArea: {
|
||||
auto& row_start = longhand(PropertyID::GridRowStart)->as_grid_track_placement();
|
||||
auto& column_start = longhand(PropertyID::GridColumnStart)->as_grid_track_placement();
|
||||
|
|
|
@ -2526,6 +2526,106 @@ WebIDL::ExceptionOr<JS::Value> ECDSA::verify(AlgorithmParams const& params, GC::
|
|||
return JS::Value(result);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#ecdh-operations
|
||||
WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> ECDH::generate_key(AlgorithmParams const& params, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
|
||||
{
|
||||
// 1. If usages contains an entry which is not "deriveKey" or "deriveBits" then throw a SyntaxError.
|
||||
for (auto const& usage : key_usages) {
|
||||
if (usage != Bindings::KeyUsage::Derivekey && usage != Bindings::KeyUsage::Derivebits) {
|
||||
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage))));
|
||||
}
|
||||
}
|
||||
|
||||
auto const& normalized_algorithm = static_cast<EcKeyGenParams const&>(params);
|
||||
|
||||
// 2. If the namedCurve member of normalizedAlgorithm is "P-256", "P-384" or "P-521":
|
||||
// Generate an Elliptic Curve key pair, as defined in [RFC6090]
|
||||
// with domain parameters for the curve identified by the namedCurve member of normalizedAlgorithm.
|
||||
Variant<Empty, ::Crypto::Curves::SECP256r1, ::Crypto::Curves::SECP384r1> curve;
|
||||
if (normalized_algorithm.named_curve.is_one_of("P-256"sv, "P-384"sv, "P-521"sv)) {
|
||||
if (normalized_algorithm.named_curve.equals_ignoring_ascii_case("P-256"sv))
|
||||
curve = ::Crypto::Curves::SECP256r1 {};
|
||||
|
||||
if (normalized_algorithm.named_curve.equals_ignoring_ascii_case("P-384"sv))
|
||||
curve = ::Crypto::Curves::SECP384r1 {};
|
||||
|
||||
// FIXME: Support P-521
|
||||
if (normalized_algorithm.named_curve.equals_ignoring_ascii_case("P-521"sv))
|
||||
return WebIDL::NotSupportedError::create(m_realm, "'P-521' is not supported yet"_string);
|
||||
} else {
|
||||
// If the namedCurve member of normalizedAlgorithm is a value specified in an applicable specification
|
||||
// that specifies the use of that value with ECDH:
|
||||
// Perform the ECDH generation steps specified in that specification,
|
||||
// passing in normalizedAlgorithm and resulting in an elliptic curve key pair.
|
||||
|
||||
// Otherwise: throw a NotSupportedError
|
||||
return WebIDL::NotSupportedError::create(m_realm, "Only 'P-256', 'P-384' and 'P-521' is supported"_string);
|
||||
}
|
||||
|
||||
// 3. If performing the operation results in an error, then throw a OperationError.
|
||||
auto maybe_private_key_data = curve.visit(
|
||||
[](Empty const&) -> ErrorOr<ByteBuffer> { return Error::from_string_literal("noop error"); },
|
||||
[](auto instance) { return instance.generate_private_key(); });
|
||||
|
||||
if (maybe_private_key_data.is_error())
|
||||
return WebIDL::OperationError::create(m_realm, "Failed to create valid crypto instance"_string);
|
||||
|
||||
auto private_key_data = maybe_private_key_data.release_value();
|
||||
|
||||
auto maybe_public_key_data = curve.visit(
|
||||
[](Empty const&) -> ErrorOr<ByteBuffer> { return Error::from_string_literal("noop error"); },
|
||||
[&](auto instance) { return instance.generate_public_key(private_key_data); });
|
||||
|
||||
if (maybe_public_key_data.is_error())
|
||||
return WebIDL::OperationError::create(m_realm, "Failed to create valid crypto instance"_string);
|
||||
|
||||
auto public_key_data = maybe_public_key_data.release_value();
|
||||
|
||||
// 4. Let algorithm be a new EcKeyAlgorithm object.
|
||||
auto algorithm = EcKeyAlgorithm::create(m_realm);
|
||||
|
||||
// 5. Set the name attribute of algorithm to "ECDH".
|
||||
algorithm->set_name("ECDH"_string);
|
||||
|
||||
// 6. Set the namedCurve attribute of algorithm to equal the namedCurve member of normalizedAlgorithm.
|
||||
algorithm->set_named_curve(normalized_algorithm.named_curve);
|
||||
|
||||
// 7. Let publicKey be a new CryptoKey representing the public key of the generated key pair.
|
||||
auto public_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { public_key_data });
|
||||
|
||||
// 8. Set the [[type]] internal slot of publicKey to "public"
|
||||
public_key->set_type(Bindings::KeyType::Public);
|
||||
|
||||
// 9. Set the [[algorithm]] internal slot of publicKey to algorithm.
|
||||
public_key->set_algorithm(algorithm);
|
||||
|
||||
// 10. Set the [[extractable]] internal slot of publicKey to true.
|
||||
public_key->set_extractable(true);
|
||||
|
||||
// 11. Set the [[usages]] internal slot of publicKey to be the empty list.
|
||||
public_key->set_usages({});
|
||||
|
||||
// 12. Let privateKey be a new CryptoKey representing the private key of the generated key pair.
|
||||
auto private_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { private_key_data });
|
||||
|
||||
// 13. Set the [[type]] internal slot of privateKey to "private"
|
||||
private_key->set_type(Bindings::KeyType::Private);
|
||||
|
||||
// 14. Set the [[algorithm]] internal slot of privateKey to algorithm.
|
||||
private_key->set_algorithm(algorithm);
|
||||
|
||||
// 15. Set the [[extractable]] internal slot of privateKey to extractable.
|
||||
private_key->set_extractable(extractable);
|
||||
|
||||
// 16. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "deriveKey", "deriveBits" ].
|
||||
private_key->set_usages(usage_intersection(key_usages, { { Bindings::KeyUsage::Derivekey, Bindings::KeyUsage::Derivebits } }));
|
||||
|
||||
// 17. Let result be a new CryptoKeyPair dictionary.
|
||||
// 18. Set the publicKey attribute of result to be publicKey.
|
||||
// 19. Set the privateKey attribute of result to be privateKey.
|
||||
// 20. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].
|
||||
return Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>> { CryptoKeyPair::create(m_realm, public_key, private_key) };
|
||||
}
|
||||
// https://wicg.github.io/webcrypto-secure-curves/#ed25519-operations
|
||||
WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> ED25519::generate_key([[maybe_unused]] AlgorithmParams const& params, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
|
||||
{
|
||||
|
|
|
@ -493,6 +493,22 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ECDH : public AlgorithmMethods {
|
||||
public:
|
||||
virtual WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
|
||||
// TODO: virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, GC::Ref<CryptoKey>, Optional<u32>) override;
|
||||
// TODO: virtual WebIDL::ExceptionOr<GC::Ref<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
|
||||
// TODO: virtual WebIDL::ExceptionOr<GC::Ref<JS::Object>> export_key(Bindings::KeyFormat, GC::Ref<CryptoKey>) override;
|
||||
|
||||
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ECDH(realm)); }
|
||||
|
||||
private:
|
||||
explicit ECDH(JS::Realm& realm)
|
||||
: AlgorithmMethods(realm)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class ED25519 : public AlgorithmMethods {
|
||||
public:
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> sign(AlgorithmParams const&, GC::Ref<CryptoKey>, ByteBuffer const&) override;
|
||||
|
|
|
@ -801,10 +801,10 @@ SupportedAlgorithmsMap supported_algorithms()
|
|||
// FIXME: define_an_algorithm<ECDSA>("exportKey"_string, "ECDSA"_string);
|
||||
|
||||
// https://w3c.github.io/webcrypto/#ecdh-registration
|
||||
// FIXME: define_an_algorithm<ECDH, EcKeyGenParams>("generateKey"_string, "ECDH"_string);
|
||||
// FIXME: define_an_algorithm<ECDH, EcdhKeyDerivePrams>("deriveBits"_string, "ECDH"_string);
|
||||
// FIXME: define_an_algorithm<ECDH, EcKeyImportParams>("importKey"_string, "ECDH"_string);
|
||||
// FIXME: define_an_algorithm<ECDH>("exportKey"_string, "ECDH"_string);
|
||||
define_an_algorithm<ECDH, EcKeyGenParams>("generateKey"_string, "ECDH"_string);
|
||||
|
||||
// https://w3c.github.io/webcrypto/#aes-ctr-registration
|
||||
define_an_algorithm<AesCtr, AesCtrParams>("encrypt"_string, "AES-CTR"_string);
|
||||
|
|
|
@ -1606,7 +1606,7 @@ GC::Ref<HTML::HTMLAllCollection> Document::all()
|
|||
GC::Ref<CSS::FontFaceSet> Document::fonts()
|
||||
{
|
||||
if (!m_fonts)
|
||||
m_fonts = CSS::FontFaceSet::create(realm());
|
||||
m_fonts = CSS::FontFaceSet::create(page(), realm());
|
||||
return *m_fonts;
|
||||
}
|
||||
|
||||
|
|
|
@ -575,7 +575,7 @@ CanvasRenderingContext2D::PreparedText CanvasRenderingContext2D::prepare_text(By
|
|||
Gfx::FloatPoint anchor { 0, 0 };
|
||||
auto physical_alignment = Gfx::TextAlignment::CenterLeft;
|
||||
|
||||
auto glyph_run = Gfx::shape_text(anchor, 0, replaced_text.code_points(), *font, Gfx::GlyphRun::TextType::Ltr);
|
||||
auto glyph_run = Gfx::shape_text(anchor, 0, replaced_text.code_points(), *font, Gfx::GlyphRun::TextType::Ltr, {});
|
||||
|
||||
// 8. Let result be an array constructed by iterating over each glyph in the inline box from left to right (if any), adding to the array, for each glyph, the shape of the glyph as it is in the inline box, positioned on a coordinate space using CSS pixels with its origin is at the anchor point.
|
||||
PreparedText prepared_text { glyph_run, physical_alignment, { 0, 0, static_cast<int>(glyph_run->width()), static_cast<int>(height) } };
|
||||
|
|
|
@ -161,7 +161,7 @@ ENUMERATE_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE)
|
|||
GC::Ref<CSS::FontFaceSet> WorkerGlobalScope::fonts()
|
||||
{
|
||||
if (!m_fonts)
|
||||
m_fonts = CSS::FontFaceSet::create(realm());
|
||||
m_fonts = CSS::FontFaceSet::create(*page(), realm());
|
||||
return *m_fonts;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibGfx/Font/FontVariant.h>
|
||||
#include <LibWeb/Layout/BreakNode.h>
|
||||
#include <LibWeb/Layout/InlineFormattingContext.h>
|
||||
#include <LibWeb/Layout/InlineLevelIterator.h>
|
||||
|
@ -200,6 +201,255 @@ Gfx::GlyphRun::TextType InlineLevelIterator::resolve_text_direction_from_context
|
|||
return Gfx::GlyphRun::TextType::ContextDependent;
|
||||
}
|
||||
|
||||
HashMap<StringView, u8> InlineLevelIterator::shape_features_map() const
|
||||
{
|
||||
HashMap<StringView, u8> features;
|
||||
|
||||
auto& computed_values = m_current_node->computed_values();
|
||||
|
||||
// 6.4 https://drafts.csswg.org/css-fonts/#font-variant-ligatures-prop
|
||||
auto ligature = computed_values.font_variant_ligatures();
|
||||
if (ligature.normal) {
|
||||
// A value of normal specifies that common default features are enabled, as described in detail in the next section.
|
||||
features.set("liga"sv, 1);
|
||||
features.set("clig"sv, 1);
|
||||
} else if (ligature.none) {
|
||||
/* nothing */
|
||||
} else {
|
||||
switch (ligature.common) {
|
||||
case Gfx::FontVariantLigatures::Common::Common:
|
||||
// Enables display of common ligatures (OpenType features: liga, clig).
|
||||
features.set("liga"sv, 1);
|
||||
features.set("clig"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Common::NoCommon:
|
||||
// Disables display of common ligatures (OpenType features: liga, clig).
|
||||
features.set("liga"sv, 0);
|
||||
features.set("clig"sv, 0);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Common::Unset:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ligature.discretionary) {
|
||||
case Gfx::FontVariantLigatures::Discretionary::Discretionary:
|
||||
// Enables display of discretionary ligatures (OpenType feature: dlig).
|
||||
features.set("dlig"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Discretionary::NoDiscretionary:
|
||||
// Disables display of discretionary ligatures (OpenType feature: dlig).
|
||||
features.set("dlig"sv, 0);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Discretionary::Unset:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ligature.historical) {
|
||||
case Gfx::FontVariantLigatures::Historical::Historical:
|
||||
// Enables display of historical ligatures (OpenType feature: hlig).
|
||||
features.set("hlig"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Historical::NoHistorical:
|
||||
// Disables display of historical ligatures (OpenType feature: hlig).
|
||||
features.set("hlig"sv, 0);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Historical::Unset:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ligature.contextual) {
|
||||
case Gfx::FontVariantLigatures::Contextual::Contextual:
|
||||
// Enables display of contextual ligatures (OpenType feature: calt).
|
||||
features.set("calt"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Contextual::NoContextual:
|
||||
// Disables display of contextual ligatures (OpenType feature: calt).
|
||||
features.set("calt"sv, 0);
|
||||
break;
|
||||
case Gfx::FontVariantLigatures::Contextual::Unset:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 6.5 https://drafts.csswg.org/css-fonts/#font-variant-position-prop
|
||||
switch (computed_values.font_variant_position()) {
|
||||
case CSS::FontVariantPosition::Normal:
|
||||
// None of the features listed below are enabled.
|
||||
break;
|
||||
case CSS::FontVariantPosition::Sub:
|
||||
// Enables display of subscripts (OpenType feature: subs).
|
||||
features.set("subs"sv, 1);
|
||||
break;
|
||||
case CSS::FontVariantPosition::Super:
|
||||
// Enables display of superscripts (OpenType feature: sups).
|
||||
features.set("sups"sv, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 6.6 https://drafts.csswg.org/css-fonts/#font-variant-caps-prop
|
||||
switch (computed_values.font_variant_caps()) {
|
||||
case CSS::FontVariantCaps::Normal:
|
||||
// None of the features listed below are enabled.
|
||||
break;
|
||||
case CSS::FontVariantCaps::SmallCaps:
|
||||
// Enables display of small capitals (OpenType feature: smcp). Small-caps glyphs typically use the form of uppercase letters but are reduced to the size of lowercase letters.
|
||||
features.set("smcp"sv, 1);
|
||||
break;
|
||||
case CSS::FontVariantCaps::AllSmallCaps:
|
||||
// Enables display of small capitals for both upper and lowercase letters (OpenType features: c2sc, smcp).
|
||||
features.set("c2sc"sv, 1);
|
||||
features.set("smcp"sv, 1);
|
||||
break;
|
||||
case CSS::FontVariantCaps::PetiteCaps:
|
||||
// Enables display of petite capitals (OpenType feature: pcap).
|
||||
features.set("pcap"sv, 1);
|
||||
break;
|
||||
case CSS::FontVariantCaps::AllPetiteCaps:
|
||||
// Enables display of petite capitals for both upper and lowercase letters (OpenType features: c2pc, pcap).
|
||||
features.set("c2pc"sv, 1);
|
||||
features.set("pcap"sv, 1);
|
||||
break;
|
||||
case CSS::FontVariantCaps::Unicase:
|
||||
// Enables display of mixture of small capitals for uppercase letters with normal lowercase letters (OpenType feature: unic).
|
||||
features.set("unic"sv, 1);
|
||||
break;
|
||||
case CSS::FontVariantCaps::TitlingCaps:
|
||||
// Enables display of titling capitals (OpenType feature: titl).
|
||||
features.set("titl"sv, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 6.7 https://drafts.csswg.org/css-fonts/#font-variant-numeric-prop
|
||||
auto numeric = computed_values.font_variant_numeric();
|
||||
// None of the features listed below are enabled.
|
||||
if (numeric.normal) {
|
||||
/* passthrough */
|
||||
}
|
||||
|
||||
if (numeric.figure == Gfx::FontVariantNumeric::Figure::Oldstyle) {
|
||||
// Enables display of old-style numerals (OpenType feature: onum).
|
||||
features.set("onum"sv, 1);
|
||||
} else if (numeric.figure == Gfx::FontVariantNumeric::Figure::Lining) {
|
||||
// Enables display of lining numerals (OpenType feature: lnum).
|
||||
features.set("lnum"sv, 1);
|
||||
}
|
||||
|
||||
if (numeric.spacing == Gfx::FontVariantNumeric::Spacing::Proportional) {
|
||||
// Enables display of proportional numerals (OpenType feature: pnum).
|
||||
features.set("pnum"sv, 1);
|
||||
} else if (numeric.spacing == Gfx::FontVariantNumeric::Spacing::Tabular) {
|
||||
// Enables display of tabular numerals (OpenType feature: tnum).
|
||||
features.set("tnum"sv, 1);
|
||||
}
|
||||
|
||||
if (numeric.fraction == Gfx::FontVariantNumeric::Fraction::Diagonal) {
|
||||
// Enables display of diagonal fractions (OpenType feature: frac).
|
||||
features.set("frac"sv, 1);
|
||||
} else if (numeric.fraction == Gfx::FontVariantNumeric::Fraction::Stacked) {
|
||||
// Enables display of stacked fractions (OpenType feature: afrc).
|
||||
features.set("afrc"sv, 1);
|
||||
}
|
||||
|
||||
if (numeric.ordinal) {
|
||||
// Enables display of letter forms used with ordinal numbers (OpenType feature: ordn).
|
||||
features.set("ordn"sv, 1);
|
||||
}
|
||||
if (numeric.slashed_zero) {
|
||||
// Enables display of slashed zeros (OpenType feature: zero).
|
||||
features.set("zero"sv, 1);
|
||||
}
|
||||
|
||||
// 6.10 https://drafts.csswg.org/css-fonts/#font-variant-east-asian-prop
|
||||
auto east_asian = computed_values.font_variant_east_asian();
|
||||
switch (east_asian.variant) {
|
||||
case Gfx::FontVariantEastAsian::Variant::Jis78:
|
||||
// Enables display of JIS78 forms (OpenType feature: jp78).
|
||||
features.set("jp78"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantEastAsian::Variant::Jis83:
|
||||
// Enables display of JIS83 forms (OpenType feature: jp83).
|
||||
features.set("jp83"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantEastAsian::Variant::Jis90:
|
||||
// Enables display of JIS90 forms (OpenType feature: jp90).
|
||||
features.set("jp90"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantEastAsian::Variant::Jis04:
|
||||
// Enables display of JIS04 forms (OpenType feature: jp04).
|
||||
features.set("jp04"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantEastAsian::Variant::Simplified:
|
||||
// Enables display of simplified forms (OpenType feature: smpl).
|
||||
features.set("smpl"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantEastAsian::Variant::Traditional:
|
||||
// Enables display of traditional forms (OpenType feature: trad).
|
||||
features.set("trad"sv, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (east_asian.width) {
|
||||
case Gfx::FontVariantEastAsian::Width::FullWidth:
|
||||
// Enables display of full-width forms (OpenType feature: fwid).
|
||||
features.set("fwid"sv, 1);
|
||||
break;
|
||||
case Gfx::FontVariantEastAsian::Width::Proportional:
|
||||
// Enables display of proportional-width forms (OpenType feature: pwid).
|
||||
features.set("pwid"sv, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (east_asian.ruby) {
|
||||
// Enables display of ruby forms (OpenType feature: ruby).
|
||||
features.set("ruby"sv, 1);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
Gfx::ShapeFeatures InlineLevelIterator::create_and_merge_font_features() const
|
||||
{
|
||||
HashMap<StringView, u8> merged_features;
|
||||
auto& computed_values = m_inline_formatting_context.containing_block().computed_values();
|
||||
|
||||
// https://www.w3.org/TR/css-fonts-3/#feature-precedence
|
||||
|
||||
// FIXME 1. Font features enabled by default, including features required for a given script.
|
||||
|
||||
// FIXME 2. If the font is defined via an @font-face rule, the font features implied by the font-feature-settings descriptor in the @font-face rule.
|
||||
|
||||
// 3. Font features implied by the value of the ‘font-variant’ property, the related ‘font-variant’ subproperties and any other CSS property that uses OpenType features (e.g. the ‘font-kerning’ property).
|
||||
for (auto& it : shape_features_map()) {
|
||||
merged_features.set(it.key, it.value);
|
||||
}
|
||||
|
||||
// FIXME 4. Feature settings determined by properties other than ‘font-variant’ or ‘font-feature-settings’. For example, setting a non-default value for the ‘letter-spacing’ property disables common ligatures.
|
||||
|
||||
// 5. Font features implied by the value of ‘font-feature-settings’ property.
|
||||
auto font_feature_settings = computed_values.font_feature_settings();
|
||||
if (font_feature_settings.has_value()) {
|
||||
auto const& feature_settings = font_feature_settings.value();
|
||||
for (auto const& [key, feature_value] : feature_settings) {
|
||||
merged_features.set(key, feature_value.resolved(*m_current_node.ptr()));
|
||||
}
|
||||
}
|
||||
|
||||
Gfx::ShapeFeatures shape_features;
|
||||
shape_features.ensure_capacity(merged_features.size());
|
||||
|
||||
for (auto& it : merged_features) {
|
||||
shape_features.append({ { it.key[0], it.key[1], it.key[2], it.key[3] }, static_cast<u32>(it.value) });
|
||||
}
|
||||
|
||||
return shape_features;
|
||||
}
|
||||
|
||||
Optional<InlineLevelIterator::Item> InlineLevelIterator::next_without_lookahead()
|
||||
{
|
||||
if (!m_current_node)
|
||||
|
@ -293,7 +543,8 @@ Optional<InlineLevelIterator::Item> InlineLevelIterator::next_without_lookahead(
|
|||
x = tab_stop_dist.to_float();
|
||||
}
|
||||
|
||||
auto glyph_run = Gfx::shape_text({ x, 0 }, letter_spacing.to_float(), chunk.view, chunk.font, text_type);
|
||||
auto shape_features = create_and_merge_font_features();
|
||||
auto glyph_run = Gfx::shape_text({ x, 0 }, letter_spacing.to_float(), chunk.view, chunk.font, text_type, shape_features);
|
||||
|
||||
CSSPixels chunk_width = CSSPixels::nearest_value_for(glyph_run->width());
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ private:
|
|||
|
||||
void add_extra_box_model_metrics_to_item(Item&, bool add_leading_metrics, bool add_trailing_metrics);
|
||||
|
||||
HashMap<StringView, u8> shape_features_map() const;
|
||||
Gfx::ShapeFeatures create_and_merge_font_features() const;
|
||||
|
||||
Layout::Node const* next_inline_node_in_pre_order(Layout::Node const& current, Layout::Node const* stay_within);
|
||||
|
||||
Layout::InlineFormattingContext& m_inline_formatting_context;
|
||||
|
|
|
@ -458,10 +458,20 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
|||
if (auto box_sizing = computed_style.box_sizing(); box_sizing.has_value())
|
||||
computed_values.set_box_sizing(box_sizing.release_value());
|
||||
|
||||
if (auto maybe_font_variant = computed_style.font_variant(); maybe_font_variant.has_value())
|
||||
computed_values.set_font_variant(maybe_font_variant.release_value());
|
||||
if (auto maybe_font_language_override = computed_style.font_language_override(); maybe_font_language_override.has_value())
|
||||
computed_values.set_font_language_override(maybe_font_language_override.release_value());
|
||||
if (auto font_variant_alternates = computed_style.font_variant_alternates(); !font_variant_alternates.normal)
|
||||
computed_values.set_font_variant_alternates(font_variant_alternates);
|
||||
if (auto maybe_font_variant_caps = computed_style.font_variant_caps(); maybe_font_variant_caps.has_value())
|
||||
computed_values.set_font_variant_caps(maybe_font_variant_caps.release_value());
|
||||
if (auto font_variant_east_asian = computed_style.font_variant_east_asian(); !font_variant_east_asian.normal)
|
||||
computed_values.set_font_variant_east_asian(font_variant_east_asian);
|
||||
if (auto font_variant_ligatures = computed_style.font_variant_ligatures(); !font_variant_ligatures.normal)
|
||||
computed_values.set_font_variant_ligatures(font_variant_ligatures);
|
||||
if (auto font_variant_numeric = computed_style.font_variant_numeric(); !font_variant_numeric.normal)
|
||||
computed_values.set_font_variant_numeric(font_variant_numeric);
|
||||
if (auto maybe_font_variant_position = computed_style.font_variant_position(); maybe_font_variant_position.has_value())
|
||||
computed_values.set_font_variant_position(maybe_font_variant_position.release_value());
|
||||
if (auto maybe_font_feature_settings = computed_style.font_feature_settings(); maybe_font_feature_settings.has_value())
|
||||
computed_values.set_font_feature_settings(maybe_font_feature_settings.release_value());
|
||||
if (auto maybe_font_variation_settings = computed_style.font_variation_settings(); maybe_font_variation_settings.has_value())
|
||||
|
|
|
@ -177,8 +177,6 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto position = viewport_position;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
|
||||
if (!paint_root())
|
||||
|
@ -190,20 +188,20 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
|||
auto handled_event = EventResult::Dropped;
|
||||
|
||||
GC::Ptr<Painting::Paintable> paintable;
|
||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
|
||||
paintable = result->paintable;
|
||||
|
||||
if (paintable) {
|
||||
auto* containing_block = paintable->containing_block();
|
||||
while (containing_block) {
|
||||
auto handled_scroll_event = containing_block->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
||||
auto handled_scroll_event = containing_block->handle_mousewheel({}, viewport_position, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
||||
if (handled_scroll_event)
|
||||
return EventResult::Handled;
|
||||
|
||||
containing_block = containing_block->containing_block();
|
||||
}
|
||||
|
||||
if (paintable->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y))
|
||||
if (paintable->handle_mousewheel({}, viewport_position, buttons, modifiers, wheel_delta_x, wheel_delta_y))
|
||||
return EventResult::Handled;
|
||||
|
||||
auto node = dom_node_for_event_dispatch(*paintable);
|
||||
|
@ -212,7 +210,7 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
|||
// FIXME: Support wheel events in nested browsing contexts.
|
||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||
auto& iframe = static_cast<HTML::HTMLIFrameElement&>(*node);
|
||||
auto position_in_iframe = position.translated(compute_mouse_event_offset({}, paintable->layout_node()));
|
||||
auto position_in_iframe = viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node()));
|
||||
iframe.content_navigable()->event_handler().handle_mousewheel(position_in_iframe, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
||||
return EventResult::Dropped;
|
||||
}
|
||||
|
@ -222,10 +220,9 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
|||
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||
auto client_offset = compute_mouse_event_client_offset(position);
|
||||
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
||||
if (node->dispatch_event(UIEvents::WheelEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::wheel, screen_position, page_offset, client_offset, offset, wheel_delta_x, wheel_delta_y, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors())) {
|
||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
||||
if (node->dispatch_event(UIEvents::WheelEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::wheel, screen_position, page_offset, viewport_position, offset, wheel_delta_x, wheel_delta_y, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors())) {
|
||||
m_navigable->active_window()->scroll_by(wheel_delta_x, wheel_delta_y);
|
||||
}
|
||||
|
||||
|
@ -246,26 +243,24 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto position = viewport_position;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
||||
GC::Ptr<Painting::Paintable> paintable;
|
||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
|
||||
paintable = result->paintable;
|
||||
|
||||
if (paintable && paintable->wants_mouse_events()) {
|
||||
if (paintable->handle_mouseup({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||
if (paintable->handle_mouseup({}, viewport_position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||
return EventResult::Cancelled;
|
||||
|
||||
// Things may have changed as a consequence of Layout::Node::handle_mouseup(). Hit test again.
|
||||
if (!paint_root())
|
||||
return EventResult::Handled;
|
||||
|
||||
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::Exact); result.has_value())
|
||||
if (auto result = paint_root()->hit_test(viewport_position, Painting::HitTestType::Exact); result.has_value())
|
||||
paintable = result->paintable;
|
||||
}
|
||||
|
||||
|
@ -277,7 +272,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
|
|||
if (node) {
|
||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||
return content_navigable->event_handler().handle_mouseup(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||
return content_navigable->event_handler().handle_mouseup(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||
return EventResult::Dropped;
|
||||
}
|
||||
|
||||
|
@ -290,22 +285,21 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
|
|||
goto after_node_use;
|
||||
}
|
||||
|
||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||
auto client_offset = compute_mouse_event_client_offset(position);
|
||||
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
handled_event = EventResult::Handled;
|
||||
|
||||
bool run_activation_behavior = false;
|
||||
if (node.ptr() == m_mousedown_target) {
|
||||
if (button == UIEvents::MouseButton::Primary) {
|
||||
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
} else if (button == UIEvents::MouseButton::Middle) {
|
||||
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::auxclick, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::auxclick, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
} else if (button == UIEvents::MouseButton::Secondary) {
|
||||
// Allow the user to bypass custom context menus by holding shift, like Firefox.
|
||||
if ((modifiers & UIEvents::Mod_Shift) == 0)
|
||||
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::contextmenu, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::contextmenu, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
else
|
||||
run_activation_behavior = true;
|
||||
}
|
||||
|
@ -378,8 +372,6 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto position = viewport_position;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
|
||||
if (!paint_root())
|
||||
|
@ -390,7 +382,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
|
||||
{
|
||||
GC::Ptr<Painting::Paintable> paintable;
|
||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
|
||||
paintable = result->paintable;
|
||||
else
|
||||
return EventResult::Dropped;
|
||||
|
@ -403,7 +395,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
document->set_hovered_node(node);
|
||||
|
||||
if (paintable->wants_mouse_events()) {
|
||||
if (paintable->handle_mousedown({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||
if (paintable->handle_mousedown({}, viewport_position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||
return EventResult::Cancelled;
|
||||
}
|
||||
|
||||
|
@ -412,7 +404,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
|
||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||
return content_navigable->event_handler().handle_mousedown(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||
return content_navigable->event_handler().handle_mousedown(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||
return EventResult::Dropped;
|
||||
}
|
||||
|
||||
|
@ -426,10 +418,9 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
return EventResult::Dropped;
|
||||
|
||||
m_mousedown_target = node.ptr();
|
||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||
auto client_offset = compute_mouse_event_client_offset(position);
|
||||
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousedown, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousedown, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
// NOTE: Dispatching an event may have disturbed the world.
|
||||
|
@ -437,7 +428,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
return EventResult::Accepted;
|
||||
|
||||
if (button == UIEvents::MouseButton::Primary) {
|
||||
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
|
||||
if (auto result = paint_root()->hit_test(viewport_position, Painting::HitTestType::TextCursor); result.has_value()) {
|
||||
auto paintable = result->paintable;
|
||||
auto dom_node = paintable->dom_node();
|
||||
if (dom_node) {
|
||||
|
@ -494,8 +485,6 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto position = viewport_position;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
|
||||
if (!paint_root())
|
||||
|
@ -510,7 +499,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
GC::Ptr<Painting::Paintable> paintable;
|
||||
Optional<int> start_index;
|
||||
|
||||
if (auto result = target_for_mouse_position(position); result.has_value()) {
|
||||
if (auto result = target_for_mouse_position(viewport_position); result.has_value()) {
|
||||
paintable = result->paintable;
|
||||
start_index = result->index_in_node;
|
||||
}
|
||||
|
@ -519,7 +508,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
if (paintable) {
|
||||
if (paintable->wants_mouse_events()) {
|
||||
document.set_hovered_node(paintable->dom_node());
|
||||
if (paintable->handle_mousemove({}, position, buttons, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||
if (paintable->handle_mousemove({}, viewport_position, buttons, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||
return EventResult::Cancelled;
|
||||
|
||||
// FIXME: It feels a bit aggressive to always update the cursor like this.
|
||||
|
@ -530,7 +519,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
|
||||
if (node && is<HTML::HTMLIFrameElement>(*node)) {
|
||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||
return content_navigable->event_handler().handle_mousemove(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, buttons, modifiers);
|
||||
return content_navigable->event_handler().handle_mousemove(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, buttons, modifiers);
|
||||
return EventResult::Dropped;
|
||||
}
|
||||
|
||||
|
@ -563,14 +552,13 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
hovered_node_cursor = cursor_css_to_gfx(cursor);
|
||||
}
|
||||
|
||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||
auto client_offset = compute_mouse_event_client_offset(position);
|
||||
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
||||
auto movement = compute_mouse_event_movement(screen_position);
|
||||
|
||||
m_mousemove_previous_screen_position = screen_position;
|
||||
|
||||
bool continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, client_offset, offset, movement, UIEvents::MouseButton::Primary, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
bool continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, viewport_position, offset, movement, UIEvents::MouseButton::Primary, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
if (!continue_)
|
||||
return EventResult::Cancelled;
|
||||
|
||||
|
@ -580,7 +568,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
}
|
||||
|
||||
if (m_in_mouse_selection) {
|
||||
auto hit = paint_root()->hit_test(position, Painting::HitTestType::TextCursor);
|
||||
auto hit = paint_root()->hit_test(viewport_position, Painting::HitTestType::TextCursor);
|
||||
if (m_mouse_selection_target) {
|
||||
if (hit.has_value()) {
|
||||
m_mouse_selection_target->set_selection_focus(*hit->paintable->dom_node(), hit->index_in_node);
|
||||
|
@ -635,16 +623,13 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
|||
|
||||
auto& document = *m_navigable->active_document();
|
||||
|
||||
auto scroll_offset = document.navigable()->viewport_scroll_offset();
|
||||
auto position = viewport_position.translated(scroll_offset);
|
||||
|
||||
document.update_layout();
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
||||
GC::Ptr<Painting::Paintable> paintable;
|
||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
|
||||
paintable = result->paintable;
|
||||
else
|
||||
return EventResult::Dropped;
|
||||
|
@ -665,7 +650,7 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
|||
|
||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||
return content_navigable->event_handler().handle_doubleclick(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||
return content_navigable->event_handler().handle_doubleclick(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||
return EventResult::Dropped;
|
||||
}
|
||||
|
||||
|
@ -675,17 +660,16 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
|||
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||
auto client_offset = compute_mouse_event_client_offset(position);
|
||||
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::dblclick, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::dblclick, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
// NOTE: Dispatching an event may have disturbed the world.
|
||||
if (!paint_root() || paint_root() != node->document().paintable_box())
|
||||
return EventResult::Accepted;
|
||||
|
||||
if (button == UIEvents::MouseButton::Primary) {
|
||||
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
|
||||
if (auto result = paint_root()->hit_test(viewport_position, Painting::HitTestType::TextCursor); result.has_value()) {
|
||||
if (!result->paintable->dom_node())
|
||||
return EventResult::Accepted;
|
||||
if (!is<Painting::TextPaintable>(*result->paintable))
|
||||
|
@ -738,19 +722,18 @@ EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPi
|
|||
return EventResult::Dropped;
|
||||
}
|
||||
|
||||
auto offset = compute_mouse_event_offset(viewport_position, paintable->layout_node());
|
||||
auto client_offset = compute_mouse_event_client_offset(viewport_position);
|
||||
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||
auto offset = compute_mouse_event_offset(page_offset, paintable->layout_node());
|
||||
|
||||
switch (type) {
|
||||
case DragEvent::Type::DragStart:
|
||||
return m_drag_and_drop_event_handler->handle_drag_start(document.realm(), screen_position, page_offset, client_offset, offset, button, buttons, modifiers, move(files));
|
||||
return m_drag_and_drop_event_handler->handle_drag_start(document.realm(), screen_position, page_offset, viewport_position, offset, button, buttons, modifiers, move(files));
|
||||
case DragEvent::Type::DragMove:
|
||||
return m_drag_and_drop_event_handler->handle_drag_move(document.realm(), document, *node, screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
|
||||
return m_drag_and_drop_event_handler->handle_drag_move(document.realm(), document, *node, screen_position, page_offset, viewport_position, offset, button, buttons, modifiers);
|
||||
case DragEvent::Type::DragEnd:
|
||||
return m_drag_and_drop_event_handler->handle_drag_leave(document.realm(), screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
|
||||
return m_drag_and_drop_event_handler->handle_drag_leave(document.realm(), screen_position, page_offset, viewport_position, offset, button, buttons, modifiers);
|
||||
case DragEvent::Type::Drop:
|
||||
return m_drag_and_drop_event_handler->handle_drop(document.realm(), screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
|
||||
return m_drag_and_drop_event_handler->handle_drop(document.realm(), screen_position, page_offset, viewport_position, offset, button, buttons, modifiers);
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -1113,15 +1096,6 @@ void EventHandler::set_mouse_event_tracking_paintable(Painting::Paintable* paint
|
|||
m_mouse_event_tracking_paintable = paintable;
|
||||
}
|
||||
|
||||
CSSPixelPoint EventHandler::compute_mouse_event_client_offset(CSSPixelPoint event_page_position) const
|
||||
{
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-mouseevent-clientx
|
||||
// The clientX attribute must return the x-coordinate of the position where the event occurred relative to the origin of the viewport.
|
||||
|
||||
auto scroll_offset = m_navigable->active_document()->navigable()->viewport_scroll_offset();
|
||||
return event_page_position.translated(-scroll_offset);
|
||||
}
|
||||
|
||||
CSSPixelPoint EventHandler::compute_mouse_event_page_offset(CSSPixelPoint event_client_offset) const
|
||||
{
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-mouseevent-pagex
|
||||
|
|
|
@ -578,6 +578,14 @@ Vector<GC::Root<DOM::Document>> Page::documents_in_active_window() const
|
|||
return documents;
|
||||
}
|
||||
|
||||
URL::URL Page::url() const
|
||||
{
|
||||
if (!top_level_traversable_is_initialized())
|
||||
return {};
|
||||
|
||||
return top_level_traversable()->active_document()->url();
|
||||
}
|
||||
|
||||
void Page::clear_selection()
|
||||
{
|
||||
for (auto const& document : documents_in_active_window()) {
|
||||
|
|
|
@ -212,6 +212,8 @@ public:
|
|||
FindInPageResult find_in_page_previous_match();
|
||||
Optional<FindInPageQuery> last_find_in_page_query() const { return m_last_find_in_page_query; }
|
||||
|
||||
URL::URL url() const;
|
||||
|
||||
private:
|
||||
explicit Page(GC::Ref<PageClient>);
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
@ -368,6 +370,7 @@ public:
|
|||
virtual void page_did_request_select_dropdown([[maybe_unused]] Web::CSSPixelPoint content_position, [[maybe_unused]] Web::CSSPixels minimum_width, [[maybe_unused]] Vector<Web::HTML::SelectItem> items) { }
|
||||
|
||||
virtual void page_did_finish_text_test([[maybe_unused]] String const& text) { }
|
||||
virtual void page_did_finish_loading_page_and_fonts([[maybe_unused]] URL::URL const& url) { }
|
||||
|
||||
virtual void page_did_change_theme_color(Gfx::Color) { }
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ void DisplayListRecorder::draw_text(Gfx::IntRect const& rect, String raw_text, G
|
|||
if (rect.is_empty())
|
||||
return;
|
||||
|
||||
auto glyph_run = Gfx::shape_text({}, 0, raw_text.code_points(), font, Gfx::GlyphRun::TextType::Ltr);
|
||||
auto glyph_run = Gfx::shape_text({}, 0, raw_text.code_points(), font, Gfx::GlyphRun::TextType::Ltr, {});
|
||||
float baseline_x = 0;
|
||||
if (alignment == Gfx::TextAlignment::CenterLeft) {
|
||||
baseline_x = rect.x();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibMedia/Audio/PlaybackStream.h>
|
||||
#include <LibWeb/Platform/AudioCodecPlugin.h>
|
||||
|
||||
|
|
|
@ -7,11 +7,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/EventReceiver.h>
|
||||
#include <LibHTTP/HeaderMap.h>
|
||||
#include <LibTLS/TLSv12.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWebSocket/Message.h>
|
||||
|
||||
namespace WebSocket {
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/Socket.h>
|
||||
#include <LibTLS/TLSv12.h>
|
||||
#include <LibWebSocket/Impl/WebSocketImplSerenity.h>
|
||||
|
||||
namespace WebSocket {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <LibCrypto/Hash/HashManager.h>
|
||||
#include <LibWebSocket/Impl/WebSocketImplSerenity.h>
|
||||
#include <LibWebSocket/WebSocket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace WebSocket {
|
||||
|
||||
|
|
|
@ -231,11 +231,14 @@ public:
|
|||
Function<void(String const&)> on_inspector_executed_console_script;
|
||||
Function<void(String const&)> on_inspector_exported_inspector_html;
|
||||
Function<void()> on_web_content_crashed;
|
||||
Function<void(URL::URL const&)> on_loading_page_and_fonts_finish;
|
||||
|
||||
virtual Web::DevicePixelSize viewport_size() const = 0;
|
||||
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0;
|
||||
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint content_position) const = 0;
|
||||
|
||||
u64 page_id() const;
|
||||
|
||||
protected:
|
||||
static constexpr auto ZOOM_MIN_LEVEL = 0.3f;
|
||||
static constexpr auto ZOOM_MAX_LEVEL = 5.0f;
|
||||
|
@ -245,7 +248,6 @@ protected:
|
|||
|
||||
WebContentClient& client();
|
||||
WebContentClient const& client() const;
|
||||
u64 page_id() const;
|
||||
virtual void update_zoom() = 0;
|
||||
|
||||
void handle_resize();
|
||||
|
|
|
@ -93,6 +93,15 @@ void WebContentClient::did_finish_text_test(u64 page_id, String const& text)
|
|||
}
|
||||
}
|
||||
|
||||
void WebContentClient::did_finish_loading_page_and_fonts(u64 page_id, URL::URL const& url)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||
if (view->on_loading_page_and_fonts_finish)
|
||||
view->on_loading_page_and_fonts_finish(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebContentClient::did_find_in_page(u64 page_id, size_t current_match_index, Optional<size_t> const& total_match_count)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||
|
|
|
@ -108,6 +108,7 @@ private:
|
|||
virtual void did_request_select_dropdown(u64 page_id, Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> const& items) override;
|
||||
virtual void did_finish_handling_input_event(u64 page_id, Web::EventResult event_result) override;
|
||||
virtual void did_finish_text_test(u64 page_id, String const& text) override;
|
||||
virtual void did_finish_loading_page_and_fonts(u64 page_id, URL::URL const& url) override;
|
||||
virtual void did_find_in_page(u64 page_id, size_t current_match_index, Optional<size_t> const& total_match_count) override;
|
||||
virtual void did_change_theme_color(u64 page_id, Gfx::Color color) override;
|
||||
virtual void did_insert_clipboard_entry(u64 page_id, String const& data, String const& presentation_style, String const& mime_type) override;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Format.h>
|
||||
#include <LibCrypto/ASN1/PEM.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -402,6 +402,7 @@ ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::File& f
|
|||
#include <LibWeb/CSS/Enums.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/PropertyID.h>
|
||||
#include <LibWeb/CSS/PropertyName.h>
|
||||
#include <LibWeb/CSS/CSSStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
||||
|
@ -436,6 +437,9 @@ Optional<PropertyID> property_id_from_camel_case_string(StringView string)
|
|||
|
||||
Optional<PropertyID> property_id_from_string(StringView string)
|
||||
{
|
||||
if (is_a_custom_property_name_string(string))
|
||||
return PropertyID::Custom;
|
||||
|
||||
if (Infra::is_ascii_case_insensitive_match(string, "all"sv))
|
||||
return PropertyID::All;
|
||||
)~~~");
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue