| 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* ancestorToNotify = loadedImport->parent(); ancestorToNotify
; ancestorToNotify = ancestorToNotify->parent()) { |
| 242 m_master->didLoadAllImports(); | 262 if (haveChildrenLoaded(ancestorToNotify)) |
| 263 ancestorToNotify->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 |