OLD | NEW |
1 /* | 1 /* |
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
6 Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. | 6 Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. |
7 | 7 |
8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "wtf/CurrentTime.h" | 36 #include "wtf/CurrentTime.h" |
37 | 37 |
38 namespace blink { | 38 namespace blink { |
39 | 39 |
40 CSSStyleSheetResource* CSSStyleSheetResource::fetch(FetchRequest& request, | 40 CSSStyleSheetResource* CSSStyleSheetResource::fetch(FetchRequest& request, |
41 ResourceFetcher* fetcher) { | 41 ResourceFetcher* fetcher) { |
42 DCHECK_EQ(request.resourceRequest().frameType(), | 42 DCHECK_EQ(request.resourceRequest().frameType(), |
43 WebURLRequest::FrameTypeNone); | 43 WebURLRequest::FrameTypeNone); |
44 request.mutableResourceRequest().setRequestContext( | 44 request.mutableResourceRequest().setRequestContext( |
45 WebURLRequest::RequestContextStyle); | 45 WebURLRequest::RequestContextStyle); |
46 return toCSSStyleSheetResource( | 46 CSSStyleSheetResource* resource = toCSSStyleSheetResource( |
47 fetcher->requestResource(request, CSSStyleSheetResourceFactory())); | 47 fetcher->requestResource(request, CSSStyleSheetResourceFactory())); |
| 48 // TODO(kouhei): Dedupe this logic w/ ScriptResource::fetch |
| 49 if (resource && !request.integrityMetadata().isEmpty()) |
| 50 resource->setIntegrityMetadata(request.integrityMetadata()); |
| 51 return resource; |
48 } | 52 } |
49 | 53 |
50 CSSStyleSheetResource* CSSStyleSheetResource::createForTest( | 54 CSSStyleSheetResource* CSSStyleSheetResource::createForTest( |
51 const ResourceRequest& request, | 55 const ResourceRequest& request, |
52 const String& charset) { | 56 const String& charset) { |
53 return new CSSStyleSheetResource(request, ResourceLoaderOptions(), charset); | 57 return new CSSStyleSheetResource(request, ResourceLoaderOptions(), charset); |
54 } | 58 } |
55 | 59 |
56 CSSStyleSheetResource::CSSStyleSheetResource( | 60 CSSStyleSheetResource::CSSStyleSheetResource( |
57 const ResourceRequest& resourceRequest, | 61 const ResourceRequest& resourceRequest, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 static_cast<StyleSheetResourceClient*>(c)->didAppendFirstData(this); | 96 static_cast<StyleSheetResourceClient*>(c)->didAppendFirstData(this); |
93 | 97 |
94 // |c| might be removed in didAppendFirstData, so ensure it is still a client. | 98 // |c| might be removed in didAppendFirstData, so ensure it is still a client. |
95 if (hasClient(c) && !isLoading()) | 99 if (hasClient(c) && !isLoading()) |
96 static_cast<StyleSheetResourceClient*>(c)->setCSSStyleSheet( | 100 static_cast<StyleSheetResourceClient*>(c)->setCSSStyleSheet( |
97 resourceRequest().url(), response().url(), encoding(), this); | 101 resourceRequest().url(), response().url(), encoding(), this); |
98 } | 102 } |
99 | 103 |
100 const String CSSStyleSheetResource::sheetText( | 104 const String CSSStyleSheetResource::sheetText( |
101 MIMETypeCheck mimeTypeCheck) const { | 105 MIMETypeCheck mimeTypeCheck) const { |
102 if (!data() || data()->isEmpty() || !canUseSheet(mimeTypeCheck)) | 106 if (!canUseSheet(mimeTypeCheck)) |
103 return String(); | 107 return String(); |
104 | 108 |
105 if (!m_decodedSheetText.isNull()) | 109 // Use cached decoded sheet text when available |
| 110 if (!m_decodedSheetText.isNull()) { |
| 111 // We should have the decoded sheet text cached when the resource is fully |
| 112 // loaded. |
| 113 DCHECK_EQ(getStatus(), Resource::Cached); |
| 114 |
106 return m_decodedSheetText; | 115 return m_decodedSheetText; |
| 116 } |
107 | 117 |
108 // Don't cache the decoded text, regenerating is cheap and it can use quite a | 118 if (!data() || data()->isEmpty()) |
109 // bit of memory | 119 return String(); |
| 120 |
110 return decodedText(); | 121 return decodedText(); |
111 } | 122 } |
112 | 123 |
113 void CSSStyleSheetResource::appendData(const char* data, size_t length) { | 124 void CSSStyleSheetResource::appendData(const char* data, size_t length) { |
114 Resource::appendData(data, length); | 125 Resource::appendData(data, length); |
115 if (m_didNotifyFirstData) | 126 if (m_didNotifyFirstData) |
116 return; | 127 return; |
117 ResourceClientWalker<StyleSheetResourceClient> w(clients()); | 128 ResourceClientWalker<StyleSheetResourceClient> w(clients()); |
118 while (StyleSheetResourceClient* c = w.next()) | 129 while (StyleSheetResourceClient* c = w.next()) |
119 c->didAppendFirstData(this); | 130 c->didAppendFirstData(this); |
120 m_didNotifyFirstData = true; | 131 m_didNotifyFirstData = true; |
121 } | 132 } |
122 | 133 |
123 void CSSStyleSheetResource::checkNotify() { | 134 void CSSStyleSheetResource::checkNotify() { |
124 // Decode the data to find out the encoding and keep the sheet text around | 135 // Decode the data to find out the encoding and cache the decoded sheet text. |
125 // during checkNotify() | 136 if (data()) { |
126 if (data()) | |
127 m_decodedSheetText = decodedText(); | 137 m_decodedSheetText = decodedText(); |
| 138 } |
128 | 139 |
129 ResourceClientWalker<StyleSheetResourceClient> w(clients()); | 140 ResourceClientWalker<StyleSheetResourceClient> w(clients()); |
130 while (StyleSheetResourceClient* c = w.next()) { | 141 while (StyleSheetResourceClient* c = w.next()) { |
131 markClientFinished(c); | 142 markClientFinished(c); |
132 c->setCSSStyleSheet(resourceRequest().url(), response().url(), encoding(), | 143 c->setCSSStyleSheet(resourceRequest().url(), response().url(), encoding(), |
133 this); | 144 this); |
134 } | 145 } |
135 // Clear the decoded text as it is unlikely to be needed immediately again and | 146 |
136 // is cheap to regenerate. | 147 // Clear raw bytes as now we have the full decoded sheet text. |
137 m_decodedSheetText = String(); | 148 // We wait for all LinkStyle::setCSSStyleSheet to run (at least once) |
| 149 // as SubresourceIntegrity checks require raw bytes. |
| 150 // Note that LinkStyle::setCSSStyleSheet can be called from didAddClient too, |
| 151 // but is safe as we should have a cached ResourceIntegrityDisposition. |
| 152 clearData(); |
138 } | 153 } |
139 | 154 |
140 void CSSStyleSheetResource::destroyDecodedDataIfPossible() { | 155 void CSSStyleSheetResource::destroyDecodedDataIfPossible() { |
141 if (!m_parsedStyleSheetCache) | 156 if (!m_parsedStyleSheetCache) |
142 return; | 157 return; |
143 | 158 |
144 setParsedStyleSheetCache(nullptr); | 159 setParsedStyleSheetCache(nullptr); |
145 setDecodedSize(0); | 160 setDecodedSize(0); |
146 } | 161 } |
147 | 162 |
| 163 void CSSStyleSheetResource::destroyDecodedDataForFailedRevalidation() { |
| 164 m_decodedSheetText = String(); |
| 165 destroyDecodedDataIfPossible(); |
| 166 } |
| 167 |
148 bool CSSStyleSheetResource::canUseSheet(MIMETypeCheck mimeTypeCheck) const { | 168 bool CSSStyleSheetResource::canUseSheet(MIMETypeCheck mimeTypeCheck) const { |
149 if (errorOccurred()) | 169 if (errorOccurred()) |
150 return false; | 170 return false; |
151 | 171 |
152 // This check exactly matches Firefox. Note that we grab the Content-Type | 172 // This check exactly matches Firefox. Note that we grab the Content-Type |
153 // header directly because we want to see what the value is BEFORE content | 173 // header directly because we want to see what the value is BEFORE content |
154 // sniffing. Firefox does this by setting a "type hint" on the channel. This | 174 // sniffing. Firefox does this by setting a "type hint" on the channel. This |
155 // implementation should be observationally equivalent. | 175 // implementation should be observationally equivalent. |
156 // | 176 // |
157 // This code defaults to allowing the stylesheet for non-HTTP protocols so | 177 // This code defaults to allowing the stylesheet for non-HTTP protocols so |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 // This stylesheet resource did conflict with another resource and was not | 213 // This stylesheet resource did conflict with another resource and was not |
194 // added to the cache. | 214 // added to the cache. |
195 setParsedStyleSheetCache(nullptr); | 215 setParsedStyleSheetCache(nullptr); |
196 return; | 216 return; |
197 } | 217 } |
198 setParsedStyleSheetCache(sheet); | 218 setParsedStyleSheetCache(sheet); |
199 setDecodedSize(m_parsedStyleSheetCache->estimatedSizeInBytes()); | 219 setDecodedSize(m_parsedStyleSheetCache->estimatedSizeInBytes()); |
200 } | 220 } |
201 | 221 |
202 } // namespace blink | 222 } // namespace blink |
OLD | NEW |