ContentExtensionRule.h [plain text]
#pragma once
#if ENABLE(CONTENT_EXTENSIONS)
#include "ContentExtensionActions.h"
#include "ResourceLoadInfo.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
namespace ContentExtensions {
struct Trigger {
String urlFilter;
bool urlFilterIsCaseSensitive { false };
bool topURLConditionIsCaseSensitive { false };
ResourceFlags flags { 0 };
Vector<String> conditions;
enum class ConditionType {
None,
IfDomain,
UnlessDomain,
IfTopURL,
UnlessTopURL,
};
ConditionType conditionType { ConditionType::None };
WEBCORE_EXPORT Trigger isolatedCopy() const;
~Trigger()
{
ASSERT(conditions.isEmpty() == (conditionType == ConditionType::None));
if (topURLConditionIsCaseSensitive)
ASSERT(conditionType == ConditionType::IfTopURL || conditionType == ConditionType::UnlessTopURL);
}
bool isEmpty() const
{
return urlFilter.isEmpty()
&& !urlFilterIsCaseSensitive
&& !topURLConditionIsCaseSensitive
&& !flags
&& conditions.isEmpty()
&& conditionType == ConditionType::None;
}
bool operator==(const Trigger& other) const
{
return urlFilter == other.urlFilter
&& urlFilterIsCaseSensitive == other.urlFilterIsCaseSensitive
&& topURLConditionIsCaseSensitive == other.topURLConditionIsCaseSensitive
&& flags == other.flags
&& conditions == other.conditions
&& conditionType == other.conditionType;
}
};
struct TriggerHash {
static unsigned hash(const Trigger& trigger)
{
unsigned hash = trigger.urlFilterIsCaseSensitive ? 10619863 : 40960001;
if (!trigger.urlFilter.isNull())
hash ^= StringHash::hash(trigger.urlFilter);
hash = WTF::pairIntHash(hash, DefaultHash<ResourceFlags>::Hash::hash(trigger.flags));
for (const String& condition : trigger.conditions)
hash ^= StringHash::hash(condition);
hash ^= 1 << static_cast<unsigned>(trigger.conditionType);
return hash;
}
static bool equal(const Trigger& a, const Trigger& b)
{
return a == b;
}
static const bool safeToCompareToEmptyOrDeleted = false;
};
struct TriggerHashTraits : public WTF::CustomHashTraits<Trigger> {
static const bool emptyValueIsZero = false;
static const bool hasIsEmptyValueFunction = true;
static void constructDeletedValue(Trigger& trigger)
{
new (NotNull, std::addressof(trigger.urlFilter)) String(WTF::HashTableDeletedValue);
}
static bool isDeletedValue(const Trigger& trigger)
{
return trigger.urlFilter.isHashTableDeletedValue();
}
static Trigger emptyValue()
{
return Trigger();
}
static bool isEmptyValue(const Trigger& trigger)
{
return trigger.isEmpty();
}
};
struct Action {
Action(ActionType type, const String& stringArgument, uint32_t actionID = std::numeric_limits<uint32_t>::max())
: m_type(type)
, m_actionID(actionID)
, m_stringArgument(stringArgument)
{
ASSERT(hasStringArgument(type));
}
Action(ActionType type, uint32_t actionID = std::numeric_limits<uint32_t>::max())
: m_type(type)
, m_actionID(actionID)
{
ASSERT(!hasStringArgument(type));
}
bool operator==(const Action& other) const
{
return m_type == other.m_type
&& m_extensionIdentifier == other.m_extensionIdentifier
&& m_actionID == other.m_actionID
&& m_stringArgument == other.m_stringArgument;
}
static Action deserialize(const SerializedActionByte* actions, const uint32_t actionsLength, uint32_t location);
static ActionType deserializeType(const SerializedActionByte* actions, const uint32_t actionsLength, uint32_t location);
static uint32_t serializedLength(const SerializedActionByte* actions, const uint32_t actionsLength, uint32_t location);
void setExtensionIdentifier(const String& extensionIdentifier) { m_extensionIdentifier = extensionIdentifier; }
const String& extensionIdentifier() const { return m_extensionIdentifier; }
ActionType type() const { return m_type; }
uint32_t actionID() const { return m_actionID; }
const String& stringArgument() const { return m_stringArgument; }
WEBCORE_EXPORT Action isolatedCopy() const;
private:
Action(String&& extensionIdentifier, ActionType type, uint32_t actionID, String&& stringArgument)
: m_extensionIdentifier(WTFMove(extensionIdentifier))
, m_type(type)
, m_actionID(actionID)
, m_stringArgument(WTFMove(stringArgument))
{ }
String m_extensionIdentifier;
ActionType m_type;
uint32_t m_actionID;
String m_stringArgument;
};
class ContentExtensionRule {
public:
WEBCORE_EXPORT ContentExtensionRule(Trigger&&, Action&&);
const Trigger& trigger() const { return m_trigger; }
const Action& action() const { return m_action; }
ContentExtensionRule isolatedCopy() const
{
return { m_trigger.isolatedCopy(), m_action.isolatedCopy() };
}
bool operator==(const ContentExtensionRule& other) const
{
return m_trigger == other.m_trigger && m_action == other.m_action;
}
private:
Trigger m_trigger;
Action m_action;
};
} }
#endif // ENABLE(CONTENT_EXTENSIONS)