2025-04-08 14:33:01 +01:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <LibWeb/CSS/Serialize.h>
|
|
|
|
|
#include <LibWeb/CSS/URL.h>
|
2025-05-02 17:25:56 +01:00
|
|
|
|
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
2025-04-08 14:33:01 +01:00
|
|
|
|
|
|
|
|
|
namespace Web::CSS {
|
|
|
|
|
|
2025-06-09 17:20:04 +01:00
|
|
|
|
URL::URL(String url, Type type, Vector<RequestURLModifier> request_url_modifiers)
|
|
|
|
|
: m_type(type)
|
|
|
|
|
, m_url(move(url))
|
2025-05-02 17:25:56 +01:00
|
|
|
|
, m_request_url_modifiers(move(request_url_modifiers))
|
2025-04-08 14:33:01 +01:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://drafts.csswg.org/cssom-1/#serialize-a-url
|
|
|
|
|
String URL::to_string() const
|
|
|
|
|
{
|
2025-06-09 17:20:04 +01:00
|
|
|
|
// To serialize a URL means to create a string represented by "url(", followed by the serialization of the URL as a
|
|
|
|
|
// string, followed by ")".
|
|
|
|
|
// AD-HOC: Serialize as src() if it was declared as that.
|
2025-04-08 14:33:01 +01:00
|
|
|
|
StringBuilder builder;
|
2025-06-09 17:20:04 +01:00
|
|
|
|
switch (m_type) {
|
|
|
|
|
case Type::Url:
|
|
|
|
|
builder.append("url("sv);
|
|
|
|
|
break;
|
|
|
|
|
case Type::Src:
|
|
|
|
|
builder.append("src("sv);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-04-08 14:33:01 +01:00
|
|
|
|
serialize_a_string(builder, m_url);
|
2025-05-02 17:25:56 +01:00
|
|
|
|
|
|
|
|
|
// AD-HOC: Serialize the RequestURLModifiers
|
|
|
|
|
// Spec issue: https://github.com/w3c/csswg-drafts/issues/12057
|
|
|
|
|
for (auto const& modifier : m_request_url_modifiers)
|
|
|
|
|
builder.appendff(" {}", modifier.to_string());
|
|
|
|
|
|
2025-04-08 14:33:01 +01:00
|
|
|
|
builder.append(')');
|
|
|
|
|
|
|
|
|
|
return builder.to_string_without_validation();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool URL::operator==(URL const&) const = default;
|
|
|
|
|
|
2025-05-02 17:25:56 +01:00
|
|
|
|
RequestURLModifier RequestURLModifier::create_cross_origin(CrossOriginModifierValue value)
|
|
|
|
|
{
|
|
|
|
|
return RequestURLModifier { Type::CrossOrigin, value };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RequestURLModifier RequestURLModifier::create_integrity(FlyString value)
|
|
|
|
|
{
|
|
|
|
|
return RequestURLModifier { Type::Integrity, move(value) };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RequestURLModifier RequestURLModifier::create_referrer_policy(ReferrerPolicyModifierValue value)
|
|
|
|
|
{
|
|
|
|
|
return RequestURLModifier { Type::ReferrerPolicy, value };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RequestURLModifier::RequestURLModifier(Type type, Value value)
|
|
|
|
|
: m_type(type)
|
|
|
|
|
, m_value(move(value))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RequestURLModifier::modify_request(GC::Ref<Fetch::Infrastructure::Request> request) const
|
|
|
|
|
{
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
case Type::CrossOrigin: {
|
|
|
|
|
// https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-crossorigin-modifier
|
|
|
|
|
// The URL request modifier steps for this modifier given request req are:
|
|
|
|
|
|
|
|
|
|
// 1. Set req’s mode to "cors".
|
|
|
|
|
request->set_mode(Fetch::Infrastructure::Request::Mode::CORS);
|
|
|
|
|
|
|
|
|
|
// 2. If the given value is use-credentials, set req’s credentials mode to "include".
|
|
|
|
|
if (m_value == CrossOriginModifierValue::UseCredentials) {
|
|
|
|
|
request->set_credentials_mode(Fetch::Infrastructure::Request::CredentialsMode::Include);
|
|
|
|
|
}
|
|
|
|
|
// 3. Otherwise, set req’s credentials mode to "same-origin".
|
|
|
|
|
else {
|
|
|
|
|
request->set_credentials_mode(Fetch::Infrastructure::Request::CredentialsMode::SameOrigin);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Type::Integrity: {
|
|
|
|
|
// https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-integrity-modifier
|
|
|
|
|
|
|
|
|
|
// The URL request modifier steps for this modifier given request req are to set request’s integrity metadata to
|
|
|
|
|
// the given <string>.
|
|
|
|
|
request->set_integrity_metadata(m_value.get<FlyString>().to_string());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Type::ReferrerPolicy: {
|
|
|
|
|
// https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-referrerpolicy-modifier
|
|
|
|
|
// The URL request modifier steps for this modifier given request req are to set request’s referrer policy to the
|
|
|
|
|
// ReferrerPolicy that matches the given value.
|
|
|
|
|
auto referrer_policy = [](ReferrerPolicyModifierValue value) {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case ReferrerPolicyModifierValue::NoReferrer:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::NoReferrer;
|
|
|
|
|
case ReferrerPolicyModifierValue::NoReferrerWhenDowngrade:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::NoReferrerWhenDowngrade;
|
|
|
|
|
case ReferrerPolicyModifierValue::SameOrigin:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::SameOrigin;
|
|
|
|
|
case ReferrerPolicyModifierValue::Origin:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::Origin;
|
|
|
|
|
case ReferrerPolicyModifierValue::StrictOrigin:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::StrictOrigin;
|
|
|
|
|
case ReferrerPolicyModifierValue::OriginWhenCrossOrigin:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::OriginWhenCrossOrigin;
|
|
|
|
|
case ReferrerPolicyModifierValue::StrictOriginWhenCrossOrigin:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::StrictOriginWhenCrossOrigin;
|
|
|
|
|
case ReferrerPolicyModifierValue::UnsafeUrl:
|
|
|
|
|
return ReferrerPolicy::ReferrerPolicy::UnsafeURL;
|
|
|
|
|
}
|
|
|
|
|
VERIFY_NOT_REACHED();
|
|
|
|
|
}(m_value.get<ReferrerPolicyModifierValue>());
|
|
|
|
|
request->set_referrer_policy(referrer_policy);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String RequestURLModifier::to_string() const
|
|
|
|
|
{
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
case Type::CrossOrigin:
|
2025-08-07 12:01:58 +01:00
|
|
|
|
return MUST(String::formatted("cross-origin({})", CSS::to_string(m_value.get<CrossOriginModifierValue>())));
|
2025-05-02 17:25:56 +01:00
|
|
|
|
case Type::Integrity:
|
|
|
|
|
return MUST(String::formatted("integrity({})", serialize_a_string(m_value.get<FlyString>())));
|
|
|
|
|
case Type::ReferrerPolicy:
|
2025-08-07 12:01:58 +01:00
|
|
|
|
return MUST(String::formatted("referrer-policy({})", CSS::to_string(m_value.get<ReferrerPolicyModifierValue>())));
|
2025-05-02 17:25:56 +01:00
|
|
|
|
}
|
|
|
|
|
VERIFY_NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RequestURLModifier::operator==(RequestURLModifier const&) const = default;
|
|
|
|
|
|
2025-04-08 14:33:01 +01:00
|
|
|
|
}
|