Commit c83ee4ee authored by ap@apple.com's avatar ap@apple.com

https://bugs.webkit.org/show_bug.cgi?id=67774

        PDF in a frameset is not displayed, always downloads

        Reviewed by Darin Adler.

        * WebKit2.xcodeproj/project.pbxproj:
        * WebProcess/Plugins/PDF: Added.
        Added BuiltInPDFView class. It implements ScrollableArea and Plugin, working with iframes,
        objects and embeds. The implementation targets Mac port only, fixing a WebKit2 regression.

        * UIProcess/WebContext.cpp: (WebKit::WebContext::getPlugins): Tell WebCore that there is a
        plug-in for PDF, so that it instantiates it in a regular fashion.

        * UIProcess/WebFrameProxy.cpp: (WebKit::WebFrameProxy::canShowMIMEType): We can now show
        PDF not only in main frame.

        * WebProcess/Plugins/PDF/BuiltInPDFView.cpp: Added. This is largely an implementation of
        ScrollableArea now, which can render the first page of a PDF. Further improvements to come.

        * WebProcess/Plugins/PDF/BuiltInPDFView.h: Added.

        * WebProcess/Plugins/Plugin.cpp: (WebKit::Plugin::updateControlTints): Give Plugin a chance
        to invalidate its tintable controls - it's necessary for PDF because scrollbars are tintable. 

        * WebProcess/Plugins/Plugin.h: (WebKit::Plugin::controller): Added a const version, since
        some ScrollableArea methods are const.

        * WebProcess/Plugins/PluginView.cpp: (WebKit::PluginView::paint): Call updateControlTints
        at updatingControlTints phase.

        * WebProcess/Plugins/PluginView.h: PDF plug-in needs to tinker with embedding FrameView to
        use Scrollbar class, so it needs to cast its PluginController up to PluginView. It's unfortunate
        that PluginView has so much NPAPI specific code, but that's how it is now.

        * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::createPlugin): If there is no real plug-in
        installed for PDF, instantiate built-in one.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96653 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e382441e
