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(NSString *pasteboardName, 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&) override;
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(bool) 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 bool isScrollableOrRubberbandable() override { return true; }
179 virtual bool hasScrollableOrRubberbandableAncestor() override { return true; }
180 virtual WebCore::IntRect scrollableAreaBoundingBox() const override;
181 virtual void setScrollOffset(const WebCore::IntPoint&) override;
182 virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&) override;
183 virtual void invalidateScrollCornerRect(const WebCore::IntRect&) override;
184 virtual WebCore::IntPoint lastKnownMousePosition() const override { return m_lastMousePositionInPluginCoordinates; }
185 virtual int scrollSize(WebCore::ScrollbarOrientation) const override;
186 virtual bool isActive() const override;
187 virtual bool isScrollCornerVisible() const override { return false; }
188 virtual int scrollPosition(WebCore::Scrollbar*) const override;
189 virtual WebCore::IntPoint scrollPosition() const override;
190 virtual WebCore::IntPoint minimumScrollPosition() const override;
191 virtual WebCore::IntPoint maximumScrollPosition() const override;
192 virtual WebCore::IntSize visibleSize() const override { return m_size; }
193 virtual WebCore::IntSize contentsSize() const override { return m_pdfDocumentSize; }
194 virtual WebCore::Scrollbar* horizontalScrollbar() const override { return m_horizontalScrollbar.get(); }
195 virtual WebCore::Scrollbar* verticalScrollbar() const override { return m_verticalScrollbar.get(); }
196 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.
197 virtual void scrollbarStyleChanged(int newStyle, bool forceUpdate) override;
198 virtual WebCore::IntRect convertFromScrollbarToContainingView(const WebCore::Scrollbar*, const WebCore::IntRect& scrollbarRect) const override;
199 virtual WebCore::IntRect convertFromContainingViewToScrollbar(const WebCore::Scrollbar*, const WebCore::IntRect& parentRect) const override;
200 virtual WebCore::IntPoint convertFromScrollbarToContainingView(const WebCore::Scrollbar*, const WebCore::IntPoint& scrollbarPoint) const override;
201 virtual WebCore::IntPoint convertFromContainingViewToScrollbar(const WebCore::Scrollbar*, const WebCore::IntPoint& parentPoint) const override;
202 virtual bool updatesScrollLayerPositionOnMainThread() const override { return true; }
203 virtual bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override;
205 // PDFPlugin functions.
206 void updateScrollbars();
207 PassRefPtr<WebCore::Scrollbar> createScrollbar(WebCore::ScrollbarOrientation);
208 void destroyScrollbar(WebCore::ScrollbarOrientation);
209 void pdfDocumentDidLoad();
210 void addArchiveResource();
211 void computePageBoxes();
212 void calculateSizes();
213 void runScriptsInPDFDocument();
215 NSEvent *nsEventForWebMouseEvent(const WebMouseEvent&);
216 WebCore::IntPoint convertFromPluginToPDFView(const WebCore::IntPoint&) const;
217 WebCore::IntPoint convertFromRootViewToPlugin(const WebCore::IntPoint&) const;
218 WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const;
220 bool supportsForms();
221 bool isFullFramePlugin();
223 void updatePageAndDeviceScaleFactors();
225 void createPasswordEntryForm();
227 RetainPtr<PDFDocument> pdfDocument() const { return m_pdfDocument; }
228 void setPDFDocument(RetainPtr<PDFDocument> document) { m_pdfDocument = document; }
230 WebCore::IntSize pdfDocumentSize() const { return m_pdfDocumentSize; }
231 void setPDFDocumentSize(WebCore::IntSize size) { m_pdfDocumentSize = size; }
233 NSData *liveData() const;
234 NSData *rawData() const { return (NSData *)m_data.get(); }
236 WebFrame* webFrame() const { return m_frame; }
238 enum UpdateCursorMode {
248 void updateCursor(const WebMouseEvent&, UpdateCursorMode = UpdateIfNeeded);
250 JSObjectRef makeJSPDFDoc(JSContextRef);
251 static JSValueRef jsPDFDocPrint(JSContextRef, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
253 void convertPostScriptDataIfNeeded();
255 // Regular plug-ins don't need access to view, but we add scrollbars to embedding FrameView for proper event handling.
256 PluginView* pluginView();
257 const PluginView* pluginView() const;
262 bool m_pdfDocumentWasMutated;
264 WebCore::IntSize m_scrollOffset;
266 RetainPtr<CALayer> m_containerLayer;
267 RetainPtr<CALayer> m_contentLayer;
268 RetainPtr<CALayer> m_horizontalScrollbarLayer;
269 RetainPtr<CALayer> m_verticalScrollbarLayer;
270 RetainPtr<CALayer> m_scrollCornerLayer;
271 RetainPtr<PDFLayerController> m_pdfLayerController;
272 RetainPtr<WKPDFPluginAccessibilityObject> m_accessibilityObject;
274 RefPtr<PDFPluginAnnotation> m_activeAnnotation;
275 RefPtr<PDFPluginPasswordField> m_passwordField;
276 RefPtr<WebCore::Element> m_annotationContainer;
278 WebCore::AffineTransform m_rootViewToPluginTransform;
279 WebMouseEvent m_lastMouseEvent;
280 WebCore::IntPoint m_lastMousePositionInPluginCoordinates;
282 String m_temporaryPDFUUID;
284 String m_lastFoundString;
286 HitTestResult m_lastHitTestResult;
288 RetainPtr<WKPDFLayerControllerDelegate> m_pdfLayerControllerDelegate;
290 WebCore::IntSize m_size;
292 WebCore::URL m_sourceURL;
294 String m_suggestedFilename;
295 RetainPtr<CFMutableDataRef> m_data;
297 RetainPtr<PDFDocument> m_pdfDocument;
298 Vector<WebCore::IntRect> m_pageBoxes;
299 WebCore::IntSize m_pdfDocumentSize; // All pages, including gaps.
301 RefPtr<WebCore::Scrollbar> m_horizontalScrollbar;
302 RefPtr<WebCore::Scrollbar> m_verticalScrollbar;
305 } // namespace WebKit
307 #endif // ENABLE(PDFKIT_PLUGIN)
309 #endif // PDFPlugin_h