Diff
Modified: branches/safari-600.3-branch/Source/WebCore/ChangeLog (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebCore/ChangeLog 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebCore/ChangeLog 2014-10-29 20:26:40 UTC (rev 175340)
@@ -1,3 +1,22 @@
+2014-08-29 Matthew Hanson <[email protected]>
+
+ Merge r175335. rdar://problem/18709436
+
+ 2014-10-29 Tim Horton <[email protected]>
+
+ Implement action menus for data detected items
+ https://bugs.webkit.org/show_bug.cgi?id=138178
+ <rdar://problem/18709436>
+
+ Reviewed by Anders Carlsson.
+
+ * WebCore.exp.in:
+ Export a symbol from Position that we need.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/spi/mac/DataDetectorsSPI.h:
+ Add a combined SPI header for all of the random bits of DataDetectors that we use.
+
2014-10-29 Lucas Forschler <[email protected]>
Merge r175147
Modified: branches/safari-600.3-branch/Source/WebCore/WebCore.exp.in (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebCore/WebCore.exp.in 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebCore/WebCore.exp.in 2014-10-29 20:26:40 UTC (rev 175340)
@@ -1334,6 +1334,7 @@
__ZN7WebCore8Gradient12addColorStopEfRKNS_5ColorE
__ZN7WebCore8GradientC1ERKNS_10FloatPointES3_
__ZN7WebCore8GradientD1Ev
+__ZN7WebCore8PositionC1EN3WTF10PassRefPtrINS_4NodeEEENS0_19LegacyEditingOffsetE
__ZN7WebCore8PositionC1EN3WTF10PassRefPtrINS_4NodeEEEiNS0_10AnchorTypeE
__ZN7WebCore8Settings13gQTKitEnabledE
__ZN7WebCore8Settings14setJavaEnabledEb
Modified: branches/safari-600.3-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2014-10-29 20:26:40 UTC (rev 175340)
@@ -1089,6 +1089,7 @@
2D481F02146B5C5500AA7834 /* CrossfadeGeneratedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2FC0551460CD6F00263633 /* CrossfadeGeneratedImage.h */; };
2D481F03146B5C6500AA7834 /* GradientImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D2FC0561460CD6F00263633 /* GradientImage.cpp */; };
2D481F04146B5C6B00AA7834 /* GradientImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2FC0571460CD6F00263633 /* GradientImage.h */; };
+ 2D59F1BF1A0044C6001F3D29 /* DataDetectorsSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D59F1BE1A0044C6001F3D29 /* DataDetectorsSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D5A592F152525230036EE51 /* ImageOrientation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */; };
2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = A8748D6612CC3763001FBA41 /* ImageOrientation.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */; };
@@ -8103,6 +8104,7 @@
2D3EF4471917915C00034184 /* WebCoreCALayerExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreCALayerExtras.mm; sourceTree = "<group>"; };
2D46F04D17B96FBD005647F0 /* IntPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntPoint.cpp; sourceTree = "<group>"; };
2D46F04F17B96FD2005647F0 /* IntSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntSize.cpp; sourceTree = "<group>"; };
+ 2D59F1BE1A0044C6001F3D29 /* DataDetectorsSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataDetectorsSPI.h; sourceTree = "<group>"; };
2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityPolicyViolationEvent.h; sourceTree = "<group>"; };
2D5BC42616F882BE007048D0 /* SecurityPolicyViolationEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SecurityPolicyViolationEvent.idl; sourceTree = "<group>"; };
2D5C9CFB19C7B52E00B3C5C1 /* PageOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageOverlay.cpp; sourceTree = "<group>"; };
@@ -17618,6 +17620,7 @@
9348428019F1A9190009D5AE /* mac */ = {
isa = PBXGroup;
children = (
+ 2D59F1BE1A0044C6001F3D29 /* DataDetectorsSPI.h */,
2DCB837719F99BBA00A7FBE4 /* NSSharingServicePickerSPI.h */,
2DCB837819F99BBA00A7FBE4 /* NSSharingServiceSPI.h */,
9348428119F1A9190009D5AE /* NSViewSPI.h */,
@@ -24136,6 +24139,7 @@
8538F05B0AD722F1006A81D1 /* DOMRange.h in Headers */,
851EE8210ABCA58100A6AA33 /* DOMRangeException.h in Headers */,
8538F05D0AD722F1006A81D1 /* DOMRangeInternal.h in Headers */,
+ 2D59F1BF1A0044C6001F3D29 /* DataDetectorsSPI.h in Headers */,
8538F0850AD72CB6006A81D1 /* DOMRanges.h in Headers */,
858C38A70AA8F20400B187A4 /* DOMRect.h in Headers */,
85E711D60AC5D5350053270F /* DOMRectInternal.h in Headers */,
Copied: branches/safari-600.3-branch/Source/WebCore/platform/spi/mac/DataDetectorsSPI.h (from rev 175335, trunk/Source/WebCore/platform/spi/mac/DataDetectorsSPI.h) (0 => 175340)
--- branches/safari-600.3-branch/Source/WebCore/platform/spi/mac/DataDetectorsSPI.h (rev 0)
+++ branches/safari-600.3-branch/Source/WebCore/platform/spi/mac/DataDetectorsSPI.h 2014-10-29 20:26:40 UTC (rev 175340)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#import "SoftLinking.h"
+#import <objc/runtime.h>
+
+typedef struct __DDScanner DDScanner, *DDScannerRef;
+typedef struct __DDScanQuery *DDScanQueryRef;
+typedef struct __DDResult *DDResultRef;
+
+typedef enum {
+ DDScannerTypeStandard = 0,
+} DDScannerType;
+
+enum {
+ DDScannerOptionStopAtFirstMatch = 1,
+};
+typedef CFIndex DDScannerOptions;
+
+enum {
+ DDScannerCopyResultsOptionsNone = 0,
+ DDScannerCopyResultsOptionsNoOverlap = 1 << 0,
+};
+typedef CFIndex DDScannerCopyResultsOptions;
+
+SOFT_LINK_PRIVATE_FRAMEWORK_OPTIONAL(DataDetectors)
+SOFT_LINK_PRIVATE_FRAMEWORK_OPTIONAL(DataDetectorsCore)
+
+extern "C" {
+
+SOFT_LINK(DataDetectorsCore, DDScannerCreate, DDScannerRef, (DDScannerType type, DDScannerOptions options, CFErrorRef* errorRef), (type, options, errorRef))
+SOFT_LINK(DataDetectorsCore, DDScanQueryCreateFromString, DDScanQueryRef, (CFAllocatorRef allocator, CFStringRef string, CFRange range), (allocator, string, range))
+SOFT_LINK(DataDetectorsCore, DDScannerScanQuery, DDScanQueryRef, (DDScannerRef scanner, DDScanQueryRef query), (scanner, query))
+SOFT_LINK(DataDetectorsCore, DDScannerCopyResultsWithOptions, CFArrayRef, (DDScannerRef scanner, DDScannerCopyResultsOptions options), (scanner, options))
+SOFT_LINK(DataDetectorsCore, DDResultGetRange, CFRange, (DDResultRef result), (result))
+
+}
+
+SOFT_LINK_CLASS(DataDetectors, DDActionContext)
+SOFT_LINK_CLASS(DataDetectors, DDActionsManager)
+
+@interface DDActionContext : NSObject <NSCopying, NSSecureCoding>
+
+@property NSRect highlightFrame;
+@property (retain) NSArray *allResults;
+@property (retain) __attribute__((NSObject)) DDResultRef mainResult;
+
+@end
+
+@interface DDActionsManager : NSObject
+
++ (DDActionsManager *)sharedManager;
+- (NSArray *)menuItemsForResult:(DDResultRef)result actionContext:(DDActionContext *)context;
+
+@end
Modified: branches/safari-600.3-branch/Source/WebKit2/ChangeLog (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/ChangeLog 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/ChangeLog 2014-10-29 20:26:40 UTC (rev 175340)
@@ -1,3 +1,77 @@
+2014-08-29 Matthew Hanson <[email protected]>
+
+ Merge r175335. rdar://problem/18709436
+
+ 2014-10-29 Tim Horton <[email protected]>
+
+ Implement action menus for data detected items
+ https://bugs.webkit.org/show_bug.cgi?id=138178
+ <rdar://problem/18709436>
+
+ Reviewed by Anders Carlsson.
+
+ * Shared/API/c/WKActionMenuTypes.h:
+ Add a new type.
+
+ * Shared/WebHitTestResult.cpp:
+ (WebKit::WebHitTestResult::Data::Data):
+ (WebKit::WebHitTestResult::Data::encode):
+ (WebKit::WebHitTestResult::Data::decode):
+ * Shared/WebHitTestResult.h:
+ (WebKit::WebHitTestResult::isTextNode):
+ Determine, store, encode, and decode whether or not the hit node is a text node.
+
+ * Shared/mac/ActionMenuHitTestResult.h:
+ * Shared/mac/ActionMenuHitTestResult.mm: Renamed from Source/WebKit2/Shared/mac/ActionMenuHitTestResult.cpp.
+ (WebKit::ActionMenuHitTestResult::encode):
+ (WebKit::ActionMenuHitTestResult::decode):
+ Make ActionMenuHitTestResult an Obj-C++ file.
+ Store, encode, and decode (securely!) a DDActionContext and FloatRect
+ representing the bounding box of the data detected item, if any.
+
+ * UIProcess/API/mac/WKView.mm:
+ (-[WKView initWithFrame:context:configuration:webView:]):
+ (-[WKView willOpenMenu:withEvent:]): Deleted.
+ Stop using willOpenMenu; we'll use NSMenuDelegate's menuNeedsUpdate: instead.
+ Hook up WKActionMenuController as our action menu's delegate.
+
+ * UIProcess/mac/WKActionMenuController.mm:
+ (-[WKActionMenuController prepareForMenu:withEvent:]):
+ Call _updateActionMenuItems *after* we've adjusted _state, so that it
+ can depend on the value being correct.
+
+ (-[WKActionMenuController willOpenMenu:withEvent:]):
+ (-[WKActionMenuController didPerformActionMenuHitTest:]):
+ Move menu updating to menuNeedsUpdate for more accurate timing.
+
+ (_updateActionMenuItems):
+ When building the menu, if we have a text node that is not a link,
+ and hit a data detected item, retrieve the menu from the DDActionContext.
+ If we have nothing, make sure to reset _type, and if the final hit-test
+ is still pending, build a menu with a dummy item.
+
+ * WebKit2.xcodeproj/project.pbxproj:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::performActionMenuHitTestAtLocation): Moved to WebPageMac.
+ * WebProcess/WebPage/mac/WebPageMac.mm:
+ (WebKit::rangeExpandedAroundPosition):
+ Factor this out of performDictionaryLookupAtLocation.
+
+ (WebKit::WebPage::performDictionaryLookupAtLocation):
+ Make use of rangeExpandedAroundPosition.
+
+ (WebKit::scanForDataDetectedItems):
+ Expand to four lines of context around the hit point.
+ Convert that range to plain text, and feed it to DataDetectors.
+ Find the result that intersects the hit point, and make a DDActionContext
+ for it. Also, store the bounding box of the first quad of the detected
+ text, to provide to Data Detectors as a hint for UI placement.
+
+ (WebKit::WebPage::performActionMenuHitTestAtLocation):
+ If the hit node is a text node, call scanForDataDetectedItems and
+ store the resultant DDActionContext and bounding rect on our
+ ActionMenuHitTestResult for transfer to the UI process.
+
2014-10-29 Lucas Forschler <[email protected]>
Merge r175256
Modified: branches/safari-600.3-branch/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h 2014-10-29 20:26:40 UTC (rev 175340)
@@ -35,7 +35,8 @@
enum {
kWKActionMenuNone = 0,
kWKActionMenuLink,
- kWKActionMenuImage
+ kWKActionMenuImage,
+ kWKActionMenuDataDetectedItem
};
typedef uint32_t _WKActionMenuType;
Modified: branches/safari-600.3-branch/Source/WebKit2/Shared/WebHitTestResult.cpp (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/Shared/WebHitTestResult.cpp 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/Shared/WebHitTestResult.cpp 2014-10-29 20:26:40 UTC (rev 175340)
@@ -52,6 +52,7 @@
, isContentEditable(hitTestResult.isContentEditable())
, elementBoundingBox(elementBoundingBoxInWindowCoordinates(hitTestResult))
, isScrollbar(hitTestResult.scrollbar())
+ , isTextNode(hitTestResult.innerNode() && hitTestResult.innerNode()->isTextNode())
{
}
@@ -70,6 +71,7 @@
encoder << isContentEditable;
encoder << elementBoundingBox;
encoder << isScrollbar;
+ encoder << isTextNode;
}
bool WebHitTestResult::Data::decode(IPC::ArgumentDecoder& decoder, WebHitTestResult::Data& hitTestResultData)
@@ -82,7 +84,8 @@
|| !decoder.decode(hitTestResultData.linkTitle)
|| !decoder.decode(hitTestResultData.isContentEditable)
|| !decoder.decode(hitTestResultData.elementBoundingBox)
- || !decoder.decode(hitTestResultData.isScrollbar))
+ || !decoder.decode(hitTestResultData.isScrollbar)
+ || !decoder.decode(hitTestResultData.isTextNode))
return false;
return true;
Modified: branches/safari-600.3-branch/Source/WebKit2/Shared/WebHitTestResult.h (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/Shared/WebHitTestResult.h 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/Shared/WebHitTestResult.h 2014-10-29 20:26:40 UTC (rev 175340)
@@ -52,6 +52,7 @@
bool isContentEditable;
WebCore::IntRect elementBoundingBox;
bool isScrollbar;
+ bool isTextNode;
Data();
explicit Data(const WebCore::HitTestResult&);
@@ -79,6 +80,8 @@
bool isScrollbar() const { return m_data.isScrollbar; }
+ bool isTextNode() const { return m_data.isTextNode; }
+
private:
explicit WebHitTestResult(const WebHitTestResult::Data& hitTestResultData)
: m_data(hitTestResultData)
Deleted: branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.cpp (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.cpp 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.cpp 2014-10-29 20:26:40 UTC (rev 175340)
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2014 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 "ActionMenuHitTestResult.h"
-
-#include "ArgumentDecoder.h"
-#include "ArgumentEncoder.h"
-
-namespace WebKit {
-
-void ActionMenuHitTestResult::encode(IPC::ArgumentEncoder& encoder) const
-{
- ShareableBitmap::Handle handle;
-
- // FIXME: We should consider sharing the raw original resource data so that metadata and whatnot are preserved.
- if (image)
- image->createHandle(handle, SharedMemory::ReadOnly);
-
- encoder << handle;
-}
-
-bool ActionMenuHitTestResult::decode(IPC::ArgumentDecoder& decoder, ActionMenuHitTestResult& actionMenuHitTestResult)
-{
- ShareableBitmap::Handle handle;
- if (!decoder.decode(handle))
- return false;
-
- if (!handle.isNull())
- actionMenuHitTestResult.image = ShareableBitmap::create(handle, SharedMemory::ReadOnly);
-
- return true;
-}
-
-} // namespace WebKit
Modified: branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.h (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.h 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.h 2014-10-29 20:26:40 UTC (rev 175340)
@@ -27,7 +27,10 @@
#define ActionMenuHitTestResult_h
#include "ShareableBitmap.h"
+#include <WebCore/FloatRect.h>
+OBJC_CLASS DDActionContext;
+
namespace IPC {
class ArgumentDecoder;
class ArgumentEncoder;
@@ -40,6 +43,9 @@
static bool decode(IPC::ArgumentDecoder&, ActionMenuHitTestResult&);
RefPtr<ShareableBitmap> image;
+
+ RetainPtr<DDActionContext> actionContext;
+ WebCore::FloatRect actionBoundingBox;
};
} // namespace WebKit
Copied: branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.mm (from rev 175335, trunk/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.mm) (0 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.mm (rev 0)
+++ branches/safari-600.3-branch/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.mm 2014-10-29 20:26:40 UTC (rev 175340)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#import "config.h"
+#import "ActionMenuHitTestResult.h"
+
+#import "ArgumentCodersCF.h"
+#import "ArgumentDecoder.h"
+#import "ArgumentEncoder.h"
+#import "WebCoreArgumentCoders.h"
+#import <WebCore/DataDetectorsSPI.h>
+
+namespace WebKit {
+
+void ActionMenuHitTestResult::encode(IPC::ArgumentEncoder& encoder) const
+{
+ ShareableBitmap::Handle handle;
+
+ // FIXME: We should consider sharing the raw original resource data so that metadata and whatnot are preserved.
+ if (image)
+ image->createHandle(handle, SharedMemory::ReadOnly);
+
+ encoder << handle;
+
+ bool hasActionContext = actionContext;
+ encoder << hasActionContext;
+ if (hasActionContext) {
+ RetainPtr<NSMutableData> data = "" alloc] init]);
+ RetainPtr<NSKeyedArchiver> archiver = adoptNS([[NSKeyedArchiver alloc] initForWritingWithMutableData:data.get()]);
+ [archiver setRequiresSecureCoding:YES];
+ [archiver encodeObject:actionContext.get() forKey:@"actionContext"];
+ [archiver finishEncoding];
+
+ IPC::encode(encoder, reinterpret_cast<CFDataRef>(data.get()));
+ }
+
+ encoder << actionBoundingBox;
+}
+
+bool ActionMenuHitTestResult::decode(IPC::ArgumentDecoder& decoder, ActionMenuHitTestResult& actionMenuHitTestResult)
+{
+ ShareableBitmap::Handle handle;
+ if (!decoder.decode(handle))
+ return false;
+
+ if (!handle.isNull())
+ actionMenuHitTestResult.image = ShareableBitmap::create(handle, SharedMemory::ReadOnly);
+
+ bool hasActionContext;
+ if (!decoder.decode(hasActionContext))
+ return false;
+
+ if (hasActionContext) {
+ RetainPtr<CFDataRef> data;
+ if (!IPC::decode(decoder, data))
+ return false;
+
+ RetainPtr<NSKeyedUnarchiver> unarchiver = adoptNS([[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)data.get()]);
+ [unarchiver setRequiresSecureCoding:YES];
+ @try {
+ actionMenuHitTestResult.actionContext = [unarchiver decodeObjectOfClass:getDDActionContextClass() forKey:@"actionContext"];
+ } @catch (NSException *exception) {
+ LOG_ERROR("Failed to decode DDActionContext: %@", exception);
+ return false;
+ }
+
+ [unarchiver finishDecoding];
+ }
+
+ if (!decoder.decode(actionMenuHitTestResult.actionBoundingBox))
+ return false;
+
+ return true;
+}
+
+} // namespace WebKit
Modified: branches/safari-600.3-branch/Source/WebKit2/UIProcess/API/mac/WKView.mm (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/UIProcess/API/mac/WKView.mm 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/UIProcess/API/mac/WKView.mm 2014-10-29 20:26:40 UTC (rev 175340)
@@ -3538,6 +3538,7 @@
RetainPtr<NSMenu> menu = adoptNS([[NSMenu alloc] init]);
self.actionMenu = menu.get();
_data->_actionMenuController = adoptNS([[WKActionMenuController alloc] initWithPage:*_data->_page view:self]);
+ self.actionMenu.delegate = _data->_actionMenuController.get();
}
return self;
@@ -3642,11 +3643,6 @@
[_data->_actionMenuController prepareForMenu:menu withEvent:event];
}
-- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event
-{
- [_data->_actionMenuController willOpenMenu:menu withEvent:event];
-}
-
- (void)didCloseMenu:(NSMenu *)menu withEvent:(NSEvent *)event
{
[_data->_actionMenuController didCloseMenu:menu withEvent:event];
Modified: branches/safari-600.3-branch/Source/WebKit2/UIProcess/mac/WKActionMenuController.h (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/UIProcess/mac/WKActionMenuController.h 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/UIProcess/mac/WKActionMenuController.h 2014-10-29 20:26:40 UTC (rev 175340)
@@ -44,7 +44,7 @@
@class WKView;
-@interface WKActionMenuController : NSObject {
+@interface WKActionMenuController : NSObject <NSMenuDelegate> {
@private
WebKit::WebPageProxy *_page;
WKView *_wkView;
@@ -59,7 +59,6 @@
- (void)willDestroyView:(WKView *)view;
- (void)prepareForMenu:(NSMenu *)menu withEvent:(NSEvent *)event;
-- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event;
- (void)didCloseMenu:(NSMenu *)menu withEvent:(NSEvent *)event;
- (void)didPerformActionMenuHitTest:(const WebKit::ActionMenuHitTestResult&)hitTestResult;
Modified: branches/safari-600.3-branch/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm 2014-10-29 20:26:40 UTC (rev 175340)
@@ -31,12 +31,15 @@
#import "WKNSURLExtras.h"
#import "WKViewInternal.h"
#import "WebContext.h"
+#import "WebKitSystemInterface.h"
#import "WebPageMessages.h"
#import "WebPageProxy.h"
#import "WebPageProxyMessages.h"
#import "WebProcessProxy.h"
+#import <Foundation/Foundation.h>
#import <ImageIO/ImageIO.h>
#import <ImageKit/ImageKit.h>
+#import <WebCore/DataDetectorsSPI.h>
#import <WebCore/NSSharingServicePickerSPI.h>
#import <WebCore/NSViewSPI.h>
#import <WebCore/SoftLinking.h>
@@ -94,31 +97,12 @@
if (menu != _wkView.actionMenu)
return;
- [self _updateActionMenuItems];
-
_page->performActionMenuHitTestAtLocation([_wkView convertPoint:event.locationInWindow fromView:nil]);
_state = ActionMenuState::Pending;
+ [self _updateActionMenuItems];
}
-- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event
-{
- if (menu != _wkView.actionMenu)
- return;
-
- ASSERT(_state != ActionMenuState::None);
-
- // FIXME: We need to be able to cancel this if the menu goes away.
- // FIXME: Connection can be null if the process is closed; we should clean up better in that case.
- if (_state == ActionMenuState::Pending) {
- if (auto* connection = _page->process().connection())
- connection->waitForAndDispatchImmediately<Messages::WebPageProxy::DidPerformActionMenuHitTest>(_page->pageID(), std::chrono::milliseconds(500));
- }
-
- if (_state == ActionMenuState::Ready)
- [self _updateActionMenuItems];
-}
-
- (void)didCloseMenu:(NSMenu *)menu withEvent:(NSEvent *)event
{
if (menu != _wkView.actionMenu)
@@ -297,6 +281,25 @@
});
}
+#pragma mark NSMenuDelegate implementation
+
+- (void)menuNeedsUpdate:(NSMenu *)menu
+{
+ if (menu != _wkView.actionMenu)
+ return;
+
+ ASSERT(_state != ActionMenuState::None);
+
+ // FIXME: We need to be able to cancel this if the menu goes away.
+ // FIXME: Connection can be null if the process is closed; we should clean up better in that case.
+ if (_state == ActionMenuState::Pending) {
+ if (auto* connection = _page->process().connection())
+ connection->waitForAndDispatchImmediately<Messages::WebPageProxy::DidPerformActionMenuHitTest>(_page->pageID(), std::chrono::milliseconds(500));
+ }
+
+ [self _updateActionMenuItems];
+}
+
#pragma mark NSSharingServicePickerDelegate implementation
- (id <NSSharingServiceDelegate>)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker delegateForSharingService:(NSSharingService *)sharingService
@@ -385,13 +388,28 @@
if (!hitTestResult->absoluteImageURL().isEmpty() && _hitTestResult.image) {
_type = kWKActionMenuImage;
return [self _defaultMenuItemsForImage];
- } if (!hitTestResult->absoluteLinkURL().isEmpty()) {
+ }
+
+ if (!hitTestResult->absoluteLinkURL().isEmpty()) {
_type = kWKActionMenuLink;
return [self _defaultMenuItemsForLink];
}
+
+ if (hitTestResult->isTextNode()) {
+ if (DDActionContext *actionContext = _hitTestResult.actionContext.get()) {
+ WKSetDDActionContextIsForActionMenu(actionContext);
+ actionContext.highlightFrame = [_wkView.window convertRectToScreen:[_wkView convertRect:_hitTestResult.actionBoundingBox toView:nil]];
+ NSArray *dataDetectorMenuItems = [[getDDActionsManagerClass() sharedManager] menuItemsForResult:[_hitTestResult.actionContext mainResult] actionContext:actionContext];
+ if (dataDetectorMenuItems.count) {
+ _type = kWKActionMenuDataDetectedItem;
+ return dataDetectorMenuItems;
+ }
+ }
+ }
}
- return @[ ];
+ _type = kWKActionMenuNone;
+ return _state != ActionMenuState::Ready ? @[ [NSMenuItem separatorItem] ] : @[ ];
}
- (void)_updateActionMenuItems
Modified: branches/safari-600.3-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2014-10-29 20:26:40 UTC (rev 175340)
@@ -577,7 +577,7 @@
2D2ADF0916362DD500197E47 /* PDFPluginTextAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF0616362DC700197E47 /* PDFPluginTextAnnotation.mm */; };
2D2ADF0B16362DDB00197E47 /* PDFPluginAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF031636243500197E47 /* PDFPluginAnnotation.mm */; };
2D2ADF1016364D8200197E47 /* PDFPluginChoiceAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF0E16364D8200197E47 /* PDFPluginChoiceAnnotation.mm */; };
- 2D353B1219F8305D000EEACD /* ActionMenuHitTestResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D353B1019F8305D000EEACD /* ActionMenuHitTestResult.cpp */; };
+ 2D353B1219F8305D000EEACD /* ActionMenuHitTestResult.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D353B1019F8305D000EEACD /* ActionMenuHitTestResult.mm */; };
2D353B1319F8305D000EEACD /* ActionMenuHitTestResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D353B1119F8305D000EEACD /* ActionMenuHitTestResult.h */; };
2D3EF4421917646300034184 /* WebMemoryPressureHandlerIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D3EF4401917646300034184 /* WebMemoryPressureHandlerIOS.mm */; };
2D3EF4431917646300034184 /* WebMemoryPressureHandlerIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D3EF4411917646300034184 /* WebMemoryPressureHandlerIOS.h */; };
@@ -2587,7 +2587,7 @@
2D2ADF0C16363DEC00197E47 /* PDFLayerControllerDetails.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PDFLayerControllerDetails.h; path = PDF/PDFLayerControllerDetails.h; sourceTree = "<group>"; };
2D2ADF0D16364D8200197E47 /* PDFPluginChoiceAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPluginChoiceAnnotation.h; path = PDF/PDFPluginChoiceAnnotation.h; sourceTree = "<group>"; };
2D2ADF0E16364D8200197E47 /* PDFPluginChoiceAnnotation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPluginChoiceAnnotation.mm; path = PDF/PDFPluginChoiceAnnotation.mm; sourceTree = "<group>"; };
- 2D353B1019F8305D000EEACD /* ActionMenuHitTestResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActionMenuHitTestResult.cpp; sourceTree = "<group>"; };
+ 2D353B1019F8305D000EEACD /* ActionMenuHitTestResult.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ActionMenuHitTestResult.mm; sourceTree = "<group>"; };
2D353B1119F8305D000EEACD /* ActionMenuHitTestResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActionMenuHitTestResult.h; sourceTree = "<group>"; };
2D3EF4401917646300034184 /* WebMemoryPressureHandlerIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebMemoryPressureHandlerIOS.mm; path = ios/WebMemoryPressureHandlerIOS.mm; sourceTree = "<group>"; };
2D3EF4411917646300034184 /* WebMemoryPressureHandlerIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebMemoryPressureHandlerIOS.h; path = ios/WebMemoryPressureHandlerIOS.h; sourceTree = "<group>"; };
@@ -6121,7 +6121,7 @@
BC111B5A112F628200337BAB /* mac */ = {
isa = PBXGroup;
children = (
- 2D353B1019F8305D000EEACD /* ActionMenuHitTestResult.cpp */,
+ 2D353B1019F8305D000EEACD /* ActionMenuHitTestResult.mm */,
2D353B1119F8305D000EEACD /* ActionMenuHitTestResult.h */,
E179FD9B134D38060015B883 /* ArgumentCodersMac.h */,
E179FD9E134D38250015B883 /* ArgumentCodersMac.mm */,
@@ -9305,7 +9305,7 @@
1AE00D5C182DADE100087DD7 /* KeyedEncoder.cpp in Sources */,
1AC8702E130B49A2002C1257 /* WebPluginSiteDataManager.cpp in Sources */,
BC5744EF12638FB3006F0F12 /* WebPopupItem.cpp in Sources */,
- 2D353B1219F8305D000EEACD /* ActionMenuHitTestResult.cpp in Sources */,
+ 2D353B1219F8305D000EEACD /* ActionMenuHitTestResult.mm in Sources */,
0F931C1D18C5711900DBA7C3 /* ScrollingTreeOverflowScrollingNodeIOS.mm in Sources */,
D3B9484611FF4B6500032B39 /* WebPopupMenu.cpp in Sources */,
1AAF08A1192681D100B6390C /* WebUserContentControllerProxy.cpp in Sources */,
Modified: branches/safari-600.3-branch/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2014-10-29 20:26:40 UTC (rev 175340)
@@ -28,7 +28,6 @@
#include "config.h"
#include "WebPage.h"
-#include "ActionMenuHitTestResult.h"
#include "Arguments.h"
#include "DataReference.h"
#include "DragControllerAction.h"
@@ -4777,32 +4776,4 @@
send(Messages::WebPageProxy::WillChangeCurrentHistoryItemForMainFrame());
}
-void WebPage::performActionMenuHitTestAtLocation(WebCore::FloatPoint locationInViewCooordinates)
-{
- layoutIfNeeded();
-
- MainFrame& mainFrame = corePage()->mainFrame();
- if (!mainFrame.view() || !mainFrame.view()->renderView()) {
- send(Messages::WebPageProxy::DidPerformActionMenuHitTest(ActionMenuHitTestResult()));
- return;
- }
-
- RenderView& mainRenderView = *mainFrame.view()->renderView();
-
- HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
-
- HitTestResult hitTestResult(mainFrame.view()->rootViewToContents(roundedIntPoint(locationInViewCooordinates)));
- mainRenderView.hitTest(request, hitTestResult);
-
- ActionMenuHitTestResult actionMenuResult;
-
- if (Image* image = hitTestResult.image()) {
- actionMenuResult.image = ShareableBitmap::createShareable(IntSize(image->size()), ShareableBitmap::SupportsAlpha);
- if (actionMenuResult.image)
- actionMenuResult.image->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
- }
-
- send(Messages::WebPageProxy::DidPerformActionMenuHitTest(actionMenuResult));
-}
-
} // namespace WebKit
Modified: branches/safari-600.3-branch/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (175339 => 175340)
--- branches/safari-600.3-branch/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2014-10-29 20:26:40 UTC (rev 175340)
@@ -28,6 +28,7 @@
#if PLATFORM(MAC)
+#import "ActionMenuHitTestResult.h"
#import "AttributedString.h"
#import "DataReference.h"
#import "DictionaryPopupInfo.h"
@@ -52,10 +53,12 @@
#import <QuartzCore/QuartzCore.h>
#import <WebCore/AXObjectCache.h>
#import <WebCore/BackForwardController.h>
+#import <WebCore/DataDetectorsSPI.h>
#import <WebCore/EventHandler.h>
#import <WebCore/FocusController.h>
#import <WebCore/FrameLoader.h>
#import <WebCore/FrameView.h>
+#import <WebCore/GraphicsContext.h>
#import <WebCore/HTMLConverter.h>
#import <WebCore/HitTestResult.h>
#import <WebCore/KeyboardEvent.h>
@@ -68,12 +71,14 @@
#import <WebCore/RenderElement.h>
#import <WebCore/RenderObject.h>
#import <WebCore/RenderStyle.h>
+#import <WebCore/RenderView.h>
#import <WebCore/ResourceHandle.h>
#import <WebCore/ScrollView.h>
#import <WebCore/StyleInheritedData.h>
#import <WebCore/TextIterator.h>
#import <WebCore/VisibleUnits.h>
#import <WebCore/WindowsKeyboardCodes.h>
+#import <WebCore/htmlediting.h>
#import <WebKitSystemInterface.h>
using namespace WebCore;
@@ -491,6 +496,34 @@
return isPositionInRange(position, selectedRange.get());
}
+static PassRefPtr<Range> rangeExpandedAroundPosition(const VisiblePosition& position, int numberOfLinesToExpand)
+{
+ VisiblePosition contextStart = position;
+ VisiblePosition contextEnd = position;
+ for (int i = 0; i < numberOfLinesToExpand; i++) {
+ VisiblePosition n = previousLinePosition(contextStart, contextStart.lineDirectionPointForBlockDirectionNavigation());
+ if (n.isNull() || n == contextStart)
+ break;
+ contextStart = n;
+ }
+ for (int i = 0; i < numberOfLinesToExpand; i++) {
+ VisiblePosition n = nextLinePosition(contextEnd, contextEnd.lineDirectionPointForBlockDirectionNavigation());
+ if (n.isNull() || n == contextEnd)
+ break;
+ contextEnd = n;
+ }
+
+ VisiblePosition lineStart = startOfLine(contextStart);
+ if (!lineStart.isNull())
+ contextStart = lineStart;
+
+ VisiblePosition lineEnd = endOfLine(contextEnd);
+ if (!lineEnd.isNull())
+ contextEnd = lineEnd;
+
+ return makeRange(contextStart, contextEnd);
+}
+
void WebPage::performDictionaryLookupAtLocation(const FloatPoint& floatPoint)
{
if (PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame())) {
@@ -519,33 +552,9 @@
NSDictionary *options = nil;
// As context, we are going to use four lines of text before and after the point. (Dictionary can sometimes look up things that are four lines long)
- const int numberOfLinesOfContext = 4;
- VisiblePosition contextStart = position;
- VisiblePosition contextEnd = position;
- for (int i = 0; i < numberOfLinesOfContext; i++) {
- VisiblePosition n = previousLinePosition(contextStart, contextStart.lineDirectionPointForBlockDirectionNavigation());
- if (n.isNull() || n == contextStart)
- break;
- contextStart = n;
- }
- for (int i = 0; i < numberOfLinesOfContext; i++) {
- VisiblePosition n = nextLinePosition(contextEnd, contextEnd.lineDirectionPointForBlockDirectionNavigation());
- if (n.isNull() || n == contextEnd)
- break;
- contextEnd = n;
- }
+ RefPtr<Range> fullCharacterRange = rangeExpandedAroundPosition(position, 4);
+ NSRange rangeToPass = NSMakeRange(TextIterator::rangeLength(makeRange(fullCharacterRange->startPosition(), position).get()), 0);
- VisiblePosition lineStart = startOfLine(contextStart);
- if (!lineStart.isNull())
- contextStart = lineStart;
-
- VisiblePosition lineEnd = endOfLine(contextEnd);
- if (!lineEnd.isNull())
- contextEnd = lineEnd;
-
- NSRange rangeToPass = NSMakeRange(TextIterator::rangeLength(makeRange(contextStart, position).get()), 0);
-
- RefPtr<Range> fullCharacterRange = makeRange(contextStart, contextEnd);
String fullPlainTextString = plainText(fullCharacterRange.get());
NSRange extractedRange = WKExtractWordDefinitionTokenRangeFromContextualString(fullPlainTextString, rangeToPass, &options);
@@ -1045,6 +1054,95 @@
return String();
}
+static RetainPtr<DDActionContext> scanForDataDetectedItems(const HitTestResult& hitTestResult, FloatRect& actionBoundingBox)
+{
+ Node* node = hitTestResult.innerNonSharedNode();
+ if (!node)
+ return nullptr;
+ auto renderer = node->renderer();
+ if (!renderer)
+ return nullptr;
+ VisiblePosition position = renderer->positionForPoint(hitTestResult.localPoint(), nullptr);
+ if (position.isNull())
+ position = firstPositionInOrBeforeNode(node);
+
+ RefPtr<Range> contextRange = rangeExpandedAroundPosition(position, 4);
+ String fullPlainTextString = plainText(contextRange.get());
+ int hitLocation = TextIterator::rangeLength(makeRange(contextRange->startPosition(), position).get());
+
+ RetainPtr<DDScannerRef> scanner = adoptCF(DDScannerCreate(DDScannerTypeStandard, 0, nullptr));
+ RetainPtr<DDScanQueryRef> scanQuery = adoptCF(DDScanQueryCreateFromString(kCFAllocatorDefault, fullPlainTextString.createCFString().get(), CFRangeMake(0, fullPlainTextString.length())));
+
+ if (!DDScannerScanQuery(scanner.get(), scanQuery.get()))
+ return nullptr;
+
+ RetainPtr<CFArrayRef> results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap));
+
+ // Find the DDResultRef that intersects the hitTestResult's VisiblePosition.
+ DDResultRef mainResult = nullptr;
+ RefPtr<Range> mainResultRange;
+ CFIndex resultCount = CFArrayGetCount(results.get());
+ for (CFIndex i = 0; i < resultCount; i++) {
+ DDResultRef result = (DDResultRef)CFArrayGetValueAtIndex(results.get(), i);
+ CFRange resultRangeInContext = DDResultGetRange(result);
+ if (hitLocation >= resultRangeInContext.location && (hitLocation - resultRangeInContext.location) < resultRangeInContext.length) {
+ mainResult = result;
+ mainResultRange = TextIterator::subrange(contextRange.get(), resultRangeInContext.location, resultRangeInContext.length);
+ break;
+ }
+ }
+
+ if (!mainResult)
+ return nullptr;
+
+ RetainPtr<DDActionContext> actionContext = adoptNS([[getDDActionContextClass() alloc] init]);
+ [actionContext setAllResults:(NSArray *)results.get()];
+ [actionContext setMainResult:mainResult];
+
+ Vector<FloatQuad> quads;
+ mainResultRange->textQuads(quads);
+ if (!quads.isEmpty())
+ actionBoundingBox = mainResultRange->ownerDocument().view()->contentsToWindow(quads[0].enclosingBoundingBox());
+
+ return actionContext;
+}
+
+void WebPage::performActionMenuHitTestAtLocation(WebCore::FloatPoint locationInViewCooordinates)
+{
+ layoutIfNeeded();
+
+ MainFrame& mainFrame = corePage()->mainFrame();
+ if (!mainFrame.view() || !mainFrame.view()->renderView()) {
+ send(Messages::WebPageProxy::DidPerformActionMenuHitTest(ActionMenuHitTestResult()));
+ return;
+ }
+
+ RenderView& mainRenderView = *mainFrame.view()->renderView();
+
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
+
+ IntPoint locationInContentCoordinates = mainFrame.view()->rootViewToContents(roundedIntPoint(locationInViewCooordinates));
+ HitTestResult hitTestResult(locationInContentCoordinates);
+ mainRenderView.hitTest(request, hitTestResult);
+
+ ActionMenuHitTestResult actionMenuResult;
+
+ if (Image* image = hitTestResult.image()) {
+ actionMenuResult.image = ShareableBitmap::createShareable(IntSize(image->size()), ShareableBitmap::SupportsAlpha);
+ if (actionMenuResult.image)
+ actionMenuResult.image->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
+ }
+
+ // FIXME: Avoid scanning if we will just throw away the result (e.g. we're over a link).
+ if (hitTestResult.innerNode() && hitTestResult.innerNode()->isTextNode()) {
+ FloatRect actionBoundingBox;
+ actionMenuResult.actionContext = scanForDataDetectedItems(hitTestResult, actionBoundingBox);
+ actionMenuResult.actionBoundingBox = actionBoundingBox;
+ }
+
+ send(Messages::WebPageProxy::DidPerformActionMenuHitTest(actionMenuResult));
+}
+
} // namespace WebKit
#endif // PLATFORM(MAC)
Modified: branches/safari-600.3-branch/WebKitLibraries/ChangeLog (175339 => 175340)
--- branches/safari-600.3-branch/WebKitLibraries/ChangeLog 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/WebKitLibraries/ChangeLog 2014-10-29 20:26:40 UTC (rev 175340)
@@ -1,3 +1,21 @@
+2014-08-29 Matthew Hanson <[email protected]>
+
+ Merge r175335. rdar://problem/18709436
+
+ 2014-10-29 Tim Horton <[email protected]>
+
+ Implement action menus for data detected items
+ https://bugs.webkit.org/show_bug.cgi?id=138178
+ <rdar://problem/18709436>
+
+ Reviewed by Anders Carlsson.
+
+ * WebKitSystemInterface.h:
+ * libWebKitSystemInterfaceMavericks.a:
+ * libWebKitSystemInterfaceMountainLion.a:
+ * libWebKitSystemInterfaceYosemite.a:
+ Update WebKitSystemInterface.
+
2014-08-26 Dana Burkart <[email protected]>
Merge r172982. <rdar://problem/18141695>
Modified: branches/safari-600.3-branch/WebKitLibraries/WebKitSystemInterface.h (175339 => 175340)
--- branches/safari-600.3-branch/WebKitLibraries/WebKitSystemInterface.h 2014-10-29 20:24:13 UTC (rev 175339)
+++ branches/safari-600.3-branch/WebKitLibraries/WebKitSystemInterface.h 2014-10-29 20:26:40 UTC (rev 175340)
@@ -22,6 +22,7 @@
@class AVAsset;
@class AVPlayer;
+@class DDActionContext;
@class QTMovie;
@class QTMovieView;
@@ -152,9 +153,10 @@
void WKDrawTextFieldCellFocusRing(NSTextFieldCell*, NSRect);
void WKDrawBezeledTextArea(NSRect, BOOL enabled);
-void WKPopupMenu(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*, NSControlSize controlSize, bool hideArrows);
+void WKPopupMenu(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*, NSControlSize controlSize, bool usesCustomAppearance);
void WKPopupMenuWithSize(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*, NSControlSize controlSize);
void WKPopupContextMenu(NSMenu *menu, NSPoint screenLocation);
+void WKSetDDActionContextIsForActionMenu(DDActionContext *actionContext);
void WKSendUserChangeNotifications(void);
#ifndef __LP64__
BOOL WKConvertNSEventToCarbonEvent(EventRecord *carbonEvent, NSEvent *cocoaEvent);