|
Lines 1-6
Source/WebCore/css/CSSStyleSheet.cpp_sec1
|
| 1 |
/* |
1 |
/* |
| 2 |
* (C) 1999-2003 Lars Knoll (knoll@kde.org) |
2 |
* (C) 1999-2003 Lars Knoll (knoll@kde.org) |
| 3 |
* Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. |
3 |
* Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved. |
| 4 |
* |
4 |
* |
| 5 |
* This library is free software; you can redistribute it and/or |
5 |
* This library is free software; you can redistribute it and/or |
| 6 |
* modify it under the terms of the GNU Library General Public |
6 |
* modify it under the terms of the GNU Library General Public |
|
Lines 74-82
static bool isAcceptableCSSStyleSheetPar
Source/WebCore/css/CSSStyleSheet.cpp_sec2
|
| 74 |
} |
74 |
} |
| 75 |
#endif |
75 |
#endif |
| 76 |
|
76 |
|
| 77 |
CSSStyleSheet::CSSStyleSheet(Node* parentNode, const String& href, const KURL& baseURL, const String& charset) |
77 |
StyleSheetInternal::StyleSheetInternal(Node* parentNode, const String& originalURL, const KURL& finalURL, const String& charset) |
| 78 |
: StyleSheet(parentNode, href, baseURL) |
78 |
: m_ownerNode(parentNode) |
| 79 |
, m_ownerRule(0) |
79 |
, m_ownerRule(0) |
|
|
80 |
, m_originalURL(originalURL) |
| 81 |
, m_finalURL(finalURL) |
| 80 |
, m_charset(charset) |
82 |
, m_charset(charset) |
| 81 |
, m_loadCompleted(false) |
83 |
, m_loadCompleted(false) |
| 82 |
, m_cssParserMode(CSSQuirksMode) |
84 |
, m_cssParserMode(CSSQuirksMode) |
|
Lines 87-111
CSSStyleSheet::CSSStyleSheet(Node* paren
Source/WebCore/css/CSSStyleSheet.cpp_sec3
|
| 87 |
ASSERT(isAcceptableCSSStyleSheetParent(parentNode)); |
89 |
ASSERT(isAcceptableCSSStyleSheetParent(parentNode)); |
| 88 |
} |
90 |
} |
| 89 |
|
91 |
|
| 90 |
CSSStyleSheet::CSSStyleSheet(StyleRuleImport* ownerRule, const String& href, const KURL& baseURL, const String& charset) |
92 |
StyleSheetInternal::StyleSheetInternal(StyleRuleImport* ownerRule, const String& originalURL, const KURL& finalURL, const String& charset) |
| 91 |
: StyleSheet(href, baseURL) |
93 |
: m_ownerNode(0) |
| 92 |
, m_ownerRule(ownerRule) |
94 |
, m_ownerRule(ownerRule) |
|
|
95 |
, m_originalURL(originalURL) |
| 96 |
, m_finalURL(finalURL) |
| 93 |
, m_charset(charset) |
97 |
, m_charset(charset) |
| 94 |
, m_loadCompleted(false) |
98 |
, m_loadCompleted(false) |
| 95 |
, m_cssParserMode((ownerRule && ownerRule->parentStyleSheet()) ? ownerRule->parentStyleSheet()->cssParserMode() : CSSStrictMode) |
99 |
, m_cssParserMode((ownerRule && ownerRule->parentStyleSheet()) ? ownerRule->parentStyleSheet()->cssParserMode() : CSSStrictMode) |
| 96 |
, m_hasSyntacticallyValidCSSHeader(true) |
100 |
, m_hasSyntacticallyValidCSSHeader(true) |
| 97 |
, m_didLoadErrorOccur(false) |
101 |
, m_didLoadErrorOccur(false) |
| 98 |
{ |
102 |
{ |
| 99 |
CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; |
103 |
StyleSheetInternal* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; |
| 100 |
m_isUserStyleSheet = parentSheet ? parentSheet->isUserStyleSheet() : false; |
104 |
m_isUserStyleSheet = parentSheet ? parentSheet->isUserStyleSheet() : false; |
| 101 |
} |
105 |
} |
| 102 |
|
106 |
|
| 103 |
CSSStyleSheet::~CSSStyleSheet() |
107 |
StyleSheetInternal::~StyleSheetInternal() |
| 104 |
{ |
108 |
{ |
| 105 |
clearRules(); |
109 |
clearRules(); |
| 106 |
} |
110 |
} |
| 107 |
|
111 |
|
| 108 |
void CSSStyleSheet::parserAppendRule(PassRefPtr<StyleRuleBase> rule) |
112 |
void StyleSheetInternal::parserAppendRule(PassRefPtr<StyleRuleBase> rule) |
| 109 |
{ |
113 |
{ |
| 110 |
ASSERT(!rule->isCharsetRule()); |
114 |
ASSERT(!rule->isCharsetRule()); |
| 111 |
if (rule->isImportRule()) { |
115 |
if (rule->isImportRule()) { |
|
Lines 118-141
void CSSStyleSheet::parserAppendRule(Pas
Source/WebCore/css/CSSStyleSheet.cpp_sec4
|
| 118 |
m_childRules.append(rule); |
122 |
m_childRules.append(rule); |
| 119 |
} |
123 |
} |
| 120 |
|
124 |
|
| 121 |
PassRefPtr<CSSRule> CSSStyleSheet::createChildRuleCSSOMWrapper(unsigned index) |
125 |
PassRefPtr<CSSRule> StyleSheetInternal::createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper) |
| 122 |
{ |
126 |
{ |
| 123 |
ASSERT(index < length()); |
127 |
ASSERT(index < ruleCount()); |
| 124 |
|
128 |
|
| 125 |
unsigned childVectorIndex = index; |
129 |
unsigned childVectorIndex = index; |
| 126 |
if (hasCharsetRule()) { |
130 |
if (hasCharsetRule()) { |
| 127 |
if (index == 0) |
131 |
if (index == 0) |
| 128 |
return CSSCharsetRule::create(this, m_encodingFromCharsetRule); |
132 |
return CSSCharsetRule::create(parentWrapper, m_encodingFromCharsetRule); |
| 129 |
--childVectorIndex; |
133 |
--childVectorIndex; |
| 130 |
} |
134 |
} |
| 131 |
if (childVectorIndex < m_importRules.size()) |
135 |
if (childVectorIndex < m_importRules.size()) |
| 132 |
return m_importRules[childVectorIndex]->createCSSOMWrapper(this); |
136 |
return m_importRules[childVectorIndex]->createCSSOMWrapper(parentWrapper); |
| 133 |
|
137 |
|
| 134 |
childVectorIndex -= m_importRules.size(); |
138 |
childVectorIndex -= m_importRules.size(); |
| 135 |
return m_childRules[childVectorIndex]->createCSSOMWrapper(this); |
139 |
return m_childRules[childVectorIndex]->createCSSOMWrapper(parentWrapper); |
| 136 |
} |
140 |
} |
| 137 |
|
141 |
|
| 138 |
unsigned CSSStyleSheet::length() const |
142 |
unsigned StyleSheetInternal::ruleCount() const |
| 139 |
{ |
143 |
{ |
| 140 |
unsigned result = 0; |
144 |
unsigned result = 0; |
| 141 |
result += hasCharsetRule() ? 1 : 0; |
145 |
result += hasCharsetRule() ? 1 : 0; |
|
Lines 144-181
unsigned CSSStyleSheet::length() const
Source/WebCore/css/CSSStyleSheet.cpp_sec5
|
| 144 |
return result; |
148 |
return result; |
| 145 |
} |
149 |
} |
| 146 |
|
150 |
|
| 147 |
CSSRule* CSSStyleSheet::item(unsigned index) |
151 |
void StyleSheetInternal::clearCharsetRule() |
| 148 |
{ |
|
|
| 149 |
unsigned ruleCount = length(); |
| 150 |
if (index >= ruleCount) |
| 151 |
return 0; |
| 152 |
|
| 153 |
if (m_childRuleCSSOMWrappers.isEmpty()) |
| 154 |
m_childRuleCSSOMWrappers.grow(ruleCount); |
| 155 |
ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount); |
| 156 |
|
| 157 |
RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index]; |
| 158 |
if (!cssRule) |
| 159 |
cssRule = createChildRuleCSSOMWrapper(index); |
| 160 |
return cssRule.get(); |
| 161 |
} |
| 162 |
|
| 163 |
void CSSStyleSheet::clearCharsetRule() |
| 164 |
{ |
152 |
{ |
| 165 |
m_encodingFromCharsetRule = String(); |
153 |
m_encodingFromCharsetRule = String(); |
| 166 |
} |
154 |
} |
| 167 |
|
155 |
|
| 168 |
void CSSStyleSheet::clearRules() |
156 |
void StyleSheetInternal::clearRules() |
| 169 |
{ |
157 |
{ |
| 170 |
// For style rules outside the document, .parentStyleSheet can become null even if the style rule |
|
|
| 171 |
// is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but |
| 172 |
// it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection. |
| 173 |
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { |
| 174 |
if (m_childRuleCSSOMWrappers[i]) |
| 175 |
m_childRuleCSSOMWrappers[i]->setParentStyleSheet(0); |
| 176 |
} |
| 177 |
m_childRuleCSSOMWrappers.clear(); |
| 178 |
|
| 179 |
for (unsigned i = 0; i < m_importRules.size(); ++i) { |
158 |
for (unsigned i = 0; i < m_importRules.size(); ++i) { |
| 180 |
ASSERT(m_importRules.at(i)->parentStyleSheet() == this); |
159 |
ASSERT(m_importRules.at(i)->parentStyleSheet() == this); |
| 181 |
m_importRules[i]->clearParentStyleSheet(); |
160 |
m_importRules[i]->clearParentStyleSheet(); |
|
Lines 185-229
void CSSStyleSheet::clearRules()
Source/WebCore/css/CSSStyleSheet.cpp_sec6
|
| 185 |
clearCharsetRule(); |
164 |
clearCharsetRule(); |
| 186 |
} |
165 |
} |
| 187 |
|
166 |
|
| 188 |
void CSSStyleSheet::parserSetEncodingFromCharsetRule(const String& encoding) |
167 |
void StyleSheetInternal::parserSetEncodingFromCharsetRule(const String& encoding) |
| 189 |
{ |
168 |
{ |
| 190 |
// Parser enforces that there is ever only one @charset. |
169 |
// Parser enforces that there is ever only one @charset. |
| 191 |
ASSERT(m_encodingFromCharsetRule.isNull()); |
170 |
ASSERT(m_encodingFromCharsetRule.isNull()); |
| 192 |
m_encodingFromCharsetRule = encoding; |
171 |
m_encodingFromCharsetRule = encoding; |
| 193 |
} |
172 |
} |
| 194 |
|
173 |
|
| 195 |
PassRefPtr<CSSRuleList> CSSStyleSheet::rules() |
174 |
bool StyleSheetInternal::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index) |
| 196 |
{ |
175 |
{ |
| 197 |
KURL url = finalURL(); |
176 |
ASSERT(index <= ruleCount()); |
| 198 |
Document* document = findDocument(); |
|
|
| 199 |
if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url)) |
| 200 |
return 0; |
| 201 |
// IE behavior. |
| 202 |
RefPtr<StaticCSSRuleList> nonCharsetRules = StaticCSSRuleList::create(); |
| 203 |
unsigned ruleCount = length(); |
| 204 |
for (unsigned i = 0; i < ruleCount; ++i) { |
| 205 |
CSSRule* rule = item(i); |
| 206 |
if (rule->isCharsetRule()) |
| 207 |
continue; |
| 208 |
nonCharsetRules->rules().append(rule); |
| 209 |
} |
| 210 |
return nonCharsetRules.release(); |
| 211 |
} |
| 212 |
|
| 213 |
unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, ExceptionCode& ec) |
| 214 |
{ |
| 215 |
ec = 0; |
| 216 |
if (index > length()) { |
| 217 |
ec = INDEX_SIZE_ERR; |
| 218 |
return 0; |
| 219 |
} |
| 220 |
CSSParser p(cssParserMode()); |
| 221 |
RefPtr<StyleRuleBase> rule = p.parseRule(this, ruleString); |
| 222 |
|
| 223 |
if (!rule) { |
| 224 |
ec = SYNTAX_ERR; |
| 225 |
return 0; |
| 226 |
} |
| 227 |
// Parser::parseRule doesn't currently allow @charset so we don't need to deal with it. |
177 |
// Parser::parseRule doesn't currently allow @charset so we don't need to deal with it. |
| 228 |
ASSERT(!rule->isCharsetRule()); |
178 |
ASSERT(!rule->isCharsetRule()); |
| 229 |
|
179 |
|
|
Lines 232-330
unsigned CSSStyleSheet::insertRule(const
Source/WebCore/css/CSSStyleSheet.cpp_sec7
|
| 232 |
if (hasCharsetRule()) { |
182 |
if (hasCharsetRule()) { |
| 233 |
if (childVectorIndex == 0) { |
183 |
if (childVectorIndex == 0) { |
| 234 |
// Nothing can be inserted before @charset. |
184 |
// Nothing can be inserted before @charset. |
| 235 |
ec = HIERARCHY_REQUEST_ERR; |
185 |
return false; |
| 236 |
return 0; |
|
|
| 237 |
} |
186 |
} |
| 238 |
--childVectorIndex; |
187 |
--childVectorIndex; |
| 239 |
} |
188 |
} |
| 240 |
|
189 |
|
| 241 |
if (childVectorIndex < m_importRules.size() || (childVectorIndex == m_importRules.size() && rule->isImportRule())) { |
190 |
if (childVectorIndex < m_importRules.size() || (childVectorIndex == m_importRules.size() && rule->isImportRule())) { |
| 242 |
// Inserting non-import rule before @import is not allowed. |
191 |
// Inserting non-import rule before @import is not allowed. |
| 243 |
if (!rule->isImportRule()) { |
192 |
if (!rule->isImportRule()) |
| 244 |
ec = HIERARCHY_REQUEST_ERR; |
193 |
return false; |
| 245 |
return 0; |
|
|
| 246 |
} |
| 247 |
m_importRules.insert(childVectorIndex, static_cast<StyleRuleImport*>(rule.get())); |
194 |
m_importRules.insert(childVectorIndex, static_cast<StyleRuleImport*>(rule.get())); |
| 248 |
m_importRules[childVectorIndex]->requestStyleSheet(); |
195 |
m_importRules[childVectorIndex]->requestStyleSheet(); |
| 249 |
goto success; |
196 |
// FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded. |
|
|
197 |
styleSheetChanged(); |
| 198 |
return true; |
| 250 |
} |
199 |
} |
| 251 |
// Inserting @import rule after a non-import rule is not allowed. |
200 |
// Inserting @import rule after a non-import rule is not allowed. |
| 252 |
if (rule->isImportRule()) { |
201 |
if (rule->isImportRule()) |
| 253 |
ec = HIERARCHY_REQUEST_ERR; |
202 |
return false; |
| 254 |
return 0; |
|
|
| 255 |
} |
| 256 |
childVectorIndex -= m_importRules.size(); |
203 |
childVectorIndex -= m_importRules.size(); |
| 257 |
|
204 |
|
| 258 |
m_childRules.insert(childVectorIndex, rule.release()); |
205 |
m_childRules.insert(childVectorIndex, rule); |
| 259 |
|
206 |
|
| 260 |
success: |
|
|
| 261 |
if (!m_childRuleCSSOMWrappers.isEmpty()) |
| 262 |
m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); |
| 263 |
|
| 264 |
// FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded. |
| 265 |
styleSheetChanged(); |
207 |
styleSheetChanged(); |
| 266 |
return index; |
208 |
return true; |
| 267 |
} |
|
|
| 268 |
|
| 269 |
int CSSStyleSheet::addRule(const String& selector, const String& style, int index, ExceptionCode& ec) |
| 270 |
{ |
| 271 |
insertRule(selector + " { " + style + " }", index, ec); |
| 272 |
|
| 273 |
// As per Microsoft documentation, always return -1. |
| 274 |
return -1; |
| 275 |
} |
| 276 |
|
| 277 |
int CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec) |
| 278 |
{ |
| 279 |
return addRule(selector, style, length(), ec); |
| 280 |
} |
209 |
} |
| 281 |
|
210 |
|
| 282 |
PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules() |
211 |
void StyleSheetInternal::wrapperDeleteRule(unsigned index) |
| 283 |
{ |
212 |
{ |
| 284 |
KURL url = finalURL(); |
213 |
ASSERT(index < ruleCount()); |
| 285 |
Document* document = findDocument(); |
|
|
| 286 |
if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url)) |
| 287 |
return 0; |
| 288 |
if (!m_ruleListCSSOMWrapper) |
| 289 |
m_ruleListCSSOMWrapper = adoptPtr(new StyleSheetCSSRuleList(this)); |
| 290 |
return m_ruleListCSSOMWrapper.get(); |
| 291 |
} |
| 292 |
|
214 |
|
| 293 |
void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec) |
|
|
| 294 |
{ |
| 295 |
if (index >= length()) { |
| 296 |
ec = INDEX_SIZE_ERR; |
| 297 |
return; |
| 298 |
} |
| 299 |
|
| 300 |
ec = 0; |
| 301 |
unsigned childVectorIndex = index; |
215 |
unsigned childVectorIndex = index; |
| 302 |
if (hasCharsetRule()) { |
216 |
if (hasCharsetRule()) { |
| 303 |
if (childVectorIndex == 0) { |
217 |
if (childVectorIndex == 0) { |
| 304 |
clearCharsetRule(); |
218 |
clearCharsetRule(); |
| 305 |
goto success; |
219 |
styleSheetChanged(); |
|
|
220 |
return; |
| 306 |
} |
221 |
} |
| 307 |
--childVectorIndex; |
222 |
--childVectorIndex; |
| 308 |
} |
223 |
} |
| 309 |
if (childVectorIndex < m_importRules.size()) { |
224 |
if (childVectorIndex < m_importRules.size()) { |
| 310 |
m_importRules[childVectorIndex]->clearParentStyleSheet(); |
225 |
m_importRules[childVectorIndex]->clearParentStyleSheet(); |
| 311 |
m_importRules.remove(childVectorIndex); |
226 |
m_importRules.remove(childVectorIndex); |
| 312 |
goto success; |
227 |
styleSheetChanged(); |
|
|
228 |
return; |
| 313 |
} |
229 |
} |
| 314 |
childVectorIndex -= m_importRules.size(); |
230 |
childVectorIndex -= m_importRules.size(); |
| 315 |
|
231 |
|
| 316 |
m_childRules.remove(childVectorIndex); |
232 |
m_childRules.remove(childVectorIndex); |
| 317 |
|
|
|
| 318 |
success: |
| 319 |
if (!m_childRuleCSSOMWrappers.isEmpty()) { |
| 320 |
m_childRuleCSSOMWrappers[index]->setParentStyleSheet(0); |
| 321 |
m_childRuleCSSOMWrappers.remove(index); |
| 322 |
} |
| 323 |
|
| 324 |
styleSheetChanged(); |
233 |
styleSheetChanged(); |
| 325 |
} |
234 |
} |
| 326 |
|
235 |
|
| 327 |
void CSSStyleSheet::addNamespace(CSSParser* p, const AtomicString& prefix, const AtomicString& uri) |
236 |
void StyleSheetInternal::addNamespace(CSSParser* p, const AtomicString& prefix, const AtomicString& uri) |
| 328 |
{ |
237 |
{ |
| 329 |
if (uri.isNull()) |
238 |
if (uri.isNull()) |
| 330 |
return; |
239 |
return; |
|
Lines 337-343
void CSSStyleSheet::addNamespace(CSSPars
Source/WebCore/css/CSSStyleSheet.cpp_sec8
|
| 337 |
p->m_defaultNamespace = uri; |
246 |
p->m_defaultNamespace = uri; |
| 338 |
} |
247 |
} |
| 339 |
|
248 |
|
| 340 |
const AtomicString& CSSStyleSheet::determineNamespace(const AtomicString& prefix) |
249 |
const AtomicString& StyleSheetInternal::determineNamespace(const AtomicString& prefix) |
| 341 |
{ |
250 |
{ |
| 342 |
if (prefix.isNull()) |
251 |
if (prefix.isNull()) |
| 343 |
return nullAtom; // No namespace. If an element/attribute has a namespace, we won't match it. |
252 |
return nullAtom; // No namespace. If an element/attribute has a namespace, we won't match it. |
|
Lines 350-361
const AtomicString& CSSStyleSheet::deter
Source/WebCore/css/CSSStyleSheet.cpp_sec9
|
| 350 |
return nullAtom; // Assume we won't match any namespaces. |
259 |
return nullAtom; // Assume we won't match any namespaces. |
| 351 |
} |
260 |
} |
| 352 |
|
261 |
|
| 353 |
bool CSSStyleSheet::parseString(const String &string, CSSParserMode cssParserMode) |
262 |
bool StyleSheetInternal::parseString(const String &string, CSSParserMode cssParserMode) |
| 354 |
{ |
263 |
{ |
| 355 |
return parseStringAtLine(string, cssParserMode, 0); |
264 |
return parseStringAtLine(string, cssParserMode, 0); |
| 356 |
} |
265 |
} |
| 357 |
|
266 |
|
| 358 |
bool CSSStyleSheet::parseStringAtLine(const String& string, CSSParserMode cssParserMode, int startLineNumber) |
267 |
bool StyleSheetInternal::parseStringAtLine(const String& string, CSSParserMode cssParserMode, int startLineNumber) |
| 359 |
{ |
268 |
{ |
| 360 |
setCSSParserMode(cssParserMode); |
269 |
setCSSParserMode(cssParserMode); |
| 361 |
CSSParser p(cssParserMode); |
270 |
CSSParser p(cssParserMode); |
|
Lines 363-369
bool CSSStyleSheet::parseStringAtLine(co
Source/WebCore/css/CSSStyleSheet.cpp_sec10
|
| 363 |
return true; |
272 |
return true; |
| 364 |
} |
273 |
} |
| 365 |
|
274 |
|
| 366 |
bool CSSStyleSheet::isLoading() |
275 |
bool StyleSheetInternal::isLoading() const |
| 367 |
{ |
276 |
{ |
| 368 |
for (unsigned i = 0; i < m_importRules.size(); ++i) { |
277 |
for (unsigned i = 0; i < m_importRules.size(); ++i) { |
| 369 |
if (m_importRules[i]->isLoading()) |
278 |
if (m_importRules[i]->isLoading()) |
|
Lines 372-378
bool CSSStyleSheet::isLoading()
Source/WebCore/css/CSSStyleSheet.cpp_sec11
|
| 372 |
return false; |
281 |
return false; |
| 373 |
} |
282 |
} |
| 374 |
|
283 |
|
| 375 |
void CSSStyleSheet::checkLoaded() |
284 |
void StyleSheetInternal::checkLoaded() |
| 376 |
{ |
285 |
{ |
| 377 |
if (isLoading()) |
286 |
if (isLoading()) |
| 378 |
return; |
287 |
return; |
|
Lines 380-387
void CSSStyleSheet::checkLoaded()
Source/WebCore/css/CSSStyleSheet.cpp_sec12
|
| 380 |
// Avoid |this| being deleted by scripts that run via |
289 |
// Avoid |this| being deleted by scripts that run via |
| 381 |
// ScriptableDocumentParser::executeScriptsWaitingForStylesheets(). |
290 |
// ScriptableDocumentParser::executeScriptsWaitingForStylesheets(). |
| 382 |
// See <rdar://problem/6622300>. |
291 |
// See <rdar://problem/6622300>. |
| 383 |
RefPtr<CSSStyleSheet> protector(this); |
292 |
RefPtr<StyleSheetInternal> protector(this); |
| 384 |
if (CSSStyleSheet* styleSheet = parentStyleSheet()) |
293 |
if (StyleSheetInternal* styleSheet = parentStyleSheet()) |
| 385 |
styleSheet->checkLoaded(); |
294 |
styleSheet->checkLoaded(); |
| 386 |
|
295 |
|
| 387 |
RefPtr<Node> owner = ownerNode(); |
296 |
RefPtr<Node> owner = ownerNode(); |
|
Lines 394-443
void CSSStyleSheet::checkLoaded()
Source/WebCore/css/CSSStyleSheet.cpp_sec13
|
| 394 |
} |
303 |
} |
| 395 |
} |
304 |
} |
| 396 |
|
305 |
|
| 397 |
void CSSStyleSheet::notifyLoadedSheet(const CachedCSSStyleSheet* sheet) |
306 |
void StyleSheetInternal::notifyLoadedSheet(const CachedCSSStyleSheet* sheet) |
| 398 |
{ |
307 |
{ |
| 399 |
ASSERT(sheet); |
308 |
ASSERT(sheet); |
| 400 |
m_didLoadErrorOccur |= sheet->errorOccurred(); |
309 |
m_didLoadErrorOccur |= sheet->errorOccurred(); |
| 401 |
} |
310 |
} |
| 402 |
|
311 |
|
| 403 |
void CSSStyleSheet::startLoadingDynamicSheet() |
312 |
void StyleSheetInternal::startLoadingDynamicSheet() |
| 404 |
{ |
313 |
{ |
| 405 |
if (Node* owner = ownerNode()) |
314 |
if (Node* owner = ownerNode()) |
| 406 |
owner->startLoadingDynamicSheet(); |
315 |
owner->startLoadingDynamicSheet(); |
| 407 |
} |
316 |
} |
| 408 |
|
317 |
|
| 409 |
Node* CSSStyleSheet::findStyleSheetOwnerNode() const |
318 |
Node* StyleSheetInternal::findStyleSheetOwnerNode() const |
| 410 |
{ |
319 |
{ |
| 411 |
for (const CSSStyleSheet* sheet = this; sheet; sheet = sheet->parentStyleSheet()) { |
320 |
for (const StyleSheetInternal* sheet = this; sheet; sheet = sheet->parentStyleSheet()) { |
| 412 |
if (Node* ownerNode = sheet->ownerNode()) |
321 |
if (Node* ownerNode = sheet->ownerNode()) |
| 413 |
return ownerNode; |
322 |
return ownerNode; |
| 414 |
} |
323 |
} |
| 415 |
return 0; |
324 |
return 0; |
| 416 |
} |
325 |
} |
| 417 |
|
326 |
|
| 418 |
Document* CSSStyleSheet::findDocument() |
327 |
Document* StyleSheetInternal::findDocument() |
| 419 |
{ |
328 |
{ |
| 420 |
Node* ownerNode = findStyleSheetOwnerNode(); |
329 |
Node* ownerNode = findStyleSheetOwnerNode(); |
| 421 |
|
330 |
|
| 422 |
return ownerNode ? ownerNode->document() : 0; |
331 |
return ownerNode ? ownerNode->document() : 0; |
| 423 |
} |
332 |
} |
| 424 |
|
|
|
| 425 |
MediaList* CSSStyleSheet::media() const |
| 426 |
{ |
| 427 |
if (!m_mediaQueries) |
| 428 |
return 0; |
| 429 |
return m_mediaQueries->ensureMediaList(const_cast<CSSStyleSheet*>(this)); |
| 430 |
} |
| 431 |
|
333 |
|
| 432 |
void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries) |
334 |
void StyleSheetInternal::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries) |
| 433 |
{ |
335 |
{ |
| 434 |
m_mediaQueries = mediaQueries; |
336 |
m_mediaQueries = mediaQueries; |
| 435 |
} |
337 |
} |
| 436 |
|
338 |
|
| 437 |
void CSSStyleSheet::styleSheetChanged() |
339 |
void StyleSheetInternal::styleSheetChanged() |
| 438 |
{ |
340 |
{ |
| 439 |
CSSStyleSheet* rootSheet = this; |
341 |
StyleSheetInternal* rootSheet = this; |
| 440 |
while (CSSStyleSheet* parent = rootSheet->parentStyleSheet()) |
342 |
while (StyleSheetInternal* parent = rootSheet->parentStyleSheet()) |
| 441 |
rootSheet = parent; |
343 |
rootSheet = parent; |
| 442 |
|
344 |
|
| 443 |
/* FIXME: We don't need to do everything updateStyleSelector does, |
345 |
/* FIXME: We don't need to do everything updateStyleSelector does, |
|
Lines 447-454
void CSSStyleSheet::styleSheetChanged()
Source/WebCore/css/CSSStyleSheet.cpp_sec14
|
| 447 |
if (Document* documentToUpdate = rootSheet->findDocument()) |
349 |
if (Document* documentToUpdate = rootSheet->findDocument()) |
| 448 |
documentToUpdate->styleSelectorChanged(DeferRecalcStyle); |
350 |
documentToUpdate->styleSelectorChanged(DeferRecalcStyle); |
| 449 |
} |
351 |
} |
|
|
352 |
|
| 353 |
KURL StyleSheetInternal::baseURL() const |
| 354 |
{ |
| 355 |
if (!m_finalURL.isNull()) |
| 356 |
return m_finalURL; |
| 357 |
if (StyleSheetInternal* parentSheet = parentStyleSheet()) |
| 358 |
return parentSheet->baseURL(); |
| 359 |
if (!m_ownerNode) |
| 360 |
return KURL(); |
| 361 |
return m_ownerNode->document()->baseURL(); |
| 362 |
} |
| 450 |
|
363 |
|
| 451 |
KURL CSSStyleSheet::completeURL(const String& url) const |
364 |
KURL StyleSheetInternal::completeURL(const String& url) const |
| 452 |
{ |
365 |
{ |
| 453 |
// Always return a null URL when passed a null string. |
366 |
// Always return a null URL when passed a null string. |
| 454 |
// FIXME: Should we change the KURL constructor to have this behavior? |
367 |
// FIXME: Should we change the KURL constructor to have this behavior? |
|
Lines 461-473
KURL CSSStyleSheet::completeURL(const St
Source/WebCore/css/CSSStyleSheet.cpp_sec15
|
| 461 |
return KURL(baseURL(), url, encoding); |
374 |
return KURL(baseURL(), url, encoding); |
| 462 |
} |
375 |
} |
| 463 |
|
376 |
|
| 464 |
void CSSStyleSheet::addSubresourceStyleURLs(ListHashSet<KURL>& urls) |
377 |
void StyleSheetInternal::addSubresourceStyleURLs(ListHashSet<KURL>& urls) |
| 465 |
{ |
378 |
{ |
| 466 |
Deque<CSSStyleSheet*> styleSheetQueue; |
379 |
Deque<StyleSheetInternal*> styleSheetQueue; |
| 467 |
styleSheetQueue.append(this); |
380 |
styleSheetQueue.append(this); |
| 468 |
|
381 |
|
| 469 |
while (!styleSheetQueue.isEmpty()) { |
382 |
while (!styleSheetQueue.isEmpty()) { |
| 470 |
CSSStyleSheet* styleSheet = styleSheetQueue.takeFirst(); |
383 |
StyleSheetInternal* styleSheet = styleSheetQueue.takeFirst(); |
| 471 |
|
384 |
|
| 472 |
for (unsigned i = 0; i < styleSheet->m_importRules.size(); ++i) { |
385 |
for (unsigned i = 0; i < styleSheet->m_importRules.size(); ++i) { |
| 473 |
StyleRuleImport* importRule = styleSheet->m_importRules[i].get(); |
386 |
StyleRuleImport* importRule = styleSheet->m_importRules[i].get(); |
|
Lines 486-510
void CSSStyleSheet::addSubresourceStyleU
Source/WebCore/css/CSSStyleSheet.cpp_sec16
|
| 486 |
} |
399 |
} |
| 487 |
} |
400 |
} |
| 488 |
|
401 |
|
| 489 |
CSSImportRule* CSSStyleSheet::ensureCSSOMWrapper(StyleRuleImport* importRule) |
402 |
StyleSheetInternal* StyleSheetInternal::parentStyleSheet() const |
| 490 |
{ |
403 |
{ |
| 491 |
for (unsigned i = 0; i < m_importRules.size(); ++i) { |
404 |
return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; |
| 492 |
if (m_importRules[i] == importRule) |
|
|
| 493 |
return static_cast<CSSImportRule*>(item(i)); |
| 494 |
} |
| 495 |
ASSERT_NOT_REACHED(); |
| 496 |
return 0; |
| 497 |
} |
405 |
} |
| 498 |
|
406 |
|
| 499 |
CSSImportRule* CSSStyleSheet::ownerRule() const |
407 |
CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetInternal> styleSheet, CSSImportRule* ownerRule) |
| 500 |
{ |
408 |
: m_internal(styleSheet) |
| 501 |
return parentStyleSheet() ? parentStyleSheet()->ensureCSSOMWrapper(m_ownerRule) : 0; |
409 |
, m_isDisabled(false) |
|
|
410 |
, m_ownerRule(ownerRule) |
| 411 |
{ |
| 502 |
} |
412 |
} |
| 503 |
|
413 |
|
| 504 |
CSSStyleSheet* CSSStyleSheet::parentStyleSheet() const |
414 |
CSSStyleSheet::~CSSStyleSheet() |
| 505 |
{ |
415 |
{ |
| 506 |
ASSERT(isCSSStyleSheet()); |
416 |
// For style rules outside the document, .parentStyleSheet can become null even if the style rule |
| 507 |
return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; |
417 |
// is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but |
|
|
418 |
// it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection. |
| 419 |
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { |
| 420 |
if (m_childRuleCSSOMWrappers[i]) |
| 421 |
m_childRuleCSSOMWrappers[i]->setParentStyleSheet(0); |
| 422 |
} |
| 423 |
} |
| 424 |
|
| 425 |
void CSSStyleSheet::setDisabled(bool disabled) |
| 426 |
{ |
| 427 |
if (disabled == m_isDisabled) |
| 428 |
return; |
| 429 |
m_isDisabled = disabled; |
| 430 |
m_internal->styleSheetChanged(); |
| 431 |
} |
| 432 |
|
| 433 |
unsigned CSSStyleSheet::length() const |
| 434 |
{ |
| 435 |
return m_internal->ruleCount(); |
| 436 |
} |
| 437 |
|
| 438 |
CSSRule* CSSStyleSheet::item(unsigned index) |
| 439 |
{ |
| 440 |
unsigned ruleCount = length(); |
| 441 |
if (index >= ruleCount) |
| 442 |
return 0; |
| 443 |
|
| 444 |
if (m_childRuleCSSOMWrappers.isEmpty()) |
| 445 |
m_childRuleCSSOMWrappers.grow(ruleCount); |
| 446 |
ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount); |
| 447 |
|
| 448 |
RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index]; |
| 449 |
if (!cssRule) |
| 450 |
cssRule = m_internal->createChildRuleCSSOMWrapper(index, this); |
| 451 |
return cssRule.get(); |
| 452 |
} |
| 453 |
|
| 454 |
PassRefPtr<CSSRuleList> CSSStyleSheet::rules() |
| 455 |
{ |
| 456 |
KURL url = m_internal->finalURL(); |
| 457 |
Document* document = m_internal->findDocument(); |
| 458 |
if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url)) |
| 459 |
return 0; |
| 460 |
// IE behavior. |
| 461 |
RefPtr<StaticCSSRuleList> nonCharsetRules = StaticCSSRuleList::create(); |
| 462 |
unsigned ruleCount = length(); |
| 463 |
for (unsigned i = 0; i < ruleCount; ++i) { |
| 464 |
CSSRule* rule = item(i); |
| 465 |
if (rule->isCharsetRule()) |
| 466 |
continue; |
| 467 |
nonCharsetRules->rules().append(rule); |
| 468 |
} |
| 469 |
return nonCharsetRules.release(); |
| 470 |
} |
| 471 |
|
| 472 |
unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, ExceptionCode& ec) |
| 473 |
{ |
| 474 |
ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_internal->ruleCount()); |
| 475 |
|
| 476 |
ec = 0; |
| 477 |
if (index > length()) { |
| 478 |
ec = INDEX_SIZE_ERR; |
| 479 |
return 0; |
| 480 |
} |
| 481 |
CSSParser p(m_internal->cssParserMode()); |
| 482 |
RefPtr<StyleRuleBase> rule = p.parseRule(m_internal.get(), ruleString); |
| 483 |
|
| 484 |
if (!rule) { |
| 485 |
ec = SYNTAX_ERR; |
| 486 |
return 0; |
| 487 |
} |
| 488 |
bool success = m_internal->wrapperInsertRule(rule, index); |
| 489 |
if (!success) { |
| 490 |
ec = HIERARCHY_REQUEST_ERR; |
| 491 |
return 0; |
| 492 |
} |
| 493 |
if (!m_childRuleCSSOMWrappers.isEmpty()) |
| 494 |
m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); |
| 495 |
return index; |
| 496 |
} |
| 497 |
|
| 498 |
void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec) |
| 499 |
{ |
| 500 |
ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_internal->ruleCount()); |
| 501 |
|
| 502 |
if (index >= length()) { |
| 503 |
ec = INDEX_SIZE_ERR; |
| 504 |
return; |
| 505 |
} |
| 506 |
m_internal->wrapperDeleteRule(index); |
| 507 |
|
| 508 |
if (!m_childRuleCSSOMWrappers.isEmpty()) { |
| 509 |
m_childRuleCSSOMWrappers[index]->setParentStyleSheet(0); |
| 510 |
m_childRuleCSSOMWrappers.remove(index); |
| 511 |
} |
| 512 |
} |
| 513 |
|
| 514 |
int CSSStyleSheet::addRule(const String& selector, const String& style, int index, ExceptionCode& ec) |
| 515 |
{ |
| 516 |
insertRule(selector + " { " + style + " }", index, ec); |
| 517 |
|
| 518 |
// As per Microsoft documentation, always return -1. |
| 519 |
return -1; |
| 520 |
} |
| 521 |
|
| 522 |
int CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec) |
| 523 |
{ |
| 524 |
return addRule(selector, style, length(), ec); |
| 525 |
} |
| 526 |
|
| 527 |
|
| 528 |
PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules() |
| 529 |
{ |
| 530 |
KURL url = m_internal->finalURL(); |
| 531 |
Document* document = m_internal->findDocument(); |
| 532 |
if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url)) |
| 533 |
return 0; |
| 534 |
if (!m_ruleListCSSOMWrapper) |
| 535 |
m_ruleListCSSOMWrapper = adoptPtr(new StyleSheetCSSRuleList(this)); |
| 536 |
return m_ruleListCSSOMWrapper.get(); |
| 537 |
} |
| 538 |
|
| 539 |
MediaList* CSSStyleSheet::media() const |
| 540 |
{ |
| 541 |
if (!m_internal->mediaQueries()) |
| 542 |
return 0; |
| 543 |
return m_internal->mediaQueries()->ensureMediaList(const_cast<CSSStyleSheet*>(this)); |
| 544 |
} |
| 545 |
|
| 546 |
CSSStyleSheet* CSSStyleSheet::parentStyleSheet() const |
| 547 |
{ |
| 548 |
return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; |
| 549 |
} |
| 550 |
|
| 551 |
void CSSStyleSheet::clearChildRuleCSSOMWrappers() |
| 552 |
{ |
| 553 |
m_childRuleCSSOMWrappers.clear(); |
| 508 |
} |
554 |
} |
| 509 |
|
555 |
|
| 510 |
} |
556 |
} |