diff options
Diffstat (limited to 'WebCore/loader')
47 files changed, 904 insertions, 522 deletions
diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/CachedCSSStyleSheet.cpp index 3fc28ff..245d944 100644 --- a/WebCore/loader/CachedCSSStyleSheet.cpp +++ b/WebCore/loader/CachedCSSStyleSheet.cpp @@ -31,6 +31,7 @@ #include "CachedResourceClientWalker.h" #include "HTTPParsers.h" #include "TextResourceDecoder.h" +#include "SharedBuffer.h" #include "loader.h" #include <wtf/Vector.h> diff --git a/WebCore/loader/CachedFont.cpp b/WebCore/loader/CachedFont.cpp index 3d9eeb9..d295618 100644 --- a/WebCore/loader/CachedFont.cpp +++ b/WebCore/loader/CachedFont.cpp @@ -34,15 +34,16 @@ #include "Cache.h" #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" -#include "DOMImplementation.h" #include "FontPlatformData.h" -#ifdef STORE_FONT_CUSTOM_PLATFORM_DATA -#include "FontCustomPlatformData.h" -#endif +#include "SharedBuffer.h" #include "TextResourceDecoder.h" #include "loader.h" #include <wtf/Vector.h> +#ifdef STORE_FONT_CUSTOM_PLATFORM_DATA +#include "FontCustomPlatformData.h" +#endif + #if ENABLE(SVG_FONTS) #include "HTMLNames.h" #include "NodeList.h" @@ -156,7 +157,7 @@ bool CachedFont::ensureSVGFontData() SVGFontElement* CachedFont::getSVGFontById(const String& fontName) const { ASSERT(m_isSVGFont); - RefPtr<NodeList> list = m_externalSVGDocument->getElementsByTagName(SVGNames::fontTag.localName()); + RefPtr<NodeList> list = m_externalSVGDocument->getElementsByTagNameNS(SVGNames::fontTag.namespaceURI(), SVGNames::fontTag.localName()); if (!list) return 0; diff --git a/WebCore/loader/CachedImage.cpp b/WebCore/loader/CachedImage.cpp index dd93041..8831d3b 100644 --- a/WebCore/loader/CachedImage.cpp +++ b/WebCore/loader/CachedImage.cpp @@ -34,6 +34,7 @@ #include "FrameView.h" #include "Request.h" #include "Settings.h" +#include "SharedBuffer.h" #include <wtf/CurrentTime.h> #include <wtf/StdLibExtras.h> #include <wtf/Vector.h> diff --git a/WebCore/loader/CachedImage.h b/WebCore/loader/CachedImage.h index 2aa35ac..cda03a2 100644 --- a/WebCore/loader/CachedImage.h +++ b/WebCore/loader/CachedImage.h @@ -25,7 +25,6 @@ #include "CachedResource.h" #include "ImageObserver.h" -#include "Image.h" #include "IntRect.h" #include "Timer.h" #include <wtf/Vector.h> diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/CachedResource.cpp index 640d1f7..c69791d 100644 --- a/WebCore/loader/CachedResource.cpp +++ b/WebCore/loader/CachedResource.cpp @@ -32,6 +32,7 @@ #include "KURL.h" #include "PurgeableBuffer.h" #include "Request.h" +#include "SharedBuffer.h" #include <wtf/CurrentTime.h> #include <wtf/MathExtras.h> #include <wtf/RefCountedLeakCounter.h> diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h index bad632b..2539729 100644 --- a/WebCore/loader/CachedResource.h +++ b/WebCore/loader/CachedResource.h @@ -27,7 +27,6 @@ #include "FrameLoaderTypes.h" #include "PlatformString.h" #include "ResourceResponse.h" -#include "SharedBuffer.h" #include <wtf/HashCountedSet.h> #include <wtf/HashSet.h> #include <wtf/OwnPtr.h> diff --git a/WebCore/loader/CachedScript.cpp b/WebCore/loader/CachedScript.cpp index 31483d6..28e6137 100644 --- a/WebCore/loader/CachedScript.cpp +++ b/WebCore/loader/CachedScript.cpp @@ -29,6 +29,7 @@ #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" +#include "SharedBuffer.h" #include "TextResourceDecoder.h" #include <wtf/Vector.h> diff --git a/WebCore/loader/CachedXSLStyleSheet.cpp b/WebCore/loader/CachedXSLStyleSheet.cpp index 59c3907..430ad46 100644 --- a/WebCore/loader/CachedXSLStyleSheet.cpp +++ b/WebCore/loader/CachedXSLStyleSheet.cpp @@ -29,6 +29,7 @@ #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" +#include "SharedBuffer.h" #include "TextResourceDecoder.h" #include <wtf/Vector.h> diff --git a/WebCore/loader/CrossOriginPreflightResultCache.h b/WebCore/loader/CrossOriginPreflightResultCache.h index faf55e5..f8a7c55 100644 --- a/WebCore/loader/CrossOriginPreflightResultCache.h +++ b/WebCore/loader/CrossOriginPreflightResultCache.h @@ -24,6 +24,9 @@ * */ +#ifndef CrossOriginPreflightResultCacheItem_h +#define CrossOriginPreflightResultCacheItem_h + #include "KURLHash.h" #include "StringHash.h" #include <wtf/HashMap.h> @@ -77,3 +80,5 @@ namespace WebCore { }; } // namespace WebCore + +#endif diff --git a/WebCore/loader/DocLoader.cpp b/WebCore/loader/DocLoader.cpp index 08dfa33..6862616 100644 --- a/WebCore/loader/DocLoader.cpp +++ b/WebCore/loader/DocLoader.cpp @@ -34,7 +34,6 @@ #include "CachedScript.h" #include "CachedXSLStyleSheet.h" #include "Console.h" -#include "CString.h" #include "Document.h" #include "DOMWindow.h" #include "HTMLElement.h" @@ -44,9 +43,13 @@ #include "loader.h" #include "SecurityOrigin.h" #include "Settings.h" +<<<<<<< HEAD #if ENABLE(LINK_PREFETCH) #include "CachedLinkPrefetch.h" #endif +======= +#include <wtf/text/CString.h> +>>>>>>> webkit.org at r58033 #define PRELOAD_DEBUG 0 @@ -473,7 +476,7 @@ void DocLoader::requestPreload(CachedResource::Type type, const String& url, con { String encoding; if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet) - encoding = charset.isEmpty() ? m_doc->frame()->loader()->encoding() : charset; + encoding = charset.isEmpty() ? m_doc->frame()->loader()->writer()->encoding() : charset; CachedResource* resource = requestResource(type, url, encoding, true); if (!resource || m_preloads.contains(resource)) diff --git a/WebCore/loader/DocumentLoader.cpp b/WebCore/loader/DocumentLoader.cpp index dca416e..e835f80 100644 --- a/WebCore/loader/DocumentLoader.cpp +++ b/WebCore/loader/DocumentLoader.cpp @@ -269,7 +269,7 @@ void DocumentLoader::finishedLoading() commitIfReady(); if (FrameLoader* loader = frameLoader()) { loader->finishedLoadingDocument(this); - loader->end(); + loader->writer()->end(); } } @@ -311,7 +311,7 @@ void DocumentLoader::setupForReplaceByMIMEType(const String& newMIMEType) } frameLoader()->finishedLoadingDocument(this); - m_frame->loader()->end(); + m_frame->loader()->writer()->end(); frameLoader()->setReplacing(); m_gotFirstByte = false; diff --git a/WebCore/loader/DocumentThreadableLoader.cpp b/WebCore/loader/DocumentThreadableLoader.cpp index d0f6c04..3bebbe6 100644 --- a/WebCore/loader/DocumentThreadableLoader.cpp +++ b/WebCore/loader/DocumentThreadableLoader.cpp @@ -217,6 +217,10 @@ void DocumentThreadableLoader::didReceiveData(SubresourceLoader* loader, const c ASSERT(m_client); ASSERT_UNUSED(loader, loader == m_loader); + // Ignore response body of preflight requests. + if (m_actualRequest) + return; + m_client->didReceiveData(data, lengthReceived); } diff --git a/WebCore/loader/DocumentWriter.cpp b/WebCore/loader/DocumentWriter.cpp new file mode 100644 index 0000000..ba0695e --- /dev/null +++ b/WebCore/loader/DocumentWriter.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2010. Adam Barth. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DocumentWriter.h" + +#include "DOMImplementation.h" +#include "DOMWindow.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameLoaderClient.h" +#include "FrameView.h" +#include "PlaceholderDocument.h" +#include "PluginDocument.h" +#include "SecurityOrigin.h" +#include "SegmentedString.h" +#include "Settings.h" +#include "TextResourceDecoder.h" +#include "Tokenizer.h" + +namespace WebCore { + +static inline bool canReferToParentFrameEncoding(const Frame* frame, const Frame* parentFrame) +{ + return parentFrame && parentFrame->document()->securityOrigin()->canAccess(frame->document()->securityOrigin()); +} + +DocumentWriter::DocumentWriter(Frame* frame) + : m_frame(frame) + , m_receivedData(false) + , m_encodingWasChosenByUser(false) +{ +} + +void DocumentWriter::replaceDocument(const String& html) +{ + m_frame->loader()->stopAllLoaders(); + begin(m_frame->loader()->url(), true, m_frame->document()->securityOrigin()); + addData(html); + end(); +} + +void DocumentWriter::clear() +{ + m_decoder = 0; + m_receivedData = false; + if (!m_encodingWasChosenByUser) + m_encoding = String(); +} + +void DocumentWriter::begin() +{ + begin(KURL()); +} + +PassRefPtr<Document> DocumentWriter::createDocument() +{ + if (!m_frame->loader()->isDisplayingInitialEmptyDocument() && m_frame->loader()->client()->shouldUsePluginDocument(m_mimeType)) + return PluginDocument::create(m_frame); + if (!m_frame->loader()->client()->hasHTMLView()) + return PlaceholderDocument::create(m_frame); + return DOMImplementation::createDocument(m_mimeType, m_frame, m_frame->inViewSourceMode()); +} + +void DocumentWriter::begin(const KURL& url, bool dispatch, SecurityOrigin* origin) +{ + // We need to take a reference to the security origin because |clear| + // might destroy the document that owns it. + RefPtr<SecurityOrigin> forcedSecurityOrigin = origin; + + // Create a new document before clearing the frame, because it may need to + // inherit an aliased security context. + RefPtr<Document> document = createDocument(); + + bool resetScripting = !(m_frame->loader()->isDisplayingInitialEmptyDocument() && m_frame->document()->securityOrigin()->isSecureTransitionTo(url)); + m_frame->loader()->clear(resetScripting, resetScripting); + if (resetScripting) + m_frame->script()->updatePlatformScriptObjects(); + + m_frame->loader()->setURL(url); + document->setURL(url); + m_frame->setDocument(document); + + if (m_decoder) + document->setDecoder(m_decoder.get()); + if (forcedSecurityOrigin) + document->setSecurityOrigin(forcedSecurityOrigin.get()); + + m_frame->domWindow()->setURL(document->url()); + m_frame->domWindow()->setSecurityOrigin(document->securityOrigin()); + + m_frame->loader()->didBeginDocument(dispatch); + + document->implicitOpen(); + + if (m_frame->view() && m_frame->loader()->client()->hasHTMLView()) + m_frame->view()->setContentsSize(IntSize()); +} + +void DocumentWriter::addData(const char* str, int len, bool flush) +{ + if (len == 0 && !flush) + return; + + if (len == -1) + len = strlen(str); + + Tokenizer* tokenizer = m_frame->document()->tokenizer(); + if (tokenizer && tokenizer->wantsRawData()) { + if (len > 0) + tokenizer->writeRawData(str, len); + return; + } + + if (!m_decoder) { + if (Settings* settings = m_frame->settings()) { + m_decoder = TextResourceDecoder::create(m_mimeType, + settings->defaultTextEncodingName(), + settings->usesEncodingDetector()); + Frame* parentFrame = m_frame->tree()->parent(); + // Set the hint encoding to the parent frame encoding only if + // the parent and the current frames share the security origin. + // We impose this condition because somebody can make a child frame + // containing a carefully crafted html/javascript in one encoding + // that can be mistaken for hintEncoding (or related encoding) by + // an auto detector. When interpreted in the latter, it could be + // an attack vector. + // FIXME: This might be too cautious for non-7bit-encodings and + // we may consider relaxing this later after testing. + if (canReferToParentFrameEncoding(m_frame, parentFrame)) + m_decoder->setHintEncoding(parentFrame->document()->decoder()); + } else + m_decoder = TextResourceDecoder::create(m_mimeType, String()); + Frame* parentFrame = m_frame->tree()->parent(); + if (m_encoding.isEmpty()) { + if (canReferToParentFrameEncoding(m_frame, parentFrame)) + m_decoder->setEncoding(parentFrame->document()->inputEncoding(), TextResourceDecoder::EncodingFromParentFrame); + } else { + m_decoder->setEncoding(m_encoding, + m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader); + } + m_frame->document()->setDecoder(m_decoder.get()); + } + + String decoded = m_decoder->decode(str, len); + if (flush) + decoded += m_decoder->flush(); + if (decoded.isEmpty()) + return; + + if (!m_receivedData) { + m_receivedData = true; + if (m_decoder->encoding().usesVisualOrdering()) + m_frame->document()->setVisuallyOrdered(); + m_frame->document()->recalcStyle(Node::Force); + } + + if (tokenizer) { + ASSERT(!tokenizer->wantsRawData()); + tokenizer->write(decoded, true); + } +} + +void DocumentWriter::addData(const String& str) +{ + if (str.isNull()) + return; + + if (!m_receivedData) { + m_receivedData = true; + m_frame->document()->setParseMode(Document::Strict); + } + + if (Tokenizer* tokenizer = m_frame->document()->tokenizer()) + tokenizer->write(str, true); +} + +void DocumentWriter::end() +{ + m_frame->loader()->didEndDocument(); + endIfNotLoadingMainResource(); +} + +void DocumentWriter::endIfNotLoadingMainResource() +{ + if (m_frame->loader()->isLoadingMainResource() || !m_frame->page() || !m_frame->document()) + return; + + // http://bugs.webkit.org/show_bug.cgi?id=10854 + // The frame's last ref may be removed and it can be deleted by checkCompleted(), + // so we'll add a protective refcount + RefPtr<Frame> protector(m_frame); + + // make sure nothing's left in there + addData(0, 0, true); + m_frame->document()->finishParsing(); +} + +String DocumentWriter::encoding() const +{ + if (m_encodingWasChosenByUser && !m_encoding.isEmpty()) + return m_encoding; + if (m_decoder && m_decoder->encoding().isValid()) + return m_decoder->encoding().name(); + Settings* settings = m_frame->settings(); + return settings ? settings->defaultTextEncodingName() : String(); +} + +void DocumentWriter::setEncoding(const String& name, bool userChosen) +{ + m_frame->loader()->willSetEncoding(); + m_encoding = name; + m_encodingWasChosenByUser = userChosen; +} + +void DocumentWriter::setDecoder(TextResourceDecoder* decoder) +{ + m_decoder = decoder; +} + +String DocumentWriter::deprecatedFrameEncoding() const +{ + return m_frame->loader()->url().isEmpty() ? m_encoding : encoding(); +} + +} // namespace WebCore diff --git a/WebCore/loader/DocumentWriter.h b/WebCore/loader/DocumentWriter.h new file mode 100644 index 0000000..a06fb7f --- /dev/null +++ b/WebCore/loader/DocumentWriter.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010. Adam Barth. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Adam Barth. ("Adam Barth") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DocumentWriter_h +#define DocumentWriter_h + +#include "KURL.h" +#include "PlatformString.h" + +namespace WebCore { + +class Document; +class Frame; +class SecurityOrigin; +class TextResourceDecoder; + +class DocumentWriter : public Noncopyable { +public: + DocumentWriter(Frame*); + + void replaceDocument(const String&); + + void begin(); + void begin(const KURL&, bool dispatchWindowObjectAvailable = true, SecurityOrigin* forcedSecurityOrigin = 0); + void addData(const char* string, int length = -1, bool flush = false); + void addData(const String&); + void end(); + void endIfNotLoadingMainResource(); + void clear(); + + String encoding() const; + void setEncoding(const String& encoding, bool userChosen); + + // FIXME: It's really unforunate to need to expose this piece of state. + // I suspect a better design is to disentangle user-provided encodings, + // default encodings, and the decoding we're currently using. + String deprecatedFrameEncoding() const; + + const String& mimeType() const { return m_mimeType; } + void setMIMEType(const String& type) { m_mimeType = type; } + + void setDecoder(TextResourceDecoder*); + +private: + PassRefPtr<Document> createDocument(); + + Frame* m_frame; + + bool m_receivedData; + String m_mimeType; + + bool m_encodingWasChosenByUser; + String m_encoding; + RefPtr<TextResourceDecoder> m_decoder; +}; + +} // namespace WebCore + +#endif // DocumentWriter_h diff --git a/WebCore/loader/EmptyClients.h b/WebCore/loader/EmptyClients.h index 0d25818..9c764b9 100644 --- a/WebCore/loader/EmptyClients.h +++ b/WebCore/loader/EmptyClients.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Eric Seidel (eric@webkit.org) - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,12 +36,10 @@ #include "EditorClient.h" #include "FloatRect.h" #include "FocusDirection.h" -#include "FormState.h" #include "FrameLoaderClient.h" #include "InspectorClient.h" #include "PluginHalterClient.h" #include "ResourceError.h" -#include "SharedBuffer.h" /* This file holds empty Client stubs for use by WebCore. @@ -119,12 +117,12 @@ public: virtual bool tabsToLinks() const { return false; } virtual IntRect windowResizerRect() const { return IntRect(); } - virtual void addToDirtyRegion(const IntRect&) { } - virtual void scrollBackingStore(int, int, const IntRect&, const IntRect&) { } - virtual void updateBackingStore() { } - virtual void repaint(const IntRect&, bool, bool, bool) { } + virtual void invalidateWindow(const IntRect&, bool) { } + virtual void invalidateContentsAndWindow(const IntRect&, bool) { } + virtual void invalidateContentsForSlowScroll(const IntRect&, bool) {}; virtual void scroll(const IntSize&, const IntRect&, const IntRect&) { } + virtual IntPoint screenToWindow(const IntPoint& p) const { return p; } virtual IntRect windowToScreen(const IntRect& r) const { return r; } virtual PlatformPageClient platformPageClient() const { return 0; } @@ -150,7 +148,7 @@ public: #endif virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) { } - virtual void iconForFiles(const Vector<String>&, PassRefPtr<FileChooser>) { } + virtual void chooseIconForFiles(const Vector<String>&, FileChooser*) { } virtual void formStateDidChange(const Node*) { } @@ -164,7 +162,11 @@ public: virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const {} virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) {} +<<<<<<< HEAD virtual void cancelGeolocationPermissionRequestForFrame(Frame*) {} +======= + virtual void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*) {} +>>>>>>> webkit.org at r58033 #if USE(ACCELERATED_COMPOSITING) virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) {}; @@ -205,7 +207,6 @@ public: virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long) { } virtual void dispatchDidFailLoading(DocumentLoader*, unsigned long, const ResourceError&) { } virtual bool dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int) { return false; } - virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long, const ScriptString&) { } virtual void dispatchDidHandleOnloadEvents() { } virtual void dispatchDidReceiveServerRedirectForProvisionalLoad() { } @@ -305,6 +306,9 @@ public: virtual void didTransferChildFrameToNewDocument() { } virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool) { return 0; } virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&) { return 0; } +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + virtual PassRefPtr<Widget> createMediaPlayerProxyPlugin(const IntSize&, HTMLMediaElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&) { return 0; } +#endif virtual ObjectContentType objectContentType(const KURL&, const String&) { return ObjectContentType(); } virtual String overrideMediaType() const { return String(); } @@ -481,29 +485,14 @@ public: virtual ~EmptyInspectorClient() { } virtual void inspectorDestroyed() { } - - virtual Page* createPage() { return 0; }; - - virtual String localizedStringsURL() { return String(); } - - virtual String hiddenPanels() { return String(); } - - virtual void showWindow() { } - virtual void closeWindow() { } - - virtual void attachWindow() { } - virtual void detachWindow() { } - - virtual void setAttachedWindowHeight(unsigned) { } + + virtual void openInspectorFrontend(InspectorController*) { } virtual void highlight(Node*) { } virtual void hideHighlight() { } - virtual void inspectedURLChanged(const String&) { } virtual void populateSetting(const String&, String*) { } virtual void storeSetting(const String&, const String&) { } - - virtual void inspectorWindowObjectCleared() { } }; } diff --git a/WebCore/loader/FTPDirectoryDocument.cpp b/WebCore/loader/FTPDirectoryDocument.cpp index 62173f5..66136b5 100644 --- a/WebCore/loader/FTPDirectoryDocument.cpp +++ b/WebCore/loader/FTPDirectoryDocument.cpp @@ -27,7 +27,6 @@ #include "FTPDirectoryDocument.h" #include "CharacterNames.h" -#include "CString.h" #include "HTMLNames.h" #include "HTMLTableElement.h" #include "HTMLTokenizer.h" @@ -39,6 +38,7 @@ #include "SharedBuffer.h" #include "Text.h" +#include <wtf/text/CString.h> #include <wtf/CurrentTime.h> #include <wtf/StdLibExtras.h> diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp index d28dc50..5e592a5 100644 --- a/WebCore/loader/FrameLoader.cpp +++ b/WebCore/loader/FrameLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * Copyright (C) 2008 Alp Toker <alp@atoker.com> @@ -39,7 +39,6 @@ #include "ArchiveFactory.h" #endif #include "BackForwardList.h" -#include "CString.h" #include "Cache.h" #include "CachedPage.h" #include "Chrome.h" @@ -64,6 +63,9 @@ #include "HTMLAppletElement.h" #include "HTMLFormElement.h" #include "HTMLFrameElement.h" +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +#include "HTMLMediaElement.h" +#endif #include "HTMLNames.h" #include "HTMLObjectElement.h" #include "HTTPParsers.h" @@ -83,9 +85,11 @@ #include "PluginDatabase.h" #include "PluginDocument.h" #include "ProgressTracker.h" -#include "RenderPart.h" +#include "RenderEmbeddedObject.h" +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +#include "RenderVideo.h" +#endif #include "RenderView.h" -#include "RenderWidget.h" #include "ResourceHandle.h" #include "ResourceRequest.h" #include "ScriptController.h" @@ -105,6 +109,7 @@ #include "XMLHttpRequest.h" #include "XMLTokenizer.h" #include "XSSAuditor.h" +#include <wtf/text/CString.h> #include <wtf/CurrentTime.h> #include <wtf/StdLibExtras.h> @@ -177,6 +182,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) , m_policyChecker(frame) , m_history(frame) , m_notifer(frame) + , m_writer(frame) , m_state(FrameStateCommittedPage) , m_loadType(FrameLoadTypeStandard) , m_delegateIsHandlingProvisionalLoadError(false) @@ -192,7 +198,6 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) , m_isLoadingMainResource(false) , m_needsClear(false) , m_receivedData(false) - , m_encodingWasChosenByUser(false) , m_containsPlugIns(false) , m_checkTimer(this, &FrameLoader::checkTimerFired) , m_shouldCallCheckCompleted(false) @@ -205,6 +210,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) , m_loadingFromCachedPage(false) , m_suppressOpenerInNewFrame(false) , m_sandboxFlags(SandboxAll) + , m_forcedSandboxFlags(SandboxNone) #ifndef NDEBUG , m_didDispatchDidCommitLoad(false) #endif @@ -232,8 +238,8 @@ void FrameLoader::init() setState(FrameStateProvisional); m_provisionalDocumentLoader->setResponse(ResourceResponse(KURL(), "text/html", 0, String(), String())); m_provisionalDocumentLoader->finishedLoading(); - begin(KURL(), false); - end(); + writer()->begin(KURL(), false); + writer()->end(); m_frame->document()->cancelParsing(); m_creatingInitialEmptyDocument = false; m_didCallImplicitClose = true; @@ -276,7 +282,11 @@ Frame* FrameLoader::createWindow(FrameLoader* frameLoaderForFrameLookup, const F return frame; } } - + + // Sandboxed frames cannot open new auxiliary browsing contexts. + if (isDocumentSandboxed(SandboxNavigation)) + return 0; + // FIXME: Setting the referrer should be the caller's responsibility. FrameLoadRequest requestWithReferrer = request; requestWithReferrer.resourceRequest().setHTTPReferrer(m_outgoingReferrer); @@ -366,7 +376,7 @@ void FrameLoader::urlSelected(const ResourceRequest& request, const String& pass m_suppressOpenerInNewFrame = false; } -bool FrameLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String& urlString, const AtomicString& frameName) +bool FrameLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String& urlString, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList) { // Support for <frame src="javascript:string"> KURL scriptURL; @@ -379,7 +389,7 @@ bool FrameLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String Frame* frame = ownerElement->contentFrame(); if (frame) - frame->redirectScheduler()->scheduleLocationChange(url.string(), m_outgoingReferrer, true, true, isProcessingUserGesture()); + frame->redirectScheduler()->scheduleLocationChange(url.string(), m_outgoingReferrer, lockHistory, lockBackForwardList, isProcessingUserGesture()); else frame = loadSubframe(ownerElement, url, frameName, m_outgoingReferrer); @@ -484,6 +494,9 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F if (!shouldAllowNavigation(targetFrame)) return; if (!targetFrame) { + if (!DOMWindow::allowPopUp(m_frame) && !isProcessingUserGesture()) + return; + targetFrame = m_frame; frameRequest.setFrameName(targetOrBaseTarget); } @@ -709,14 +722,6 @@ void FrameLoader::cancelAndClear() m_frame->script()->updatePlatformScriptObjects(); } -void FrameLoader::replaceDocument(const String& html) -{ - stopAllLoaders(); - begin(m_URL, true, m_frame->document()->securityOrigin()); - write(html); - end(); -} - void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, bool clearFrameView) { m_frame->editor()->clear(); @@ -747,12 +752,10 @@ void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, boo if (clearFrameView && m_frame->view()) m_frame->view()->clear(); - m_frame->setSelectionGranularity(CharacterGranularity); - // Do not drop the document before the ScriptController and view are cleared // as some destructors might still try to access the document. m_frame->setDocument(0); - m_decoder = 0; + writer()->clear(); m_containsPlugIns = false; @@ -765,16 +768,12 @@ void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, boo m_shouldCallCheckCompleted = false; m_shouldCallCheckLoadComplete = false; - m_receivedData = false; m_isDisplayingInitialEmptyDocument = false; - - if (!m_encodingWasChosenByUser) - m_encoding = String(); } void FrameLoader::receivedFirstData() { - begin(m_workingURL, false); + writer()->begin(m_workingURL, false); dispatchDidCommitLoad(); dispatchDidClearWindowObjectsInAllWorlds(); @@ -805,193 +804,57 @@ void FrameLoader::receivedFirstData() m_frame->redirectScheduler()->scheduleRedirect(delay, url); } -const String& FrameLoader::responseMIMEType() const +void FrameLoader::setURL(const KURL& url) { - return m_responseMIMEType; -} - -void FrameLoader::setResponseMIMEType(const String& type) -{ - m_responseMIMEType = type; -} - -void FrameLoader::begin() -{ - begin(KURL()); + KURL ref(url); + ref.setUser(String()); + ref.setPass(String()); + ref.removeFragmentIdentifier(); + m_outgoingReferrer = ref.string(); + m_URL = url; } -void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin) +void FrameLoader::didBeginDocument(bool dispatch) { - // We need to take a reference to the security origin because |clear| - // might destroy the document that owns it. - RefPtr<SecurityOrigin> forcedSecurityOrigin = origin; - - RefPtr<Document> document; - - // Create a new document before clearing the frame, because it may need to inherit an aliased security context. - if (!m_isDisplayingInitialEmptyDocument && m_client->shouldUsePluginDocument(m_responseMIMEType)) - document = PluginDocument::create(m_frame); - else if (!m_client->hasHTMLView()) - document = PlaceholderDocument::create(m_frame); - else - document = DOMImplementation::createDocument(m_responseMIMEType, m_frame, m_frame->inViewSourceMode()); - - bool resetScripting = !(m_isDisplayingInitialEmptyDocument && m_frame->document()->securityOrigin()->isSecureTransitionTo(url)); - clear(resetScripting, resetScripting); - if (resetScripting) - m_frame->script()->updatePlatformScriptObjects(); - m_needsClear = true; m_isComplete = false; m_didCallImplicitClose = false; m_isLoadingMainResource = true; m_isDisplayingInitialEmptyDocument = m_creatingInitialEmptyDocument; - KURL ref(url); - ref.setUser(String()); - ref.setPass(String()); - ref.removeFragmentIdentifier(); - m_outgoingReferrer = ref.string(); - m_URL = url; - - document->setURL(m_URL); - m_frame->setDocument(document); - if (m_pendingStateObject) { - document->statePopped(m_pendingStateObject.get()); + m_frame->document()->statePopped(m_pendingStateObject.get()); m_pendingStateObject.clear(); } - - if (m_decoder) - document->setDecoder(m_decoder.get()); - if (forcedSecurityOrigin) - document->setSecurityOrigin(forcedSecurityOrigin.get()); - - m_frame->domWindow()->setURL(document->url()); - m_frame->domWindow()->setSecurityOrigin(document->securityOrigin()); if (dispatch) dispatchDidClearWindowObjectsInAllWorlds(); - + updateFirstPartyForCookies(); +<<<<<<< HEAD Settings* settings = document->settings(); document->docLoader()->setAutoLoadImages(settings && settings->loadsImagesAutomatically()); #ifdef ANDROID_BLOCK_NETWORK_IMAGE document->docLoader()->setBlockNetworkImage(settings && settings->blockNetworkImage()); #endif +======= + Settings* settings = m_frame->document()->settings(); + m_frame->document()->docLoader()->setAutoLoadImages(settings && settings->loadsImagesAutomatically()); +>>>>>>> webkit.org at r58033 if (m_documentLoader) { String dnsPrefetchControl = m_documentLoader->response().httpHeaderField("X-DNS-Prefetch-Control"); if (!dnsPrefetchControl.isEmpty()) - document->parseDNSPrefetchControlHeader(dnsPrefetchControl); + m_frame->document()->parseDNSPrefetchControlHeader(dnsPrefetchControl); } history()->restoreDocumentState(); - - document->implicitOpen(); - - if (m_frame->view() && m_client->hasHTMLView()) - m_frame->view()->setContentsSize(IntSize()); -} - -void FrameLoader::write(const char* str, int len, bool flush) -{ - if (len == 0 && !flush) - return; - - if (len == -1) - len = strlen(str); - - Tokenizer* tokenizer = m_frame->document()->tokenizer(); - if (tokenizer && tokenizer->wantsRawData()) { - if (len > 0) - tokenizer->writeRawData(str, len); - return; - } - - if (!m_decoder) { - if (Settings* settings = m_frame->settings()) { - m_decoder = TextResourceDecoder::create(m_responseMIMEType, - settings->defaultTextEncodingName(), - settings->usesEncodingDetector()); - Frame* parentFrame = m_frame->tree()->parent(); - // Set the hint encoding to the parent frame encoding only if - // the parent and the current frames share the security origin. - // We impose this condition because somebody can make a child frame - // containing a carefully crafted html/javascript in one encoding - // that can be mistaken for hintEncoding (or related encoding) by - // an auto detector. When interpreted in the latter, it could be - // an attack vector. - // FIXME: This might be too cautious for non-7bit-encodings and - // we may consider relaxing this later after testing. - if (canReferToParentFrameEncoding(m_frame, parentFrame)) - m_decoder->setHintEncoding(parentFrame->document()->decoder()); - } else - m_decoder = TextResourceDecoder::create(m_responseMIMEType, String()); - Frame* parentFrame = m_frame->tree()->parent(); - if (m_encoding.isEmpty()) { - if (canReferToParentFrameEncoding(m_frame, parentFrame)) - m_decoder->setEncoding(parentFrame->document()->inputEncoding(), TextResourceDecoder::EncodingFromParentFrame); - } else { - m_decoder->setEncoding(m_encoding, - m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader); - } - m_frame->document()->setDecoder(m_decoder.get()); - } - - String decoded = m_decoder->decode(str, len); - if (flush) - decoded += m_decoder->flush(); - if (decoded.isEmpty()) - return; - - if (!m_receivedData) { - m_receivedData = true; - if (m_decoder->encoding().usesVisualOrdering()) - m_frame->document()->setVisuallyOrdered(); - m_frame->document()->recalcStyle(Node::Force); - } - - if (tokenizer) { - ASSERT(!tokenizer->wantsRawData()); - tokenizer->write(decoded, true); - } -} - -void FrameLoader::write(const String& str) -{ - if (str.isNull()) - return; - - if (!m_receivedData) { - m_receivedData = true; - m_frame->document()->setParseMode(Document::Strict); - } - - if (Tokenizer* tokenizer = m_frame->document()->tokenizer()) - tokenizer->write(str, true); } -void FrameLoader::end() +void FrameLoader::didEndDocument() { m_isLoadingMainResource = false; - endIfNotLoadingMainResource(); -} - -void FrameLoader::endIfNotLoadingMainResource() -{ - if (m_isLoadingMainResource || !m_frame->page() || !m_frame->document()) - return; - - // http://bugs.webkit.org/show_bug.cgi?id=10854 - // The frame's last ref may be removed and it can be deleted by checkCompleted(), - // so we'll add a protective refcount - RefPtr<Frame> protector(m_frame); - - // make sure nothing's left in there - write(0, 0, true); - m_frame->document()->finishParsing(); } void FrameLoader::iconLoadDecisionAvailable() @@ -1277,17 +1140,7 @@ void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive) } #endif -String FrameLoader::encoding() const -{ - if (m_encodingWasChosenByUser && !m_encoding.isEmpty()) - return m_encoding; - if (m_decoder && m_decoder->encoding().isValid()) - return m_decoder->encoding().name(); - Settings* settings = m_frame->settings(); - return settings ? settings->defaultTextEncodingName() : String(); -} - -bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const AtomicString& frameName, +bool FrameLoader::requestObject(RenderEmbeddedObject* renderer, const String& url, const AtomicString& frameName, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues) { if (url.isEmpty() && mimeType.isEmpty()) @@ -1305,7 +1158,11 @@ bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const A bool useFallback; if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(), useFallback)) { Settings* settings = m_frame->settings(); - if (!m_client->allowPlugins(settings && settings->arePluginsEnabled()) + if ((!allowPlugins(AboutToInstantiatePlugin) + // Application plugins are plugins implemented by the user agent, for example Qt plugins, + // as opposed to third-party code such as flash. The user agent decides whether or not they are + // permitted, rather than WebKit. + && !MIMETypeRegistry::isApplicationPluginMIMEType(mimeType)) || (!settings->isJavaEnabled() && MIMETypeRegistry::isJavaAppletMIMEType(mimeType))) return false; if (isDocumentSandboxed(SandboxPlugins)) @@ -1374,19 +1231,13 @@ static HTMLPlugInElement* toPlugInElement(Node* node) if (!node) return 0; -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) ASSERT(node->hasTagName(objectTag) || node->hasTagName(embedTag) - || node->hasTagName(videoTag) || node->hasTagName(audioTag) || node->hasTagName(appletTag)); -#else - ASSERT(node->hasTagName(objectTag) || node->hasTagName(embedTag) - || node->hasTagName(appletTag)); -#endif return static_cast<HTMLPlugInElement*>(node); } -bool FrameLoader::loadPlugin(RenderPart* renderer, const KURL& url, const String& mimeType, +bool FrameLoader::loadPlugin(RenderEmbeddedObject* renderer, const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback) { RefPtr<Widget> widget; @@ -1407,12 +1258,59 @@ bool FrameLoader::loadPlugin(RenderPart* renderer, const KURL& url, const String if (widget) { renderer->setWidget(widget); m_containsPlugIns = true; - } + +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + renderer->node()->setNeedsStyleRecalc(SyntheticStyleChange); +#endif + } else + renderer->setShowsMissingPluginIndicator(); } return widget != 0; } +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +PassRefPtr<Widget> FrameLoader::loadMediaPlayerProxyPlugin(Node* node, const KURL& url, + const Vector<String>& paramNames, const Vector<String>& paramValues) +{ + ASSERT(node->hasTagName(videoTag) || node->hasTagName(audioTag)); + + if (!m_frame->script()->xssAuditor()->canLoadObject(url.string())) + return 0; + + KURL completedURL; + if (!url.isEmpty()) + completedURL = completeURL(url); + + if (!SecurityOrigin::canLoad(completedURL, String(), frame()->document())) { + FrameLoader::reportLocalLoadFailed(m_frame, completedURL.string()); + return 0; + } + + HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node); + RenderPart* renderer = toRenderPart(node->renderer()); + IntSize size; + + if (renderer) + size = IntSize(renderer->contentWidth(), renderer->contentHeight()); + else if (mediaElement->isVideo()) + size = RenderVideo::defaultSize(); + + checkIfRunInsecureContent(m_frame->document()->securityOrigin(), completedURL); + + RefPtr<Widget> widget = m_client->createMediaPlayerProxyPlugin(size, mediaElement, completedURL, + paramNames, paramValues, "application/x-media-element-proxy-plugin"); + + if (widget && renderer) { + renderer->setWidget(widget); + m_containsPlugIns = true; + renderer->node()->setNeedsStyleRecalc(SyntheticStyleChange); + } + + return widget ? widget.release() : 0; +} +#endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO) + String FrameLoader::outgoingReferrer() const { return m_outgoingReferrer; @@ -1428,7 +1326,7 @@ bool FrameLoader::isMixedContent(SecurityOrigin* context, const KURL& url) if (context->protocol() != "https") return false; // We only care about HTTPS security origins. - if (!url.isValid() || url.protocolIs("https") || url.protocolIs("about") || url.protocolIs("data")) + if (!url.isValid() || SecurityOrigin::shouldTreatURLSchemeAsSecure(url.protocol())) return false; // Loading these protocols is secure. return true; @@ -1499,7 +1397,7 @@ void FrameLoader::provisionalLoadStarted() bool FrameLoader::isProcessingUserGesture() { Frame* frame = m_frame->tree()->top(); - if (!frame->script()->canExecuteScripts()) + if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript)) return true; // If JavaScript is disabled, a user gesture must have initiated the navigation. return frame->script()->processingUserGesture(mainThreadNormalWorld()); // FIXME: Use pageIsProcessingUserGesture. } @@ -1509,12 +1407,10 @@ void FrameLoader::resetMultipleFormSubmissionProtection() m_submittedFormURL = KURL(); } -void FrameLoader::setEncoding(const String& name, bool userChosen) +void FrameLoader::willSetEncoding() { if (!m_workingURL.isEmpty()) receivedFirstData(); - m_encoding = name; - m_encodingWasChosenByUser = userChosen; } void FrameLoader::addData(const char* bytes, int length) @@ -1522,7 +1418,7 @@ void FrameLoader::addData(const char* bytes, int length) ASSERT(m_workingURL.isEmpty()); ASSERT(m_frame->document()); ASSERT(m_frame->document()->parsing()); - write(bytes, length); + writer()->addData(bytes, length); } #if ENABLE(WML) @@ -1778,7 +1674,10 @@ void FrameLoader::loadInSameDocument(const KURL& url, SerializedScriptValue* sta history()->updateBackForwardListForFragmentScroll(); } + String oldURL; bool hashChange = equalIgnoringFragmentIdentifier(url, m_URL) && url.fragmentIdentifier() != m_URL.fragmentIdentifier(); + oldURL = m_URL; + m_URL = url; history()->updateForSameDocumentNavigation(); @@ -1789,11 +1688,11 @@ void FrameLoader::loadInSameDocument(const KURL& url, SerializedScriptValue* sta // It's important to model this as a load that starts and immediately finishes. // Otherwise, the parent frame may think we never finished loading. started(); - - if (hashChange) { - if (FrameView* view = m_frame->view()) - view->scrollToFragment(m_URL); - } + + // We need to scroll to the fragment whether or not a hash change occurred, since + // the user might have scrolled since the previous navigation. + if (FrameView* view = m_frame->view()) + view->scrollToFragment(m_URL); m_isComplete = false; checkCompleted(); @@ -1805,13 +1704,15 @@ void FrameLoader::loadInSameDocument(const KURL& url, SerializedScriptValue* sta checkLoadComplete(); } + m_client->dispatchDidNavigateWithinPage(); + if (stateObject) { m_frame->document()->statePopped(stateObject); m_client->dispatchDidPopStateWithinPage(); } if (hashChange) { - m_frame->document()->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false)); + m_frame->document()->enqueueHashchangeEvent(oldURL, m_URL); m_client->dispatchDidChangeLocationWithinPage(); } @@ -1844,6 +1745,15 @@ void FrameLoader::started() frame->loader()->m_isComplete = false; } +bool FrameLoader::allowPlugins(ReasonForCallingAllowPlugins reason) +{ + Settings* settings = m_frame->settings(); + bool allowed = m_client->allowPlugins(settings && settings->arePluginsEnabled()); + if (!allowed && reason == AboutToInstantiatePlugin) + m_frame->loader()->client()->didNotAllowPlugins(); + return allowed; +} + bool FrameLoader::containsPlugins() const { return m_containsPlugIns; @@ -2297,16 +2207,16 @@ bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const if (m_frame == targetFrame) return true; - // A sandboxed frame can only navigate itself and its descendants. - if (isDocumentSandboxed(SandboxNavigation) && !targetFrame->tree()->isDescendantOf(m_frame)) - return false; - // Let a frame navigate the top-level window that contains it. This is // important to allow because it lets a site "frame-bust" (escape from a // frame created by another web site). - if (targetFrame == m_frame->tree()->top()) + if (!isDocumentSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree()->top()) return true; + // A sandboxed frame can only navigate itself and its descendants. + if (isDocumentSandboxed(SandboxNavigation) && !targetFrame->tree()->isDescendantOf(m_frame)) + return false; + // Let a frame navigate its opener if the opener is a top-level window. if (!targetFrame->tree()->parent() && m_frame->loader()->opener() == targetFrame) return true; @@ -2645,7 +2555,7 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage) ASSERT_NOT_REACHED(); } - m_responseMIMEType = dl->responseMIMEType(); + writer()->setMIMEType(dl->responseMIMEType()); // Tell the client we've committed this URL. ASSERT(m_frame->view()); @@ -2692,7 +2602,7 @@ void FrameLoader::clientRedirected(const KURL& url, double seconds, double fireD // load as part of the original navigation. If we don't have a document loader, we have // no "original" load on which to base a redirect, so we treat the redirect as a normal load. // Loads triggered by JavaScript form submissions never count as quick redirects. - m_quickRedirectComing = lockBackForwardList && m_documentLoader && !m_isExecutingJavaScriptFormAction; + m_quickRedirectComing = (lockBackForwardList || history()->currentItemShouldBeReplaced()) && m_documentLoader && !m_isExecutingJavaScriptFormAction; } bool FrameLoader::shouldReload(const KURL& currentURL, const KURL& destinationURL) @@ -2737,7 +2647,7 @@ void FrameLoader::open(CachedPage& cachedPage) closeURL(); // Delete old status bar messages (if it _was_ activated on last URL). - if (m_frame->script()->canExecuteScripts()) { + if (m_frame->script()->canExecuteScripts(NotAboutToExecuteScript)) { m_frame->setJSStatusBarText(String()); m_frame->setJSDefaultStatusBarText(String()); } @@ -2790,7 +2700,7 @@ void FrameLoader::open(CachedFrameBase& cachedFrame) m_frame->domWindow()->setURL(document->url()); m_frame->domWindow()->setSecurityOrigin(document->securityOrigin()); - m_decoder = document->decoder(); + writer()->setDecoder(document->decoder()); updateFirstPartyForCookies(); @@ -2858,7 +2768,15 @@ void FrameLoader::finishedLoadingDocument(DocumentLoader* loader) #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size // If loading a webarchive, run through webarchive machinery +#if PLATFORM(CHROMIUM) + // https://bugs.webkit.org/show_bug.cgi?id=36426 + // FIXME: For debugging purposes, should be removed before closing the bug. + // Make real copy of the string so we fail here if the responseMIMEType + // string is bad. + const String responseMIMEType = loader->responseMIMEType(); +#else const String& responseMIMEType = loader->responseMIMEType(); +#endif // FIXME: Mac's FrameLoaderClient::finishedLoading() method does work that is required even with Archive loads // so we still need to call it. Other platforms should only call finishLoading for non-archive loads @@ -2883,14 +2801,14 @@ void FrameLoader::finishedLoadingDocument(DocumentLoader* loader) ArchiveResource* mainResource = archive->mainResource(); loader->setParsedArchiveData(mainResource->data()); - m_responseMIMEType = mainResource->mimeType(); + writer()->setMIMEType(mainResource->mimeType()); closeURL(); didOpenURL(mainResource->url()); String userChosenEncoding = documentLoader()->overrideEncoding(); bool encodingIsUserChosen = !userChosenEncoding.isNull(); - setEncoding(encodingIsUserChosen ? userChosenEncoding : mainResource->textEncoding(), encodingIsUserChosen); + writer()->setEncoding(encodingIsUserChosen ? userChosenEncoding : mainResource->textEncoding(), encodingIsUserChosen); ASSERT(m_frame->document()); @@ -3307,7 +3225,7 @@ void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadTyp // Always try UTF-8. If that fails, try frame encoding (if any) and then the default. // For a newly opened frame with an empty URL, encoding() should not be used, because this methods asks decoder, which uses ISO-8859-1. Settings* settings = m_frame->settings(); - request.setResponseContentDispositionEncodingFallbackArray("UTF-8", m_URL.isEmpty() ? m_encoding : encoding(), settings ? settings->defaultTextEncodingName() : String()); + request.setResponseContentDispositionEncodingFallbackArray("UTF-8", writer()->deprecatedFrameEncoding(), settings ? settings->defaultTextEncodingName() : String()); } void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, String origin) @@ -3769,7 +3687,7 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name) { Frame* frame = m_frame->tree()->find(name); if (!shouldAllowNavigation(frame)) - return 0; + return 0; return frame; } @@ -3896,9 +3814,11 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) // - The HistoryItem has a history state object // - Navigating to an anchor within the page, with no form data stored on the target item or the current history entry, // and the URLs in the frame tree match the history item for fragment scrolling. + // - The HistoryItem is not the same as the current item, because such cases are treated as a new load. HistoryItem* currentItem = history()->currentItem(); - bool sameDocumentNavigation = (!item->formData() && !(currentItem && currentItem->formData()) && history()->urlsMatchItem(item)) - || (currentItem && item->documentSequenceNumber() == currentItem->documentSequenceNumber()); + bool sameDocumentNavigation = ((!item->formData() && !(currentItem && currentItem->formData()) && history()->urlsMatchItem(item)) + || (currentItem && item->documentSequenceNumber() == currentItem->documentSequenceNumber())) + && item != currentItem; #if ENABLE(WML) // All WML decks should go through the real load mechanism, not the scroll-to-anchor code @@ -3986,7 +3906,7 @@ void FrameLoader::dispatchDocumentElementAvailable() void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() { - if (!m_frame->script()->canExecuteScripts()) + if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript)) return; Vector<DOMWrapperWorld*> worlds; @@ -3997,7 +3917,7 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) { - if (!m_frame->script()->canExecuteScripts() || !m_frame->script()->existingWindowShell(world)) + if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript) || !m_frame->script()->existingWindowShell(world)) return; m_client->dispatchDidClearWindowObjectInWorld(world); @@ -4009,15 +3929,13 @@ void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) if (Page* page = m_frame->page()) { if (InspectorController* inspector = page->inspectorController()) inspector->inspectedWindowScriptObjectCleared(m_frame); - if (InspectorController* inspector = page->parentInspectorController()) - inspector->windowScriptObjectAvailable(); } #endif } void FrameLoader::updateSandboxFlags() { - SandboxFlags flags = SandboxNone; + SandboxFlags flags = m_forcedSandboxFlags; if (Frame* parentFrame = m_frame->tree()->parent()) flags |= parentFrame->loader()->sandboxFlags(); if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement()) diff --git a/WebCore/loader/FrameLoader.h b/WebCore/loader/FrameLoader.h index abe3b3a..adfebd4 100644 --- a/WebCore/loader/FrameLoader.h +++ b/WebCore/loader/FrameLoader.h @@ -32,6 +32,7 @@ #define FrameLoader_h #include "CachePolicy.h" +#include "DocumentWriter.h" #include "FrameLoaderTypes.h" #include "HistoryController.h" #include "PolicyCallback.h" @@ -67,7 +68,10 @@ class HTMLFrameOwnerElement; class IconLoader; class IntSize; class NavigationAction; -class RenderPart; +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +class Node; +#endif +class RenderEmbeddedObject; class ResourceError; class ResourceLoader; class ResourceResponse; @@ -98,6 +102,7 @@ public: PolicyChecker* policyChecker() const { return &m_policyChecker; } HistoryController* history() const { return &m_history; } ResourceLoadNotifier* notifier() const { return &m_notifer; } + DocumentWriter* writer() const { return &m_writer; } // FIXME: This is not cool, people. There are too many different functions that all start loads. // We should aim to consolidate these into a smaller set of functions, and try to reuse more of @@ -215,7 +220,7 @@ public: void changeLocation(const KURL&, const String& referrer, bool lockHistory = true, bool lockBackForwardList = true, bool userGesture = false, bool refresh = false); void urlSelected(const ResourceRequest&, const String& target, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, bool userGesture, ReferrerPolicy); - bool requestFrame(HTMLFrameOwnerElement*, const String& url, const AtomicString& frameName); + bool requestFrame(HTMLFrameOwnerElement*, const String& url, const AtomicString& frameName, bool lockHistory = true, bool lockBackForwardList = true); void submitForm(const char* action, const String& url, PassRefPtr<FormData>, const String& target, const String& contentType, const String& boundary, @@ -227,24 +232,16 @@ public: void didExplicitOpen(); + // Callbacks from DocumentWriter + void didBeginDocument(bool dispatchWindowObjectAvailable); + void didEndDocument(); + void willSetEncoding(); + KURL iconURL(); void commitIconURLToIconDatabase(const KURL&); KURL baseURL() const; - void replaceDocument(const String&); - - void begin(); - void begin(const KURL&, bool dispatchWindowObjectAvailable = true, SecurityOrigin* forcedSecurityOrigin = 0); - - void write(const char* string, int length = -1, bool flush = false); - void write(const String&); - void end(); - void endIfNotLoadingMainResource(); - - void setEncoding(const String& encoding, bool userChosen); - String encoding() const; - void tokenizerProcessedData(); void handledOnloadEvents(); @@ -260,6 +257,9 @@ public: bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } SandboxFlags sandboxFlags() const { return m_sandboxFlags; } + // The following sandbox flags will be forced, regardless of changes to + // the sandbox attribute of any parent frames. + void setForcedSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags = flags; m_sandboxFlags |= flags; } // Mixed content related functions. static bool isMixedContent(SecurityOrigin* context, const KURL&); @@ -281,9 +281,10 @@ public: const KURL& url() const { return m_URL; } - void setResponseMIMEType(const String&); - const String& responseMIMEType() const; + // setURL is a low-level setter and does not trigger loading. + void setURL(const KURL&); + bool allowPlugins(ReasonForCallingAllowPlugins); bool containsPlugins() const; void loadDone(); @@ -294,7 +295,7 @@ public: bool isComplete() const; - bool requestObject(RenderPart* frame, const String& url, const AtomicString& frameName, + bool requestObject(RenderEmbeddedObject*, const String& url, const AtomicString& frameName, const String& serviceType, const Vector<String>& paramNames, const Vector<String>& paramValues); KURL completeURL(const String& url); @@ -323,6 +324,10 @@ public: void open(CachedFrameBase&); +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + PassRefPtr<Widget> loadMediaPlayerProxyPlugin(Node*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues); +#endif + // FIXME: Should these really be public? void completed(); bool allAncestorsAreComplete() const; // including this @@ -340,6 +345,10 @@ public: static ObjectContentType defaultObjectContentType(const KURL& url, const String& mimeType); + bool isDisplayingInitialEmptyDocument() const { return m_isDisplayingInitialEmptyDocument; } + + void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true); + private: bool canCachePageContainingThisFrame(); #ifndef NDEBUG @@ -352,8 +361,8 @@ private: void started(); bool shouldUsePlugin(const KURL&, const String& mimeType, bool hasFallback, bool& useFallback); - bool loadPlugin(RenderPart*, const KURL&, const String& mimeType, - const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback); + bool loadPlugin(RenderEmbeddedObject*, const KURL&, const String& mimeType, + const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback); void navigateWithinDocument(HistoryItem*); void navigateToDifferentDocument(HistoryItem*, FrameLoadType); @@ -404,8 +413,6 @@ private: void updateHistoryAfterClientRedirect(); - void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true); - bool shouldReloadToHandleUnreachableURL(DocumentLoader*); void dispatchDidCommitLoad(); @@ -465,6 +472,7 @@ private: mutable PolicyChecker m_policyChecker; mutable HistoryController m_history; mutable ResourceLoadNotifier m_notifer; + mutable DocumentWriter m_writer; FrameState m_state; FrameLoadType m_loadType; @@ -488,8 +496,6 @@ private: bool m_isExecutingJavaScriptFormAction; - String m_responseMIMEType; - bool m_didCallImplicitClose; bool m_wasUnloadEventEmitted; bool m_unloadEventBeingDispatched; @@ -509,10 +515,6 @@ private: bool m_needsClear; bool m_receivedData; - bool m_encodingWasChosenByUser; - String m_encoding; - RefPtr<TextResourceDecoder> m_decoder; - bool m_containsPlugIns; KURL m_submittedFormURL; @@ -533,6 +535,7 @@ private: bool m_suppressOpenerInNewFrame; SandboxFlags m_sandboxFlags; + SandboxFlags m_forcedSandboxFlags; #ifndef NDEBUG bool m_didDispatchDidCommitLoad; diff --git a/WebCore/loader/FrameLoaderClient.h b/WebCore/loader/FrameLoaderClient.h index 4f78805..b2931c8 100644 --- a/WebCore/loader/FrameLoaderClient.h +++ b/WebCore/loader/FrameLoaderClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,7 +32,6 @@ #include "FrameLoaderTypes.h" #include "ScrollTypes.h" #include <wtf/Forward.h> -#include <wtf/Platform.h> #include <wtf/Vector.h> typedef class _jobject* jobject; @@ -56,6 +55,9 @@ namespace WebCore { class HistoryItem; class HTMLAppletElement; class HTMLFrameOwnerElement; +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + class HTMLMediaElement; +#endif class HTMLPlugInElement; class IntSize; class KURL; @@ -110,12 +112,12 @@ namespace WebCore { virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) = 0; virtual void dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&) = 0; virtual bool dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length) = 0; - virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const ScriptString&) = 0; virtual void dispatchDidHandleOnloadEvents() = 0; virtual void dispatchDidReceiveServerRedirectForProvisionalLoad() = 0; virtual void dispatchDidCancelClientRedirect() = 0; virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate) = 0; + virtual void dispatchDidNavigateWithinPage() { } virtual void dispatchDidChangeLocationWithinPage() = 0; virtual void dispatchDidPushStateWithinPage() = 0; virtual void dispatchDidReplaceStateWithinPage() = 0; @@ -226,6 +228,9 @@ namespace WebCore { virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) = 0; virtual void dispatchDidFailToStartPlugin(const PluginView*) const { } +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + virtual PassRefPtr<Widget> createMediaPlayerProxyPlugin(const IntSize&, HTMLMediaElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&) = 0; +#endif virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType) = 0; virtual String overrideMediaType() const = 0; @@ -263,6 +268,15 @@ namespace WebCore { virtual bool allowJavaScript(bool enabledPerSettings) { return enabledPerSettings; } virtual bool allowPlugins(bool enabledPerSettings) { return enabledPerSettings; } virtual bool allowImages(bool enabledPerSettings) { return enabledPerSettings; } + + // This callback notifies the client that the frame was about to run + // JavaScript but did not because allowJavaScript returned false. We + // have a separate callback here because there are a number of places + // that need to know if JavaScript is enabled but are not necessarily + // preparing to execute script. + virtual void didNotAllowScript() { } + // This callback is similar, but for plugins. + virtual void didNotAllowPlugins() { } }; } // namespace WebCore diff --git a/WebCore/loader/FrameLoaderTypes.h b/WebCore/loader/FrameLoaderTypes.h index 8288bce..34872ad 100644 --- a/WebCore/loader/FrameLoaderTypes.h +++ b/WebCore/loader/FrameLoaderTypes.h @@ -92,7 +92,7 @@ namespace WebCore { SendReferrer, NoReferrer }; - + enum SandboxFlag { SandboxNone = 0, SandboxNavigation = 1, @@ -100,14 +100,20 @@ namespace WebCore { SandboxOrigin = 1 << 2, SandboxForms = 1 << 3, SandboxScripts = 1 << 4, + SandboxTopNavigation = 1 << 5, SandboxAll = -1 // Mask with all bits set to 1. }; - + enum SecurityCheckPolicy { SkipSecurityCheck, DoSecurityCheck }; + enum ReasonForCallingAllowPlugins { + AboutToInstantiatePlugin, + NotAboutToInstantiatePlugin + }; + typedef int SandboxFlags; } diff --git a/WebCore/loader/HistoryController.cpp b/WebCore/loader/HistoryController.cpp index 55b68dc..e3d3b6b 100644 --- a/WebCore/loader/HistoryController.cpp +++ b/WebCore/loader/HistoryController.cpp @@ -33,7 +33,6 @@ #include "BackForwardList.h" #include "CachedPage.h" -#include "CString.h" #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoader.h" @@ -46,6 +45,7 @@ #include "PageCache.h" #include "PageGroup.h" #include "Settings.h" +#include <wtf/text/CString.h> namespace WebCore { @@ -445,6 +445,15 @@ void HistoryController::setCurrentItemTitle(const String& title) m_currentItem->setTitle(title); } +bool HistoryController::currentItemShouldBeReplaced() const +{ + // From the HTML5 spec for location.assign(): + // "If the browsing context's session history contains only one Document, + // and that was the about:blank Document created when the browsing context + // was created, then the navigation must be done with replacement enabled." + return m_currentItem && !m_previousItem && equalIgnoringCase(m_currentItem->urlString(), blankURL()); +} + void HistoryController::setProvisionalItem(HistoryItem* item) { m_provisionalItem = item; @@ -656,15 +665,17 @@ void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject, void HistoryController::replaceState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) { - Page* page = m_frame->page(); - ASSERT(page); - HistoryItem* current = page->backForwardList()->currentItem(); - ASSERT(current); + // FIXME: We should always have m_currentItem here!! + // https://bugs.webkit.org/show_bug.cgi?id=36464 + if (!m_currentItem) { + ASSERT_NOT_REACHED(); + return; + } if (!urlString.isEmpty()) - current->setURLString(urlString); - current->setTitle(title); - current->setStateObject(stateObject); + m_currentItem->setURLString(urlString); + m_currentItem->setTitle(title); + m_currentItem->setStateObject(stateObject); } } // namespace WebCore diff --git a/WebCore/loader/HistoryController.h b/WebCore/loader/HistoryController.h index 7c4a1ac..64f7854 100644 --- a/WebCore/loader/HistoryController.h +++ b/WebCore/loader/HistoryController.h @@ -72,6 +72,7 @@ public: HistoryItem* currentItem() const { return m_currentItem.get(); } void setCurrentItem(HistoryItem*); void setCurrentItemTitle(const String&); + bool currentItemShouldBeReplaced() const; HistoryItem* provisionalItem() const { return m_provisionalItem.get(); } void setProvisionalItem(HistoryItem*); diff --git a/WebCore/loader/ImageLoader.cpp b/WebCore/loader/ImageLoader.cpp index 929b28a..5625b52 100644 --- a/WebCore/loader/ImageLoader.cpp +++ b/WebCore/loader/ImageLoader.cpp @@ -277,6 +277,11 @@ void ImageLoader::dispatchPendingLoadEvents() loadEventSender().dispatchPendingEvents(); } +void ImageLoader::elementWillMoveToNewOwnerDocument() +{ + setImage(0); +} + ImageEventSender::ImageEventSender(const AtomicString& eventType) : m_eventType(eventType) , m_timer(this, &ImageEventSender::timerFired) diff --git a/WebCore/loader/ImageLoader.h b/WebCore/loader/ImageLoader.h index 44fe98e..a585354 100644 --- a/WebCore/loader/ImageLoader.h +++ b/WebCore/loader/ImageLoader.h @@ -45,6 +45,8 @@ public: // doesn't change; starts new load unconditionally (matches Firefox and Opera behavior). void updateFromElementIgnoringPreviousError(); + void elementWillMoveToNewOwnerDocument(); + Element* element() const { return m_element; } bool imageComplete() const { return m_imageComplete; } diff --git a/WebCore/loader/MainResourceLoader.cpp b/WebCore/loader/MainResourceLoader.cpp index 3e75880..28587e2 100644 --- a/WebCore/loader/MainResourceLoader.cpp +++ b/WebCore/loader/MainResourceLoader.cpp @@ -285,7 +285,7 @@ void MainResourceLoader::continueAfterContentPolicy(PolicyAction policy) #if PLATFORM(QT) void MainResourceLoader::substituteMIMETypeFromPluginDatabase(const ResourceResponse& r) { - if (!m_frame->settings()->arePluginsEnabled()) + if (!m_frame->loader()->allowPlugins(NotAboutToInstantiatePlugin)) return; String filename = r.url().lastPathComponent(); @@ -517,7 +517,7 @@ bool MainResourceLoader::loadNow(ResourceRequest& r) else if (shouldLoadEmpty || frameLoader()->representationExistsForURLScheme(url.protocol())) handleEmptyLoad(url, !shouldLoadEmpty); else - m_handle = ResourceHandle::create(r, this, m_frame.get(), false, true, true); + m_handle = ResourceHandle::create(r, this, m_frame.get(), false, true); return false; } diff --git a/WebCore/loader/MainResourceLoader.h b/WebCore/loader/MainResourceLoader.h index eaaf2e8..5ed0cc8 100644 --- a/WebCore/loader/MainResourceLoader.h +++ b/WebCore/loader/MainResourceLoader.h @@ -26,6 +26,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef MainResourceLoader_h +#define MainResourceLoader_h + #include "FrameLoaderTypes.h" #include "ResourceLoader.h" #include "SubstituteData.h" @@ -107,3 +110,5 @@ namespace WebCore { }; } + +#endif diff --git a/WebCore/loader/MediaDocument.cpp b/WebCore/loader/MediaDocument.cpp index a2d6276..27361fc 100644 --- a/WebCore/loader/MediaDocument.cpp +++ b/WebCore/loader/MediaDocument.cpp @@ -227,7 +227,7 @@ void MediaDocument::replaceMediaElementTimerFired(Timer<MediaDocument>*) embedElement->setAttribute(heightAttr, "100%"); embedElement->setAttribute(nameAttr, "plugin"); embedElement->setAttribute(srcAttr, url().string()); - embedElement->setAttribute(typeAttr, frame()->loader()->responseMIMEType()); + embedElement->setAttribute(typeAttr, frame()->loader()->writer()->mimeType()); ExceptionCode ec; videoElement->parent()->replaceChild(embedElement, videoElement, ec); diff --git a/WebCore/loader/PluginDocument.cpp b/WebCore/loader/PluginDocument.cpp index 788691f..7024333 100644 --- a/WebCore/loader/PluginDocument.cpp +++ b/WebCore/loader/PluginDocument.cpp @@ -34,6 +34,7 @@ #include "HTMLNames.h" #include "MainResourceLoader.h" #include "Page.h" +#include "RenderEmbeddedObject.h" #include "RenderWidget.h" #include "SegmentedString.h" #include "Settings.h" @@ -47,6 +48,7 @@ using namespace HTMLNames; class PluginTokenizer : public Tokenizer { public: PluginTokenizer(Document* doc) : m_doc(doc), m_embedElement(0) {} + static Widget* pluginWidgetFromDocument(Document* doc); private: virtual void write(const SegmentedString&, bool appendData); @@ -62,7 +64,21 @@ private: Document* m_doc; HTMLEmbedElement* m_embedElement; }; - + +Widget* PluginTokenizer::pluginWidgetFromDocument(Document* doc) +{ + ASSERT(doc); + RefPtr<Element> body = doc->body(); + if (body) { + RefPtr<Node> node = body->firstChild(); + if (node && node->renderer()) { + ASSERT(node->renderer()->isEmbeddedObject()); + return toRenderEmbeddedObject(node->renderer())->widget(); + } + } + return 0; +} + void PluginTokenizer::write(const SegmentedString&, bool) { ASSERT_NOT_REACHED(); @@ -89,7 +105,7 @@ void PluginTokenizer::createDocumentStructure() m_embedElement->setAttribute(nameAttr, "plugin"); m_embedElement->setAttribute(srcAttr, m_doc->url().string()); - m_embedElement->setAttribute(typeAttr, m_doc->frame()->loader()->responseMIMEType()); + m_embedElement->setAttribute(typeAttr, m_doc->frame()->loader()->writer()->mimeType()); body->appendChild(embedElement, ec); } @@ -104,7 +120,7 @@ bool PluginTokenizer::writeRawData(const char*, int) if (Frame* frame = m_doc->frame()) { Settings* settings = frame->settings(); - if (settings && settings->arePluginsEnabled()) { + if (settings && frame->loader()->allowPlugins(NotAboutToInstantiatePlugin)) { m_doc->updateLayout(); if (RenderWidget* renderer = toRenderWidget(m_embedElement->renderer())) { @@ -146,5 +162,19 @@ Tokenizer* PluginDocument::createTokenizer() { return new PluginTokenizer(this); } - + +Widget* PluginDocument::pluginWidget() +{ + return PluginTokenizer::pluginWidgetFromDocument(this); +} + +Node* PluginDocument::pluginNode() +{ + RefPtr<Element> body_element = body(); + if (body_element) + return body_element->firstChild(); + + return 0; +} + } diff --git a/WebCore/loader/PluginDocument.h b/WebCore/loader/PluginDocument.h index 1d5c964..7b4b36b 100644 --- a/WebCore/loader/PluginDocument.h +++ b/WebCore/loader/PluginDocument.h @@ -28,7 +28,9 @@ #include "HTMLDocument.h" namespace WebCore { - + +class Node; +class Widget; class PluginDocument : public HTMLDocument { public: static PassRefPtr<PluginDocument> create(Frame* frame) @@ -36,6 +38,9 @@ public: return adoptRef(new PluginDocument(frame)); } + Widget* pluginWidget(); + Node* pluginNode(); + private: PluginDocument(Frame*); diff --git a/WebCore/loader/ProgressTracker.cpp b/WebCore/loader/ProgressTracker.cpp index 458de68..2e12204 100644 --- a/WebCore/loader/ProgressTracker.cpp +++ b/WebCore/loader/ProgressTracker.cpp @@ -26,13 +26,13 @@ #include "config.h" #include "ProgressTracker.h" -#include "CString.h" #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderClient.h" #include "Logging.h" #include "ResourceResponse.h" +#include <wtf/text/CString.h> #include <wtf/CurrentTime.h> using std::min; diff --git a/WebCore/loader/RedirectScheduler.cpp b/WebCore/loader/RedirectScheduler.cpp index 4b44422..fbbfb0c 100644 --- a/WebCore/loader/RedirectScheduler.cpp +++ b/WebCore/loader/RedirectScheduler.cpp @@ -43,91 +43,168 @@ #include "HTMLFormElement.h" #include "HTMLFrameOwnerElement.h" #include "Page.h" +#include "UserGestureIndicator.h" #include <wtf/CurrentTime.h> namespace WebCore { -struct ScheduledRedirection : Noncopyable { - enum Type { redirection, locationChange, historyNavigation, formSubmission }; - - const Type type; - const double delay; - const String url; - const String referrer; - const FrameLoadRequest frameRequest; - const RefPtr<Event> event; - const RefPtr<FormState> formState; - const int historySteps; - const bool lockHistory; - const bool lockBackForwardList; - const bool wasUserGesture; - const bool wasRefresh; - const bool wasDuringLoad; - bool toldClient; - - ScheduledRedirection(double delay, const String& url, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool refresh) - : type(redirection) - , delay(delay) - , url(url) - , historySteps(0) - , lockHistory(lockHistory) - , lockBackForwardList(lockBackForwardList) - , wasUserGesture(wasUserGesture) - , wasRefresh(refresh) - , wasDuringLoad(false) - , toldClient(false) +class ScheduledNavigation : public Noncopyable { +public: + ScheduledNavigation(double delay, bool lockHistory, bool lockBackForwardList, bool wasDuringLoad) + : m_delay(delay) + , m_lockHistory(lockHistory) + , m_lockBackForwardList(lockBackForwardList) + , m_wasDuringLoad(wasDuringLoad) { - ASSERT(!url.isEmpty()); } + virtual ~ScheduledNavigation() { } - ScheduledRedirection(const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool refresh, bool duringLoad) - : type(locationChange) - , delay(0) - , url(url) - , referrer(referrer) - , historySteps(0) - , lockHistory(lockHistory) - , lockBackForwardList(lockBackForwardList) - , wasUserGesture(wasUserGesture) - , wasRefresh(refresh) - , wasDuringLoad(duringLoad) - , toldClient(false) + virtual void fire(Frame*) = 0; + + // This method feels a bit like RTTI, but I don't see a cleaner way to get the behavior we want. + virtual bool isLocationChange() const { return true; } + + virtual bool shouldStartTimer(Frame*) { return true; } + virtual void didStartTimer(Frame*, Timer<RedirectScheduler>*) { } + virtual void didStopTimer(Frame*, bool /* newLoadInProgress */) { } + + double delay() const { return m_delay; } + bool lockHistory() const { return m_lockHistory; } + bool lockBackForwardList() const { return m_lockBackForwardList; } + bool wasDuringLoad() const { return m_wasDuringLoad; } + +private: + double m_delay; + bool m_lockHistory; + bool m_lockBackForwardList; + bool m_wasDuringLoad; +}; + +class ScheduledURLNavigation : public ScheduledNavigation { +public: + ScheduledURLNavigation(double delay, const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool duringLoad) + : ScheduledNavigation(delay, lockHistory, lockBackForwardList, duringLoad) + , m_url(url) + , m_referrer(referrer) + , m_wasUserGesture(wasUserGesture) + , m_haveToldClient(false) { - ASSERT(!url.isEmpty()); } - explicit ScheduledRedirection(int historyNavigationSteps) - : type(historyNavigation) - , delay(0) - , historySteps(historyNavigationSteps) - , lockHistory(false) - , lockBackForwardList(false) - , wasUserGesture(false) - , wasRefresh(false) - , wasDuringLoad(false) - , toldClient(false) + virtual void fire(Frame* frame) { + frame->loader()->changeLocation(KURL(ParsedURLString, m_url), m_referrer, lockHistory(), lockBackForwardList(), m_wasUserGesture, false); + } + + virtual void didStartTimer(Frame* frame, Timer<RedirectScheduler>* timer) + { + if (m_haveToldClient) + return; + m_haveToldClient = true; + frame->loader()->clientRedirected(KURL(ParsedURLString, m_url), delay(), currentTime() + timer->nextFireInterval(), lockBackForwardList()); } - ScheduledRedirection(const FrameLoadRequest& frameRequest, - bool lockHistory, bool lockBackForwardList, PassRefPtr<Event> event, PassRefPtr<FormState> formState, - bool duringLoad) - : type(formSubmission) - , delay(0) - , frameRequest(frameRequest) - , event(event) - , formState(formState) - , historySteps(0) - , lockHistory(lockHistory) - , lockBackForwardList(lockBackForwardList) - , wasUserGesture(false) - , wasRefresh(false) - , wasDuringLoad(duringLoad) - , toldClient(false) + virtual void didStopTimer(Frame* frame, bool newLoadInProgress) + { + if (!m_haveToldClient) + return; + frame->loader()->clientRedirectCancelledOrFinished(newLoadInProgress); + } + + String url() const { return m_url; } + String referrer() const { return m_referrer; } + bool wasUserGesture() const { return m_wasUserGesture; } + +private: + String m_url; + String m_referrer; + bool m_wasUserGesture; + bool m_haveToldClient; +}; + +class ScheduledRedirect : public ScheduledURLNavigation { +public: + ScheduledRedirect(double delay, const String& url, bool lockHistory, bool lockBackForwardList, bool wasUserGesture) + : ScheduledURLNavigation(delay, url, String(), lockHistory, lockBackForwardList, wasUserGesture, false) { } + + virtual bool isLocationChange() const { return false; } + virtual bool shouldStartTimer(Frame* frame) { return frame->loader()->allAncestorsAreComplete(); } +}; + +class ScheduledLocationChange : public ScheduledURLNavigation { +public: + ScheduledLocationChange(const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool duringLoad) + : ScheduledURLNavigation(0.0, url, referrer, lockHistory, lockBackForwardList, wasUserGesture, duringLoad) { } +}; + +class ScheduledRefresh : public ScheduledURLNavigation { +public: + ScheduledRefresh(const String& url, const String& referrer, bool wasUserGesture) + : ScheduledURLNavigation(0.0, url, referrer, true, true, wasUserGesture, false) { } + + virtual void fire(Frame* frame) + { + frame->loader()->changeLocation(KURL(ParsedURLString, url()), referrer(), lockHistory(), lockBackForwardList(), wasUserGesture(), true); + } +}; + +class ScheduledHistoryNavigation : public ScheduledNavigation { +public: + explicit ScheduledHistoryNavigation(int historySteps) : ScheduledNavigation(0, false, false, false), m_historySteps(historySteps) { } + + virtual void fire(Frame* frame) + { + FrameLoader* loader = frame->loader(); + if (!m_historySteps) { + // Special case for go(0) from a frame -> reload only the frame + loader->urlSelected(loader->url(), "", 0, lockHistory(), lockBackForwardList(), false, SendReferrer); + return; + } + // go(i!=0) from a frame navigates into the history of the frame only, + // in both IE and NS (but not in Mozilla). We can't easily do that. + frame->page()->goBackOrForward(m_historySteps); + } + +private: + int m_historySteps; +}; + +class ScheduledFormSubmission : public ScheduledNavigation { +public: + ScheduledFormSubmission(const FrameLoadRequest& frameRequest, bool lockHistory, bool lockBackForwardList, PassRefPtr<Event> event, PassRefPtr<FormState> formState, bool duringLoad) + : ScheduledNavigation(0, lockHistory, lockBackForwardList, duringLoad) + , m_frameRequest(frameRequest) + , m_event(event) + , m_formState(formState) + , m_wasProcessingUserGesture(UserGestureIndicator::processingUserGesture()) { ASSERT(!frameRequest.isEmpty()); - ASSERT(this->formState); + ASSERT(m_formState); + } + + virtual void fire(Frame* frame) + { + UserGestureIndicator gestureIndicator(m_wasProcessingUserGesture ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture); + + // The submitForm function will find a target frame before using the redirection timer. + // Now that the timer has fired, we need to repeat the security check which normally is done when + // selecting a target, in case conditions have changed. Other code paths avoid this by targeting + // without leaving a time window. If we fail the check just silently drop the form submission. + if (!m_formState->sourceFrame()->loader()->shouldAllowNavigation(frame)) + return; + frame->loader()->loadFrameRequest(m_frameRequest, lockHistory(), lockBackForwardList(), m_event, m_formState, SendReferrer); } + + // FIXME: Implement didStartTimer? It would make sense to report form + // submissions as client redirects too. But we didn't do that in the past + // when form submission used a separate delay mechanism, so doing it will + // be a behavior change. + +private: + const FrameLoadRequest m_frameRequest; + const RefPtr<Event> m_event; + const RefPtr<FormState> m_formState; + bool m_wasProcessingUserGesture; }; RedirectScheduler::RedirectScheduler(Frame* frame) @@ -142,29 +219,27 @@ RedirectScheduler::~RedirectScheduler() bool RedirectScheduler::redirectScheduledDuringLoad() { - return m_scheduledRedirection && m_scheduledRedirection->wasDuringLoad; + return m_redirect && m_redirect->wasDuringLoad(); } void RedirectScheduler::clear() { m_timer.stop(); - m_scheduledRedirection.clear(); + m_redirect.clear(); } void RedirectScheduler::scheduleRedirect(double delay, const String& url) { - if (delay < 0 || delay > INT_MAX / 1000) - return; - if (!m_frame->page()) return; - + if (delay < 0 || delay > INT_MAX / 1000) + return; if (url.isEmpty()) return; // We want a new history item if the refresh timeout is > 1 second. - if (!m_scheduledRedirection || delay <= m_scheduledRedirection->delay) - schedule(new ScheduledRedirection(delay, url, true, delay <= 1, false, false)); + if (!m_redirect || delay <= m_redirect->delay()) + schedule(new ScheduledRedirect(delay, url, true, delay <= 1, false)); } bool RedirectScheduler::mustLockBackForwardList(Frame* targetFrame) @@ -172,7 +247,7 @@ bool RedirectScheduler::mustLockBackForwardList(Frame* targetFrame) // Navigation of a subframe during loading of an ancestor frame does not create a new back/forward item. // The definition of "during load" is any time before all handlers for the load event have been run. // See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation for this. - + for (Frame* ancestor = targetFrame->tree()->parent(); ancestor; ancestor = ancestor->tree()->parent()) { Document* document = ancestor->document(); if (!ancestor->loader()->isComplete() || (document && document->processingLoadEvent())) @@ -185,7 +260,6 @@ void RedirectScheduler::scheduleLocationChange(const String& url, const String& { if (!m_frame->page()) return; - if (url.isEmpty()) return; @@ -205,7 +279,7 @@ void RedirectScheduler::scheduleLocationChange(const String& url, const String& // This may happen when a frame changes the location of another frame. bool duringLoad = !loader->committedFirstRealDocumentLoad(); - schedule(new ScheduledRedirection(url, referrer, lockHistory, lockBackForwardList, wasUserGesture, false, duringLoad)); + schedule(new ScheduledLocationChange(url, referrer, lockHistory, lockBackForwardList, wasUserGesture, duringLoad)); } void RedirectScheduler::scheduleFormSubmission(const FrameLoadRequest& frameRequest, @@ -227,37 +301,25 @@ void RedirectScheduler::scheduleFormSubmission(const FrameLoadRequest& frameRequ bool lockBackForwardList = mustLockBackForwardList(m_frame) || (formState->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent()); - schedule(new ScheduledRedirection(frameRequest, lockHistory, lockBackForwardList, event, formState, duringLoad)); + schedule(new ScheduledFormSubmission(frameRequest, lockHistory, lockBackForwardList, event, formState, duringLoad)); } void RedirectScheduler::scheduleRefresh(bool wasUserGesture) { if (!m_frame->page()) return; - const KURL& url = m_frame->loader()->url(); - if (url.isEmpty()) return; - schedule(new ScheduledRedirection(url.string(), m_frame->loader()->outgoingReferrer(), true, true, wasUserGesture, true, false)); + schedule(new ScheduledRefresh(url.string(), m_frame->loader()->outgoingReferrer(), wasUserGesture)); } bool RedirectScheduler::locationChangePending() { - if (!m_scheduledRedirection) + if (!m_redirect) return false; - - switch (m_scheduledRedirection->type) { - case ScheduledRedirection::redirection: - return false; - case ScheduledRedirection::historyNavigation: - case ScheduledRedirection::locationChange: - case ScheduledRedirection::formSubmission: - return true; - } - ASSERT_NOT_REACHED(); - return false; + return m_redirect->isLocationChange(); } void RedirectScheduler::scheduleHistoryNavigation(int steps) @@ -284,119 +346,64 @@ void RedirectScheduler::scheduleHistoryNavigation(int steps) #endif // In all other cases, schedule the history traversal to occur asynchronously. - schedule(new ScheduledRedirection(steps)); + schedule(new ScheduledHistoryNavigation(steps)); } void RedirectScheduler::timerFired(Timer<RedirectScheduler>*) { if (!m_frame->page()) return; - if (m_frame->page()->defersLoading()) return; - OwnPtr<ScheduledRedirection> redirection(m_scheduledRedirection.release()); - FrameLoader* loader = m_frame->loader(); - - switch (redirection->type) { - case ScheduledRedirection::redirection: - case ScheduledRedirection::locationChange: - loader->changeLocation(KURL(ParsedURLString, redirection->url), redirection->referrer, - redirection->lockHistory, redirection->lockBackForwardList, redirection->wasUserGesture, redirection->wasRefresh); - return; - case ScheduledRedirection::historyNavigation: - if (redirection->historySteps == 0) { - // Special case for go(0) from a frame -> reload only the frame - loader->urlSelected(loader->url(), "", 0, redirection->lockHistory, redirection->lockBackForwardList, redirection->wasUserGesture, SendReferrer); - return; - } - // go(i!=0) from a frame navigates into the history of the frame only, - // in both IE and NS (but not in Mozilla). We can't easily do that. - m_frame->page()->goBackOrForward(redirection->historySteps); - return; - case ScheduledRedirection::formSubmission: - // The submitForm function will find a target frame before using the redirection timer. - // Now that the timer has fired, we need to repeat the security check which normally is done when - // selecting a target, in case conditions have changed. Other code paths avoid this by targeting - // without leaving a time window. If we fail the check just silently drop the form submission. - if (!redirection->formState->sourceFrame()->loader()->shouldAllowNavigation(m_frame)) - return; - loader->loadFrameRequest(redirection->frameRequest, redirection->lockHistory, redirection->lockBackForwardList, - redirection->event, redirection->formState, SendReferrer); - return; - } - - ASSERT_NOT_REACHED(); + OwnPtr<ScheduledNavigation> redirect(m_redirect.release()); + redirect->fire(m_frame); } -void RedirectScheduler::schedule(PassOwnPtr<ScheduledRedirection> redirection) +void RedirectScheduler::schedule(PassOwnPtr<ScheduledNavigation> redirect) { ASSERT(m_frame->page()); - FrameLoader* loader = m_frame->loader(); // If a redirect was scheduled during a load, then stop the current load. // Otherwise when the current load transitions from a provisional to a // committed state, pending redirects may be cancelled. - if (redirection->wasDuringLoad) { - if (DocumentLoader* provisionalDocumentLoader = loader->provisionalDocumentLoader()) + if (redirect->wasDuringLoad()) { + if (DocumentLoader* provisionalDocumentLoader = m_frame->loader()->provisionalDocumentLoader()) provisionalDocumentLoader->stopLoading(); - loader->stopLoading(UnloadEventPolicyUnloadAndPageHide); + m_frame->loader()->stopLoading(UnloadEventPolicyUnloadAndPageHide); } cancel(); - m_scheduledRedirection = redirection; - if (!loader->isComplete() && m_scheduledRedirection->type != ScheduledRedirection::redirection) - loader->completed(); + m_redirect = redirect; + + if (!m_frame->loader()->isComplete() && m_redirect->isLocationChange()) + m_frame->loader()->completed(); + startTimer(); } void RedirectScheduler::startTimer() { - if (!m_scheduledRedirection) + if (!m_redirect) return; ASSERT(m_frame->page()); - - FrameLoader* loader = m_frame->loader(); - if (m_timer.isActive()) return; - - if (m_scheduledRedirection->type == ScheduledRedirection::redirection && !loader->allAncestorsAreComplete()) + if (!m_redirect->shouldStartTimer(m_frame)) return; - m_timer.startOneShot(m_scheduledRedirection->delay); - - switch (m_scheduledRedirection->type) { - case ScheduledRedirection::locationChange: - case ScheduledRedirection::redirection: - if (m_scheduledRedirection->toldClient) - return; - m_scheduledRedirection->toldClient = true; - loader->clientRedirected(KURL(ParsedURLString, m_scheduledRedirection->url), - m_scheduledRedirection->delay, - currentTime() + m_timer.nextFireInterval(), - m_scheduledRedirection->lockBackForwardList); - return; - case ScheduledRedirection::formSubmission: - // FIXME: It would make sense to report form submissions as client redirects too. - // But we didn't do that in the past when form submission used a separate delay - // mechanism, so doing it will be a behavior change. - return; - case ScheduledRedirection::historyNavigation: - // Don't report history navigations. - return; - } - ASSERT_NOT_REACHED(); + m_timer.startOneShot(m_redirect->delay()); + m_redirect->didStartTimer(m_frame, &m_timer); } void RedirectScheduler::cancel(bool newLoadInProgress) { m_timer.stop(); - OwnPtr<ScheduledRedirection> redirection(m_scheduledRedirection.release()); - if (redirection && redirection->toldClient) - m_frame->loader()->clientRedirectCancelledOrFinished(newLoadInProgress); + OwnPtr<ScheduledNavigation> redirect(m_redirect.release()); + if (redirect) + redirect->didStopTimer(m_frame, newLoadInProgress); } } // namespace WebCore diff --git a/WebCore/loader/RedirectScheduler.h b/WebCore/loader/RedirectScheduler.h index 005a173..ac3731c 100644 --- a/WebCore/loader/RedirectScheduler.h +++ b/WebCore/loader/RedirectScheduler.h @@ -44,7 +44,7 @@ class Frame; class String; struct FrameLoadRequest; -struct ScheduledRedirection; +class ScheduledNavigation; class RedirectScheduler : public Noncopyable { public: @@ -67,13 +67,13 @@ public: private: void timerFired(Timer<RedirectScheduler>*); - void schedule(PassOwnPtr<ScheduledRedirection>); + void schedule(PassOwnPtr<ScheduledNavigation>); static bool mustLockBackForwardList(Frame* targetFrame); Frame* m_frame; Timer<RedirectScheduler> m_timer; - OwnPtr<ScheduledRedirection> m_scheduledRedirection; + OwnPtr<ScheduledNavigation> m_redirect; }; } // namespace WebCore diff --git a/WebCore/loader/ResourceLoadNotifier.cpp b/WebCore/loader/ResourceLoadNotifier.cpp index 9280434..d225cb8 100644 --- a/WebCore/loader/ResourceLoadNotifier.cpp +++ b/WebCore/loader/ResourceLoadNotifier.cpp @@ -103,11 +103,6 @@ void ResourceLoadNotifier::didFailToLoad(ResourceLoader* loader, const ResourceE #endif } -void ResourceLoadNotifier::didLoadResourceByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString) -{ - m_frame->loader()->client()->dispatchDidLoadResourceByXMLHttpRequest(identifier, sourceString); -} - void ResourceLoadNotifier::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) { m_frame->loader()->client()->assignIdentifierToInitialRequest(identifier, loader, request); diff --git a/WebCore/loader/ResourceLoadNotifier.h b/WebCore/loader/ResourceLoadNotifier.h index 23e4246..b0a5cbf 100644 --- a/WebCore/loader/ResourceLoadNotifier.h +++ b/WebCore/loader/ResourceLoadNotifier.h @@ -55,7 +55,6 @@ public: void didReceiveData(ResourceLoader*, const char*, int, int lengthReceived); void didFinishLoad(ResourceLoader*); void didFailToLoad(ResourceLoader*, const ResourceError&); - void didLoadResourceByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString); void assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&); void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); diff --git a/WebCore/loader/ResourceLoader.cpp b/WebCore/loader/ResourceLoader.cpp index d14afc8..183d2ce 100644 --- a/WebCore/loader/ResourceLoader.cpp +++ b/WebCore/loader/ResourceLoader.cpp @@ -34,6 +34,7 @@ #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoader.h" +#include "InspectorTimelineAgent.h" #include "Page.h" #include "ProgressTracker.h" #include "ResourceHandle.h" @@ -111,6 +112,17 @@ bool ResourceLoader::load(const ResourceRequest& r) ASSERT(!m_documentLoader->isSubstituteLoadPending(this)); ResourceRequest clientRequest(r); + + // https://bugs.webkit.org/show_bug.cgi?id=26391 + // The various plug-in implementations call directly to ResourceLoader::load() instead of piping requests + // through FrameLoader. As a result, they miss the FrameLoader::addExtraFieldsToRequest() step which sets + // up the 1st party for cookies URL. Until plug-in implementations can be reigned in to pipe through that + // method, we need to make sure there is always a 1st party for cookies set. + if (clientRequest.firstPartyForCookies().isNull()) { + if (Document* document = m_frame->document()) + clientRequest.setFirstPartyForCookies(document->firstPartyForCookies()); + } + willSendRequest(clientRequest, ResourceResponse()); if (clientRequest.isNull()) { didFail(frameLoader()->cancelledError(r)); @@ -132,7 +144,7 @@ bool ResourceLoader::load(const ResourceRequest& r) return true; } - m_handle = ResourceHandle::create(clientRequest, this, m_frame.get(), m_defersLoading, m_shouldContentSniff, true); + m_handle = ResourceHandle::create(clientRequest, this, m_frame.get(), m_defersLoading, m_shouldContentSniff); return true; } @@ -397,16 +409,44 @@ void ResourceLoader::didSendData(ResourceHandle*, unsigned long long bytesSent, void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent::instanceCount()) { + InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0; + if (timelineAgent) + timelineAgent->willReceiveResourceResponse(identifier(), response); + } +#endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response)) return; #endif didReceiveResponse(response); +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent::instanceCount()) { + InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0; + if (timelineAgent) + timelineAgent->didReceiveResourceResponse(); + } +#endif } void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, int length, int lengthReceived) { +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent::instanceCount()) { + InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0; + if (timelineAgent) + timelineAgent->willReceiveResourceData(identifier()); + } +#endif didReceiveData(data, length, lengthReceived, false); +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent::instanceCount()) { + InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0; + if (timelineAgent) + timelineAgent->didReceiveResourceData(); + } +#endif } void ResourceLoader::didFinishLoading(ResourceHandle*) diff --git a/WebCore/loader/WorkerThreadableLoader.cpp b/WebCore/loader/WorkerThreadableLoader.cpp index 6837ca1..2583498 100644 --- a/WebCore/loader/WorkerThreadableLoader.cpp +++ b/WebCore/loader/WorkerThreadableLoader.cpp @@ -42,7 +42,6 @@ #include "WorkerContext.h" #include "WorkerLoaderProxy.h" #include "WorkerThread.h" -#include <memory> #include <wtf/OwnPtr.h> #include <wtf/Threading.h> #include <wtf/Vector.h> @@ -101,7 +100,7 @@ WorkerThreadableLoader::MainThreadBridge::~MainThreadBridge() { } -void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, auto_ptr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options) +void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options) { ASSERT(isMainThread()); ASSERT(context->isDocument()); @@ -174,7 +173,7 @@ void WorkerThreadableLoader::MainThreadBridge::didSendData(unsigned long long by m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSendData, m_workerClientWrapper, bytesSent, totalBytesToBeSent), m_taskMode); } -static void workerContextDidReceiveResponse(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, auto_ptr<CrossThreadResourceResponseData> responseData) +static void workerContextDidReceiveResponse(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<CrossThreadResourceResponseData> responseData) { ASSERT_UNUSED(context, context->isWorkerContext()); OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData)); @@ -186,7 +185,7 @@ void WorkerThreadableLoader::MainThreadBridge::didReceiveResponse(const Resource m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveResponse, m_workerClientWrapper, response), m_taskMode); } -static void workerContextDidReceiveData(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, auto_ptr<Vector<char> > vectorData) +static void workerContextDidReceiveData(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData) { ASSERT_UNUSED(context, context->isWorkerContext()); workerClientWrapper->didReceiveData(vectorData->data(), vectorData->size()); @@ -194,9 +193,9 @@ static void workerContextDidReceiveData(ScriptExecutionContext* context, RefPtr< void WorkerThreadableLoader::MainThreadBridge::didReceiveData(const char* data, int lengthReceived) { - auto_ptr<Vector<char> > vector(new Vector<char>(lengthReceived)); // needs to be an auto_ptr for usage with createCallbackTask. + OwnPtr<Vector<char> > vector(new Vector<char>(lengthReceived)); // needs to be an OwnPtr for usage with createCallbackTask. memcpy(vector->data(), data, lengthReceived); - m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveData, m_workerClientWrapper, vector), m_taskMode); + m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveData, m_workerClientWrapper, vector.release()), m_taskMode); } static void workerContextDidFinishLoading(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier) @@ -232,7 +231,7 @@ void WorkerThreadableLoader::MainThreadBridge::didFailRedirectCheck() m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidFailRedirectCheck, m_workerClientWrapper), m_taskMode); } -static void workerContextDidReceiveAuthenticationCancellation(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, auto_ptr<CrossThreadResourceResponseData> responseData) +static void workerContextDidReceiveAuthenticationCancellation(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<CrossThreadResourceResponseData> responseData) { ASSERT_UNUSED(context, context->isWorkerContext()); OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData)); diff --git a/WebCore/loader/WorkerThreadableLoader.h b/WebCore/loader/WorkerThreadableLoader.h index 09f8f85..81da2e0 100644 --- a/WebCore/loader/WorkerThreadableLoader.h +++ b/WebCore/loader/WorkerThreadableLoader.h @@ -38,7 +38,7 @@ #include "ThreadableLoaderClient.h" #include "ThreadableLoaderClientWrapper.h" -#include <memory> +#include <wtf/PassOwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -109,7 +109,7 @@ namespace WebCore { static void mainThreadDestroy(ScriptExecutionContext*, MainThreadBridge*); ~MainThreadBridge(); - static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, std::auto_ptr<CrossThreadResourceRequestData>, ThreadableLoaderOptions); + static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, PassOwnPtr<CrossThreadResourceRequestData>, ThreadableLoaderOptions); static void mainThreadCancel(ScriptExecutionContext*, MainThreadBridge*); virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent); virtual void didReceiveResponse(const ResourceResponse&); diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp index c8a485a..526043b 100644 --- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp +++ b/WebCore/loader/appcache/ApplicationCacheGroup.cpp @@ -443,7 +443,7 @@ PassRefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const KUR } } - return ResourceHandle::create(request, this, m_frame, false, true, false); + return ResourceHandle::create(request, this, m_frame, false, true); } void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response) diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/WebCore/loader/appcache/ApplicationCacheStorage.cpp index 1e97d78..2d82c21 100644 --- a/WebCore/loader/appcache/ApplicationCacheStorage.cpp +++ b/WebCore/loader/appcache/ApplicationCacheStorage.cpp @@ -32,11 +32,11 @@ #include "ApplicationCacheHost.h" #include "ApplicationCacheGroup.h" #include "ApplicationCacheResource.h" -#include "CString.h" #include "FileSystem.h" #include "KURL.h" #include "SQLiteStatement.h" #include "SQLiteTransaction.h" +#include <wtf/text/CString.h> #include <wtf/StdLibExtras.h> #include <wtf/StringExtras.h> diff --git a/WebCore/loader/appcache/DOMApplicationCache.h b/WebCore/loader/appcache/DOMApplicationCache.h index 077cae0..b398756 100644 --- a/WebCore/loader/appcache/DOMApplicationCache.h +++ b/WebCore/loader/appcache/DOMApplicationCache.h @@ -50,6 +50,7 @@ public: static PassRefPtr<DOMApplicationCache> create(Frame* frame) { return adoptRef(new DOMApplicationCache(frame)); } ~DOMApplicationCache() { ASSERT(!m_frame); } + Frame* frame() const { return m_frame; } void disconnectFrame(); unsigned short status() const; diff --git a/WebCore/loader/appcache/DOMApplicationCache.idl b/WebCore/loader/appcache/DOMApplicationCache.idl index 9c3a359..9794baf 100644 --- a/WebCore/loader/appcache/DOMApplicationCache.idl +++ b/WebCore/loader/appcache/DOMApplicationCache.idl @@ -55,12 +55,12 @@ module offline { attribute EventListener onobsolete; // EventTarget interface - [Custom] void addEventListener(in DOMString type, - in EventListener listener, - in boolean useCapture); - [Custom] void removeEventListener(in DOMString type, + [JSCCustom] void addEventListener(in DOMString type, in EventListener listener, in boolean useCapture); + [JSCCustom] void removeEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); boolean dispatchEvent(in Event evt) raises(EventException); }; diff --git a/WebCore/loader/archive/cf/LegacyWebArchive.cpp b/WebCore/loader/archive/cf/LegacyWebArchive.cpp index 3141e98..931b159 100644 --- a/WebCore/loader/archive/cf/LegacyWebArchive.cpp +++ b/WebCore/loader/archive/cf/LegacyWebArchive.cpp @@ -29,7 +29,6 @@ #include "config.h" #include "LegacyWebArchive.h" -#include "CString.h" #include "Cache.h" #include "Document.h" #include "DocumentLoader.h" @@ -47,6 +46,7 @@ #include "Range.h" #include "SelectionController.h" #include "SharedBuffer.h" +#include <wtf/text/CString.h> #include <wtf/ListHashSet.h> #include <wtf/RetainPtr.h> diff --git a/WebCore/loader/icon/IconFetcher.cpp b/WebCore/loader/icon/IconFetcher.cpp index d1aa2f3..3d3df39 100644 --- a/WebCore/loader/icon/IconFetcher.cpp +++ b/WebCore/loader/icon/IconFetcher.cpp @@ -32,6 +32,7 @@ #include "HTMLNames.h" #include "ResourceHandle.h" #include "ResourceRequest.h" +#include "SharedBuffer.h" namespace WebCore { diff --git a/WebCore/loader/icon/IconLoader.cpp b/WebCore/loader/icon/IconLoader.cpp index 5dd000e..eb49087 100644 --- a/WebCore/loader/icon/IconLoader.cpp +++ b/WebCore/loader/icon/IconLoader.cpp @@ -49,9 +49,9 @@ IconLoader::IconLoader(Frame* frame) { } -auto_ptr<IconLoader> IconLoader::create(Frame* frame) +PassOwnPtr<IconLoader> IconLoader::create(Frame* frame) { - return auto_ptr<IconLoader>(new IconLoader(frame)); + return new IconLoader(frame); } IconLoader::~IconLoader() diff --git a/WebCore/loader/icon/IconLoader.h b/WebCore/loader/icon/IconLoader.h index 7b96ed8..1ebac48 100644 --- a/WebCore/loader/icon/IconLoader.h +++ b/WebCore/loader/icon/IconLoader.h @@ -27,7 +27,6 @@ #define IconLoader_h #include "SubresourceLoaderClient.h" -#include <memory> #include <wtf/Forward.h> #include <wtf/Noncopyable.h> #include <wtf/RefPtr.h> @@ -40,7 +39,7 @@ class SharedBuffer; class IconLoader : private SubresourceLoaderClient, public Noncopyable { public: - static std::auto_ptr<IconLoader> create(Frame*); + static PassOwnPtr<IconLoader> create(Frame*); ~IconLoader(); void startLoading(); diff --git a/WebCore/loader/icon/wince/IconDatabaseWince.cpp b/WebCore/loader/icon/wince/IconDatabaseWince.cpp index e6d686c..54a36e5 100644 --- a/WebCore/loader/icon/wince/IconDatabaseWince.cpp +++ b/WebCore/loader/icon/wince/IconDatabaseWince.cpp @@ -22,12 +22,12 @@ #include "IconDatabase.h" #include "AutodrainedPool.h" -#include "CString.h" #include "DocumentLoader.h" #include "FileSystem.h" #include "IconDatabaseClient.h" #include "IconRecord.h" #include "Image.h" +#include <wtf/text/CString.h> namespace WebCore { diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp index 24f141f..808ae54 100644 --- a/WebCore/loader/loader.cpp +++ b/WebCore/loader/loader.cpp @@ -27,7 +27,6 @@ #include "Cache.h" #include "CachedImage.h" #include "CachedResource.h" -#include "CString.h" #include "DocLoader.h" #include "Frame.h" #include "FrameLoader.h" @@ -37,6 +36,7 @@ #include "ResourceRequest.h" #include "ResourceResponse.h" #include "SecurityOrigin.h" +#include "SharedBuffer.h" #include "SubresourceLoader.h" #include <wtf/Assertions.h> #include <wtf/Vector.h> @@ -295,6 +295,8 @@ void Loader::Host::nonCacheRequestComplete() { --m_nonCachedRequestsInFlight; ASSERT(m_nonCachedRequestsInFlight >= 0); + + cache()->loader()->scheduleServePendingRequests(); } bool Loader::Host::hasRequests() const @@ -331,7 +333,6 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser bool shouldLimitRequests = !m_name.isNull() || docLoader->doc()->parsing() || !docLoader->doc()->haveStylesheetsLoaded(); if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) { serveLowerPriority = false; - cache()->loader()->scheduleServePendingRequests(); return; } requestsPending.removeFirst(); |