2011-10-04 Alexey Proskuryakov <ap@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=67774
PDF in a frameset is not displayed, always downloads
Reviewed by Darin Adler.
* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:
Added exports necessary to subclass a ScrollableArea.
2011-10-04 Anders Carlsson <andersca@apple.com>
ScrollElasticityController should keep track of the rubberband timer state
......@@ -150,6 +150,7 @@ __ZN7WebCore10ScrollView18setFixedLayoutSizeERKNS_7IntSizeE
__ZN7WebCore10ScrollView20setCanHaveScrollbarsEb
__ZN7WebCore10ScrollView23setScrollbarsSuppressedEbb
__ZN7WebCore10ScrollView24windowResizerRectChangedEv
__ZN7WebCore10ScrollView8addChildEN3WTF10PassRefPtrINS_6WidgetEEE
__ZN7WebCore10deleteFileERKN3WTF6StringE
__ZN7WebCore10handCursorEv
__ZN7WebCore10setCookiesEPNS_8DocumentERKNS_4KURLERKN3WTF6StringE
......@@ -366,9 +367,18 @@ __ZN7WebCore14SchemeRegistry24registerURLSchemeAsLocalERKN3WTF6StringE
__ZN7WebCore14SchemeRegistry25registerURLSchemeAsSecureERKN3WTF6StringE
__ZN7WebCore14SchemeRegistry32registerURLSchemeAsEmptyDocumentERKN3WTF6StringE
__ZN7WebCore14SchemeRegistry34shouldLoadURLSchemeAsEmptyDocumentERKN3WTF6StringE
__ZN7WebCore14ScrollableArea16handleWheelEventERKNS_18PlatformWheelEventE
__ZN7WebCore14ScrollableArea17willEndLiveResizeEv
__ZN7WebCore14ScrollableArea19willStartLiveResizeEv
__ZN7WebCore14ScrollableArea22invalidateScrollCornerERKNS_7IntRectE
__ZN7WebCore14ScrollableArea23didAddVerticalScrollbarEPNS_9ScrollbarE
__ZN7WebCore14ScrollableArea24setScrollbarOverlayStyleENS_21ScrollbarOverlayStyleE
__ZN7WebCore14ScrollableArea25didAddHorizontalScrollbarEPNS_9ScrollbarE
__ZN7WebCore14ScrollableArea27willRemoveVerticalScrollbarEPNS_9ScrollbarE
__ZN7WebCore14ScrollableArea28setScrollOffsetFromInternalsERKNS_8IntPointE
__ZN7WebCore14ScrollableArea29willRemoveHorizontalScrollbarEPNS_9ScrollbarE
__ZN7WebCore14ScrollableAreaC2Ev
__ZN7WebCore14ScrollableAreaD2Ev
__ZN7WebCore14ScrollbarTheme11nativeThemeEv
__ZN7WebCore14SecurityOrigin14threadsafeCopyEv
__ZN7WebCore14SecurityOrigin16createFromStringERKN3WTF6StringE
......@@ -404,9 +414,12 @@ __ZN7WebCore15FocusController15setInitialFocusENS_14FocusDirectionEPNS_13Keyboar
__ZN7WebCore15FocusController9setActiveEb
__ZN7WebCore15GraphicsContext12setFillColorERKNS_5ColorENS_10ColorSpaceE
__ZN7WebCore15GraphicsContext15setFillGradientEN3WTF10PassRefPtrINS_8GradientEEE
__ZN7WebCore15GraphicsContext18setShouldAntialiasEb
__ZN7WebCore15GraphicsContext20setShouldSmoothFontsEb
__ZN7WebCore15GraphicsContext20endTransparencyLayerEv
__ZN7WebCore15GraphicsContext21setCompositeOperationENS_17CompositeOperatorE
__ZN7WebCore15GraphicsContext22beginTransparencyLayerEf
__ZN7WebCore15GraphicsContext28setImageInterpolationQualityENS_20InterpolationQualityE
__ZN7WebCore15GraphicsContext4clipERKNS_4PathE
__ZN7WebCore15GraphicsContext4clipERKNS_7IntRectE
__ZN7WebCore15GraphicsContext4clipERKNS_9FloatRectE
......@@ -706,10 +719,12 @@ __ZN7WebCore4Page15addSchedulePairEN3WTF10PassRefPtrINS_12SchedulePairEEE
__ZN7WebCore4Page15didMoveOnscreenEv
__ZN7WebCore4Page16setCanStartMediaEb
__ZN7WebCore4Page16setDefersLoadingEb
__ZN7WebCore4Page17addScrollableAreaEPNS_14ScrollableAreaE
__ZN7WebCore4Page17willMoveOffscreenEv
__ZN7WebCore4Page18removeSchedulePairEN3WTF10PassRefPtrINS_12SchedulePairEEE
__ZN7WebCore4Page18setPageScaleFactorEfRKNS_8IntPointE
__ZN7WebCore4Page19visitedStateChangedEPNS_9PageGroupEy
__ZN7WebCore4Page20removeScrollableAreaEPNS_14ScrollableAreaE
__ZN7WebCore4Page20setDeviceScaleFactorEf
__ZN7WebCore4Page20unmarkAllTextMatchesEv
__ZN7WebCore4Page21markAllMatchesForTextERKN3WTF6StringEjbj
......@@ -857,9 +872,11 @@ __ZN7WebCore8Document17getFocusableNodesERN3WTF6VectorINS1_6RefPtrINS_4NodeEEELm
__ZN7WebCore8Document19accessSVGExtensionsEv
__ZN7WebCore8Document20styleSelectorChangedENS_23StyleSelectorUpdateFlagE
__ZN7WebCore8Document22createDocumentFragmentEv
__ZN7WebCore8Document23didAddWheelEventHandlerEv
__ZN7WebCore8Document24addMediaCanStartListenerEPNS_21MediaCanStartListenerE
__ZN7WebCore8Document24setShouldCreateRenderersEb
__ZN7WebCore8Document25scheduleForcedStyleRecalcEv
__ZN7WebCore8Document26didRemoveWheelEventHandlerEv
__ZN7WebCore8Document26pageSizeAndMarginsInPixelsEiRNS_7IntSizeERiS3_S3_S3_
__ZN7WebCore8Document27removeMediaCanStartListenerEPNS_21MediaCanStartListenerE
__ZN7WebCore8Document36updateLayoutIgnorePendingStylesheetsEv
......@@ -1042,8 +1059,13 @@ __ZN7WebCore9PageGroup26removeUserScriptsFromWorldEPNS_15DOMWrapperWorldE
__ZN7WebCore9PageGroup26setShouldTrackVisitedLinksEb
__ZN7WebCore9PageGroup29removeUserStyleSheetFromWorldEPNS_15DOMWrapperWorldERKNS_4KURLE
__ZN7WebCore9PageGroup30removeUserStyleSheetsFromWorldEPNS_15DOMWrapperWorldE
__ZN7WebCore9Scrollbar7mouseUpEv
__ZN7WebCore9PageGroup9pageGroupERKN3WTF6StringE
__ZN7WebCore9Scrollbar13setProportionEii
__ZN7WebCore9Scrollbar21createNativeScrollbarEPNS_14ScrollableAreaENS_20ScrollbarOrientationENS_20ScrollbarControlSizeE
__ZN7WebCore9Scrollbar22maxOverlapBetweenPagesEv
__ZN7WebCore9Scrollbar8setStepsEiii
__ZN7WebCore9Scrollbar9mouseDownERKNS_18PlatformMouseEventE
__ZN7WebCore9TimerBase4stopEv
__ZN7WebCore9TimerBase5startEdd
__ZN7WebCore9TimerBaseC2Ev
......@@ -1074,6 +1096,7 @@ __ZNK7WebCore10ScrollView14scrollbarModesERNS_13ScrollbarModeES2_
__ZNK7WebCore10ScrollView14useFixedLayoutEv
__ZNK7WebCore10ScrollView15fixedLayoutSizeEv
__ZNK7WebCore10ScrollView16contentsToWindowERKNS_7IntRectE
__ZNK7WebCore10ScrollView16windowToContentsERKNS_7IntRectE
__ZNK7WebCore10ScrollView16contentsToWindowERKNS_8IntPointE
__ZNK7WebCore10ScrollView16windowToContentsERKNS_8IntPointE
__ZNK7WebCore10ScrollView18visibleContentRectEb
......@@ -1168,12 +1191,14 @@ __ZNK7WebCore14FrameSelection6boundsEb
__ZNK7WebCore14RenderListItem10markerTextEv
__ZNK7WebCore14ResourceHandle10connectionEv
__ZNK7WebCore14ResourceLoader11frameLoaderEv
__ZNK7WebCore14ScrollableArea14scrollAnimatorEv
__ZNK7WebCore14SecurityOrigin10canDisplayERKNS_4KURLE
__ZNK7WebCore14SecurityOrigin18databaseIdentifierEv
__ZNK7WebCore14SecurityOrigin5equalEPKS0_
__ZNK7WebCore15FocusController18focusedOrMainFrameEv
__ZNK7WebCore15GraphicsContext15platformContextEv
__ZNK7WebCore15GraphicsContext16paintingDisabledEv
__ZNK7WebCore15GraphicsContext20updatingControlTintsEv
__ZNK7WebCore15ProgressTracker17estimatedProgressEv
__ZNK7WebCore15ProtectionSpace10serverTypeEv
__ZNK7WebCore15ProtectionSpace26receivesCredentialSecurelyEv
......
......@@ -5454,7 +5454,7 @@
C6F08FCA1431000D00685849 /* JSMutationRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C6F08FC81431000D00685849 /* JSMutationRecord.h */; };
C6F41047130C6E8900393DE4 /* EntryBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6F41046130C6E8900393DE4 /* EntryBase.cpp */; };
CA3BF67C10D99BAE00E6CE53 /* ScrollAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */; };
CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */; };
CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */; settings = {ATTRIBUTES = (Private, ); }; };
CD82030A1395AB6A00F956C6 /* WebVideoFullscreenController.h in Headers */ = {isa = PBXBuildFile; fileRef = CD8203061395AB6A00F956C6 /* WebVideoFullscreenController.h */; settings = {ATTRIBUTES = (Private, ); }; };
CD82030B1395AB6A00F956C6 /* WebVideoFullscreenController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD8203071395AB6A00F956C6 /* WebVideoFullscreenController.mm */; settings = {COMPILER_FLAGS = "-Wno-undef"; }; };
CD82030C1395AB6A00F956C6 /* WebVideoFullscreenHUDWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = CD8203081395AB6A00F956C6 /* WebVideoFullscreenHUDWindowController.h */; settings = {ATTRIBUTES = (Private, ); }; };
2011-10-04 Alexey Proskuryakov <ap@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=67774
PDF in a frameset is not displayed, always downloads
Reviewed by Darin Adler.
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/Plugins/PDF: Added.
Added BuiltInPDFView class. It implements ScrollableArea and Plugin, working with iframes,
objects and embeds. The implementation targets Mac port only, fixing a WebKit2 regression.
* UIProcess/WebContext.cpp: (WebKit::WebContext::getPlugins): Tell WebCore that there is a
plug-in for PDF, so that it instantiates it in a regular fashion.
* UIProcess/WebFrameProxy.cpp: (WebKit::WebFrameProxy::canShowMIMEType): We can now show
PDF not only in main frame.
* WebProcess/Plugins/PDF/BuiltInPDFView.cpp: Added. This is largely an implementation of
ScrollableArea now, which can render the first page of a PDF. Further improvements to come.
* WebProcess/Plugins/PDF/BuiltInPDFView.h: Added.
* WebProcess/Plugins/Plugin.cpp: (WebKit::Plugin::updateControlTints): Give Plugin a chance
to invalidate its tintable controls - it's necessary for PDF because scrollbars are tintable.
* WebProcess/Plugins/Plugin.h: (WebKit::Plugin::controller): Added a const version, since
some ScrollableArea methods are const.
* WebProcess/Plugins/PluginView.cpp: (WebKit::PluginView::paint): Call updateControlTints
at updatingControlTints phase.
* WebProcess/Plugins/PluginView.h: PDF plug-in needs to tinker with embedding FrameView to
use Scrollbar class, so it needs to cast its PluginController up to PluginView. It's unfortunate
that PluginView has so much NPAPI specific code, but that's how it is now.
* WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::createPlugin): If there is no real plug-in
installed for PDF, instantiate built-in one.
2011-10-04 Jon Lee <jonlee@apple.com>
REGRESSION (WK2): (Shift-)option-tabbing skips over elements when transitioning from chrome to webview
......
......@@ -61,6 +61,10 @@
#include <wtf/CurrentTime.h>
#include <wtf/MainThread.h>
#if PLATFORM(MAC)
#include "BuiltInPDFView.h"
#endif
#ifndef NDEBUG
#include <wtf/RefCountedLeakCounter.h>
#endif
......@@ -555,6 +559,11 @@ void WebContext::getPlugins(bool refresh, Vector<PluginInfo>& pluginInfos)
Vector<PluginModuleInfo> plugins = m_pluginInfoStore.plugins();
for (size_t i = 0; i < plugins.size(); ++i)
pluginInfos.append(plugins[i].info);
#if PLATFORM(MAC)
// Add built-in PDF last, so that it's not used when a real plug-in is installed.
pluginInfos.append(BuiltInPDFView::pluginInfo());
#endif
}
void WebContext::getPluginPath(const String& mimeType, const String& urlString, String& pluginPath)
......
......@@ -109,8 +109,8 @@ bool WebFrameProxy::canShowMIMEType(const String& mimeType) const
return true;
#if PLATFORM(MAC)
// On Mac, we can show PDFs in the main frame.
if (isMainFrame() && !mimeType.isEmpty())
// On Mac, we can show PDFs.
if (!mimeType.isEmpty())
return WebContext::pdfAndPostScriptMIMETypes().contains(mimeType);
#endif
......
......@@ -825,6 +825,7 @@
E179FD9C134D38060015B883 /* ArgumentCodersMac.h in Headers */ = {isa = PBXBuildFile; fileRef = E179FD9B134D38060015B883 /* ArgumentCodersMac.h */; };
E179FD9F134D38250015B883 /* ArgumentCodersMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = E179FD9E134D38250015B883 /* ArgumentCodersMac.mm */; };
E18C92F412DB9E7100CF2AEB /* PrintInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18C92F312DB9E7100CF2AEB /* PrintInfo.cpp */; };
E199875E142C045400BB2DE7 /* BuiltInPDFView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E199875C142BFC9700BB2DE7 /* BuiltInPDFView.cpp */; };
E1A31732134CEA6C007C9A4F /* AttributedString.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A31731134CEA6C007C9A4F /* AttributedString.h */; };
E1A31735134CEA80007C9A4F /* AttributedString.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1A31734134CEA80007C9A4F /* AttributedString.mm */; };
E1BB16A413201B9B00F49431 /* WKFullKeyboardAccessWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BB1688132018BA00F49431 /* WKFullKeyboardAccessWatcher.h */; };
......@@ -1802,6 +1803,8 @@
E179FD9B134D38060015B883 /* ArgumentCodersMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentCodersMac.h; sourceTree = "<group>"; };
E179FD9E134D38250015B883 /* ArgumentCodersMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ArgumentCodersMac.mm; sourceTree = "<group>"; };
E18C92F312DB9E7100CF2AEB /* PrintInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrintInfo.cpp; sourceTree = "<group>"; };
E199875A142BF9B800BB2DE7 /* BuiltInPDFView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BuiltInPDFView.h; path = PDF/BuiltInPDFView.h; sourceTree = "<group>"; };
E199875C142BFC9700BB2DE7 /* BuiltInPDFView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BuiltInPDFView.cpp; path = PDF/BuiltInPDFView.cpp; sourceTree = "<group>"; };
E1A31731134CEA6C007C9A4F /* AttributedString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttributedString.h; sourceTree = "<group>"; };
E1A31734134CEA80007C9A4F /* AttributedString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AttributedString.mm; sourceTree = "<group>"; };
E1BB1688132018BA00F49431 /* WKFullKeyboardAccessWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKFullKeyboardAccessWatcher.h; sourceTree = "<group>"; };
......@@ -2071,6 +2074,7 @@
1A6FB7AA11E64B4900DB1371 /* Plugins */ = {
isa = PBXGroup;
children = (
E199875B142BF9CF00BB2DE7 /* PDF */,
1A6FB90811E66FB100DB1371 /* Netscape */,
1A6FB7D011E651E200DB1371 /* Plugin.cpp */,
1A6FB7D111E651E200DB1371 /* Plugin.h */,
......@@ -3436,6 +3440,15 @@
path = FullScreen/mac;
sourceTree = "<group>";
};
E199875B142BF9CF00BB2DE7 /* PDF */ = {
isa = PBXGroup;
children = (
E199875C142BFC9700BB2DE7 /* BuiltInPDFView.cpp */,
E199875A142BF9B800BB2DE7 /* BuiltInPDFView.h */,
);
name = PDF;
sourceTree = "<group>";
};
F638955A133BF57D008941D5 /* mac */ = {
isa = PBXGroup;
children = (
......@@ -4555,6 +4568,7 @@
5272B28A1406985D0096A5D0 /* StatisticsData.cpp in Sources */,
1A2BB6D014117B4D000F35D4 /* PluginProcessConnectionMessageReceiver.cpp in Sources */,
7801C099142290C400FAF9AF /* WebHitTestResult.cpp in Sources */,
E199875E142C045400BB2DE7 /* BuiltInPDFView.cpp in Sources */,
0F174AA7142AAC610039250F /* WKGeometry.cpp in Sources */,
B62E7310143047A60069EC35 /* WKHitTestResult.cpp in Sources */,
);
......
/*
* Copyright (C) 2011 Apple Inc. 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "BuiltInPDFView.h"
#include "PluginView.h"
#include "ShareableBitmap.h"
#include "WebEvent.h"
#include "WebEventConversion.h"
#include <WebCore/FocusController.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameView.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/HTTPHeaderMap.h>
#include <WebCore/Page.h>
#include <WebCore/PluginData.h>
#include <WebCore/ScrollAnimator.h>
#include <WebCore/ScrollbarTheme.h>
using namespace WebCore;
using namespace std;
namespace WebKit {
const uint64_t pdfDocumentRequestID = 1; // PluginController supports loading multiple streams, but we only need one for PDF.
PassRefPtr<BuiltInPDFView> BuiltInPDFView::create(Page* page)
{
return adoptRef(new BuiltInPDFView(page));
}
BuiltInPDFView::BuiltInPDFView(Page* page)
: m_page(page)
{
m_page->addScrollableArea(this);
}
BuiltInPDFView::~BuiltInPDFView()
{
if (m_page)
m_page->removeScrollableArea(this);
if (m_horizontalScrollbar)
willRemoveHorizontalScrollbar(m_horizontalScrollbar.get());
if (m_verticalScrollbar)
willRemoveVerticalScrollbar(m_verticalScrollbar.get());
}
PluginInfo BuiltInPDFView::pluginInfo()
{
PluginInfo info;
info.name = "WebKit built-in PDF"; // FIXME: Name and description should be localizable.
MimeClassInfo mimeClassInfo;
mimeClassInfo.type ="application/pdf";
mimeClassInfo.desc = "Portable Document Format";
mimeClassInfo.extensions.append("pdf");
info.mimes.append(mimeClassInfo);
return info;
}
PluginView* BuiltInPDFView::pluginView()
{
return static_cast<PluginView*>(controller());
}
const PluginView* BuiltInPDFView::pluginView() const
{
return static_cast<const PluginView*>(controller());
}
void BuiltInPDFView::calculateDocumentSize()
{
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), 1); // FIXME: Draw all pages of a document.
if (!pdfPage)
return;
CGRect box = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox);
if (CGRectIsEmpty(box))
box = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);
m_pdfDocumentSize = IntSize(box.size);
}
void BuiltInPDFView::updateScrollbars()
{
if (m_horizontalScrollbar) {
if (m_frameRect.width() >= m_pdfDocumentSize.width())
destroyScrollbar(HorizontalScrollbar);
} else if (m_frameRect.width() < m_pdfDocumentSize.width())
m_horizontalScrollbar = createScrollbar(HorizontalScrollbar);
if (m_verticalScrollbar) {
if (m_frameRect.height() >= m_pdfDocumentSize.height())
destroyScrollbar(VerticalScrollbar);
} else if (m_frameRect.height() < m_pdfDocumentSize.height())
m_verticalScrollbar = createScrollbar(VerticalScrollbar);
int horizontalScrollbarHeight = (m_horizontalScrollbar && !m_horizontalScrollbar->isOverlayScrollbar()) ? m_horizontalScrollbar->height() : 0;
int verticalScrollbarWidth = (m_verticalScrollbar && !m_verticalScrollbar->isOverlayScrollbar()) ? m_verticalScrollbar->width() : 0;
// FIXME: Use document page size for PageDown step.
int clientHeight = m_pdfDocumentSize.height();
int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
if (m_horizontalScrollbar) {
m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_horizontalScrollbar->setProportion(m_frameRect.width() - verticalScrollbarWidth, m_pdfDocumentSize.width());
IntRect scrollbarRect(pluginView()->x(), pluginView()->y() + m_frameRect.height() - m_horizontalScrollbar->height(), m_frameRect.width(), m_horizontalScrollbar->height());
if (m_verticalScrollbar)
scrollbarRect.contract(m_verticalScrollbar->width(), 0);
m_horizontalScrollbar->setFrameRect(scrollbarRect);
}
if (m_verticalScrollbar) {
m_verticalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_verticalScrollbar->setProportion(m_frameRect.height() - horizontalScrollbarHeight, m_pdfDocumentSize.height());
IntRect scrollbarRect(IntRect(pluginView()->x() + m_frameRect.width() - m_verticalScrollbar->width(), pluginView()->y(), m_verticalScrollbar->width(), m_frameRect.height()));
if (m_horizontalScrollbar)
scrollbarRect.contract(0, m_horizontalScrollbar->height());
m_verticalScrollbar->setFrameRect(scrollbarRect);
}
}
void BuiltInPDFView::didAddHorizontalScrollbar(Scrollbar* scrollbar)
{
pluginView()->frame()->document()->didAddWheelEventHandler();
ScrollableArea::didAddHorizontalScrollbar(scrollbar);
}
void BuiltInPDFView::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
{
ScrollableArea::willRemoveHorizontalScrollbar(scrollbar);
// FIXME: Maybe need a separate ScrollableArea::didRemoveHorizontalScrollbar callback?
if (PluginView* pluginView = this->pluginView())
pluginView->frame()->document()->didRemoveWheelEventHandler();
}
PassRefPtr<Scrollbar> BuiltInPDFView::createScrollbar(ScrollbarOrientation orientation)
{
// FIXME: Support custom scrollbar styles.
RefPtr<Scrollbar> widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
if (orientation == HorizontalScrollbar)
scrollAnimator()->didAddHorizontalScrollbar(widget.get());
else
scrollAnimator()->didAddVerticalScrollbar(widget.get());
pluginView()->frame()->view()->addChild(widget.get());
return widget.release();
}
void BuiltInPDFView::destroyScrollbar(ScrollbarOrientation orientation)
{
RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_horizontalScrollbar : m_verticalScrollbar;
if (!scrollbar)
return;
if (orientation == HorizontalScrollbar)
scrollAnimator()->willRemoveHorizontalScrollbar(scrollbar.get());
else
scrollAnimator()->willRemoveVerticalScrollbar(scrollbar.get());
scrollbar->removeFromParent();
scrollbar->disconnectFromScrollableArea();
scrollbar = 0;
}
void BuiltInPDFView::pdfDocumentDidLoad()
{
calculateDocumentSize();
updateScrollbars();
controller()->invalidate(IntRect(0, 0, m_frameRect.width(), m_frameRect.height()));
}
bool BuiltInPDFView::initialize(const Parameters& parameters)
{
// Load the src URL if needed.
if (!parameters.loadManually && !parameters.url.isEmpty())
controller()->loadURL(pdfDocumentRequestID, "GET", parameters.url.string(), String(), HTTPHeaderMap(), Vector<uint8_t>(), false);
return true;
}
void BuiltInPDFView::destroy()
{
}
void BuiltInPDFView::paint(GraphicsContext* graphicsContext, const IntRect& dirtyRectInWindowCoordinates)
{
if (!m_pdfDocument) // FIXME: Draw background and loading progress.
return;
// FIXME: This function just draws the fist page of a document at top left corner.
// We should show the whole document, centering small ones.
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), 1);
if (!pdfPage)
return;
scrollAnimator()->contentAreaWillPaint();
CGContextRef context = graphicsContext->platformContext();
GraphicsContextStateSaver stateSaver(*graphicsContext);
graphicsContext->clip(dirtyRectInWindowCoordinates);
graphicsContext->setImageInterpolationQuality(InterpolationHigh);
graphicsContext->setShouldAntialias(true);
graphicsContext->setShouldSmoothFonts(true);
CGRect pageBox = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox);
if (CGRectIsEmpty(pageBox))
pageBox = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);
CGContextClipToRect(context, CGRectMake(m_frameRect.x(), m_frameRect.y(), m_pdfDocumentSize.width() - m_scrollOffset.width(), m_pdfDocumentSize.height() - m_scrollOffset.height()));
CGContextTranslateCTM(context, m_frameRect.x() - pageBox.origin.x - m_scrollOffset.width(), m_frameRect.y() + pageBox.origin.y + m_pdfDocumentSize.height() - m_scrollOffset.height());
CGContextScaleCTM(context, 1, -1);
CGContextDrawPDFPage(context, pdfPage);
stateSaver.restore();
stateSaver.save();
// Undo translation to window coordinates performed by PluginView::paint().
IntRect dirtyRect = pluginView()->parent()->windowToContents(dirtyRectInWindowCoordinates);
IntPoint documentOriginInWindowCoordinates = pluginView()->parent()->windowToContents(IntPoint());
graphicsContext->translate(-documentOriginInWindowCoordinates.x(), -documentOriginInWindowCoordinates.y());
if (m_horizontalScrollbar)
m_horizontalScrollbar->paint(graphicsContext, dirtyRect);
if (m_verticalScrollbar)
m_verticalScrollbar->paint(graphicsContext, dirtyRect);
IntRect dirtyCornerRect = intersection(scrollCornerRect(), dirtyRect);
ScrollbarTheme::nativeTheme()->paintScrollCorner(0, graphicsContext, dirtyCornerRect);
}
void BuiltInPDFView::updateControlTints(GraphicsContext* graphicsContext)
{
ASSERT(graphicsContext->updatingControlTints());
if (m_horizontalScrollbar)
m_horizontalScrollbar->invalidate();
if (m_verticalScrollbar)
m_verticalScrollbar->invalidate();
invalidateScrollCorner(scrollCornerRect());
}
PassRefPtr<ShareableBitmap> BuiltInPDFView::snapshot()
{
return 0;
}
#if PLATFORM(MAC)
PlatformLayer* BuiltInPDFView::pluginLayer()
{
return 0;
}
#endif
bool BuiltInPDFView::isTransparent()
{
// This should never be called from the web process.
ASSERT_NOT_REACHED();
return false;
}
void BuiltInPDFView::geometryDidChange(const IntRect& frameRect, const IntRect& clipRect)
{
if (m_frameRect == frameRect) {
// Nothing to do.
return;
}
m_frameRect = frameRect;
updateScrollbars();
}
void BuiltInPDFView::visibilityDidChange()
{
}
void BuiltInPDFView::frameDidFinishLoading(uint64_t)
{
ASSERT_NOT_REACHED();
}
void BuiltInPDFView::frameDidFail(uint64_t, bool)
{
ASSERT_NOT_REACHED();
}
void BuiltInPDFView::didEvaluateJavaScript(uint64_t, const WTF::String&)
{
ASSERT_NOT_REACHED();
}
void BuiltInPDFView::streamDidReceiveResponse(uint64_t streamID, const KURL&, uint32_t, uint32_t, const WTF::String&, const WTF::String&)
{
ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID);
}
void BuiltInPDFView::streamDidReceiveData(uint64_t streamID, const char* bytes, int length)
{
ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID);
if (!m_dataBuffer)
m_dataBuffer.adoptCF(CFDataCreateMutable(0, 0));
CFDataAppendBytes(m_dataBuffer.get(), reinterpret_cast<const UInt8*>(bytes), length);
}
void BuiltInPDFView::streamDidFinishLoading(uint64_t streamID)
{
ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID);
RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_dataBuffer.get()));
m_pdfDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get()));
pdfDocumentDidLoad();
}
void BuiltInPDFView::streamDidFail(uint64_t streamID, bool wasCancelled)
{
ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID);
m_dataBuffer.clear();
}
void BuiltInPDFView::manualStreamDidReceiveResponse(const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers)
{
}
void BuiltInPDFView::manualStreamDidReceiveData(const char* bytes, int length)
{
if (!m_dataBuffer)
m_dataBuffer.adoptCF(CFDataCreateMutable(0, 0));
CFDataAppendBytes(m_dataBuffer.get(), reinterpret_cast<const UInt8*>(bytes), length);
}
void BuiltInPDFView::manualStreamDidFinishLoading()
{
RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_dataBuffer.get()));
m_pdfDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get()));
pdfDocumentDidLoad();