Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
PDFPlugin: Find-in-page
https://bugs.webkit.org/show_bug.cgi?id=105710
<rdar://problem/12555331>

Reviewed by Alexey Proskuryakov.

Make use of PDFLayerController's find-in-page functionality to mimic WebKit's.
Add two Plugin methods, countFindMatches and findString, and make use of them
if attempting to find-in-page within a PluginDocument.

* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::NetscapePlugin::countFindMatches): Added. We don't support find-in-page for NetscapePlugin.
(WebKit::NetscapePlugin::findString): Added. We don't support find-in-page for NetscapePlugin.
* WebProcess/Plugins/Netscape/NetscapePlugin.h: Add countFindMatches and findString.
* WebProcess/Plugins/PDF/PDFLayerControllerDetails.h: Add requisite PDFLayerController interfaces.
* WebProcess/Plugins/PDF/PDFPlugin.h: Add countFindMatches, findString, and nextMatchForString,
as well as  storage for the most-recently-searched string.
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::writeItemsToPasteboard):
(WebKit::PDFPlugin::countFindMatches):
(WebKit::PDFPlugin::nextMatchForString):
(WebKit::PDFPlugin::findString):
* WebProcess/Plugins/PDF/SimplePDFPlugin.h: Add countFindMatches and findString.
* WebProcess/Plugins/Plugin.h: Add countFindMatches and findString.
* WebProcess/Plugins/PluginProxy.h: Add countFindMatches and findString, but since PDFPlugin
is in-process, we don't need to forward these calls to the PluginProcess.
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::countFindMatches): Forward countFindMatches to the plugin.
(WebKit::PluginView::findString): Forward findString to the plugin.
* WebProcess/Plugins/PluginView.h: Add countFindMatches and findString.
* WebProcess/WebPage/FindController.cpp:
(WebKit::pluginViewForFrame): If the given frame hosts a PluginDocument, grab its PluginView.
(WebKit::FindController::countStringMatches): Forward countStringMatches to PluginView if necessary.
(WebKit::FindController::updateFindUIAfterPageScroll): Only use unmarkAllTextMatches if we're using
ordinary find-in-page and don't have a plugin. If we have a plugin, disable our overlay, as it must
be handled by the plugin itself, and request the number of matches for the search from the plugin.
(WebKit::FindController::findString): If necessary, forward findString to the plugin.
(WebKit::FindController::hideFindUI): Hide the search highlight by searching for an empty string.


Canonical link: https://commits.webkit.org/123945@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@138461 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
hortont424 committed Dec 25, 2012
1 parent 1f23ac9 commit a2ade1e
Show file tree
Hide file tree
Showing 12 changed files with 235 additions and 11 deletions.
41 changes: 41 additions & 0 deletions Source/WebKit2/ChangeLog
@@ -1,3 +1,44 @@
2012-12-25 Tim Horton <timothy_horton@apple.com>

PDFPlugin: Find-in-page
https://bugs.webkit.org/show_bug.cgi?id=105710
<rdar://problem/12555331>

Reviewed by Alexey Proskuryakov.

Make use of PDFLayerController's find-in-page functionality to mimic WebKit's.
Add two Plugin methods, countFindMatches and findString, and make use of them
if attempting to find-in-page within a PluginDocument.

* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::NetscapePlugin::countFindMatches): Added. We don't support find-in-page for NetscapePlugin.
(WebKit::NetscapePlugin::findString): Added. We don't support find-in-page for NetscapePlugin.
* WebProcess/Plugins/Netscape/NetscapePlugin.h: Add countFindMatches and findString.
* WebProcess/Plugins/PDF/PDFLayerControllerDetails.h: Add requisite PDFLayerController interfaces.
* WebProcess/Plugins/PDF/PDFPlugin.h: Add countFindMatches, findString, and nextMatchForString,
as well as storage for the most-recently-searched string.
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::writeItemsToPasteboard):
(WebKit::PDFPlugin::countFindMatches):
(WebKit::PDFPlugin::nextMatchForString):
(WebKit::PDFPlugin::findString):
* WebProcess/Plugins/PDF/SimplePDFPlugin.h: Add countFindMatches and findString.
* WebProcess/Plugins/Plugin.h: Add countFindMatches and findString.
* WebProcess/Plugins/PluginProxy.h: Add countFindMatches and findString, but since PDFPlugin
is in-process, we don't need to forward these calls to the PluginProcess.
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::countFindMatches): Forward countFindMatches to the plugin.
(WebKit::PluginView::findString): Forward findString to the plugin.
* WebProcess/Plugins/PluginView.h: Add countFindMatches and findString.
* WebProcess/WebPage/FindController.cpp:
(WebKit::pluginViewForFrame): If the given frame hosts a PluginDocument, grab its PluginView.
(WebKit::FindController::countStringMatches): Forward countStringMatches to PluginView if necessary.
(WebKit::FindController::updateFindUIAfterPageScroll): Only use unmarkAllTextMatches if we're using
ordinary find-in-page and don't have a plugin. If we have a plugin, disable our overlay, as it must
be handled by the plugin itself, and request the number of matches for the search from the plugin.
(WebKit::FindController::findString): If necessary, forward findString to the plugin.
(WebKit::FindController::hideFindUI): Hide the search highlight by searching for an empty string.

2012-12-24 Laszlo Gombos <l.gombos@samsung.com>

Remove wtf/Platform.h includes from {c|cpp} files
Expand Down
10 changes: 10 additions & 0 deletions Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp
Expand Up @@ -958,6 +958,16 @@ NPObject* NetscapePlugin::pluginScriptableNPObject()

return scriptableNPObject;
}

unsigned NetscapePlugin::countFindMatches(const String&, WebCore::FindOptions, unsigned)
{
return 0;
}

bool NetscapePlugin::findString(const String&, WebCore::FindOptions, unsigned)
{
return false;
}

void NetscapePlugin::contentsScaleFactorChanged(float scaleFactor)
{
Expand Down
3 changes: 3 additions & 0 deletions Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h
Expand Up @@ -213,6 +213,9 @@ class NetscapePlugin : public Plugin {
virtual bool handlesPageScaleFactor() OVERRIDE;

virtual NPObject* pluginScriptableNPObject();

virtual unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;
virtual bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;

#if PLATFORM(MAC)
virtual void windowFocusChanged(bool);
Expand Down
Expand Up @@ -83,7 +83,12 @@

- (NSArray *)findString:(NSString *)string caseSensitive:(BOOL)isCaseSensitive highlightMatches:(BOOL)shouldHighlightMatches;

- (id)currentSelection;
- (PDFSelection *)currentSelection;
- (void)setCurrentSelection:(PDFSelection *)selection;
- (PDFSelection *)searchSelection;
- (void)setSearchSelection:(PDFSelection *)selection;
- (void)gotoSelection:(PDFSelection *)selection;

- (void)copySelection;
- (void)selectAll;

Expand Down
9 changes: 9 additions & 0 deletions Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h
Expand Up @@ -32,6 +32,7 @@
#include "SimplePDFPlugin.h"
#include "WebEvent.h"
#include <WebCore/AffineTransform.h>
#include <WebCore/FindOptions.h>
#include <WebCore/ScrollableArea.h>
#include <wtf/RetainPtr.h>

Expand All @@ -41,6 +42,7 @@ typedef const struct OpaqueJSValue* JSValueRef;

OBJC_CLASS PDFAnnotation;
OBJC_CLASS PDFLayerController;
OBJC_CLASS PDFSelection;
OBJC_CLASS WKPDFLayerControllerDelegate;

namespace CoreIPC {
Expand Down Expand Up @@ -97,6 +99,11 @@ class PDFPlugin : public SimplePDFPlugin {
virtual bool isEditingCommandEnabled(const String&) OVERRIDE;
virtual bool handlesPageScaleFactor() 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);

// ScrollableArea functions.
virtual void setScrollOffset(const WebCore::IntPoint&) OVERRIDE;
virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&) OVERRIDE;
Expand Down Expand Up @@ -129,6 +136,8 @@ class PDFPlugin : public SimplePDFPlugin {
WebCore::IntPoint m_lastMousePositionInPluginCoordinates;

String m_temporaryPDFUUID;

String m_lastFoundString;

RetainPtr<WKPDFLayerControllerDelegate> m_pdfLayerControllerDelegate;
};
Expand Down
92 changes: 91 additions & 1 deletion Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm
Expand Up @@ -828,7 +828,6 @@ static NSEventType eventTypeFromWebEvent(const WebEvent& event)
WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardBufferForType(NSGeneralPboard, type, handle, buffer->size()), 0);
}
}

}

