blob: 92f96ffba497ab8a23fa4e105036c75dc394a08c [file] [log] [blame]
/*
* Copyright (C) 2011, 2012 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.
*/
#ifndef PDFPlugin_h
#define PDFPlugin_h
#if ENABLE(PDFKIT_PLUGIN)
#include "Plugin.h"
#include "WebEvent.h"
#include <WebCore/AffineTransform.h>
#include <WebCore/FindOptions.h>
#include <WebCore/ScrollableArea.h>
#include <wtf/RetainPtr.h>
typedef const struct OpaqueJSContext* JSContextRef;
typedef struct OpaqueJSValue* JSObjectRef;
typedef const struct OpaqueJSValue* JSValueRef;
OBJC_CLASS NSArray;
OBJC_CLASS NSAttributedString;
OBJC_CLASS NSData;
OBJC_CLASS NSString;
OBJC_CLASS PDFAnnotation;
OBJC_CLASS PDFLayerController;
OBJC_CLASS PDFSelection;
OBJC_CLASS WKPDFPluginAccessibilityObject;
OBJC_CLASS WKPDFLayerControllerDelegate;
namespace IPC {
class DataReference;
}
namespace WebCore {
class Element;
struct PluginInfo;
}
namespace WebKit {
class PDFPluginAnnotation;
class PDFPluginPasswordField;
class PluginView;
class WebFrame;
class PDFPlugin FINAL : public Plugin, private WebCore::ScrollableArea {
public:
static PassRefPtr<PDFPlugin> create(WebFrame*);
~PDFPlugin();
static WebCore::PluginInfo pluginInfo();
WebCore::IntSize size() const { return m_size; }
void didMutatePDFDocument() { m_pdfDocumentWasMutated = true; }
void paintControlForLayerInContext(CALayer *, CGContextRef);
void setActiveAnnotation(PDFAnnotation *);
using ScrollableArea::notifyScrollPositionChanged;
void notifyContentScaleFactorChanged(CGFloat scaleFactor);
void notifyDisplayModeChanged(int);
void notifySelectionChanged(PDFSelection *);
void clickedLink(NSURL *);
void saveToPDF();
void openWithNativeApplication();
void writeItemsToPasteboard(NSString *pasteboardName, NSArray *items, NSArray *types);
void showDefinitionForAttributedString(NSAttributedString *, CGPoint);
void performWebSearch(NSString *);
void performSpotlightSearch(NSString *);
void focusNextAnnotation();
void focusPreviousAnnotation();
void attemptToUnlockPDF(const String& password);
WebCore::FloatRect convertFromPDFViewToScreen(const WebCore::FloatRect&) const;
WebCore::IntRect boundsOnScreen() const;
bool showContextMenuAtPoint(const WebCore::IntPoint&);
private:
explicit PDFPlugin(WebFrame*);
// Plugin functions.
virtual bool initialize(const Parameters&);
virtual void destroy() OVERRIDE;
virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRectInWindowCoordinates) OVERRIDE { }
virtual void updateControlTints(WebCore::GraphicsContext*) OVERRIDE;
virtual bool supportsSnapshotting() const OVERRIDE { return true; }
virtual PassRefPtr<ShareableBitmap> snapshot() OVERRIDE;
virtual PlatformLayer* pluginLayer() OVERRIDE;
virtual bool isTransparent() OVERRIDE { return false; }
virtual bool wantsWheelEvents() OVERRIDE { return true; }
virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) OVERRIDE;
virtual void contentsScaleFactorChanged(float) OVERRIDE;
virtual void visibilityDidChange() OVERRIDE { }
virtual void frameDidFinishLoading(uint64_t requestID) OVERRIDE;
virtual void frameDidFail(uint64_t requestID, bool wasCancelled) OVERRIDE;
virtual void didEvaluateJavaScript(uint64_t requestID, const String& result) OVERRIDE;
virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) OVERRIDE;
virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) OVERRIDE;
virtual void streamDidFinishLoading(uint64_t streamID) OVERRIDE;
virtual void streamDidFail(uint64_t streamID, bool wasCancelled) OVERRIDE;
virtual void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& suggestedFileName) OVERRIDE;
virtual void manualStreamDidReceiveData(const char* bytes, int length) OVERRIDE;
virtual void manualStreamDidFinishLoading() OVERRIDE;
virtual void manualStreamDidFail(bool wasCancelled) OVERRIDE;
virtual bool handleMouseEvent(const WebMouseEvent&) OVERRIDE;
virtual bool handleWheelEvent(const WebWheelEvent&) OVERRIDE;
virtual bool handleMouseEnterEvent(const WebMouseEvent&) OVERRIDE;
virtual bool handleMouseLeaveEvent(const WebMouseEvent&) OVERRIDE;
virtual bool handleContextMenuEvent(const WebMouseEvent&) OVERRIDE;
virtual bool handleKeyboardEvent(const WebKeyboardEvent&) OVERRIDE;
virtual bool handleEditingCommand(const String& commandName, const String& argument) OVERRIDE;
virtual bool isEditingCommandEnabled(const String&) OVERRIDE;
virtual bool handlesPageScaleFactor() OVERRIDE;
virtual void setFocus(bool) OVERRIDE { }
virtual NPObject* pluginScriptableNPObject() OVERRIDE { return 0; }
virtual void windowFocusChanged(bool) OVERRIDE { }
virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) OVERRIDE { }
virtual void windowVisibilityChanged(bool) OVERRIDE { }
virtual uint64_t pluginComplexTextInputIdentifier() const OVERRIDE { return 0; }
virtual void sendComplexTextInput(const String& textInput) OVERRIDE { }
virtual void setLayerHostingMode(LayerHostingMode) OVERRIDE { }
virtual WebCore::Scrollbar* horizontalScrollbar() OVERRIDE { return m_horizontalScrollbar.get(); }
virtual WebCore::Scrollbar* verticalScrollbar() OVERRIDE { return m_verticalScrollbar.get(); }
virtual void storageBlockingStateChanged(bool) OVERRIDE { }
virtual void privateBrowsingStateChanged(bool) OVERRIDE { }
virtual bool getFormValue(String& formValue) OVERRIDE { return false; }
virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) OVERRIDE;
virtual PassRefPtr<WebCore::SharedBuffer> liveResourceData() const OVERRIDE;
virtual bool isBeingAsynchronouslyInitialized() const OVERRIDE { return false; }
virtual RetainPtr<PDFDocument> pdfDocumentForPrinting() const OVERRIDE { return m_pdfDocument; }
virtual NSObject *accessibilityObject() const OVERRIDE;
virtual unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;
virtual bool findString(const String& target, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;
PDFSelection *nextMatchForString(const String& target, BOOL searchForward, BOOL caseSensitive, BOOL wrapSearch, PDFSelection *initialSelection, BOOL startInSelection);
virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) OVERRIDE;
virtual String getSelectionString() const OVERRIDE;
virtual bool shouldAllowScripting() OVERRIDE { return false; }
virtual bool shouldAllowNavigationFromDrags() OVERRIDE { return true; }
virtual bool shouldAlwaysAutoStart() const OVERRIDE { return true; }
// ScrollableArea functions.
virtual WebCore::IntRect scrollCornerRect() const OVERRIDE;
virtual WebCore::ScrollableArea* enclosingScrollableArea() const OVERRIDE;
virtual WebCore::IntRect scrollableAreaBoundingBox() const OVERRIDE;
virtual void setScrollOffset(const WebCore::IntPoint&) OVERRIDE;
virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&) OVERRIDE;
virtual void invalidateScrollCornerRect(const WebCore::IntRect&) OVERRIDE;
virtual WebCore::IntPoint lastKnownMousePosition() const OVERRIDE { return m_lastMousePositionInPluginCoordinates; }
virtual int scrollSize(WebCore::ScrollbarOrientation) const OVERRIDE;
virtual bool isActive() const OVERRIDE;
virtual bool isScrollCornerVisible() const OVERRIDE { return false; }
virtual int scrollPosition(WebCore::Scrollbar*) const OVERRIDE;
virtual WebCore::IntPoint scrollPosition() const OVERRIDE;
virtual WebCore::IntPoint minimumScrollPosition() const OVERRIDE;
virtual WebCore::IntPoint maximumScrollPosition() const OVERRIDE;
virtual int visibleHeight() const OVERRIDE { return m_size.height(); }
virtual int visibleWidth() const OVERRIDE { return m_size.width(); }
virtual WebCore::IntSize contentsSize() const OVERRIDE { return m_pdfDocumentSize; }
virtual WebCore::Scrollbar* horizontalScrollbar() const OVERRIDE { return m_horizontalScrollbar.get(); }
virtual WebCore::Scrollbar* verticalScrollbar() const OVERRIDE { return m_verticalScrollbar.get(); }
virtual bool shouldSuspendScrollAnimations() const OVERRIDE { return false; } // If we return true, ScrollAnimatorMac will keep cycling a timer forever, waiting for a good time to animate.
virtual void scrollbarStyleChanged(int newStyle, bool forceUpdate) OVERRIDE;
virtual WebCore::IntRect convertFromScrollbarToContainingView(const WebCore::Scrollbar*, const WebCore::IntRect& scrollbarRect) const OVERRIDE;
virtual WebCore::IntRect convertFromContainingViewToScrollbar(const WebCore::Scrollbar*, const WebCore::IntRect& parentRect) const OVERRIDE;
virtual WebCore::IntPoint convertFromScrollbarToContainingView(const WebCore::Scrollbar*, const WebCore::IntPoint& scrollbarPoint) const OVERRIDE;
virtual WebCore::IntPoint convertFromContainingViewToScrollbar(const WebCore::Scrollbar*, const WebCore::IntPoint& parentPoint) const OVERRIDE;
virtual bool updatesScrollLayerPositionOnMainThread() const OVERRIDE { return true; }
// PDFPlugin functions.
void updateScrollbars();
PassRefPtr<WebCore::Scrollbar> createScrollbar(WebCore::ScrollbarOrientation);
void destroyScrollbar(WebCore::ScrollbarOrientation);
void pdfDocumentDidLoad();
void addArchiveResource();
void computePageBoxes();
void calculateSizes();
void runScriptsInPDFDocument();
NSEvent *nsEventForWebMouseEvent(const WebMouseEvent&);
WebCore::IntPoint convertFromPluginToPDFView(const WebCore::IntPoint&) const;
WebCore::IntPoint convertFromRootViewToPlugin(const WebCore::IntPoint&) const;
WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const;
bool supportsForms();
bool isFullFramePlugin();
void updatePageAndDeviceScaleFactors();
void createPasswordEntryForm();
RetainPtr<PDFDocument> pdfDocument() const { return m_pdfDocument; }
void setPDFDocument(RetainPtr<PDFDocument> document) { m_pdfDocument = document; }
WebCore::IntSize pdfDocumentSize() const { return m_pdfDocumentSize; }
void setPDFDocumentSize(WebCore::IntSize size) { m_pdfDocumentSize = size; }
NSData *liveData() const;
NSData *rawData() const { return (NSData *)m_data.get(); }
WebFrame* webFrame() const { return m_frame; }
enum UpdateCursorMode {
UpdateIfNeeded,
ForceUpdate
};
enum HitTestResult {
None,
Text
};
void updateCursor(const WebMouseEvent&, UpdateCursorMode = UpdateIfNeeded);
JSObjectRef makeJSPDFDoc(JSContextRef);
static JSValueRef jsPDFDocPrint(JSContextRef, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
void convertPostScriptDataIfNeeded();
// Regular plug-ins don't need access to view, but we add scrollbars to embedding FrameView for proper event handling.
PluginView* pluginView();
const PluginView* pluginView() const;
WebFrame* m_frame;
bool m_isPostScript;
bool m_pdfDocumentWasMutated;
WebCore::IntSize m_scrollOffset;
RetainPtr<CALayer> m_containerLayer;
RetainPtr<CALayer> m_contentLayer;
RetainPtr<CALayer> m_horizontalScrollbarLayer;
RetainPtr<CALayer> m_verticalScrollbarLayer;
RetainPtr<CALayer> m_scrollCornerLayer;
RetainPtr<PDFLayerController> m_pdfLayerController;
RetainPtr<WKPDFPluginAccessibilityObject> m_accessibilityObject;
RefPtr<PDFPluginAnnotation> m_activeAnnotation;
RefPtr<PDFPluginPasswordField> m_passwordField;
RefPtr<WebCore::Element> m_annotationContainer;
WebCore::AffineTransform m_rootViewToPluginTransform;
WebMouseEvent m_lastMouseEvent;
WebCore::IntPoint m_lastMousePositionInPluginCoordinates;
String m_temporaryPDFUUID;
String m_lastFoundString;
HitTestResult m_lastHitTestResult;
RetainPtr<WKPDFLayerControllerDelegate> m_pdfLayerControllerDelegate;
WebCore::IntSize m_size;
WebCore::URL m_sourceURL;
String m_suggestedFilename;
RetainPtr<CFMutableDataRef> m_data;
RetainPtr<PDFDocument> m_pdfDocument;
Vector<WebCore::IntRect> m_pageBoxes;
WebCore::IntSize m_pdfDocumentSize; // All pages, including gaps.
RefPtr<WebCore::Scrollbar> m_horizontalScrollbar;
RefPtr<WebCore::Scrollbar> m_verticalScrollbar;
};
} // namespace WebKit
#endif // ENABLE(PDFKIT_PLUGIN)
#endif // PDFPlugin_h