void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow) { assert(!m_webView); bool isShiftKeyDown = ::GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT; WKContextRef context; if (isShiftKeyDown) context = WKContextGetSharedThreadContext(); else context = WKContextGetSharedProcessContext(); WKPageNamespaceRef pageNamespace = WKPageNamespaceCreate(context); m_webView = WKViewCreate(webViewRect, pageNamespace, parentWindow->window()); WKPageUIClient uiClient = { 0, /* version */ parentWindow, /* clientInfo */ createNewPage, showPage, closePage, runJavaScriptAlert, runJavaScriptConfirm, runJavaScriptPrompt, setStatusText, contentsSizeChanged }; WKPageSetPageUIClient(WKViewGetPage(m_webView), &uiClient); }
gpointer Shell::launchWPE(gpointer data) { Shell::m_instance = static_cast<Shell*>(data); GMainContext* threadContext = g_main_context_new(); GMainLoop* threadLoop = g_main_loop_new(threadContext, FALSE); g_main_context_push_thread_default(threadContext); auto pageGroupIdentifier = adoptWK(WKStringCreateWithUTF8CString("WPEPageGroup")); auto pageGroup = adoptWK(WKPageGroupCreateWithIdentifier(pageGroupIdentifier.get())); auto context = adoptWK(WKContextCreate()); Shell::instance().m_view = adoptWK(WKViewCreate(context.get(), pageGroup.get())); auto view = Shell::instance().m_view.get(); WKViewResize(view, Shell::instance().m_environment.outputSize()); WKViewMakeWPEInputTarget(view); const char* url = g_getenv("WPE_SHELL_URL"); if (!url) url = "http://www.webkit.org/blog-files/3d-transforms/poster-circle.html"; auto shellURL = adoptWK(WKURLCreateWithUTF8CString(url)); WKPageLoadURL(WKViewGetPage(view), shellURL.get()); g_main_loop_run(threadLoop); return nullptr; }
PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef) { m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); m_view = WKViewCreate(contextRef, pageGroupRef); gtk_container_add(GTK_CONTAINER(m_window), GTK_WIDGET(m_view)); gtk_widget_show(GTK_WIDGET(m_view)); gtk_widget_show(m_window); }
PlatformWebView::PlatformWebView(WKPageNamespaceRef namespaceRef) { registerWindowClass(); RECT viewRect = {0, 0, 800, 600}; m_window = CreateWindowExW(0, hostWindowClassName, L"WebKitTestRunner", WS_OVERLAPPEDWINDOW, 0 /*XOFFSET*/, 0 /*YOFFSET*/, viewRect.right, viewRect.bottom, 0, 0, GetModuleHandle(0), 0); m_view = WKViewCreate(viewRect, namespaceRef, m_window); }
void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow) { assert(!m_webView); static WKContextRef context = WKContextCreate(); m_webView = WKViewCreate(webViewRect, context, 0, parentWindow->window()); WKPageUIClient uiClient = { kWKPageUIClientCurrentVersion, parentWindow, /* clientInfo */ 0, /* createNewPage_deprecatedForUseWithV0 */ showPage, closePage, 0, /* takeFocus */ 0, /* focus */ 0, /* unfocus */ runJavaScriptAlert, runJavaScriptConfirm, runJavaScriptPrompt, setStatusText, 0, /* mouseDidMoveOverElement_deprecatedForUseWithV0 */ 0, /* missingPluginButtonClicked */ 0, /* didNotHandleKeyEvent */ 0, /* didNotHandleWheelEvent */ 0, /* toolbarsAreVisible */ 0, /* setToolbarsAreVisible */ 0, /* menuBarIsVisible */ 0, /* setMenuBarIsVisible */ 0, /* statusBarIsVisible */ 0, /* setStatusBarIsVisible */ 0, /* isResizable */ 0, /* setIsResizable */ 0, /* getWindowFrame */ 0, /* setWindowFrame */ 0, /* runBeforeUnloadConfirmPanel */ 0, /* didDraw */ 0, /* pageDidScroll */ 0, /* exceededDatabaseQuota */ 0, /* runOpenPanel */ 0, /* decidePolicyForGeolocationPermissionRequest */ 0, /* headerHeight */ 0, /* footerHeight */ 0, /* drawHeader */ 0, /* drawFooter */ 0, /* printFrame */ 0, /* runModal */ 0, /* didCompleteRubberBandForMainFrame */ 0, /* saveDataToFileInDownloadsFolder */ 0, /* shouldInterruptJavaScript */ createNewPage, mouseDidMoveOverElement, }; WKPageSetPageUIClient(WKViewGetPage(m_webView), &uiClient); WKViewSetIsInWindow(m_webView, true); }
PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef) : m_parentWindowMessageObserver(0) { registerWindowClass(); RECT viewRect = {0, 0, 800, 600}; m_window = CreateWindowExW(0, hostWindowClassName, L"TestWebKitAPI", WS_OVERLAPPEDWINDOW, viewRect.left, viewRect.top, viewRect.right, viewRect.bottom, 0, 0, 0, this); m_view = WKViewCreate(viewRect, contextRef, pageGroupRef, m_window); }
void BrowserView::create(RECT webViewRect, HWND parentWindow) { assert(!m_webView); WKContextRef context = WKContextCreateWithProcessModel(kWKProcessModelSecondaryProcess); WKPageNamespaceRef pageNamespace = WKPageNamespaceCreate(context); m_webView = WKViewCreate(webViewRect, pageNamespace, parentWindow); }
PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef, WKPageRef /* relatedPage */, WKDictionaryRef /*options*/) : m_windowIsKey(true) { registerWindowClass(); RECT viewRect = {0, 0, 800, 600}; m_window = CreateWindowExW(0, hostWindowClassName, L"WebKitTestRunner", WS_OVERLAPPEDWINDOW, 0 /*XOFFSET*/, 0 /*YOFFSET*/, viewRect.right, viewRect.bottom, 0, 0, GetModuleHandle(0), 0); m_view = WKViewCreate(viewRect, contextRef, pageGroupRef, m_window); WKViewSetIsInWindow(m_view, true); }
TEST(WebKitNix, WebViewTranslatedScaled) { // This test opens a webpage that contains a white background, no viewport // metatag and a red rectangle (20x20)px at (0,0) position. The viewport is // then translated to (10,10) position. After that it's applied a scale=2.0 // At this point we will have a red rectangle of (40x40)px at (10,10). const WKSize size = WKSizeMake(100, 100); ToolsNix::GLOffscreenBuffer offscreenBuffer(size.width, size.height); ASSERT_TRUE(offscreenBuffer.makeCurrent()); WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); WKRetainPtr<WKViewRef> view(AdoptWK, WKViewCreate(context.get(), 0)); Util::ForceRepaintClient forceRepaintClient(view.get()); forceRepaintClient.setClearColor(0, 0, 1, 1); const int delta = 10; WKViewSetUserViewportTranslation(view.get(), delta, delta); WKViewInitialize(view.get()); WKPageSetUseFixedLayout(WKViewGetPage(view.get()), true); WKViewSetSize(view.get(), size); glViewport(0, 0, size.width, size.height); forceRepaintClient.clear(); Util::PageLoader loader(view.get()); loader.waitForLoadURLAndRepaint("../nix/red-square"); for (double scale = 1.0; scale < 3.0; scale++) { WKViewSetContentScaleFactor(view.get(), scale); loader.forceRepaint(); ToolsNix::RGBAPixel outsideTheContent = offscreenBuffer.readPixelAtPoint(delta - 1, delta - 1); EXPECT_EQ(ToolsNix::RGBAPixel::blue(), outsideTheContent); ToolsNix::RGBAPixel squareTopLeft = offscreenBuffer.readPixelAtPoint(delta, delta); EXPECT_EQ(ToolsNix::RGBAPixel::red(), squareTopLeft); const int scaledSize = scale * 20; ToolsNix::RGBAPixel squareBottomRight = offscreenBuffer.readPixelAtPoint(delta + scaledSize - 1, delta + scaledSize - 1); EXPECT_EQ(ToolsNix::RGBAPixel::red(), squareBottomRight); ToolsNix::RGBAPixel outsideSquare = offscreenBuffer.readPixelAtPoint(delta + scaledSize, delta + scaledSize); EXPECT_EQ(ToolsNix::RGBAPixel::white(), outsideSquare); } }
PlatformWebView::PlatformWebView(WKContextRef context, WKPageGroupRef pageGroup, WKPageRef /* relatedPage */, WKDictionaryRef options) : m_view(WKViewCreate(context, pageGroup)) , m_window(gtk_window_new(GTK_WINDOW_POPUP)) , m_windowIsKey(true) , m_options(options) { gtk_container_add(GTK_CONTAINER(m_window), GTK_WIDGET(m_view)); GtkAllocation size = { 0, 0, 800, 600 }; gtk_widget_size_allocate(m_window, &size); gtk_window_resize(GTK_WINDOW(m_window), 800, 600); gtk_widget_show_all(m_window); while (gtk_events_pending()) gtk_main_iteration(); }
void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow) { assert(!m_webView); bool isShiftKeyDown = ::GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT; WKContextRef context; if (isShiftKeyDown) context = WKContextGetSharedThreadContext(); else context = WKContextGetSharedProcessContext(); m_webView = WKViewCreate(webViewRect, context, 0, parentWindow->window()); WKPageUIClient uiClient = { 0, /* version */ parentWindow, /* clientInfo */ createNewPage, showPage, closePage, runJavaScriptAlert, runJavaScriptConfirm, runJavaScriptPrompt, setStatusText, mouseDidMoveOverElement, 0, /* didNotHandleKeyEvent */ 0, /* toolbarsAreVisible */ 0, /* setToolbarsAreVisible */ 0, /* menuBarIsVisible */ 0, /* setMenuBarIsVisible */ 0, /* statusBarIsVisible */ 0, /* setStatusBarIsVisible */ 0, /* isResizable */ 0, /* setIsResizable */ 0, /* getWindowFrame */ 0, /* setWindowFrame */ 0, /* runBeforeUnloadConfirmPanel */ 0, /* didDraw */ 0, /* pageDidScroll */ 0, /* exceededDatabaseQuota */ 0 /* runOpenPanel */ }; WKPageSetPageUIClient(WKViewGetPage(m_webView), &uiClient); }
void Tab::init() { m_view = WKViewCreate(m_context, m_browser->contentPageGroup()); WKViewInitialize(m_view); WKViewSetIsFocused(m_view, true); WKViewSetIsVisible(m_view, true); m_page = WKViewGetPage(m_view); WKStringRef appName = WKStringCreateWithUTF8CString("Drowser"); WKPageSetApplicationNameForUserAgent(m_page, appName); WKRelease(appName); WKViewClient client; std::memset(&client, 0, sizeof(WKViewClient)); client.version = kWKViewClientCurrentVersion; client.clientInfo = this; client.viewNeedsDisplay = &Tab::onViewNeedsDisplayCallback; WKViewSetViewClient(m_view, &client); WKPageLoaderClient loaderClient; memset(&loaderClient, 0, sizeof(WKPageLoaderClient)); loaderClient.version = kWKPageLoaderClientCurrentVersion; loaderClient.clientInfo = this; loaderClient.didStartProgress = &Tab::onStartProgressCallback; loaderClient.didChangeProgress = &Tab::onChangeProgressCallback; loaderClient.didFinishProgress = &Tab::onFinishProgressCallback; loaderClient.didCommitLoadForFrame = &Tab::onCommitLoadForFrame; loaderClient.didReceiveTitleForFrame = &Tab::onReceiveTitleForFrame; loaderClient.didFailProvisionalLoadWithErrorForFrame = &Tab::onFailProvisionalLoadWithErrorForFrameCallback; WKPageSetPageLoaderClient(m_page, &loaderClient); WKPageUIClient uiClient; memset(&uiClient, 0, sizeof(WKPageUIClient)); uiClient.version = kWKPageUIClientCurrentVersion; uiClient.clientInfo = this; uiClient.createNewPage = &Tab::createNewPageCallback; uiClient.mouseDidMoveOverElement = &Tab::onMouseDidMoveOverElement; WKPageSetPageUIClient(m_page, &uiClient); }
TEST(WebKit2, WKViewUserViewportToContents) { // This test creates a WKView and uses the WKViewUserViewportToContents // function to convert viewport coordinates to contents (page) coordinates. // It scrolls and scales around the contents and check if the coordinates // conversion math is right. WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); WKRetainPtr<WKViewRef> webView(AdoptWK, WKViewCreate(context.get(), 0)); WKViewInitialize(webView.get()); WKPageSetUseFixedLayout(WKViewGetPage(webView.get()), false); WKPoint out; // At scale 1.0 the viewport and contents coordinates should match. WKViewSetContentScaleFactor(webView.get(), 1.0); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0); EXPECT_EQ(out.y, 0); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 10); EXPECT_EQ(out.y, 10); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 30); EXPECT_EQ(out.y, 30); // At scale 2.0 the viewport distance values will be half // the ones seem in the contents. WKViewSetContentScaleFactor(webView.get(), 2.0); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0); EXPECT_EQ(out.y, 0); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 5); EXPECT_EQ(out.y, 5); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 25); EXPECT_EQ(out.y, 25); // At scale 0.5 the viewport distance values will be twice // the ones seem in the contents. WKViewSetContentScaleFactor(webView.get(), 0.5); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0); EXPECT_EQ(out.y, 0); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 40); EXPECT_EQ(out.y, 40); // Let's add translation to the viewport. const int delta = 10; WKViewSetUserViewportTranslation(webView.get(), delta, delta); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0 - delta / 0.5); EXPECT_EQ(out.y, 0 - delta / 0.5); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 20 - delta / 0.5); EXPECT_EQ(out.y, 20 - delta / 0.5); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20 - delta / 0.5); EXPECT_EQ(out.y, 20 - delta / 0.5); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 40 - delta / 0.5); EXPECT_EQ(out.y, 40 - delta / 0.5); }
TEST(WebKitNix, WebViewUpdateTextInputState) { memset(&stateReceived, 0, sizeof(stateReceived)); WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); WKRetainPtr<WKViewRef> view(AdoptWK, WKViewCreate(context.get(), 0)); NIXViewClient nixViewClient; memset(&nixViewClient, 0, sizeof(NIXViewClient)); nixViewClient.version = kNIXViewClientCurrentVersion; nixViewClient.updateTextInputState = updateTextInputState; NIXViewSetNixViewClient(view.get(), &nixViewClient); WKViewInitialize(view.get()); WKPageLoaderClient pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(WKPageLoaderClient)); pageLoaderClient.version = kWKPageLoaderClientCurrentVersion; pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrame; WKPageSetPageLoaderClient(WKViewGetPage(view.get()), &pageLoaderClient); const WKSize size = WKSizeMake(100, 100); WKViewSetSize(view.get(), size); NIXMouseEvent nixEvent; memset(&nixEvent, 0, sizeof(NIXMouseEvent)); nixEvent.type = kNIXInputEventTypeMouseDown; nixEvent.button = kWKEventMouseButtonLeftButton; nixEvent.x = 55; nixEvent.y = 55; nixEvent.globalX = 55; nixEvent.globalY = 55; nixEvent.clickCount = 1; nixEvent.modifiers = static_cast<NIXInputEventModifiers>(0);; nixEvent.timestamp = 0; // Simple test on content editable. WKRetainPtr<WKURLRef> editableContentUrl = adoptWK(Util::createURLForResource("../nix/single-tap-on-editable-content", "html")); WKPageLoadURL(WKViewGetPage(view.get()), editableContentUrl.get()); Util::run(&didFinishLoad); NIXViewSendMouseEvent(view.get(), &nixEvent); nixEvent.type = kNIXInputEventTypeMouseUp; NIXViewSendMouseEvent(view.get(), &nixEvent); Util::run(&didUpdateTextInputState); ASSERT_TRUE(didFinishLoad); ASSERT_TRUE(didUpdateTextInputState); ASSERT_TRUE(stateReceived.isContentEditable); ASSERT_TRUE(WKStringIsEqualToUTF8CString(stateReceived.surroundingText, "foobar")); WKRelease(stateReceived.surroundingText); ASSERT_TRUE(WKStringIsEmpty(stateReceived.submitLabel)); WKRelease(stateReceived.submitLabel); ASSERT_FALSE(stateReceived.inputMethodHints & NIXImhSensitiveData); ASSERT_TRUE(!WKRectIsEqual(stateReceived.cursorRect, invalidRectState)); ASSERT_TRUE(!WKRectIsEqual(stateReceived.editorRect, invalidRectState)); ASSERT_TRUE(!WKRectIsEqual(stateReceived.cursorRect, stateReceived.editorRect)); // Test on a form field. didFinishLoad = false; memset(&stateReceived, 0, sizeof(stateReceived)); editableContentUrl = adoptWK(Util::createURLForResource("../nix/single-tap-on-form-field", "html")); WKPageLoadURL(WKViewGetPage(view.get()), editableContentUrl.get()); Util::run(&didFinishLoad); nixEvent.type = kNIXInputEventTypeMouseDown; NIXViewSendMouseEvent(view.get(), &nixEvent); nixEvent.type = kNIXInputEventTypeMouseUp; NIXViewSendMouseEvent(view.get(), &nixEvent); didUpdateTextInputState = false; Util::run(&didUpdateTextInputState); WKRelease(stateReceived.surroundingText); ASSERT_TRUE(didFinishLoad); ASSERT_TRUE(didUpdateTextInputState); ASSERT_TRUE(WKStringIsEqualToUTF8CString(stateReceived.submitLabel, "submitLabelValue")); WKRelease(stateReceived.submitLabel); ASSERT_TRUE(stateReceived.inputMethodHints & NIXImhSensitiveData); }
TEST(WebKitNix, SuspendResumeAPI) { // This test uses a page that changes its title - showing current time. // As the suspend method is called the page's changes are paused. The // animation continues as we call the resume method. During this process // there are checkpoints to ensure that changes are pausing/resuming. const WKSize size = WKSizeMake(150, 100); ToolsNix::GLOffscreenBuffer offscreenBuffer(size.width, size.height); ASSERT_TRUE(offscreenBuffer.makeCurrent()); WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); WKRetainPtr<WKViewRef> view(AdoptWK, WKViewCreate(context.get(), 0)); Util::ForceRepaintClient forceRepaintClient(view.get()); forceRepaintClient.setClearColor(0, 0, 1, 1); WKViewInitialize(view.get()); WKViewSetSize(view.get(), size); glViewport(0, 0, size.width, size.height); forceRepaintClient.clear(); Util::PageLoader loader(view.get()); loader.waitForLoadURLAndRepaint("../nix/SuspendResume"); size_t bufferSize = WKStringGetMaximumUTF8CStringSize(WKPageCopyTitle(WKViewGetPage(view.get()))); char firstSampleBeforeSuspend[bufferSize]; char secondSampleBeforeSuspend[bufferSize]; char firstSampleAfterSuspend[bufferSize]; char secondSampleAfterSuspend[bufferSize]; char firstSampleAfterResume[bufferSize]; WKStringGetUTF8CString(WKPageCopyTitle(WKViewGetPage(view.get())), firstSampleBeforeSuspend, bufferSize); // After collecting the first sample a repaint is needed to get viewport updated accordingly. // This proccess is repeated for each collected sample. Util::sleep(0.1); loader.forceRepaint(); WKStringGetUTF8CString(WKPageCopyTitle(WKViewGetPage(view.get())), secondSampleBeforeSuspend, bufferSize); // The timer is ticking - two different samples. EXPECT_STRNE(firstSampleBeforeSuspend, secondSampleBeforeSuspend); // Force an update before suspending otherwise we can get same sample value after suspending // and the test becomes flacky. Util::sleep(0.1); loader.forceRepaint(); WKViewSuspendActiveDOMObjectsAndAnimations(view.get()); Util::sleep(0.1); loader.forceRepaint(); WKStringGetUTF8CString(WKPageCopyTitle(WKViewGetPage(view.get())), firstSampleAfterSuspend, bufferSize); // The timer is paused - still two different samples. EXPECT_STRNE(secondSampleBeforeSuspend, firstSampleAfterSuspend); Util::sleep(0.1); loader.forceRepaint(); WKStringGetUTF8CString(WKPageCopyTitle(WKViewGetPage(view.get())), secondSampleAfterSuspend, bufferSize); // The timer is paused - two samples collected while paused so they are equal. EXPECT_STREQ(firstSampleAfterSuspend, secondSampleAfterSuspend); WKViewResumeActiveDOMObjectsAndAnimations(view.get()); Util::sleep(0.1); loader.forceRepaint(); WKStringGetUTF8CString(WKPageCopyTitle(WKViewGetPage(view.get())), firstSampleAfterResume, bufferSize); // The timer is ticking again - two different samples. EXPECT_STRNE(secondSampleAfterSuspend, firstSampleAfterResume); }