CSSGroupingRule.cpp [plain text]
#include "config.h"
#include "CSSGroupingRule.h"
#include "CSSParser.h"
#include "CSSRuleList.h"
#include "CSSStyleSheet.h"
#include "ExceptionCode.h"
#include "StyleRule.h"
#include <wtf/text/StringBuilder.h>
namespace WebCore {
CSSGroupingRule::CSSGroupingRule(StyleRuleGroup& groupRule, CSSStyleSheet* parent)
: CSSRule(parent)
, m_groupRule(groupRule)
, m_childRuleCSSOMWrappers(groupRule.childRules().size())
{
}
CSSGroupingRule::~CSSGroupingRule()
{
ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
if (m_childRuleCSSOMWrappers[i])
m_childRuleCSSOMWrappers[i]->setParentRule(0);
}
}
ExceptionOr<unsigned> CSSGroupingRule::insertRule(const String& ruleString, unsigned index)
{
ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
if (index > m_groupRule->childRules().size()) {
return Exception { INDEX_SIZE_ERR };
}
CSSStyleSheet* styleSheet = parentStyleSheet();
RefPtr<StyleRuleBase> newRule = CSSParser::parseRule(parserContext(), styleSheet ? &styleSheet->contents() : nullptr, ruleString);
if (!newRule) {
return Exception { SYNTAX_ERR };
}
if (newRule->isImportRule() || newRule->isNamespaceRule()) {
return Exception { HIERARCHY_REQUEST_ERR };
}
CSSStyleSheet::RuleMutationScope mutationScope(this);
m_groupRule->wrapperInsertRule(index, newRule.releaseNonNull());
m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
return index;
}
ExceptionOr<void> CSSGroupingRule::deleteRule(unsigned index)
{
ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
if (index >= m_groupRule->childRules().size()) {
return Exception { INDEX_SIZE_ERR };
}
CSSStyleSheet::RuleMutationScope mutationScope(this);
m_groupRule->wrapperRemoveRule(index);
if (m_childRuleCSSOMWrappers[index])
m_childRuleCSSOMWrappers[index]->setParentRule(0);
m_childRuleCSSOMWrappers.remove(index);
return { };
}
void CSSGroupingRule::appendCssTextForItems(StringBuilder& result) const
{
unsigned size = length();
for (unsigned i = 0; i < size; ++i) {
result.appendLiteral(" ");
result.append(item(i)->cssText());
result.append('\n');
}
}
unsigned CSSGroupingRule::length() const
{
return m_groupRule->childRules().size();
}
CSSRule* CSSGroupingRule::item(unsigned index) const
{
if (index >= length())
return nullptr;
ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
RefPtr<CSSRule>& rule = m_childRuleCSSOMWrappers[index];
if (!rule)
rule = m_groupRule->childRules()[index]->createCSSOMWrapper(const_cast<CSSGroupingRule*>(this));
return rule.get();
}
CSSRuleList& CSSGroupingRule::cssRules() const
{
if (!m_ruleListCSSOMWrapper)
m_ruleListCSSOMWrapper = std::make_unique<LiveCSSRuleList<CSSGroupingRule>>(const_cast<CSSGroupingRule&>(*this));
return *m_ruleListCSSOMWrapper;
}
void CSSGroupingRule::reattach(StyleRuleBase& rule)
{
m_groupRule = static_cast<StyleRuleGroup&>(rule);
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
if (m_childRuleCSSOMWrappers[i])
m_childRuleCSSOMWrappers[i]->reattach(*m_groupRule.get().childRules()[i]);
}
}
}