13c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch/* 23c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * Copyright (C) 2013 Google Inc. All rights reserved. 33c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * 43c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * Redistribution and use in source and binary forms, with or without 53c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * modification, are permitted provided that the following conditions are 63c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * met: 73c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * 83c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * * Redistributions of source code must retain the above copyright 93c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * notice, this list of conditions and the following disclaimer. 103c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * * Redistributions in binary form must reproduce the above 113c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * copyright notice, this list of conditions and the following disclaimer 123c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * in the documentation and/or other materials provided with the 133c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * distribution. 143c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * * Neither the name of Google Inc. nor the names of its 153c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * contributors may be used to endorse or promote products derived from 163c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * this software without specific prior written permission. 173c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * 183c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 193c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 203c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 223c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 233c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 243c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 253c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 263c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 273c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 283c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 293c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch */ 303c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 313c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "config.h" 32e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)#include "core/html/HTMLImportLoader.h" 333c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 343c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "core/dom/Document.h" 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/custom/CustomElementRegistrationContext.h" 36e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h" 37a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "core/frame/ContentSecurityPolicyResponseHeaders.h" 383c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "core/html/HTMLDocument.h" 39a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "core/html/HTMLImport.h" 40e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)#include "core/html/HTMLImportLoaderClient.h" 413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "core/loader/DocumentWriter.h" 423c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 433c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 44a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)namespace WebCore { 453c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 46e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)PassRefPtr<HTMLImportLoader> HTMLImportLoader::create(HTMLImport* import, ResourceFetcher* fetcher) 47e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){ 48e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) RefPtr<HTMLImportLoader> self = adoptRef(new HTMLImportLoader(import, fetcher)); 49a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return self.release(); 50e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)} 51e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 52e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)HTMLImportLoader::HTMLImportLoader(HTMLImport* import, ResourceFetcher* fetcher) 53a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) : m_import(import) 54a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) , m_fetcher(fetcher) 55a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) , m_state(StateLoading) 563c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 573c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 583c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 59e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)HTMLImportLoader::~HTMLImportLoader() 603c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 61a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_importedDocument) 62a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_importedDocument->setImport(0); 633c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 643c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 65e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::startLoading(const ResourcePtr<RawResource>& resource) 663c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 67a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setResource(resource); 683c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 693c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 70e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::responseReceived(Resource* resource, const ResourceResponse& response) 713c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 72a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Current canAccess() implementation isn't sufficient for catching cross-domain redirects: http://crbug.com/256976 73a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!m_fetcher->canAccess(resource, PotentiallyCORSEnabled)) { 74a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setState(StateError); 753c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return; 763c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch } 773c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 78a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setState(startWritingAndParsing(response)); 793c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 803c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 81e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::dataReceived(Resource*, const char* data, int length) 823c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 83a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) RefPtr<DocumentWriter> protectingWriter(m_writer); 84a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_writer->addData(data, length); 85a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 863c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 87e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::notifyFinished(Resource* resource) 88a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 89a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // The writer instance indicates that a part of the document can be already loaded. 90a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // We don't take such a case as an error because the partially-loaded document has been visible from script at this point. 91a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (resource->loadFailedOrCanceled() && !m_writer) { 92a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setState(StateError); 93a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return; 943c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch } 953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 96a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setState(finishWriting()); 973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 99e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)HTMLImportLoader::State HTMLImportLoader::startWritingAndParsing(const ResourceResponse& response) 1003c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 101a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) DocumentInit init = DocumentInit(response.url(), 0, m_import->master()->contextDocument(), m_import) 102a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) .withRegistrationContext(m_import->master()->registrationContext()); 1038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_importedDocument = HTMLDocument::create(init); 1043c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch m_importedDocument->initContentSecurityPolicy(ContentSecurityPolicyResponseHeaders(response)); 1053c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch m_writer = DocumentWriter::create(m_importedDocument.get(), response.mimeType(), response.textEncodingName()); 1063c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 1073c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return StateLoading; 1083c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1093c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 110e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)HTMLImportLoader::State HTMLImportLoader::finishWriting() 1113c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 1123c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return StateWritten; 1133c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1143c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 115e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)HTMLImportLoader::State HTMLImportLoader::finishParsing() 1163c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 1173c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return StateReady; 1183c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1193c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 120e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::setState(State state) 1213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 122a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_state == state) 123a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return; 1243c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 125a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_state = state; 1263c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 127a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_state == StateReady || m_state == StateError || m_state == StateWritten) { 128a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (RefPtr<DocumentWriter> writer = m_writer.release()) 129a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) writer->end(); 130a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 131a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 132a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Since DocumentWriter::end() can let setState() reenter, we shouldn't refer to m_state here. 133a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (state == StateReady || state == StateError) 134a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) didFinish(); 1353c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 137e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::didFinishParsing() 1383c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 139a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setState(finishParsing()); 1403c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 142e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)Document* HTMLImportLoader::importedDocument() const 1433c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 144a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_state == StateError) 145a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return 0; 146a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return m_importedDocument.get(); 1473c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1483c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 149e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)bool HTMLImportLoader::isProcessing() const 1503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 151a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!m_importedDocument) 152a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return !isDone(); 153a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return m_importedDocument->parsing(); 1543c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1553c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 156e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::didFinish() 1573c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 158a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) for (size_t i = 0; i < m_clients.size(); ++i) 159a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_clients[i]->didFinish(); 160a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 161a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) clearResource(); 162a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 163a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(!m_importedDocument || !m_importedDocument->parsing()); 1643c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1653c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 166e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::addClient(HTMLImportLoaderClient* client) 1673c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 168a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(kNotFound == m_clients.find(client)); 169a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_clients.append(client); 170a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (isDone()) 171a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) client->didFinish(); 1723c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1733c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 174e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)void HTMLImportLoader::removeClient(HTMLImportLoaderClient* client) 1753c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 176a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(kNotFound != m_clients.find(client)); 177a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_clients.remove(m_clients.find(client)); 1783c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 1793c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 180a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1813c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} // namespace WebCore 182