OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 if (!m_owner) | 70 if (!m_owner) |
71 return; | 71 return; |
72 | 72 |
73 if (!m_owner->document()->frame() && !m_owner->document()->imports()) | 73 if (!m_owner->document()->frame() && !m_owner->document()->imports()) |
74 return; | 74 return; |
75 | 75 |
76 LinkRequestBuilder builder(m_owner); | 76 LinkRequestBuilder builder(m_owner); |
77 if (!builder.isValid()) | 77 if (!builder.isValid()) |
78 return; | 78 return; |
79 | 79 |
80 HTMLImportsController* controller = m_owner->document()->imports(); | 80 if (!m_owner->document()->imports()) { |
81 if (!controller) { | |
82 ASSERT(m_owner->document()->frame()); // The document should be the mast er. | 81 ASSERT(m_owner->document()->frame()); // The document should be the mast er. |
83 m_owner->document()->setImports(HTMLImportsController::create(m_owner->d ocument())); | 82 HTMLImportsController::provideTo(m_owner->document()); |
84 controller = m_owner->document()->imports(); | |
85 } | 83 } |
86 | 84 |
85 HTMLImportsController* controller = m_owner->document()->imports()->controll er(); | |
87 if (RefPtr<HTMLImportLoader> found = controller->findLinkFor(builder.url())) { | 86 if (RefPtr<HTMLImportLoader> found = controller->findLinkFor(builder.url())) { |
88 m_loader = found; | 87 m_loader = found; |
89 return; | 88 return; |
90 } | 89 } |
91 | 90 |
92 CachedResourceRequest request = builder.build(true); | 91 CachedResourceRequest request = builder.build(true); |
93 request.setPotentiallyCrossOriginEnabled(controller->securityOrigin(), DoNot AllowStoredCredentials); | 92 request.setPotentiallyCrossOriginEnabled(controller->securityOrigin(), DoNot AllowStoredCredentials); |
94 CachedResourceHandle<CachedRawResource> resource = controller->cachedResourc eLoader()->requestRawResource(request); | 93 CachedResourceHandle<CachedRawResource> resource = controller->cachedResourc eLoader()->requestRawResource(request); |
95 if (!resource) | 94 if (!resource) |
96 return; | 95 return; |
97 | 96 |
98 m_loader = HTMLImportLoader::create(controller, builder.url(), resource); | 97 m_loader = HTMLImportLoader::create(controller, builder.url(), resource); |
99 } | 98 } |
100 | 99 |
101 void LinkImport::ownerRemoved() | 100 void LinkImport::ownerRemoved() |
102 { | 101 { |
103 m_owner = 0; | 102 m_owner = 0; |
104 m_loader.clear(); | 103 m_loader.clear(); |
105 } | 104 } |
106 | 105 |
107 | 106 |
108 PassRefPtr<HTMLImportLoader> HTMLImportLoader::create(HTMLImportsController* con troller, const KURL& url, const CachedResourceHandle<CachedScript>& resource) | 107 PassRefPtr<HTMLImportLoader> HTMLImportLoader::create(HTMLImport* parent, const KURL& url, const CachedResourceHandle<CachedScript>& resource) |
109 { | 108 { |
110 RefPtr<HTMLImportLoader> loader = adoptRef(new HTMLImportLoader(controller, url, resource)); | 109 RefPtr<HTMLImportLoader> loader = adoptRef(new HTMLImportLoader(parent, url, resource)); |
111 controller->addImport(loader); | 110 loader->controller()->addImport(loader); |
112 return loader; | 111 return loader.release(); |
113 } | 112 } |
114 | 113 |
115 HTMLImportLoader::HTMLImportLoader(HTMLImportsController* controller, const KURL & url, const CachedResourceHandle<CachedScript>& resource) | 114 HTMLImportLoader::HTMLImportLoader(HTMLImport* parent, const KURL& url, const Ca chedResourceHandle<CachedScript>& resource) |
116 : m_controller(controller) | 115 : m_parent(parent) |
117 , m_state(StateLoading) | 116 , m_state(StateLoading) |
118 , m_resource(resource) | 117 , m_resource(resource) |
119 , m_url(url) | 118 , m_url(url) |
120 { | 119 { |
121 m_resource->addClient(this); | 120 m_resource->addClient(this); |
122 } | 121 } |
123 | 122 |
124 HTMLImportLoader::~HTMLImportLoader() | 123 HTMLImportLoader::~HTMLImportLoader() |
125 { | 124 { |
125 ASSERT(!m_parent); | |
126 ASSERT(!m_importedDocument); | |
126 if (m_resource) | 127 if (m_resource) |
127 m_resource->removeClient(this); | 128 m_resource->removeClient(this); |
128 } | 129 } |
129 | 130 |
130 void HTMLImportLoader::responseReceived(CachedResource*, const ResourceResponse& response) | 131 void HTMLImportLoader::responseReceived(CachedResource*, const ResourceResponse& response) |
131 { | 132 { |
132 setState(startParsing(response)); | 133 setState(startParsing(response)); |
133 } | 134 } |
134 | 135 |
135 void HTMLImportLoader::dataReceived(CachedResource*, const char* data, int lengt h) | 136 void HTMLImportLoader::dataReceived(CachedResource*, const char* data, int lengt h) |
(...skipping 24 matching lines...) Expand all Loading... | |
160 m_writer->end(); | 161 m_writer->end(); |
161 m_writer.clear(); | 162 m_writer.clear(); |
162 } | 163 } |
163 | 164 |
164 if (m_resource) { | 165 if (m_resource) { |
165 m_resource->removeClient(this); | 166 m_resource->removeClient(this); |
166 m_resource = 0; | 167 m_resource = 0; |
167 } | 168 } |
168 | 169 |
169 | 170 |
170 if (m_controller) | 171 if (HTMLImportsController* controller = this->controller()) |
171 m_controller->didLoad(); | 172 controller->didLoad(this); |
172 } | 173 } |
173 | 174 |
174 HTMLImportLoader::State HTMLImportLoader::startParsing(const ResourceResponse& r esponse) | 175 HTMLImportLoader::State HTMLImportLoader::startParsing(const ResourceResponse& r esponse) |
175 { | 176 { |
176 // Current canAccess() implementation isn't sufficient for catching cross-do main redirects: http://crbug.com/256976 | 177 // Current canAccess() implementation isn't sufficient for catching cross-do main redirects: http://crbug.com/256976 |
177 if (!m_controller->cachedResourceLoader()->canAccess(m_resource.get())) | 178 if (!controller()->cachedResourceLoader()->canAccess(m_resource.get())) |
178 return StateError; | 179 return StateError; |
179 | 180 |
180 m_importedDocument = HTMLDocument::create(0, response.url()); | 181 m_importedDocument = HTMLDocument::create(0, response.url()); |
181 m_importedDocument->setImports(m_controller); | 182 m_importedDocument->setImports(this); |
182 m_writer = DocumentWriter::create(m_importedDocument.get(), response.mimeTyp e(), response.textEncodingName()); | 183 m_writer = DocumentWriter::create(m_importedDocument.get(), response.mimeTyp e(), response.textEncodingName()); |
183 | 184 |
184 return StateLoading; | 185 return StateLoading; |
185 } | 186 } |
186 | 187 |
187 HTMLImportLoader::State HTMLImportLoader::finish() | 188 HTMLImportLoader::State HTMLImportLoader::finish() |
188 { | 189 { |
189 if (!m_controller) | 190 if (!m_parent) |
190 return StateError; | 191 return StateError; |
191 // The writer instance indicates that a part of the document can be already loaded. | 192 // The writer instance indicates that a part of the document can be already loaded. |
192 // We don't take such a case as an error because the partially-loaded docume nt has been visible from script at this point. | 193 // We don't take such a case as an error because the partially-loaded docume nt has been visible from script at this point. |
193 if (m_resource->loadFailedOrCanceled() && !m_writer) | 194 if (m_resource->loadFailedOrCanceled() && !m_writer) |
194 return StateError; | 195 return StateError; |
195 return StateReady; | 196 return StateReady; |
196 } | 197 } |
197 | 198 |
198 Document* HTMLImportLoader::importedDocument() const | 199 Document* HTMLImportLoader::importedDocument() const |
199 { | 200 { |
200 if (m_state != StateReady) | 201 if (m_state != StateReady) |
201 return 0; | 202 return 0; |
202 return m_importedDocument.get(); | 203 return m_importedDocument.get(); |
203 } | 204 } |
204 | 205 |
205 void HTMLImportLoader::importDestroyed() | 206 void HTMLImportLoader::importDestroyed() |
206 { | 207 { |
207 m_controller = 0; | 208 m_parent = 0; |
209 m_importedDocument->setImports(0); | |
208 m_importedDocument.clear(); | 210 m_importedDocument.clear(); |
209 } | 211 } |
210 | 212 |
213 HTMLImportsController* HTMLImportLoader::controller() | |
214 { | |
215 return m_parent ? m_parent->controller() : 0; | |
216 } | |
211 | 217 |
212 PassRefPtr<HTMLImportsController> HTMLImportsController::create(Document* master ) | 218 HTMLImport* HTMLImportLoader::parent() |
213 { | 219 { |
214 return adoptRef(new HTMLImportsController(master)); | 220 return m_parent; |
221 } | |
222 | |
223 Document* HTMLImportLoader::document() | |
224 { | |
225 return m_importedDocument.get(); | |
226 } | |
227 | |
228 void HTMLImportsController::provideTo(Document* master) | |
229 { | |
230 DEFINE_STATIC_LOCAL(const char*, name, ("HTMLImportsController")); | |
231 OwnPtr<HTMLImportsController> controller = adoptPtr(new HTMLImportsControlle r(master)); | |
232 master->setImports(controller.get()); | |
233 Supplement<ScriptExecutionContext>::provideTo(master, name, controller.relea se()); | |
215 } | 234 } |
216 | 235 |
217 HTMLImportsController::HTMLImportsController(Document* master) | 236 HTMLImportsController::HTMLImportsController(Document* master) |
218 : m_master(master) | 237 : m_master(master) |
219 { | 238 { |
220 } | 239 } |
221 | 240 |
222 HTMLImportsController::~HTMLImportsController() | 241 HTMLImportsController::~HTMLImportsController() |
223 { | 242 { |
224 for (size_t i = 0; i < m_imports.size(); ++i) | 243 for (size_t i = 0; i < m_imports.size(); ++i) |
225 m_imports[i]->importDestroyed(); | 244 m_imports[i]->importDestroyed(); |
245 m_master->setImports(0); | |
226 } | 246 } |
227 | 247 |
228 void HTMLImportsController::addImport(PassRefPtr<HTMLImportLoader> link) | 248 void HTMLImportsController::addImport(PassRefPtr<HTMLImportLoader> link) |
229 { | 249 { |
230 ASSERT(!link->url().isEmpty() && link->url().isValid()); | 250 ASSERT(!link->url().isEmpty() && link->url().isValid()); |
231 m_imports.append(link); | 251 m_imports.append(link); |
232 } | 252 } |
233 | 253 |
234 void HTMLImportsController::showSecurityErrorMessage(const String& message) | 254 void HTMLImportsController::showSecurityErrorMessage(const String& message) |
235 { | 255 { |
236 m_master->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message); | 256 m_master->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message); |
237 } | 257 } |
238 | 258 |
239 void HTMLImportsController::didLoad() | 259 void HTMLImportsController::didLoad(HTMLImportLoader* loadedImport) |
240 { | 260 { |
241 if (haveLoaded()) | 261 for (HTMLImport* notifiee = loadedImport->parent(); notifiee; notifiee = not ifiee->parent()) { |
dglazkov
2013/07/10 17:54:22
notifiee->ancestorToNotify
| |
242 m_master->didLoadAllImports(); | 262 if (haveChildrenLoaded(notifiee)) |
263 notifiee->document()->didLoadAllImports(); | |
264 } | |
243 } | 265 } |
244 | 266 |
245 PassRefPtr<HTMLImportLoader> HTMLImportsController::findLinkFor(const KURL& url) const | 267 PassRefPtr<HTMLImportLoader> HTMLImportsController::findLinkFor(const KURL& url) const |
246 { | 268 { |
247 for (size_t i = 0; i < m_imports.size(); ++i) { | 269 for (size_t i = 0; i < m_imports.size(); ++i) { |
248 if (equalIgnoringFragmentIdentifier(m_imports[i]->url(), url)) | 270 if (equalIgnoringFragmentIdentifier(m_imports[i]->url(), url)) |
249 return m_imports[i]; | 271 return m_imports[i]; |
250 } | 272 } |
251 | 273 |
252 return 0; | 274 return 0; |
253 } | 275 } |
254 | 276 |
255 SecurityOrigin* HTMLImportsController::securityOrigin() const | 277 SecurityOrigin* HTMLImportsController::securityOrigin() const |
256 { | 278 { |
257 return m_master->securityOrigin(); | 279 return m_master->securityOrigin(); |
258 } | 280 } |
259 | 281 |
260 CachedResourceLoader* HTMLImportsController::cachedResourceLoader() const | 282 CachedResourceLoader* HTMLImportsController::cachedResourceLoader() const |
261 { | 283 { |
262 return m_master->cachedResourceLoader(); | 284 return m_master->cachedResourceLoader(); |
263 } | 285 } |
264 | 286 |
265 bool HTMLImportsController::haveLoaded() const | 287 bool HTMLImportsController::haveChildrenLoaded(HTMLImport* parent) const |
266 { | 288 { |
267 for (size_t i = 0; i < m_imports.size(); ++i) { | 289 for (size_t i = 0; i < m_imports.size(); ++i) { |
268 if (!m_imports[i]->isDone()) | 290 if (!m_imports[i]->isDone() && m_imports[i]->parent() == parent) |
269 return false; | 291 return false; |
270 } | 292 } |
271 | 293 |
272 return true; | 294 return true; |
273 } | 295 } |
274 | 296 |
297 HTMLImportsController* HTMLImportsController::controller() | |
298 { | |
299 return this; | |
300 } | |
301 | |
302 HTMLImport* HTMLImportsController::parent() | |
303 { | |
304 return 0; | |
305 } | |
306 | |
307 Document* HTMLImportsController::document() | |
308 { | |
309 return m_master; | |
310 } | |
311 | |
275 } // namespace WebCore | 312 } // namespace WebCore |
OLD | NEW |