OLD | NEW |
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, 2012 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 |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "core/frame/UseCounter.h" | 33 #include "core/frame/UseCounter.h" |
34 #include "core/inspector/InspectorTraceEvents.h" | 34 #include "core/inspector/InspectorTraceEvents.h" |
35 #include "platform/Histogram.h" | 35 #include "platform/Histogram.h" |
36 #include "platform/tracing/TraceEvent.h" | 36 #include "platform/tracing/TraceEvent.h" |
37 #include "platform/weborigin/SecurityOrigin.h" | 37 #include "platform/weborigin/SecurityOrigin.h" |
38 | 38 |
39 namespace blink { | 39 namespace blink { |
40 | 40 |
41 // Rough size estimate for the memory cache. | 41 // Rough size estimate for the memory cache. |
42 unsigned StyleSheetContents::estimatedSizeInBytes() const { | 42 unsigned StyleSheetContents::estimatedSizeInBytes() const { |
43 // Note that this does not take into account size of the strings hanging from
various objects. | 43 // Note that this does not take into account size of the strings hanging from |
44 // The assumption is that nearly all of of them are atomic and would exist any
way. | 44 // various objects. The assumption is that nearly all of of them are atomic |
| 45 // and would exist anyway. |
45 unsigned size = sizeof(*this); | 46 unsigned size = sizeof(*this); |
46 | 47 |
47 // FIXME: This ignores the children of media rules. | 48 // FIXME: This ignores the children of media rules. |
48 // Most rules are StyleRules. | 49 // Most rules are StyleRules. |
49 size += ruleCount() * StyleRule::averageSizeInBytes(); | 50 size += ruleCount() * StyleRule::averageSizeInBytes(); |
50 | 51 |
51 for (unsigned i = 0; i < m_importRules.size(); ++i) { | 52 for (unsigned i = 0; i < m_importRules.size(); ++i) { |
52 if (StyleSheetContents* sheet = m_importRules[i]->styleSheet()) | 53 if (StyleSheetContents* sheet = m_importRules[i]->styleSheet()) |
53 size += sheet->estimatedSizeInBytes(); | 54 size += sheet->estimatedSizeInBytes(); |
54 } | 55 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 if (!m_importRules.isEmpty()) | 115 if (!m_importRules.isEmpty()) |
115 return false; | 116 return false; |
116 // FIXME: Support cached stylesheets in import rules. | 117 // FIXME: Support cached stylesheets in import rules. |
117 if (m_ownerRule) | 118 if (m_ownerRule) |
118 return false; | 119 return false; |
119 if (m_didLoadErrorOccur) | 120 if (m_didLoadErrorOccur) |
120 return false; | 121 return false; |
121 // It is not the original sheet anymore. | 122 // It is not the original sheet anymore. |
122 if (m_isMutable) | 123 if (m_isMutable) |
123 return false; | 124 return false; |
124 // If the header is valid we are not going to need to check the SecurityOrigin
. | 125 // If the header is valid we are not going to need to check the |
| 126 // SecurityOrigin. |
125 // FIXME: Valid mime type avoids the check too. | 127 // FIXME: Valid mime type avoids the check too. |
126 if (!m_hasSyntacticallyValidCSSHeader) | 128 if (!m_hasSyntacticallyValidCSSHeader) |
127 return false; | 129 return false; |
128 return true; | 130 return true; |
129 } | 131 } |
130 | 132 |
131 bool StyleSheetContents::isCacheableForStyleElement() const { | 133 bool StyleSheetContents::isCacheableForStyleElement() const { |
132 // FIXME: Support copying import rules. | 134 // FIXME: Support copying import rules. |
133 if (!importRules().isEmpty()) | 135 if (!importRules().isEmpty()) |
134 return false; | 136 return false; |
135 // Until import rules are supported in cached sheets it's not possible for loa
ding to fail. | 137 // Until import rules are supported in cached sheets it's not possible for |
| 138 // loading to fail. |
136 DCHECK(!didLoadErrorOccur()); | 139 DCHECK(!didLoadErrorOccur()); |
137 // It is not the original sheet anymore. | 140 // It is not the original sheet anymore. |
138 if (isMutable()) | 141 if (isMutable()) |
139 return false; | 142 return false; |
140 if (!hasSyntacticallyValidCSSHeader()) | 143 if (!hasSyntacticallyValidCSSHeader()) |
141 return false; | 144 return false; |
142 return true; | 145 return true; |
143 } | 146 } |
144 | 147 |
145 void StyleSheetContents::parserAppendRule(StyleRuleBase* rule) { | 148 void StyleSheetContents::parserAppendRule(StyleRuleBase* rule) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 if (!rule->isImportRule()) | 218 if (!rule->isImportRule()) |
216 return false; | 219 return false; |
217 | 220 |
218 StyleRuleImport* importRule = toStyleRuleImport(rule); | 221 StyleRuleImport* importRule = toStyleRuleImport(rule); |
219 if (importRule->mediaQueries()) | 222 if (importRule->mediaQueries()) |
220 setHasMediaQueries(); | 223 setHasMediaQueries(); |
221 | 224 |
222 m_importRules.insert(index, importRule); | 225 m_importRules.insert(index, importRule); |
223 m_importRules[index]->setParentStyleSheet(this); | 226 m_importRules[index]->setParentStyleSheet(this); |
224 m_importRules[index]->requestStyleSheet(); | 227 m_importRules[index]->requestStyleSheet(); |
225 // FIXME: Stylesheet doesn't actually change meaningfully before the importe
d sheets are loaded. | 228 // FIXME: Stylesheet doesn't actually change meaningfully before the |
| 229 // imported sheets are loaded. |
226 return true; | 230 return true; |
227 } | 231 } |
228 // Inserting @import rule after a non-import rule is not allowed. | 232 // Inserting @import rule after a non-import rule is not allowed. |
229 if (rule->isImportRule()) | 233 if (rule->isImportRule()) |
230 return false; | 234 return false; |
231 | 235 |
232 index -= m_importRules.size(); | 236 index -= m_importRules.size(); |
233 | 237 |
234 if (index < m_namespaceRules.size() || | 238 if (index < m_namespaceRules.size() || |
235 (index == m_namespaceRules.size() && rule->isNamespaceRule())) { | 239 (index == m_namespaceRules.size() && rule->isNamespaceRule())) { |
236 // Inserting non-namespace rules other than import rule before @namespace is
not allowed. | 240 // Inserting non-namespace rules other than import rule before @namespace is |
| 241 // not allowed. |
237 if (!rule->isNamespaceRule()) | 242 if (!rule->isNamespaceRule()) |
238 return false; | 243 return false; |
239 // Inserting @namespace rule when rules other than import/namespace/charset
are present is not allowed. | 244 // Inserting @namespace rule when rules other than import/namespace/charset |
| 245 // are present is not allowed. |
240 if (!m_childRules.isEmpty()) | 246 if (!m_childRules.isEmpty()) |
241 return false; | 247 return false; |
242 | 248 |
243 StyleRuleNamespace* namespaceRule = toStyleRuleNamespace(rule); | 249 StyleRuleNamespace* namespaceRule = toStyleRuleNamespace(rule); |
244 m_namespaceRules.insert(index, namespaceRule); | 250 m_namespaceRules.insert(index, namespaceRule); |
245 // For now to be compatible with IE and Firefox if namespace rule with same
prefix is added | 251 // For now to be compatible with IE and Firefox if namespace rule with same |
246 // irrespective of adding the rule at any index, last added rule's value is
considered. | 252 // prefix is added irrespective of adding the rule at any index, last added |
247 // TODO (ramya.v@samsung.com): As per spec last valid rule should be conside
red, | 253 // rule's value is considered. |
248 // which means if namespace rule is added in the middle of existing namespac
e rules, | 254 // TODO (ramya.v@samsung.com): As per spec last valid rule should be |
249 // rule which comes later in rule list with same prefix needs to be consider
ed. | 255 // considered, which means if namespace rule is added in the middle of |
| 256 // existing namespace rules, rule which comes later in rule list with same |
| 257 // prefix needs to be considered. |
250 parserAddNamespace(namespaceRule->prefix(), namespaceRule->uri()); | 258 parserAddNamespace(namespaceRule->prefix(), namespaceRule->uri()); |
251 return true; | 259 return true; |
252 } | 260 } |
253 | 261 |
254 if (rule->isNamespaceRule()) | 262 if (rule->isNamespaceRule()) |
255 return false; | 263 return false; |
256 | 264 |
257 index -= m_namespaceRules.size(); | 265 index -= m_namespaceRules.size(); |
258 | 266 |
259 m_childRules.insert(index, rule); | 267 m_childRules.insert(index, rule); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 void StyleSheetContents::parseAuthorStyleSheet( | 316 void StyleSheetContents::parseAuthorStyleSheet( |
309 const CSSStyleSheetResource* cachedStyleSheet, | 317 const CSSStyleSheetResource* cachedStyleSheet, |
310 const SecurityOrigin* securityOrigin) { | 318 const SecurityOrigin* securityOrigin) { |
311 TRACE_EVENT1("blink,devtools.timeline", "ParseAuthorStyleSheet", "data", | 319 TRACE_EVENT1("blink,devtools.timeline", "ParseAuthorStyleSheet", "data", |
312 InspectorParseAuthorStyleSheetEvent::data(cachedStyleSheet)); | 320 InspectorParseAuthorStyleSheetEvent::data(cachedStyleSheet)); |
313 SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Style.AuthorStyleSheet.ParseTime"); | 321 SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Style.AuthorStyleSheet.ParseTime"); |
314 | 322 |
315 bool isSameOriginRequest = | 323 bool isSameOriginRequest = |
316 securityOrigin && securityOrigin->canRequest(baseURL()); | 324 securityOrigin && securityOrigin->canRequest(baseURL()); |
317 | 325 |
318 // When the response was fetched via the Service Worker, the original URL may
not be same as the base URL. | 326 // When the response was fetched via the Service Worker, the original URL may |
319 // TODO(horo): When we will use the original URL as the base URL, we can remov
e this check. crbug.com/553535 | 327 // not be same as the base URL. |
| 328 // TODO(horo): When we will use the original URL as the base URL, we can |
| 329 // remove this check. crbug.com/553535 |
320 if (cachedStyleSheet->response().wasFetchedViaServiceWorker()) { | 330 if (cachedStyleSheet->response().wasFetchedViaServiceWorker()) { |
321 const KURL originalURL( | 331 const KURL originalURL( |
322 cachedStyleSheet->response().originalURLViaServiceWorker()); | 332 cachedStyleSheet->response().originalURLViaServiceWorker()); |
323 // |originalURL| is empty when the response is created in the SW. | 333 // |originalURL| is empty when the response is created in the SW. |
324 if (!originalURL.isEmpty() && !securityOrigin->canRequest(originalURL)) | 334 if (!originalURL.isEmpty() && !securityOrigin->canRequest(originalURL)) |
325 isSameOriginRequest = false; | 335 isSameOriginRequest = false; |
326 } | 336 } |
327 | 337 |
328 CSSStyleSheetResource::MIMETypeCheck mimeTypeCheck = | 338 CSSStyleSheetResource::MIMETypeCheck mimeTypeCheck = |
329 isQuirksModeBehavior(m_parserContext.mode()) && isSameOriginRequest | 339 isQuirksModeBehavior(m_parserContext.mode()) && isSameOriginRequest |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 StyleSheetContents* parentSheet = parentStyleSheet(); | 387 StyleSheetContents* parentSheet = parentStyleSheet(); |
378 if (parentSheet) { | 388 if (parentSheet) { |
379 parentSheet->checkLoaded(); | 389 parentSheet->checkLoaded(); |
380 return; | 390 return; |
381 } | 391 } |
382 | 392 |
383 ASSERT(this == rootStyleSheet()); | 393 ASSERT(this == rootStyleSheet()); |
384 if (m_loadingClients.isEmpty()) | 394 if (m_loadingClients.isEmpty()) |
385 return; | 395 return; |
386 | 396 |
387 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run vi
a | 397 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run |
388 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also protect | 398 // via ScriptableDocumentParser::executeScriptsWaitingForResources(). Also |
389 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoade
d| | 399 // protect the |CSSStyleSheet| from being deleted during iteration via the |
390 // method. | 400 // |sheetLoaded| method. |
391 // | 401 // |
392 // When a sheet is loaded it is moved from the set of loading clients | 402 // When a sheet is loaded it is moved from the set of loading clients |
393 // to the set of completed clients. We therefore need the copy in order to | 403 // to the set of completed clients. We therefore need the copy in order to |
394 // not modify the set while iterating it. | 404 // not modify the set while iterating it. |
395 HeapVector<Member<CSSStyleSheet>> loadingClients; | 405 HeapVector<Member<CSSStyleSheet>> loadingClients; |
396 copyToVector(m_loadingClients, loadingClients); | 406 copyToVector(m_loadingClients, loadingClients); |
397 | 407 |
398 for (unsigned i = 0; i < loadingClients.size(); ++i) { | 408 for (unsigned i = 0; i < loadingClients.size(); ++i) { |
399 if (loadingClients[i]->loadCompleted()) | 409 if (loadingClients[i]->loadCompleted()) |
400 continue; | 410 continue; |
401 | 411 |
402 // sheetLoaded might be invoked after its owner node is removed from documen
t. | 412 // sheetLoaded might be invoked after its owner node is removed from |
| 413 // document. |
403 if (Node* ownerNode = loadingClients[i]->ownerNode()) { | 414 if (Node* ownerNode = loadingClients[i]->ownerNode()) { |
404 if (loadingClients[i]->sheetLoaded()) | 415 if (loadingClients[i]->sheetLoaded()) |
405 ownerNode->notifyLoadedSheetAndAllCriticalSubresources( | 416 ownerNode->notifyLoadedSheetAndAllCriticalSubresources( |
406 m_didLoadErrorOccur ? Node::ErrorOccurredLoadingSubresource | 417 m_didLoadErrorOccur ? Node::ErrorOccurredLoadingSubresource |
407 : Node::NoErrorLoadingSubresource); | 418 : Node::NoErrorLoadingSubresource); |
408 } | 419 } |
409 } | 420 } |
410 } | 421 } |
411 | 422 |
412 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) { | 423 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) { |
413 ASSERT(sheet); | 424 ASSERT(sheet); |
414 m_didLoadErrorOccur |= sheet->errorOccurred(); | 425 m_didLoadErrorOccur |= sheet->errorOccurred(); |
415 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet on
this | 426 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet on |
416 // sheet before its imports have loaded. So clear the RuleSet when the imports | 427 // this sheet before its imports have loaded. So clear the RuleSet when the |
417 // load since the import's subrules are flattened into its parent sheet's Rule
Set. | 428 // imports load since the import's subrules are flattened into its parent |
| 429 // sheet's RuleSet. |
418 clearRuleSet(); | 430 clearRuleSet(); |
419 } | 431 } |
420 | 432 |
421 void StyleSheetContents::startLoadingDynamicSheet() { | 433 void StyleSheetContents::startLoadingDynamicSheet() { |
422 StyleSheetContents* root = rootStyleSheet(); | 434 StyleSheetContents* root = rootStyleSheet(); |
423 for (const auto& client : root->m_loadingClients) | 435 for (const auto& client : root->m_loadingClients) |
424 client->startLoadingDynamicSheet(); | 436 client->startLoadingDynamicSheet(); |
425 // Copy the completed clients to a vector for iteration. | 437 // Copy the completed clients to a vector for iteration. |
426 // startLoadingDynamicSheet will move the style sheet from the | 438 // startLoadingDynamicSheet will move the style sheet from the completed state |
427 // completed state to the loading state which modifies the set of | 439 // to the loading state which modifies the set of completed clients. We |
428 // completed clients. We therefore need the copy in order to not | 440 // therefore need the copy in order to not modify the set of completed clients |
429 // modify the set of completed clients while iterating it. | 441 // while iterating it. |
430 HeapVector<Member<CSSStyleSheet>> completedClients; | 442 HeapVector<Member<CSSStyleSheet>> completedClients; |
431 copyToVector(root->m_completedClients, completedClients); | 443 copyToVector(root->m_completedClients, completedClients); |
432 for (unsigned i = 0; i < completedClients.size(); ++i) | 444 for (unsigned i = 0; i < completedClients.size(); ++i) |
433 completedClients[i]->startLoadingDynamicSheet(); | 445 completedClients[i]->startLoadingDynamicSheet(); |
434 } | 446 } |
435 | 447 |
436 StyleSheetContents* StyleSheetContents::rootStyleSheet() const { | 448 StyleSheetContents* StyleSheetContents::rootStyleSheet() const { |
437 const StyleSheetContents* root = this; | 449 const StyleSheetContents* root = this; |
438 while (root->parentStyleSheet()) | 450 while (root->parentStyleSheet()) |
439 root = root->parentStyleSheet(); | 451 root = root->parentStyleSheet(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 } | 520 } |
509 | 521 |
510 StyleSheetContents* StyleSheetContents::parentStyleSheet() const { | 522 StyleSheetContents* StyleSheetContents::parentStyleSheet() const { |
511 return m_ownerRule ? m_ownerRule->parentStyleSheet() : nullptr; | 523 return m_ownerRule ? m_ownerRule->parentStyleSheet() : nullptr; |
512 } | 524 } |
513 | 525 |
514 void StyleSheetContents::registerClient(CSSStyleSheet* sheet) { | 526 void StyleSheetContents::registerClient(CSSStyleSheet* sheet) { |
515 ASSERT(!m_loadingClients.contains(sheet) && | 527 ASSERT(!m_loadingClients.contains(sheet) && |
516 !m_completedClients.contains(sheet)); | 528 !m_completedClients.contains(sheet)); |
517 | 529 |
518 // InspectorCSSAgent::buildObjectForRule creates CSSStyleSheet without any own
er node. | 530 // InspectorCSSAgent::buildObjectForRule creates CSSStyleSheet without any |
| 531 // owner node. |
519 if (!sheet->ownerDocument()) | 532 if (!sheet->ownerDocument()) |
520 return; | 533 return; |
521 | 534 |
522 if (Document* document = clientSingleOwnerDocument()) { | 535 if (Document* document = clientSingleOwnerDocument()) { |
523 if (sheet->ownerDocument() != document) | 536 if (sheet->ownerDocument() != document) |
524 m_hasSingleOwnerDocument = false; | 537 m_hasSingleOwnerDocument = false; |
525 } | 538 } |
526 m_loadingClients.add(sheet); | 539 m_loadingClients.add(sheet); |
527 } | 540 } |
528 | 541 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 void StyleSheetContents::clearRuleSet() { | 600 void StyleSheetContents::clearRuleSet() { |
588 if (StyleSheetContents* parentSheet = parentStyleSheet()) | 601 if (StyleSheetContents* parentSheet = parentStyleSheet()) |
589 parentSheet->clearRuleSet(); | 602 parentSheet->clearRuleSet(); |
590 | 603 |
591 // Don't want to clear the StyleResolver if the RuleSet hasn't been created | 604 // Don't want to clear the StyleResolver if the RuleSet hasn't been created |
592 // since we only clear the StyleResolver so that it's members are properly | 605 // since we only clear the StyleResolver so that it's members are properly |
593 // updated in ScopedStyleResolver::addRulesFromSheet. | 606 // updated in ScopedStyleResolver::addRulesFromSheet. |
594 if (!m_ruleSet) | 607 if (!m_ruleSet) |
595 return; | 608 return; |
596 | 609 |
597 // Clearing the ruleSet means we need to recreate the styleResolver data struc
tures. | 610 // Clearing the ruleSet means we need to recreate the styleResolver data |
598 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. | 611 // structures. See the StyleResolver calls in |
| 612 // ScopedStyleResolver::addRulesFromSheet. |
599 clearResolvers(m_loadingClients); | 613 clearResolvers(m_loadingClients); |
600 clearResolvers(m_completedClients); | 614 clearResolvers(m_completedClients); |
601 m_ruleSet.clear(); | 615 m_ruleSet.clear(); |
602 } | 616 } |
603 | 617 |
604 static void removeFontFaceRules(HeapHashSet<WeakMember<CSSStyleSheet>>& clients, | 618 static void removeFontFaceRules(HeapHashSet<WeakMember<CSSStyleSheet>>& clients, |
605 const StyleRuleFontFace* fontFaceRule) { | 619 const StyleRuleFontFace* fontFaceRule) { |
606 for (const auto& sheet : clients) { | 620 for (const auto& sheet : clients) { |
607 if (Node* ownerNode = sheet->ownerNode()) | 621 if (Node* ownerNode = sheet->ownerNode()) |
608 ownerNode->document().styleEngine().removeFontFaceRules( | 622 ownerNode->document().styleEngine().removeFontFaceRules( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 visitor->trace(m_importRules); | 664 visitor->trace(m_importRules); |
651 visitor->trace(m_namespaceRules); | 665 visitor->trace(m_namespaceRules); |
652 visitor->trace(m_childRules); | 666 visitor->trace(m_childRules); |
653 visitor->trace(m_loadingClients); | 667 visitor->trace(m_loadingClients); |
654 visitor->trace(m_completedClients); | 668 visitor->trace(m_completedClients); |
655 visitor->trace(m_ruleSet); | 669 visitor->trace(m_ruleSet); |
656 visitor->trace(m_referencedFromResource); | 670 visitor->trace(m_referencedFromResource); |
657 } | 671 } |
658 | 672 |
659 } // namespace blink | 673 } // namespace blink |
OLD | NEW |