| /** |
| * (C) 1999-2003 Lars Knoll (knoll@kde.org) |
| * (C) 2002-2003 Dirk Mueller (mueller@kde.org) |
| * Copyright (C) 2002, 2005, 2006, 2012 Apple Computer, Inc. |
| * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "config.h" |
| #include "CSSMediaRule.h" |
| |
| #include "CSSParser.h" |
| #include "CSSRuleList.h" |
| #include "CSSStyleSheet.h" |
| #include "ExceptionCode.h" |
| #include "StyleRule.h" |
| #include "WebCoreMemoryInstrumentation.h" |
| #include <wtf/MemoryInstrumentationVector.h> |
| #include <wtf/text/StringBuilder.h> |
| |
| namespace WebCore { |
| |
| CSSMediaRule::CSSMediaRule(StyleRuleMedia* mediaRule, CSSStyleSheet* parent) |
| : CSSRule(parent) |
| , m_mediaRule(mediaRule) |
| , m_childRuleCSSOMWrappers(mediaRule->childRules().size()) |
| { |
| } |
| |
| CSSMediaRule::~CSSMediaRule() |
| { |
| ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); |
| |
| for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { |
| if (m_childRuleCSSOMWrappers[i]) |
| m_childRuleCSSOMWrappers[i]->setParentRule(0); |
| } |
| if (m_mediaCSSOMWrapper) |
| m_mediaCSSOMWrapper->clearParentRule(); |
| } |
| |
| unsigned CSSMediaRule::insertRule(const String& ruleString, unsigned index, ExceptionCode& ec) |
| { |
| ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); |
| |
| if (index > m_mediaRule->childRules().size()) { |
| // INDEX_SIZE_ERR: Raised if the specified index is not a valid insertion point. |
| ec = INDEX_SIZE_ERR; |
| return 0; |
| } |
| |
| CSSParser parser(parserContext()); |
| CSSStyleSheet* styleSheet = parentStyleSheet(); |
| RefPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->contents() : 0, ruleString); |
| if (!newRule) { |
| // SYNTAX_ERR: Raised if the specified rule has a syntax error and is unparsable. |
| ec = SYNTAX_ERR; |
| return 0; |
| } |
| |
| if (newRule->isImportRule()) { |
| // FIXME: an HIERARCHY_REQUEST_ERR should also be thrown for a @charset or a nested |
| // @media rule. They are currently not getting parsed, resulting in a SYNTAX_ERR |
| // to get raised above. |
| |
| // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified |
| // index, e.g., if an @import rule is inserted after a standard rule set or other |
| // at-rule. |
| ec = HIERARCHY_REQUEST_ERR; |
| return 0; |
| } |
| CSSStyleSheet::RuleMutationScope mutationScope(this); |
| |
| m_mediaRule->wrapperInsertRule(index, newRule); |
| |
| m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); |
| return index; |
| } |
| |
| void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec) |
| { |
| ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); |
| |
| if (index >= m_mediaRule->childRules().size()) { |
| // INDEX_SIZE_ERR: Raised if the specified index does not correspond to a |
| // rule in the media rule list. |
| ec = INDEX_SIZE_ERR; |
| return; |
| } |
| |
| CSSStyleSheet::RuleMutationScope mutationScope(this); |
| |
| m_mediaRule->wrapperRemoveRule(index); |
| |
| if (m_childRuleCSSOMWrappers[index]) |
| m_childRuleCSSOMWrappers[index]->setParentRule(0); |
| m_childRuleCSSOMWrappers.remove(index); |
| } |
| |
| String CSSMediaRule::cssText() const |
| { |
| StringBuilder result; |
| result.append("@media "); |
| if (m_mediaRule->mediaQueries()) { |
| result.append(m_mediaRule->mediaQueries()->mediaText()); |
| result.append(' '); |
| } |
| result.append("{ \n"); |
| |
| unsigned size = length(); |
| for (unsigned i = 0; i < size; ++i) { |
| result.append(" "); |
| result.append(item(i)->cssText()); |
| result.append('\n'); |
| } |
| |
| result.append('}'); |
| return result.toString(); |
| } |
| |
| MediaList* CSSMediaRule::media() const |
| { |
| if (!m_mediaRule->mediaQueries()) |
| return 0; |
| if (!m_mediaCSSOMWrapper) |
| m_mediaCSSOMWrapper = MediaList::create(m_mediaRule->mediaQueries(), const_cast<CSSMediaRule*>(this)); |
| return m_mediaCSSOMWrapper.get(); |
| } |
| |
| unsigned CSSMediaRule::length() const |
| { |
| return m_mediaRule->childRules().size(); |
| } |
| |
| CSSRule* CSSMediaRule::item(unsigned index) const |
| { |
| if (index >= length()) |
| return 0; |
| ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); |
| RefPtr<CSSRule>& rule = m_childRuleCSSOMWrappers[index]; |
| if (!rule) |
| rule = m_mediaRule->childRules()[index]->createCSSOMWrapper(const_cast<CSSMediaRule*>(this)); |
| return rule.get(); |
| } |
| |
| CSSRuleList* CSSMediaRule::cssRules() const |
| { |
| if (!m_ruleListCSSOMWrapper) |
| m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSMediaRule>(const_cast<CSSMediaRule*>(this))); |
| return m_ruleListCSSOMWrapper.get(); |
| } |
| |
| void CSSMediaRule::reattach(StyleRuleBase* rule) |
| { |
| ASSERT(rule); |
| ASSERT(rule->isMediaRule()); |
| m_mediaRule = static_cast<StyleRuleMedia*>(rule); |
| if (m_mediaCSSOMWrapper && m_mediaRule->mediaQueries()) |
| m_mediaCSSOMWrapper->reattach(m_mediaRule->mediaQueries()); |
| for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { |
| if (m_childRuleCSSOMWrappers[i]) |
| m_childRuleCSSOMWrappers[i]->reattach(m_mediaRule->childRules()[i].get()); |
| } |
| } |
| |
| void CSSMediaRule::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
| { |
| MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); |
| CSSRule::reportMemoryUsage(memoryObjectInfo); |
| info.addMember(m_mediaCSSOMWrapper); |
| info.addMember(m_childRuleCSSOMWrappers); |
| info.addMember(m_ruleListCSSOMWrapper); |
| } |
| |
| } // namespace WebCore |