IntPoint PDFPlugin::convertFromPDFViewToRootView(const IntPoint& point) const
Expand All @@ -849,6 +848,97 @@ static NSEventType eventTypeFromWebEvent(const WebEvent& event)
webFrame()->page()->send(Messages::WebPageProxy::DidPerformDictionaryLookup(attributedString, dictionaryPopupInfo));
}

unsigned PDFPlugin::countFindMatches(const String& target, WebCore::FindOptions options, unsigned maxMatchCount)
{
if (!target.length())
return 0;

int nsOptions = (options & FindOptionsCaseInsensitive) ? NSCaseInsensitiveSearch : 0;

return [[pdfDocument().get() findString:target withOptions:nsOptions] count];
}

PDFSelection *PDFPlugin::nextMatchForString(const String& target, BOOL searchForward, BOOL caseSensitive, BOOL wrapSearch, PDFSelection *initialSelection, BOOL startInSelection)
{
if (!target.length())
return nil;

NSStringCompareOptions options = 0;
if (!searchForward)
options |= NSBackwardsSearch;

if (!caseSensitive)
options |= NSCaseInsensitiveSearch;

PDFDocument *document = pdfDocument().get();

PDFSelection *selectionForInitialSearch = [initialSelection copy];
if (startInSelection) {
// Initially we want to include the selected text in the search. So we must modify the starting search
// selection to fit PDFDocument's search requirements: selection must have a length >= 1, begin before
// the current selection (if searching forwards) or after (if searching backwards).
int initialSelectionLength = [[initialSelection string] length];
if (searchForward) {
[selectionForInitialSearch extendSelectionAtStart:1];
[selectionForInitialSearch extendSelectionAtEnd:-initialSelectionLength];
} else {
[selectionForInitialSearch extendSelectionAtEnd:1];
[selectionForInitialSearch extendSelectionAtStart:-initialSelectionLength];
}
}

PDFSelection *foundSelection = [document findString:target fromSelection:selectionForInitialSearch withOptions:options];
[selectionForInitialSearch release];

// If we first searched in the selection, and we found the selection, search again from just past the selection.
if (startInSelection && [foundSelection isEqual:initialSelection])
foundSelection = [document findString:target fromSelection:initialSelection withOptions:options];

if (!foundSelection && wrapSearch)
foundSelection = [document findString:target fromSelection:nil withOptions:options];

return foundSelection;
}

bool PDFPlugin::findString(const String& target, WebCore::FindOptions options, unsigned maxMatchCount)
{
BOOL searchForward = !(options & FindOptionsBackwards);
BOOL caseSensitive = !(options & FindOptionsCaseInsensitive);
BOOL wrapSearch = options & FindOptionsWrapAround;

unsigned matchCount;
if (!maxMatchCount) {
// If the max was zero, any result means we exceeded the max. We can skip computing the actual count.
matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount);
} else {
matchCount = countFindMatches(target, options, maxMatchCount);
if (matchCount > maxMatchCount)
matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount);
}

if (target.isEmpty()) {
PDFSelection* searchSelection = [m_pdfLayerController.get() searchSelection];
[m_pdfLayerController.get() findString:target caseSensitive:caseSensitive highlightMatches:YES];
[m_pdfLayerController.get() setSearchSelection:searchSelection];
m_lastFoundString = emptyString();
return false;
}

if (m_lastFoundString == target) {
PDFSelection *selection = nextMatchForString(target, searchForward, caseSensitive, wrapSearch, [m_pdfLayerController.get() searchSelection], NO);
if (!selection)
return false;

[m_pdfLayerController.get() setSearchSelection:selection];
[m_pdfLayerController.get() gotoSelection:selection];
} else {
[m_pdfLayerController.get() findString:target caseSensitive:caseSensitive highlightMatches:YES];
m_lastFoundString = target;
}

return matchCount > 0;
}

} // namespace WebKit

