/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * internal interface representing CSS style rules that contain other * rules, such as @media rules */ #include "mozilla/css/GroupRule.h" #include "mozilla/dom/CSSRuleList.h" #include "nsPrintfCString.h" using namespace mozilla::dom; namespace mozilla::css { GroupRule::GroupRule(StyleSheet* aSheet, Rule* aParentRule, uint32_t aLineNumber, uint32_t aColumnNumber) : Rule(aSheet, aParentRule, aLineNumber, aColumnNumber) {} GroupRule::~GroupRule() { MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called"); if (mRuleList) { mRuleList->DropReferences(); } } NS_IMPL_ADDREF_INHERITED(GroupRule, Rule) NS_IMPL_RELEASE_INHERITED(GroupRule, Rule) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule) NS_INTERFACE_MAP_END_INHERITING(Rule) bool GroupRule::IsCCLeaf() const { if (!Rule::IsCCLeaf()) { return false; } return !mRuleList; } ServoCSSRuleList* GroupRule::CssRules() { if (!mRuleList) { // Lazily create the rule list since most style rules won't have child // rules. mRuleList = new ServoCSSRuleList(GetOrCreateRawRules(), GetStyleSheet(), this); } return mRuleList; } NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GroupRule, Rule) if (tmp->mRuleList) { // If tmp has a style sheet (which can happen if it gets unlinked // earlier than its owning style sheet), then we need to null out the // style sheet pointer on descendants now, before we clear mRuleList. tmp->mRuleList->DropReferences(); tmp->mRuleList = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GroupRule, Rule) ImplCycleCollectionTraverse(cb, tmp->mRuleList, "mRuleList"); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END #ifdef DEBUG void GroupRule::List(FILE* out, int32_t aIndent) const { // TODO list something reasonable? } #endif /* virtual */ void GroupRule::DropSheetReference() { if (mRuleList) { mRuleList->DropSheetReference(); } Rule::DropSheetReference(); } uint32_t GroupRule::InsertRule(const nsACString& aRule, uint32_t aIndex, ErrorResult& aRv) { if (IsReadOnly()) { return 0; } StyleSheet* sheet = GetStyleSheet(); if (NS_WARN_IF(!sheet)) { aRv.Throw(NS_ERROR_FAILURE); return 0; } uint32_t count = StyleRuleCount(); if (aIndex > count) { aRv.ThrowIndexSizeError(nsPrintfCString( "Can't insert rule at index %u because rule list length is %u", aIndex, count)); return 0; } NS_ASSERTION(count <= INT32_MAX, "Too many style rules!"); nsresult rv = sheet->InsertRuleIntoGroup(aRule, this, aIndex); if (NS_FAILED(rv)) { aRv.Throw(rv); return 0; } return aIndex; } void GroupRule::DeleteRule(uint32_t aIndex, ErrorResult& aRv) { if (IsReadOnly()) { return; } StyleSheet* sheet = GetStyleSheet(); if (NS_WARN_IF(!sheet)) { aRv.Throw(NS_ERROR_FAILURE); return; } uint32_t count = StyleRuleCount(); if (aIndex >= count) { aRv.ThrowIndexSizeError(nsPrintfCString( "Index %u is too large for list of length %u", aIndex, count)); return; } NS_ASSERTION(count <= INT32_MAX, "Too many style rules!"); nsresult rv = sheet->DeleteRuleFromGroup(this, aIndex); if (NS_FAILED(rv)) { aRv.Throw(rv); } } size_t GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { // TODO how to implement? return 0; } } // namespace mozilla::css