| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 namespace WebCore { | 43 namespace WebCore { |
| 44 | 44 |
| 45 PassRefPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner) | 45 PassRefPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner) |
| 46 { | 46 { |
| 47 return adoptRef(new LinkImport(owner)); | 47 return adoptRef(new LinkImport(owner)); |
| 48 } | 48 } |
| 49 | 49 |
| 50 LinkImport::LinkImport(HTMLLinkElement* owner) | 50 LinkImport::LinkImport(HTMLLinkElement* owner) |
| 51 : LinkResource(owner) | 51 : LinkResource(owner) |
| 52 , m_controller(0) | |
| 53 , m_ofSameLocation(0) | |
| 54 , m_state(StatePreparing) | |
| 55 { | 52 { |
| 56 } | 53 } |
| 57 | 54 |
| 58 LinkImport::~LinkImport() | 55 LinkImport::~LinkImport() |
| 59 { | 56 { |
| 57 } |
| 58 |
| 59 Document* LinkImport::importedDocument() const |
| 60 { |
| 61 if (!m_loader) |
| 62 return 0; |
| 63 return m_loader->importedDocument(); |
| 64 } |
| 65 |
| 66 void LinkImport::process() |
| 67 { |
| 68 if (m_loader) |
| 69 return; |
| 70 if (!m_owner) |
| 71 return; |
| 72 |
| 73 // FIXME(morrita): Should take care of sub-imports whose document doesn't ha
ve frame. |
| 74 if (!m_owner->document()->frame()) |
| 75 return; |
| 76 |
| 77 LinkRequestBuilder builder(m_owner); |
| 78 if (!builder.isValid()) |
| 79 return; |
| 80 |
| 81 HTMLImportsController* controller = m_owner->document()->ensureImports(); |
| 82 if (RefPtr<HTMLImportLoader> found = controller->findLinkFor(builder.url()))
{ |
| 83 m_loader = found; |
| 84 return; |
| 85 } |
| 86 |
| 87 CachedResourceRequest request = builder.build(true); |
| 88 CachedResourceHandle<CachedScript> resource = m_owner->document()->cachedRes
ourceLoader()->requestScript(request); |
| 89 m_loader = HTMLImportLoader::create(controller, builder.url(), resource); |
| 90 } |
| 91 |
| 92 void LinkImport::ownerRemoved() |
| 93 { |
| 94 m_owner = 0; |
| 95 m_loader.clear(); |
| 96 } |
| 97 |
| 98 |
| 99 PassRefPtr<HTMLImportLoader> HTMLImportLoader::create(HTMLImportsController* con
troller, const KURL& url, const CachedResourceHandle<CachedScript>& resource) |
| 100 { |
| 101 RefPtr<HTMLImportLoader> loader = adoptRef(new HTMLImportLoader(controller,
url, resource)); |
| 102 controller->addImport(loader); |
| 103 return loader; |
| 104 } |
| 105 |
| 106 HTMLImportLoader::HTMLImportLoader(HTMLImportsController* controller, const KURL
& url, const CachedResourceHandle<CachedScript>& resource) |
| 107 : m_controller(controller) |
| 108 , m_state(StateLoading) |
| 109 , m_resource(resource) |
| 110 , m_url(url) |
| 111 { |
| 112 m_resource->addClient(this); |
| 113 } |
| 114 |
| 115 HTMLImportLoader::~HTMLImportLoader() |
| 116 { |
| 60 if (m_resource) | 117 if (m_resource) |
| 61 m_resource->removeClient(this); | 118 m_resource->removeClient(this); |
| 62 } | 119 } |
| 63 | 120 |
| 64 LinkImport::State LinkImport::finish() | 121 void HTMLImportLoader::notifyFinished(CachedResource*) |
| 122 { |
| 123 setState(finish()); |
| 124 } |
| 125 |
| 126 void HTMLImportLoader::setState(State state) |
| 127 { |
| 128 if (m_state == state) |
| 129 return; |
| 130 m_state = state; |
| 131 |
| 132 if ((m_state == StateReady || m_state == StateError) && m_controller) |
| 133 m_controller->didLoad(); |
| 134 } |
| 135 |
| 136 HTMLImportLoader::State HTMLImportLoader::finish() |
| 65 { | 137 { |
| 66 if (!m_controller) | 138 if (!m_controller) |
| 67 return StateError; | 139 return StateError; |
| 68 | 140 |
| 69 if (m_resource->loadFailedOrCanceled()) | 141 if (m_resource->loadFailedOrCanceled()) |
| 70 return StateError; | 142 return StateError; |
| 71 | 143 |
| 72 String error; | 144 String error; |
| 73 if (!m_controller->securityOrigin()->canRequest(m_resource->response().url()
) | 145 if (!m_controller->securityOrigin()->canRequest(m_resource->response().url()
) |
| 74 && !m_resource->passesAccessControlCheck(m_controller->securityOrigin(),
error)) { | 146 && !m_resource->passesAccessControlCheck(m_controller->securityOrigin(),
error)) { |
| 75 m_controller->showSecurityErrorMessage("Import from origin '" + Security
Origin::create(m_resource->response().url())->toString() + "' has been blocked f
rom loading by Cross-Origin Resource Sharing policy: " + error); | 147 m_controller->showSecurityErrorMessage("Import from origin '" + Security
Origin::create(m_resource->response().url())->toString() + "' has been blocked f
rom loading by Cross-Origin Resource Sharing policy: " + error); |
| 76 return StateError; | 148 return StateError; |
| 77 } | 149 } |
| 78 | 150 |
| 79 // FIXME(morrita): This should be done in incremental way. | 151 // FIXME(morrita): This should be done in incremental way. |
| 80 m_importedDocument = HTMLDocument::create(0, m_resource->response().url()); | 152 m_importedDocument = HTMLDocument::create(0, m_resource->response().url()); |
| 81 m_importedDocument->setContent(m_resource->script()); | 153 m_importedDocument->setContent(m_resource->script()); |
| 82 | 154 |
| 83 return StateReady; | 155 return StateReady; |
| 84 } | 156 } |
| 85 | 157 |
| 86 void LinkImport::notifyFinished(CachedResource*) | 158 Document* HTMLImportLoader::importedDocument() const |
| 87 { | 159 { |
| 88 setState(finish()); | |
| 89 } | |
| 90 | |
| 91 void LinkImport::setState(State state) | |
| 92 { | |
| 93 if (m_state == state) | |
| 94 return; | |
| 95 m_state = state; | |
| 96 | |
| 97 if ((m_state == StateReady || m_state == StateError) | |
| 98 && m_controller) | |
| 99 m_controller->didLoad(); | |
| 100 } | |
| 101 | |
| 102 LinkImport::State LinkImport::startRequest() | |
| 103 { | |
| 104 ASSERT(m_owner); | |
| 105 ASSERT(m_state == StatePreparing); | |
| 106 | |
| 107 // FIXME(morrita): Should take care of sub-imports whose document doesn't ha
ve frame. | |
| 108 if (!m_owner->document()->frame()) | |
| 109 return StateError; | |
| 110 | |
| 111 LinkRequestBuilder builder(m_owner); | |
| 112 if (!builder.isValid()) | |
| 113 return StateError; | |
| 114 | |
| 115 m_controller = m_owner->document()->ensureImports(); | |
| 116 if (RefPtr<LinkImport> found = m_controller->findLinkFor(builder.url())) { | |
| 117 m_ofSameLocation = found.get(); | |
| 118 return StateReady; | |
| 119 } | |
| 120 | |
| 121 CachedResourceRequest request = builder.build(true); | |
| 122 m_resource = m_owner->document()->cachedResourceLoader()->requestScript(requ
est); | |
| 123 if (!m_resource) | |
| 124 return StateError; | |
| 125 | |
| 126 m_resource->addClient(this); | |
| 127 m_url = builder.url(); | |
| 128 m_controller->addImport(this); | |
| 129 | |
| 130 return StateStarted; | |
| 131 } | |
| 132 | |
| 133 Document* LinkImport::importedDocument() const | |
| 134 { | |
| 135 if (!m_owner) | |
| 136 return 0; | |
| 137 if (m_state != StateReady) | 160 if (m_state != StateReady) |
| 138 return 0; | 161 return 0; |
| 139 | |
| 140 if (m_ofSameLocation) { | |
| 141 ASSERT(!m_importedDocument); | |
| 142 return m_ofSameLocation->importedDocument(); | |
| 143 } | |
| 144 | |
| 145 return m_importedDocument.get(); | 162 return m_importedDocument.get(); |
| 146 } | 163 } |
| 147 | 164 |
| 148 void LinkImport::process() | 165 void HTMLImportLoader::importDestroyed() |
| 149 { | |
| 150 if (StatePreparing != m_state) | |
| 151 return; | |
| 152 setState(startRequest()); | |
| 153 } | |
| 154 | |
| 155 void LinkImport::ownerRemoved() | |
| 156 { | |
| 157 m_owner = 0; | |
| 158 } | |
| 159 | |
| 160 void LinkImport::importDestroyed() | |
| 161 { | 166 { |
| 162 m_controller = 0; | 167 m_controller = 0; |
| 163 m_importedDocument.clear(); | 168 m_importedDocument.clear(); |
| 164 } | 169 } |
| 165 | 170 |
| 171 |
| 166 PassOwnPtr<HTMLImportsController> HTMLImportsController::create(Document* master
) | 172 PassOwnPtr<HTMLImportsController> HTMLImportsController::create(Document* master
) |
| 167 { | 173 { |
| 168 return adoptPtr(new HTMLImportsController(master)); | 174 return adoptPtr(new HTMLImportsController(master)); |
| 169 } | 175 } |
| 170 | 176 |
| 171 HTMLImportsController::HTMLImportsController(Document* master) | 177 HTMLImportsController::HTMLImportsController(Document* master) |
| 172 : m_master(master) | 178 : m_master(master) |
| 173 { | 179 { |
| 174 } | 180 } |
| 175 | 181 |
| 176 HTMLImportsController::~HTMLImportsController() | 182 HTMLImportsController::~HTMLImportsController() |
| 177 { | 183 { |
| 178 for (size_t i = 0; i < m_imports.size(); ++i) | 184 for (size_t i = 0; i < m_imports.size(); ++i) |
| 179 m_imports[i]->importDestroyed(); | 185 m_imports[i]->importDestroyed(); |
| 180 } | 186 } |
| 181 | 187 |
| 182 void HTMLImportsController::addImport(PassRefPtr<LinkImport> link) | 188 void HTMLImportsController::addImport(PassRefPtr<HTMLImportLoader> link) |
| 183 { | 189 { |
| 184 ASSERT(!link->url().isEmpty() && link->url().isValid()); | 190 ASSERT(!link->url().isEmpty() && link->url().isValid()); |
| 185 m_imports.append(link); | 191 m_imports.append(link); |
| 186 } | 192 } |
| 187 | 193 |
| 188 void HTMLImportsController::showSecurityErrorMessage(const String& message) | 194 void HTMLImportsController::showSecurityErrorMessage(const String& message) |
| 189 { | 195 { |
| 190 m_master->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message); | 196 m_master->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message); |
| 191 } | 197 } |
| 192 | 198 |
| 193 void HTMLImportsController::didLoad() | 199 void HTMLImportsController::didLoad() |
| 194 { | 200 { |
| 195 if (haveLoaded()) | 201 if (haveLoaded()) |
| 196 m_master->didLoadAllImports(); | 202 m_master->didLoadAllImports(); |
| 197 } | 203 } |
| 198 | 204 |
| 199 PassRefPtr<LinkImport> HTMLImportsController::findLinkFor(const KURL& url) const | 205 PassRefPtr<HTMLImportLoader> HTMLImportsController::findLinkFor(const KURL& url)
const |
| 200 { | 206 { |
| 201 for (size_t i = 0; i < m_imports.size(); ++i) { | 207 for (size_t i = 0; i < m_imports.size(); ++i) { |
| 202 if (m_imports[i]->url() == url) | 208 if (m_imports[i]->url() == url) |
| 203 return m_imports[i]; | 209 return m_imports[i]; |
| 204 } | 210 } |
| 205 | 211 |
| 206 return 0; | 212 return 0; |
| 207 } | 213 } |
| 208 | 214 |
| 209 SecurityOrigin* HTMLImportsController::securityOrigin() const | 215 SecurityOrigin* HTMLImportsController::securityOrigin() const |
| 210 { | 216 { |
| 211 return m_master->securityOrigin(); | 217 return m_master->securityOrigin(); |
| 212 } | 218 } |
| 213 | 219 |
| 214 bool HTMLImportsController::haveLoaded() const | 220 bool HTMLImportsController::haveLoaded() const |
| 215 { | 221 { |
| 216 for (size_t i = 0; i < m_imports.size(); ++i) { | 222 for (size_t i = 0; i < m_imports.size(); ++i) { |
| 217 if (!m_imports[i]->isDone()) | 223 if (!m_imports[i]->isDone()) |
| 218 return false; | 224 return false; |
| 219 } | 225 } |
| 220 | 226 |
| 221 return true; | 227 return true; |
| 222 } | 228 } |
| 223 | 229 |
| 224 } // namespace WebCore | 230 } // namespace WebCore |
| OLD | NEW |