2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
29 #if ENABLE(PDFKIT_PLUGIN)
33 #include <WebCore/AffineTransform.h>
34 #include <WebCore/FindOptions.h>
35 #include <WebCore/ScrollableArea.h>
36 #include <wtf/RetainPtr.h>
38 typedef const struct OpaqueJSContext* JSContextRef;
39 typedef struct OpaqueJSValue* JSObjectRef;
40 typedef const struct OpaqueJSValue* JSValueRef;
43 OBJC_CLASS NSAttributedString;
46 OBJC_CLASS PDFAnnotation;
47 OBJC_CLASS PDFLayerController;
48 OBJC_CLASS PDFSelection;
49 OBJC_CLASS WKPDFPluginAccessibilityObject;
50 OBJC_CLASS WKPDFLayerControllerDelegate;
63 class PDFPluginAnnotation;
64 class PDFPluginPasswordField;
68 class PDFPlugin FINAL : public Plugin, private WebCore::ScrollableArea {
70 static PassRefPtr<PDFPlugin> create(WebFrame*);
73 static WebCore::PluginInfo pluginInfo();
75 WebCore::IntSize size() const { return m_size; }
77 void didMutatePDFDocument() { m_pdfDocumentWasMutated = true; }
79 void paintControlForLayerInContext(CALayer *, CGContextRef);
80 void setActiveAnnotation(PDFAnnotation *);
82 using ScrollableArea::notifyScrollPositionChanged;
83 void notifyContentScaleFactorChanged(CGFloat scaleFactor);
84 void notifyDisplayModeChanged(int);
86 void notifySelectionChanged(PDFSelection *);
88 void clickedLink(NSURL *);
90 void openWithNativeApplication();
91 void writeItemsToPasteboard(NSArray *items, NSArray *types);
92 void showDefinitionForAttributedString(NSAttributedString *, CGPoint);
93 void performWebSearch(NSString *);
94 void performSpotlightSearch(NSString *);
96 void focusNextAnnotation();
97 void focusPreviousAnnotation();
99 void attemptToUnlockPDF(const String& password);
101 WebCore::FloatRect convertFromPDFViewToScreen(const WebCore::FloatRect&) const;
102 WebCore::IntRect boundsOnScreen() const;
104 bool showContextMenuAtPoint(const WebCore::IntPoint&);
107 explicit PDFPlugin(WebFrame*);
110 virtual bool initialize(const Parameters&);
111 virtual void destroy() OVERRIDE;
112 virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRectInWindowCoordinates) OVERRIDE { }
113 virtual void updateControlTints(WebCore::GraphicsContext*) OVERRIDE;
114 virtual bool supportsSnapshotting() const OVERRIDE { return true; }
115 virtual PassRefPtr<ShareableBitmap> snapshot() OVERRIDE;
116 virtual PlatformLayer* pluginLayer() OVERRIDE;
117 virtual bool isTransparent() OVERRIDE { return false; }
118 virtual bool wantsWheelEvents() OVERRIDE { return true; }
119 virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) OVERRIDE;
120 virtual void contentsScaleFactorChanged(float) OVERRIDE;
121 virtual void visibilityDidChange() OVERRIDE { }
122 virtual void frameDidFinishLoading(uint64_t requestID) OVERRIDE;
123 virtual void frameDidFail(uint64_t requestID, bool wasCancelled) OVERRIDE;
124 virtual void didEvaluateJavaScript(uint64_t requestID, const String& result) OVERRIDE;
125 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;
126 virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) OVERRIDE;
127 virtual void streamDidFinishLoading(uint64_t streamID) OVERRIDE;
128 virtual void streamDidFail(uint64_t streamID, bool wasCancelled) OVERRIDE;
129 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;
130 virtual void manualStreamDidReceiveData(const char* bytes, int length) OVERRIDE;
131 virtual void manualStreamDidFinishLoading() OVERRIDE;
132 virtual void manualStreamDidFail(bool wasCancelled) OVERRIDE;
133 virtual bool handleMouseEvent(const WebMouseEvent&) OVERRIDE;
134 virtual bool handleWheelEvent(const WebWheelEvent&) OVERRIDE;
135 virtual bool handleMouseEnterEvent(const WebMouseEvent&) OVERRIDE;
136 virtual bool handleMouseLeaveEvent(const WebMouseEvent&) OVERRIDE;
137 virtual bool handleContextMenuEvent(const WebMouseEvent&) OVERRIDE;
138 virtual bool handleKeyboardEvent(const WebKeyboardEvent&) OVERRIDE;
139 virtual bool handleEditingCommand(const String& commandName, const String& argument) OVERRIDE;
140 virtual bool isEditingCommandEnabled(const String&) OVERRIDE;
141 virtual bool handlesPageScaleFactor() OVERRIDE;
142 virtual void setFocus(bool) OVERRIDE { }
143 virtual NPObject* pluginScriptableNPObject() OVERRIDE { return 0; }
144 virtual void windowFocusChanged(bool) OVERRIDE { }
145 virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) OVERRIDE { }
146 virtual void windowVisibilityChanged(bool) OVERRIDE { }
147 virtual uint64_t pluginComplexTextInputIdentifier() const OVERRIDE { return 0; }
148 virtual void sendComplexTextInput(const String& textInput) OVERRIDE { }
149 virtual void setLayerHostingMode(LayerHostingMode) OVERRIDE { }
150 virtual WebCore::Scrollbar* horizontalScrollbar() OVERRIDE { return m_horizontalScrollbar.get(); }
151 virtual WebCore::Scrollbar* verticalScrollbar() OVERRIDE { return m_verticalScrollbar.get(); }
152 virtual void storageBlockingStateChanged(bool) OVERRIDE { }
153 virtual void privateBrowsingStateChanged(bool) OVERRIDE { }
154 virtual bool getFormValue(String& formValue) OVERRIDE { return false; }
155 virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) OVERRIDE;
156 virtual PassRefPtr<WebCore::SharedBuffer> liveResourceData() const OVERRIDE;
158 virtual bool isBeingAsynchronouslyInitialized() const OVERRIDE { return false; }
160 virtual RetainPtr<PDFDocument> pdfDocumentForPrinting() const OVERRIDE { return m_pdfDocument; }
161 virtual NSObject *accessibilityObject() const OVERRIDE;
163 virtual unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;
164 virtual bool findString(const String& target, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;
166 PDFSelection *nextMatchForString(const String& target, BOOL searchForward, BOOL caseSensitive, BOOL wrapSearch, PDFSelection *initialSelection, BOOL startInSelection);
168 virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) OVERRIDE;
169 virtual String getSelectionString() const OVERRIDE;
171 virtual bool shouldAllowScripting() OVERRIDE { return false; }
172 virtual bool shouldAllowNavigationFromDrags() OVERRIDE { return true; }
173 virtual bool shouldAlwaysAutoStart() const OVERRIDE { return true; }
175 // ScrollableArea functions.
176 virtual WebCore::IntRect scrollCornerRect() const OVERRIDE;
177 virtual WebCore::ScrollableArea* enclosingScrollableArea() const OVERRIDE;
178 virtual WebCore::IntRect scrollableAreaBoundingBox() const OVERRIDE;
179 virtual void setScrollOffset(const WebCore::IntPoint&) OVERRIDE;
180 virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&) OVERRIDE;
181 virtual void invalidateScrollCornerRect(const WebCore::IntRect&) OVERRIDE;
182 virtual WebCore::IntPoint lastKnownMousePosition() const OVERRIDE { return m_lastMousePositionInPluginCoordinates; }
183 virtual int scrollSize(WebCore::ScrollbarOrientation) const OVERRIDE;
184 virtual bool isActive() const OVERRIDE;
185 virtual bool isScrollCornerVisible() const OVERRIDE { return false; }
186 virtual int scrollPosition(WebCore::Scrollbar*) const OVERRIDE;
187 virtual WebCore::IntPoint scrollPosition() const OVERRIDE;
188 virtual WebCore::IntPoint minimumScrollPosition() const OVERRIDE;
189 virtual WebCore::IntPoint maximumScrollPosition() const OVERRIDE;
190 virtual int visibleHeight() const OVERRIDE { return m_size.height(); }
191 virtual int visibleWidth() const OVERRIDE { return m_size.width(); }
192 virtual WebCore::IntSize contentsSize() const OVERRIDE { return m_pdfDocumentSize; }
193 virtual WebCore::Scrollbar* horizontalScrollbar() const OVERRIDE { return m_horizontalScrollbar.get(); }
194 virtual WebCore::Scrollbar* verticalScrollbar() const OVERRIDE { return m_verticalScrollbar.get(); }
195 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.
196 virtual void scrollbarStyleChanged(int newStyle, bool forceUpdate) OVERRIDE;
197 virtual WebCore::IntRect convertFromScrollbarToContainingView(const WebCore::Scrollbar*, const WebCore::IntRect& scrollbarRect) const OVERRIDE;
198 virtual WebCore::IntRect convertFromContainingViewToScrollbar(const WebCore::Scrollbar*, const WebCore::IntRect& parentRect) const OVERRIDE;
199 virtual WebCore::IntPoint convertFromScrollbarToContainingView(const WebCore::Scrollbar*, const WebCore::IntPoint& scrollbarPoint) const OVERRIDE;
200 virtual WebCore::IntPoint convertFromContainingViewToScrollbar(const WebCore::Scrollbar*, const WebCore::IntPoint& parentPoint) const OVERRIDE;
202 // PDFPlugin functions.
203 void updateScrollbars();
204 PassRefPtr<WebCore::Scrollbar> createScrollbar(WebCore::ScrollbarOrientation);
205 void destroyScrollbar(WebCore::ScrollbarOrientation);
206 void pdfDocumentDidLoad();
207 void addArchiveResource();
208 void computePageBoxes();
209 void calculateSizes();
210 void runScriptsInPDFDocument();
212 NSEvent *nsEventForWebMouseEvent(const WebMouseEvent&);
213 WebCore::IntPoint convertFromPluginToPDFView(const WebCore::IntPoint&) const;
214 WebCore::IntPoint convertFromRootViewToPlugin(const WebCore::IntPoint&) const;
215 WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const;
217 bool supportsForms();
218 bool isFullFramePlugin();
220 void updatePageAndDeviceScaleFactors();
222 void createPasswordEntryForm();
224 RetainPtr<PDFDocument> pdfDocument() const { return m_pdfDocument; }
225 void setPDFDocument(RetainPtr<PDFDocument> document) { m_pdfDocument = document; }
227 WebCore::IntSize pdfDocumentSize() const { return m_pdfDocumentSize; }
228 void setPDFDocumentSize(WebCore::IntSize size) { m_pdfDocumentSize = size; }
230 NSData *liveData() const;
231 NSData *rawData() const { return (NSData *)m_data.get(); }
233 WebFrame* webFrame() const { return m_frame; }
235 enum UpdateCursorMode {
245 void updateCursor(const WebMouseEvent&, UpdateCursorMode = UpdateIfNeeded);
247 JSObjectRef makeJSPDFDoc(JSContextRef);
248 static JSValueRef jsPDFDocPrint(JSContextRef, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
250 void convertPostScriptDataIfNeeded();
252 // Regular plug-ins don't need access to view, but we add scrollbars to embedding FrameView for proper event handling.
253 PluginView* pluginView();
254 const PluginView* pluginView() const;
259 bool m_pdfDocumentWasMutated;
261 WebCore::IntSize m_scrollOffset;
263 RetainPtr<CALayer> m_containerLayer;
264 RetainPtr<CALayer> m_contentLayer;
265 RetainPtr<CALayer> m_horizontalScrollbarLayer;
266 RetainPtr<CALayer> m_verticalScrollbarLayer;
267 RetainPtr<CALayer> m_scrollCornerLayer;
268 RetainPtr<PDFLayerController> m_pdfLayerController;
269 RetainPtr<WKPDFPluginAccessibilityObject> m_accessibilityObject;
271 RefPtr<PDFPluginAnnotation> m_activeAnnotation;
272 RefPtr<PDFPluginPasswordField> m_passwordField;
273 RefPtr<WebCore::Element> m_annotationContainer;
275 WebCore::AffineTransform m_rootViewToPluginTransform;
276 WebMouseEvent m_lastMouseEvent;
277 WebCore::IntPoint m_lastMousePositionInPluginCoordinates;
279 String m_temporaryPDFUUID;
281 String m_lastFoundString;
283 HitTestResult m_lastHitTestResult;
285 RetainPtr<WKPDFLayerControllerDelegate> m_pdfLayerControllerDelegate;
287 WebCore::IntSize m_size;
289 WebCore::URL m_sourceURL;
291 String m_suggestedFilename;
292 RetainPtr<CFMutableDataRef> m_data;
294 RetainPtr<PDFDocument> m_pdfDocument;
295 Vector<WebCore::IntRect> m_pageBoxes;
296 WebCore::IntSize m_pdfDocumentSize; // All pages, including gaps.
298 RefPtr<WebCore::Scrollbar> m_horizontalScrollbar;
299 RefPtr<WebCore::Scrollbar> m_verticalScrollbar;
302 } // namespace WebKit
304 #endif // ENABLE(PDFKIT_PLUGIN)
306 #endif // PDFPlugin_h