summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/WebProcess/WebPage/mac
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage/mac')
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h47
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm190
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp60
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm185
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm40
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm369
6 files changed, 891 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h
new file mode 100644
index 0000000..3b331b9
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef AccessibilityWebPageObject_h
+#define AccessibilityWebPageObject_h
+
+namespace WebKit {
+class WebPage;
+}
+
+@interface AccessibilityWebPageObject : NSObject {
+ WebKit::WebPage* m_page;
+
+ id m_parent;
+ NSArray* m_attributeNames;
+ NSMutableArray* m_accessibilityChildren;
+}
+
+- (void)setWebPage:(WebKit::WebPage*)page;
+
+- (void)setRemoteParent:(id)parent;
+
+@end
+
+#endif // AccessibilityWebPageObject_h
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm
new file mode 100644
index 0000000..fa4aa1a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2011 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 "AccessibilityWebPageObject.h"
+
+#import "WebFrame.h"
+#import "WebPage.h"
+#import <WebCore/AXObjectCache.h>
+#import <WebCore/Frame.h>
+#import <WebCore/FrameView.h>
+#import <WebCore/ScrollView.h>
+#import <WebCore/Scrollbar.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+@implementation AccessibilityWebPageObject
+
+- (id)accessibilityRootObjectWrapper
+{
+ WebCore::Page* page = m_page->corePage();
+ if (!page)
+ return nil;
+
+ WebCore::Frame* core = page->mainFrame();
+ if (!core || !core->document())
+ return nil;
+
+ AccessibilityObject* root = core->document()->axObjectCache()->rootObject();
+ if (!root)
+ return nil;
+
+ return root->wrapper();
+}
+
+- (void)setWebPage:(WebPage*)page
+{
+ m_page = page;
+}
+
+- (void)setRemoteParent:(id)parent
+{
+ if (parent != m_parent) {
+ [m_parent release];
+ m_parent = [parent retain];
+ }
+}
+
+- (void)dealloc
+{
+ [m_accessibilityChildren release];
+ [m_attributeNames release];
+ [m_parent release];
+ [super dealloc];
+}
+
+- (BOOL)accessibilityIsIgnored
+{
+ return NO;
+}
+
+- (NSArray *)accessibilityAttributeNames
+{
+ if (!m_attributeNames)
+ m_attributeNames = [[NSArray alloc] initWithObjects:
+ NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilityFocusedAttribute,
+ NSAccessibilityParentAttribute, NSAccessibilityWindowAttribute, NSAccessibilityTopLevelUIElementAttribute,
+ NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, NSAccessibilityChildrenAttribute, nil];
+
+ return m_attributeNames;
+}
+
+- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute
+{
+ return NO;
+}
+
+- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
+{
+ return;
+}
+
+- (NSArray *)accessibilityActionNames
+{
+ return [NSArray array];
+}
+
+- (NSArray *)accessibilityChildren
+{
+ id wrapper = [self accessibilityRootObjectWrapper];
+ if (!wrapper)
+ return [NSArray array];
+
+ return [NSArray arrayWithObject:wrapper];
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute
+{
+ if (!WebCore::AXObjectCache::accessibilityEnabled())
+ WebCore::AXObjectCache::enableAccessibility();
+
+ if ([attribute isEqualToString:NSAccessibilityParentAttribute])
+ return m_parent;
+ if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
+ return [m_parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+ if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
+ return [m_parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+ if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
+ return NSAccessibilityGroupRole;
+ if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
+ return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, nil);
+ if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
+ return [NSNumber numberWithBool:NO];
+
+ if (!m_page)
+ return nil;
+
+ if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
+ WebCore::IntPoint point = m_page->accessibilityPosition();
+ return [NSValue valueWithPoint:NSMakePoint(point.x(), point.y())];
+ }
+ if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
+ const IntSize& s = m_page->size();
+ return [NSValue valueWithSize:NSMakeSize(s.width(), s.height())];
+ }
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
+ return [self accessibilityChildren];
+
+ return [super accessibilityAttributeValue:attribute];
+}
+
+- (BOOL)accessibilityShouldUseUniqueId
+{
+ return YES;
+}
+
+- (id)accessibilityHitTest:(NSPoint)point
+{
+ // Hit-test point comes in as bottom-screen coordinates. Needs to be normalized to the frame of the web page.
+ NSPoint remotePosition = [[self accessibilityAttributeValue:NSAccessibilityPositionAttribute] pointValue];
+ NSSize remoteSize = [[self accessibilityAttributeValue:NSAccessibilitySizeAttribute] sizeValue];
+
+ // Get the y position of the WKView (we have to screen-flip and go from bottom left to top left).
+ CGFloat screenHeight = [[[NSScreen screens] objectAtIndex:0] frame].size.height;
+ remotePosition.y = (screenHeight - remotePosition.y) - remoteSize.height;
+
+ point.y = screenHeight - point.y;
+
+ // Re-center point into the web page's frame.
+ point.y -= remotePosition.y;
+ point.x -= remotePosition.x;
+
+ WebCore::FrameView* fv = m_page->mainFrame()->coreFrame()->view();
+ if (fv) {
+ point.y += fv->scrollPosition().y();
+ point.x += fv->scrollPosition().x();
+ }
+
+ return [[self accessibilityRootObjectWrapper] accessibilityHitTest:point];
+}
+
+- (id)accessibilityFocusedUIElement
+{
+ return NSAccessibilityUnignoredDescendant(self);
+}
+
+
+@end
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp b/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp
new file mode 100644
index 0000000..6bcecfd
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 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 "ChunkedUpdateDrawingArea.h"
+
+#include "UpdateChunk.h"
+#include "WebFrame.h"
+#include "WebPage.h"
+#include "WebFrameLoaderClient.h"
+#include <WebCore/Frame.h>
+#include <WebCore/GraphicsContext.h>
+#include <wtf/RetainPtr.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk)
+{
+ // FIXME: It would be better if we could avoid painting altogether when there is a custom representation.
+ if (m_webPage->mainFrameHasCustomRepresentation())
+ return;
+
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGContextRef> bitmapContext(AdoptCF, CGBitmapContextCreate(updateChunk->data(), updateChunk->rect().width(), updateChunk->rect().height(), 8, updateChunk->rect().width() * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+
+ // WebCore expects a flipped coordinate system.
+ CGContextTranslateCTM(bitmapContext.get(), 0.0, updateChunk->rect().height());
+ CGContextScaleCTM(bitmapContext.get(), 1.0, -1.0);
+
+ // Now paint into the backing store.
+ GraphicsContext graphicsContext(bitmapContext.get());
+ graphicsContext.translate(-updateChunk->rect().x(), -updateChunk->rect().y());
+
+ m_webPage->drawRect(graphicsContext, updateChunk->rect());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm
new file mode 100644
index 0000000..f8b7e71
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerBackedDrawingArea.h"
+
+#include "DrawingAreaProxyMessageKinds.h"
+#include "WebKitSystemInterface.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsLayer.h>
+#include <WebCore/Page.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void LayerBackedDrawingArea::platformInit()
+{
+ setUpUpdateLayoutRunLoopObserver();
+
+ [m_backingLayer->platformLayer() setGeometryFlipped:YES];
+#if HAVE(HOSTED_CORE_ANIMATION)
+ attachCompositingContext();
+#endif
+
+ scheduleCompositingLayerSync();
+}
+
+void LayerBackedDrawingArea::platformClear()
+{
+ if (!m_attached)
+ return;
+
+ if (m_updateLayoutRunLoopObserver) {
+ CFRunLoopObserverInvalidate(m_updateLayoutRunLoopObserver.get());
+ m_updateLayoutRunLoopObserver = 0;
+ }
+
+#if HAVE(HOSTED_CORE_ANIMATION)
+ WKCARemoteLayerClientInvalidate(m_remoteLayerRef.get());
+ m_remoteLayerRef = nullptr;
+#endif
+
+ m_attached = false;
+}
+
+void LayerBackedDrawingArea::attachCompositingContext()
+{
+ if (m_attached)
+ return;
+
+ m_attached = true;
+
+#if HAVE(HOSTED_CORE_ANIMATION)
+ mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort();
+ m_remoteLayerRef = WKCARemoteLayerClientMakeWithServerPort(serverPort);
+ WKCARemoteLayerClientSetLayer(m_remoteLayerRef.get(), m_backingLayer->platformLayer());
+
+ uint32_t contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerRef.get());
+ WebProcess::shared().connection()->sendSync(DrawingAreaProxyLegacyMessage::AttachCompositingContext, m_webPage->pageID(), CoreIPC::In(contextID), CoreIPC::Out());
+#endif
+}
+
+void LayerBackedDrawingArea::detachCompositingContext()
+{
+ m_backingLayer->removeAllChildren();
+
+ scheduleCompositingLayerSync();
+}
+
+void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer* layer)
+{
+ m_backingLayer->removeAllChildren();
+ if (layer)
+ m_backingLayer->addChild(layer);
+
+ scheduleCompositingLayerSync();
+}
+
+void LayerBackedDrawingArea::scheduleCompositingLayerSync()
+{
+// if (m_syncTimer.isActive())
+// return;
+//
+// m_syncTimer.startOneShot(0);
+
+ scheduleUpdateLayoutRunLoopObserver();
+}
+
+void LayerBackedDrawingArea::syncCompositingLayers()
+{
+ m_backingLayer->syncCompositingStateForThisLayerOnly();
+
+ bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateRecursive();
+ if (!didSync) {
+
+ }
+}
+
+void LayerBackedDrawingArea::setUpUpdateLayoutRunLoopObserver()
+{
+ if (m_updateLayoutRunLoopObserver)
+ return;
+
+ // Run before Core Animations commit observer, which has order 2000000.
+ const CFIndex runLoopOrder = 2000000 - 1;
+ CFRunLoopObserverContext context = { 0, this, 0, 0, 0 };
+ m_updateLayoutRunLoopObserver.adoptCF(CFRunLoopObserverCreate(0,
+ kCFRunLoopBeforeWaiting | kCFRunLoopExit, true /* repeats */,
+ runLoopOrder, updateLayoutRunLoopObserverCallback, &context));
+}
+
+void LayerBackedDrawingArea::scheduleUpdateLayoutRunLoopObserver()
+{
+ CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
+ CFRunLoopWakeUp(currentRunLoop);
+
+ if (CFRunLoopContainsObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes))
+ return;
+
+ CFRunLoopAddObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes);
+}
+
+void LayerBackedDrawingArea::removeUpdateLayoutRunLoopObserver()
+{
+ // FIXME: cache the run loop ref?
+ CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes);
+}
+
+void LayerBackedDrawingArea::updateLayoutRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* info)
+{
+ // Keep the drawing area alive while running the callback, since that does layout,
+ // which might replace this drawing area with one of another type.
+ RefPtr<LayerBackedDrawingArea> drawingArea = reinterpret_cast<LayerBackedDrawingArea*>(info);
+ drawingArea->updateLayoutRunLoopObserverFired();
+}
+
+void LayerBackedDrawingArea::updateLayoutRunLoopObserverFired()
+{
+ // Laying out the page can cause the drawing area to change so we keep an extra reference.
+ RefPtr<LayerBackedDrawingArea> protect(this);
+
+ m_webPage->layoutIfNeeded();
+
+ if (m_webPage->drawingArea() != this)
+ return;
+
+ if (m_attached)
+ syncCompositingLayers();
+}
+
+void LayerBackedDrawingArea::onPageClose()
+{
+ platformClear();
+}
+
+} // namespace WebKit
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm
new file mode 100644
index 0000000..83909be
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 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 "WebInspector.h"
+
+#import <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+String WebInspector::localizedStringsURL() const
+{
+ NSString *path = [[NSBundle bundleWithIdentifier:@"com.apple.WebCore"] pathForResource:@"localizedStrings" ofType:@"js"];
+ if (path)
+ return [[NSURL fileURLWithPath:path] absoluteString];
+ return String();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm
new file mode 100644
index 0000000..f3211f2
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2010 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 "WebPage.h"
+
+#include "AccessibilityWebPageObject.h"
+#include "DataReference.h"
+#include "PluginView.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebEvent.h"
+#include "WebFrame.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include <WebCore/AXObjectCache.h>
+#include <WebCore/FocusController.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/HitTestResult.h>
+#include <WebCore/KeyboardEvent.h>
+#include <WebCore/Page.h>
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/ScrollView.h>
+#include <WebCore/TextIterator.h>
+#include <WebCore/WindowsKeyboardCodes.h>
+#include <WebKitSystemInterface.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebPage::platformInitialize()
+{
+ m_page->addSchedulePair(SchedulePair::create([NSRunLoop currentRunLoop], kCFRunLoopCommonModes));
+
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ AccessibilityWebPageObject* mockAccessibilityElement = [[[AccessibilityWebPageObject alloc] init] autorelease];
+
+ // Get the pid for the starting process.
+ pid_t pid = WebProcess::shared().presenterApplicationPid();
+ WKAXInitializeElementWithPresenterPid(mockAccessibilityElement, pid);
+ [mockAccessibilityElement setWebPage:this];
+
+ // send data back over
+ NSData* remoteToken = (NSData *)WKAXRemoteTokenForElement(mockAccessibilityElement);
+ CoreIPC::DataReference dataToken = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>([remoteToken bytes]), [remoteToken length]);
+ send(Messages::WebPageProxy::DidReceiveAccessibilityPageToken(dataToken));
+ m_mockAccessibilityElement = mockAccessibilityElement;
+#endif
+}
+
+void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
+{
+}
+
+// FIXME: need to add support for input methods
+
+bool WebPage::interceptEditingKeyboardEvent(KeyboardEvent* evt, bool shouldSaveCommand)
+{
+ Node* node = evt->target()->toNode();
+ ASSERT(node);
+ Frame* frame = node->document()->frame();
+ ASSERT(frame);
+
+ const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
+ if (!keyEvent)
+ return false;
+ const Vector<KeypressCommand>& commands = evt->keypressCommands();
+ bool hasKeypressCommand = !commands.isEmpty();
+
+ bool eventWasHandled = false;
+
+ if (shouldSaveCommand || !hasKeypressCommand) {
+ Vector<KeypressCommand> commandsList;
+ Vector<CompositionUnderline> underlines;
+ unsigned start;
+ unsigned end;
+ if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::InterpretKeyEvent(keyEvent->type()),
+ Messages::WebPageProxy::InterpretKeyEvent::Reply(commandsList, start, end, underlines),
+ m_pageID, CoreIPC::Connection::NoTimeout))
+ return false;
+ if (commandsList.isEmpty())
+ return eventWasHandled;
+
+ if (commandsList[0].commandName == "setMarkedText") {
+ frame->editor()->setComposition(commandsList[0].text, underlines, start, end);
+ eventWasHandled = true;
+ } else if (commandsList[0].commandName == "insertText" && frame->editor()->hasComposition()) {
+ frame->editor()->confirmComposition(commandsList[0].text);
+ eventWasHandled = true;
+ } else if (commandsList[0].commandName == "unmarkText") {
+ frame->editor()->confirmComposition();
+ eventWasHandled = true;
+ } else {
+ for (size_t i = 0; i < commandsList.size(); i++)
+ evt->keypressCommands().append(commandsList[i]);
+ }
+ } else {
+ size_t size = commands.size();
+ // Are there commands that would just cause text insertion if executed via Editor?
+ // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
+ // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
+ // (e.g. Tab that inserts a Tab character, or Enter).
+ bool haveTextInsertionCommands = false;
+ for (size_t i = 0; i < size; ++i) {
+ if (frame->editor()->command(commands[i].commandName).isTextInsertion())
+ haveTextInsertionCommands = true;
+ }
+ if (!haveTextInsertionCommands || keyEvent->type() == PlatformKeyboardEvent::Char) {
+ for (size_t i = 0; i < size; ++i) {
+ if (commands[i].commandName == "insertText") {
+ // Don't insert null or control characters as they can result in unexpected behaviour
+ if (evt->charCode() < ' ')
+ return false;
+ eventWasHandled = frame->editor()->insertText(commands[i].text, evt);
+ } else
+ if (frame->editor()->command(commands[i].commandName).isSupported())
+ eventWasHandled = frame->editor()->command(commands[i].commandName).execute(evt);
+ }
+ }
+ }
+ return eventWasHandled;
+}
+
+void WebPage::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput)
+{
+ for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) {
+ if ((*it)->sendComplexTextInput(pluginComplexTextInputIdentifier, textInput))
+ break;
+ }
+}
+
+void WebPage::getMarkedRange(uint64_t& location, uint64_t& length)
+{
+ location = NSNotFound;
+ length = 0;
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ getLocationAndLengthFromRange(frame->editor()->compositionRange().get(), location, length);
+}
+
+static Range *characterRangeAtPoint(Frame* frame, const IntPoint point)
+{
+ VisiblePosition position = frame->visiblePositionForPoint(point);
+ if (position.isNull())
+ return NULL;
+
+ VisiblePosition previous = position.previous();
+ if (previous.isNotNull()) {
+ Range *previousCharacterRange = makeRange(previous, position).get();
+ NSRect rect = frame->editor()->firstRectForRange(previousCharacterRange);
+ if (NSPointInRect(point, rect))
+ return previousCharacterRange;
+ }
+
+ VisiblePosition next = position.next();
+ if (next.isNotNull()) {
+ Range *nextCharacterRange = makeRange(position, next).get();
+ NSRect rect = frame->editor()->firstRectForRange(nextCharacterRange);
+ if (NSPointInRect(point, rect))
+ return nextCharacterRange;
+ }
+
+ return NULL;
+}
+
+void WebPage::characterIndexForPoint(IntPoint point, uint64_t& index)
+{
+ index = NSNotFound;
+ Frame* frame = m_page->mainFrame();
+ if (!frame)
+ return;
+
+ HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(point, false);
+ frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : m_page->focusController()->focusedOrMainFrame();
+
+ Range *range = characterRangeAtPoint(frame, result.point());
+ if (!range)
+ return;
+
+ uint64_t length;
+ getLocationAndLengthFromRange(range, index, length);
+}
+
+static PassRefPtr<Range> convertToRange(Frame* frame, NSRange nsrange)
+{
+ if (nsrange.location > INT_MAX)
+ return 0;
+ if (nsrange.length > INT_MAX || nsrange.location + nsrange.length > INT_MAX)
+ nsrange.length = INT_MAX - nsrange.location;
+
+ // our critical assumption is that we are only called by input methods that
+ // concentrate on a given area containing the selection
+ // We have to do this because of text fields and textareas. The DOM for those is not
+ // directly in the document DOM, so serialization is problematic. Our solution is
+ // to use the root editable element of the selection start as the positional base.
+ // That fits with AppKit's idea of an input context.
+ Element* selectionRoot = frame->selection()->rootEditableElement();
+ Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
+ return TextIterator::rangeFromLocationAndLength(scope, nsrange.location, nsrange.length);
+}
+
+void WebPage::firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ resultRect.setLocation(IntPoint(0, 0));
+ resultRect.setSize(IntSize(0, 0));
+
+ RefPtr<Range> range = convertToRange(frame, NSMakeRange(location, length));
+ if (range) {
+ ASSERT(range->startContainer());
+ ASSERT(range->endContainer());
+ }
+
+ IntRect rect = frame->editor()->firstRectForRange(range.get());
+ resultRect = frame->view()->contentsToWindow(rect);
+}
+
+static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
+{
+ page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
+}
+
+static inline void logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
+{
+ page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity);
+}
+
+bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
+{
+ if (keyboardEvent.type() != WebEvent::KeyDown)
+ return false;
+
+ // FIXME: This should be in WebCore.
+
+ switch (keyboardEvent.windowsVirtualKeyCode()) {
+ case VK_BACK:
+ if (keyboardEvent.shiftKey())
+ m_page->goForward();
+ else
+ m_page->goBack();
+ break;
+ case VK_SPACE:
+ if (keyboardEvent.shiftKey())
+ logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage);
+ else
+ logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage);
+ break;
+ case VK_PRIOR:
+ logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage);
+ break;
+ case VK_NEXT:
+ logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage);
+ break;
+ case VK_HOME:
+ logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument);
+ break;
+ case VK_END:
+ logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument);
+ break;
+ case VK_UP:
+ if (keyboardEvent.shiftKey())
+ return false;
+ if (keyboardEvent.metaKey()) {
+ scroll(m_page.get(), ScrollUp, ScrollByDocument);
+ scroll(m_page.get(), ScrollLeft, ScrollByDocument);
+ } else if (keyboardEvent.altKey() || keyboardEvent.controlKey())
+ scroll(m_page.get(), ScrollUp, ScrollByPage);
+ else
+ scroll(m_page.get(), ScrollUp, ScrollByLine);
+ break;
+ case VK_DOWN:
+ if (keyboardEvent.shiftKey())
+ return false;
+ if (keyboardEvent.metaKey()) {
+ scroll(m_page.get(), ScrollDown, ScrollByDocument);
+ scroll(m_page.get(), ScrollLeft, ScrollByDocument);
+ } else if (keyboardEvent.altKey() || keyboardEvent.controlKey())
+ scroll(m_page.get(), ScrollDown, ScrollByPage);
+ else
+ scroll(m_page.get(), ScrollDown, ScrollByLine);
+ break;
+ case VK_LEFT:
+ if (keyboardEvent.shiftKey())
+ return false;
+ if (keyboardEvent.metaKey())
+ m_page->goBack();
+ else {
+ if (keyboardEvent.altKey() | keyboardEvent.controlKey())
+ scroll(m_page.get(), ScrollLeft, ScrollByPage);
+ else
+ scroll(m_page.get(), ScrollLeft, ScrollByLine);
+ }
+ break;
+ case VK_RIGHT:
+ if (keyboardEvent.shiftKey())
+ return false;
+ if (keyboardEvent.metaKey())
+ m_page->goForward();
+ else {
+ if (keyboardEvent.altKey() || keyboardEvent.controlKey())
+ scroll(m_page.get(), ScrollRight, ScrollByPage);
+ else
+ scroll(m_page.get(), ScrollRight, ScrollByLine);
+ }
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void WebPage::sendAccessibilityPresenterToken(const CoreIPC::DataReference& data)
+{
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ NSData* tokenData = [NSData dataWithBytes:data.data() length:data.size()];
+ [m_mockAccessibilityElement.get() setRemoteParent:WKAXRemoteElementForToken((CFDataRef)tokenData)];
+#endif
+}
+
+AccessibilityWebPageObject* WebPage::accessibilityRemoteObject()
+{
+ return m_mockAccessibilityElement.get();
+}
+
+bool WebPage::platformHasLocalDataForURL(const WebCore::KURL& url)
+{
+ NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
+ [request setValue:(NSString*)userAgent() forHTTPHeaderField:@"User-Agent"];
+ NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
+ [request release];
+
+ return cachedResponse;
+}
+
+bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
+{
+ if ([NSURLConnection canHandleRequest:request.nsURLRequest()])
+ return YES;
+
+ // FIXME: Return true if this scheme is any one WebKit2 knows how to handle.
+ return request.url().protocolIs("applewebdata");
+}
+
+} // namespace WebKit