#endif // ENABLE(PDFKIT_PLUGIN)
3 changes: 3 additions & 0 deletions Source/WebKit2/WebProcess/Plugins/PDF/SimplePDFPlugin.h
Expand Up @@ -174,6 +174,9 @@ class SimplePDFPlugin : public Plugin, protected WebCore::ScrollableArea {
virtual bool shouldAllowScripting() OVERRIDE { return false; }
virtual bool shouldAllowNavigationFromDrags() { return true; }

virtual unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned) OVERRIDE { return 0; }
virtual bool findString(const String&, WebCore::FindOptions, unsigned) OVERRIDE { return false; }

WebCore::IntSize m_scrollOffset;

private:
Expand Down
5 changes: 5 additions & 0 deletions Source/WebKit2/WebProcess/Plugins/Plugin.h
Expand Up @@ -26,6 +26,7 @@
#ifndef Plugin_h
#define Plugin_h

#include <WebCore/FindOptions.h>
#include <WebCore/GraphicsLayer.h>
#include <WebCore/KURL.h>
#include <WebCore/ScrollTypes.h>
Expand Down Expand Up @@ -254,6 +255,10 @@ class Plugin : public ThreadSafeRefCounted<Plugin> {
virtual RetainPtr<PDFDocument> pdfDocumentForPrinting() const { return 0; }
#endif

virtual unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount) = 0;

virtual bool findString(const String& target, WebCore::FindOptions, unsigned maxMatchCount) = 0;

virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint& pointInLocalCoordinates) const;

virtual bool shouldAlwaysAutoStart() const { return false; }
Expand Down
4 changes: 4 additions & 0 deletions Source/WebKit2/WebProcess/Plugins/PluginProxy.h
Expand Up @@ -32,6 +32,7 @@
#include "Plugin.h"
#include "PluginProcess.h"
#include <WebCore/AffineTransform.h>
#include <WebCore/FindOptions.h>
#include <WebCore/IntRect.h>
#include <WebCore/SecurityOrigin.h>

Expand Down Expand Up @@ -127,6 +128,9 @@ class PluginProxy : public Plugin {
virtual WebCore::Scrollbar* horizontalScrollbar();
virtual WebCore::Scrollbar* verticalScrollbar();

virtual unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned) OVERRIDE { return 0; }
virtual bool findString(const String&, WebCore::FindOptions, unsigned) OVERRIDE { return false; }

virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const OVERRIDE;

float contentsScaleFactor();
Expand Down
10 changes: 10 additions & 0 deletions Source/WebKit2/WebProcess/Plugins/PluginView.cpp
Expand Up @@ -736,6 +736,16 @@ void PluginView::setParent(ScrollView* scrollView)
initializePlugin();
}

unsigned PluginView::countFindMatches(const String& target, WebCore::FindOptions options, unsigned maxMatchCount)
{
return m_plugin->countFindMatches(target, options, maxMatchCount);
}

bool PluginView::findString(const String& target, WebCore::FindOptions options, unsigned maxMatchCount)
{
return m_plugin->findString(target, options, maxMatchCount);
}

PassOwnPtr<WebEvent> PluginView::createWebEvent(MouseEvent* event) const
{
WebEvent::Type type = WebEvent::NoType;
Expand Down
8 changes: 6 additions & 2 deletions Source/WebKit2/WebProcess/Plugins/PluginView.h
Expand Up @@ -30,6 +30,7 @@
#include "Plugin.h"
#include "PluginController.h"
#include "WebFrame.h"
#include <WebCore/FindOptions.h>
#include <WebCore/Image.h>
#include <WebCore/MediaCanStartListener.h>
#include <WebCore/PluginViewBase.h>
Expand Down Expand Up @@ -90,8 +91,11 @@ class PluginView : public WebCore::PluginViewBase, public PluginController, priv
void pageScaleFactorDidChange();
void webPageDestroyed();

virtual bool handleEditingCommand(const String& commandName, const String& argument);
virtual bool isEditingCommandEnabled(const String& commandName);
bool handleEditingCommand(const String& commandName, const String& argument);
bool isEditingCommandEnabled(const String& commandName);

unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount);
bool findString(const String& target, WebCore::FindOptions, unsigned maxMatchCount);

bool shouldAllowScripting();

Expand Down

0 comments on commit a2ade1e

Please sign in to comment.