Title: [175340] branches/safari-600.3-branch
Revision
175340
Author
[email protected]
Date
2014-10-29 13:26:40 -0700 (Wed, 29 Oct 2014)

Log Message

Merge r175335. rdar://problem/18709436

Modified Paths

Added Paths

Removed Paths

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);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to