Split remaining CSSRules into internal and CSSOM types
[WebKit-https.git] / Source / WebCore / css / CSSMediaRule.cpp
1 /**
2  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3  * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
4  * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
5  * Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include "config.h"
24 #include "CSSMediaRule.h"
25
26 #include "CSSParser.h"
27 #include "CSSRuleList.h"
28 #include "ExceptionCode.h"
29 #include "StyleRule.h"
30 #include <wtf/text/StringBuilder.h>
31
32 namespace WebCore {
33
34 CSSMediaRule::CSSMediaRule(StyleRuleMedia* mediaRule, CSSStyleSheet* parent)
35     : CSSRule(parent, CSSRule::MEDIA_RULE)
36     , m_mediaRule(mediaRule)
37     , m_childRuleCSSOMWrappers(mediaRule->childRules().size())
38 {
39 }
40
41 CSSMediaRule::~CSSMediaRule()
42 {
43     ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size());
44
45     for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
46         if (m_childRuleCSSOMWrappers[i])
47             m_childRuleCSSOMWrappers[i]->setParentRule(0);
48     }
49 }
50
51 unsigned CSSMediaRule::insertRule(const String& ruleString, unsigned index, ExceptionCode& ec)
52 {
53     ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size());
54
55     if (index > m_mediaRule->childRules().size()) {
56         // INDEX_SIZE_ERR: Raised if the specified index is not a valid insertion point.
57         ec = INDEX_SIZE_ERR;
58         return 0;
59     }
60
61     CSSParser p(cssParserMode());
62     RefPtr<StyleRuleBase> newRule = p.parseRule(parentStyleSheet(), ruleString);
63     if (!newRule) {
64         // SYNTAX_ERR: Raised if the specified rule has a syntax error and is unparsable.
65         ec = SYNTAX_ERR;
66         return 0;
67     }
68
69     if (newRule->isImportRule()) {
70         // FIXME: an HIERARCHY_REQUEST_ERR should also be thrown for a @charset or a nested
71         // @media rule.  They are currently not getting parsed, resulting in a SYNTAX_ERR
72         // to get raised above.
73
74         // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified
75         // index, e.g., if an @import rule is inserted after a standard rule set or other
76         // at-rule.
77         ec = HIERARCHY_REQUEST_ERR;
78         return 0;
79     }
80     m_mediaRule->wrapperInsertRule(index, newRule);
81
82     m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
83
84     if (CSSStyleSheet* styleSheet = parentStyleSheet())
85         styleSheet->styleSheetChanged();
86
87     return index;
88 }
89
90 void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec)
91 {
92     ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size());
93
94     if (index >= m_mediaRule->childRules().size()) {
95         // INDEX_SIZE_ERR: Raised if the specified index does not correspond to a
96         // rule in the media rule list.
97         ec = INDEX_SIZE_ERR;
98         return;
99     }
100     m_mediaRule->wrapperRemoveRule(index);
101
102     if (m_childRuleCSSOMWrappers[index])
103         m_childRuleCSSOMWrappers[index]->setParentRule(0);
104     m_childRuleCSSOMWrappers.remove(index);
105
106     if (CSSStyleSheet* styleSheet = parentStyleSheet())
107         styleSheet->styleSheetChanged();
108 }
109
110 String CSSMediaRule::cssText() const
111 {
112     StringBuilder result;
113     result.append("@media ");
114     if (m_mediaRule->mediaQueries()) {
115         result.append(m_mediaRule->mediaQueries()->mediaText());
116         result.append(' ');
117     }
118     result.append("{ \n");
119     
120     unsigned size = length();
121     for (unsigned i = 0; i < size; ++i) {
122         result.append("  ");
123         result.append(item(i)->cssText());
124         result.append('\n');
125     }
126
127     result.append('}');
128     return result.toString();
129 }
130
131 MediaList* CSSMediaRule::media() const 
132
133     return m_mediaRule->mediaQueries() ? m_mediaRule->mediaQueries()->ensureMediaList(parentStyleSheet()) : 0; 
134 }
135
136 unsigned CSSMediaRule::length() const
137
138     return m_mediaRule->childRules().size(); 
139 }
140
141 CSSRule* CSSMediaRule::item(unsigned index) const
142
143     if (index >= length())
144         return 0;
145     ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size());
146     RefPtr<CSSRule>& rule = m_childRuleCSSOMWrappers[index];
147     if (!rule)
148         rule = m_mediaRule->childRules()[index]->createCSSOMWrapper(const_cast<CSSMediaRule*>(this));
149     return rule.get();
150 }
151
152 CSSRuleList* CSSMediaRule::cssRules() const
153 {
154     if (!m_ruleListCSSOMWrapper)
155         m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSMediaRule>(const_cast<CSSMediaRule*>(this)));
156     return m_ruleListCSSOMWrapper.get();
157 }
158
159 } // namespace WebCore