diff options
author | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-13 22:14:35 +0000 |
---|---|---|
committer | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-13 22:14:35 +0000 |
commit | 70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb (patch) | |
tree | 8d1c89e7ca926f05beb7a1f35473c758a08acf07 /webkit | |
parent | 848ebfe4cfbaedfd8f2e5104690598cd9658526d (diff) | |
download | chromium_src-70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb.zip chromium_src-70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb.tar.gz chromium_src-70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb.tar.bz2 |
correctly close windows w/out leaking from JS, correctly clean up after ourselves when manually quitting test shell. This fixes the window.closed property in layout tests as well.
Review URL: http://codereview.chromium.org/10656
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5391 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/tools/test_shell/mac/main.mm | 7 | ||||
-rw-r--r-- | webkit/tools/test_shell/mac/test_webview_delegate.mm | 751 | ||||
-rw-r--r-- | webkit/tools/test_shell/mac/webview_host.mm | 1 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell.cc | 4 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell.h | 9 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_mac.mm | 73 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_win.cc | 4 |
7 files changed, 116 insertions, 733 deletions
diff --git a/webkit/tools/test_shell/mac/main.mm b/webkit/tools/test_shell/mac/main.mm index f0148fd..ffd3c38 100644 --- a/webkit/tools/test_shell/mac/main.mm +++ b/webkit/tools/test_shell/mac/main.mm @@ -69,12 +69,13 @@ static void SetCurrentTestName(char* path) { // purify leak-test results. MessageLoop::current()->RunAllPending(); + TestShell::ShutdownTestShell(); + + // get rid of the stats table last, V8 relies on it StatsTable* table = StatsTable::current(); StatsTable::set_current(NULL); delete table; - delete shell_; - TestShell::ShutdownTestShell(); TestShell::CleanupLogging(); [super dealloc]; @@ -225,7 +226,7 @@ int main(const int argc, const char *argv[]) { CommandLine::LooseValueIterator iter = parsed_command_line.GetLooseValuesBegin(); uri = *iter; - } + } TestShell* shell; if (TestShell::CreateNewWindow(uri, &shell)) { diff --git a/webkit/tools/test_shell/mac/test_webview_delegate.mm b/webkit/tools/test_shell/mac/test_webview_delegate.mm index 0955b14..3bb08bc 100644 --- a/webkit/tools/test_shell/mac/test_webview_delegate.mm +++ b/webkit/tools/test_shell/mac/test_webview_delegate.mm @@ -26,23 +26,11 @@ #include "webkit/tools/test_shell/test_shell.h" -static int32 next_page_id_ = 1; - // WebViewDelegate ----------------------------------------------------------- TestWebViewDelegate::~TestWebViewDelegate() { } -WebView* TestWebViewDelegate::CreateWebView(WebView* webview, - bool user_gesture) { - return shell_->CreateWebView(webview); -} - -WebWidget* TestWebViewDelegate::CreatePopupWidget(WebView* webview, - bool focus_on_show) { - return shell_->CreatePopupWidget(webview); -} - WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate( WebView* webview, const GURL& url, @@ -51,605 +39,43 @@ WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate( std::string* actual_mime_type) { // TODO(awalker): once Mac plugins are working, enable this code to // connect up the web plugin delegate for a plugin. -#if 0 - WindowHandle WindowHandle = GetContainingWindow(webview); - if (!WindowHandle) - return NULL; - - bool allow_wildcard = true; - WebPluginInfo info; - if (!NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid, - allow_wildcard, &info, - actual_mime_type)) - return NULL; - - if (actual_mime_type && !actual_mime_type->empty()) - return WebPluginDelegateImpl::Create(info.file, *actual_mime_type, - WindowHandle); - else - return WebPluginDelegateImpl::Create(info.file, mime_type, WindowHandle); -#else + NOTIMPLEMENTED(); return NULL; -#endif -} - -void TestWebViewDelegate::OpenURL(WebView* webview, const GURL& url, - const GURL&, // TODO(eroman): use referrer - WindowOpenDisposition disposition) { - DCHECK_NE(disposition, CURRENT_TAB); // No code for this - if (disposition == SUPPRESS_OPEN) - return; - TestShell* shell = NULL; - if (TestShell::CreateNewWindow(UTF8ToWide(url.spec()), &shell)) - shell->Show(shell->webView(), disposition); -} - -void TestWebViewDelegate::DidStartLoading(WebView* webview) { - // Ignored -} - -void TestWebViewDelegate::DidStopLoading(WebView* webview) { - // Ignored -} - -void TestWebViewDelegate::WindowObjectCleared(WebFrame* webframe) { - shell_->BindJSObjectsToWindow(webframe); -} - -WindowOpenDisposition TestWebViewDelegate::DispositionForNavigationAction( - WebView* webview, - WebFrame* frame, - const WebRequest* request, - WebNavigationType type, - WindowOpenDisposition disposition, - bool is_redirect) { - if (is_custom_policy_delegate_) { - std::wstring frame_name = frame->GetName(); - printf("Policy delegate: attempt to load %s\n", - request->GetURL().spec().c_str()); - return IGNORE_ACTION; - } else { - return static_cast<WindowOpenDisposition>( - WebViewDelegate::DispositionForNavigationAction(webview, frame, request, - type, disposition, - is_redirect)); - } -} - -void TestWebViewDelegate::SetCustomPolicyDelegate(bool isCustom) { - is_custom_policy_delegate_ = isCustom; -} - -void TestWebViewDelegate::AssignIdentifierToRequest(WebView* webview, - uint32 identifier, - const WebRequest& request) { - if (shell_->ShouldDumpResourceLoadCallbacks()) { - resource_identifier_map_[identifier] = request.GetURL().spec(); - } -} - -std::string TestWebViewDelegate::GetResourceDescription(uint32 identifier) { - ResourceMap::iterator it = resource_identifier_map_.find(identifier); - return it != resource_identifier_map_.end() ? it->second : "<unknown>"; -} - -void TestWebViewDelegate::WillSendRequest(WebView* webview, - uint32 identifier, - WebRequest* request) { - std::string request_url = request->GetURL().spec(); - - if (shell_->ShouldDumpResourceLoadCallbacks()) { - printf("%s - willSendRequest <WebRequest URL \"%s\">\n", - GetResourceDescription(identifier).c_str(), - request_url.c_str()); - } - - // Set the new substituted URL. - request->SetURL(GURL(TestShell::RewriteLocalUrl(request_url))); -} - -void TestWebViewDelegate::DidFinishLoading(WebView* webview, - uint32 identifier) { - if (shell_->ShouldDumpResourceLoadCallbacks()) { - printf("%s - didFinishLoading\n", - GetResourceDescription(identifier).c_str()); - } - - resource_identifier_map_.erase(identifier); -} - -void TestWebViewDelegate::DidFailLoadingWithError(WebView* webview, - uint32 identifier, - const WebError& error) { - if (shell_->ShouldDumpResourceLoadCallbacks()) { - printf("%s - didFailLoadingWithError <WebError code %d," - " failing URL \"%s\">\n", - GetResourceDescription(identifier).c_str(), - error.GetErrorCode(), - error.GetFailedURL().spec().c_str()); - } - - resource_identifier_map_.erase(identifier); -} - -void TestWebViewDelegate::DidStartProvisionalLoadForFrame( - WebView* webview, - WebFrame* frame, - NavigationGesture gesture) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didStartProvisionalLoadForFrame\n", - GetFrameDescription(frame).c_str()); - } - - if (!top_loading_frame_) { - top_loading_frame_ = frame; - } - UpdateAddressBar(webview); -} - -void TestWebViewDelegate::DidReceiveServerRedirectForProvisionalLoadForFrame( - WebView* webview, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didReceiveServerRedirectForProvisionalLoadForFrame\n", - GetFrameDescription(frame).c_str()); - } - - UpdateAddressBar(webview); -} - -void TestWebViewDelegate::DidFailProvisionalLoadWithError( - WebView* webview, - const WebError& error, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didFailProvisionalLoadWithError\n", - GetFrameDescription(frame).c_str()); - } - - LocationChangeDone(frame->GetProvisionalDataSource()); - - // Don't display an error page if we're running layout tests, because - // DumpRenderTree doesn't. - if (!shell_->interactive()) - return; - - // Don't display an error page if this is simply a cancelled load. Aside - // from being dumb, WebCore doesn't expect it and it will cause a crash. - if (error.GetErrorCode() == net::ERR_ABORTED) - return; - - const WebRequest& failed_request = - frame->GetProvisionalDataSource()->GetRequest(); - TestShellExtraRequestData* extra_data = - static_cast<TestShellExtraRequestData*>(failed_request.GetExtraData()); - bool replace = extra_data && extra_data->pending_page_id != -1; - - scoped_ptr<WebRequest> request(failed_request.Clone()); - request->SetURL(GURL("testshell-error:")); - - std::string error_text = - StringPrintf("Error loading url: %d", error.GetErrorCode()); - - frame->LoadAlternateHTMLString(request.get(), error_text, - error.GetFailedURL(), replace); -} - -void TestWebViewDelegate::DidCommitLoadForFrame(WebView* webview, - WebFrame* frame, - bool is_new_navigation) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didCommitLoadForFrame\n", - GetFrameDescription(frame).c_str()); - } - - UpdateForCommittedLoad(frame, is_new_navigation); -} - -void TestWebViewDelegate::DidReceiveTitle(WebView* webview, - const std::wstring& title, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didReceiveTitle\n", - GetFrameDescription(frame).c_str()); - } - - if (shell_->ShouldDumpTitleChanges()) { - printf("TITLE CHANGED: %S\n", title.c_str()); - } - [[shell_->webViewHost()->window_handle() window] - setTitle:[NSString stringWithUTF8String:WideToUTF8(title).c_str()]]; -} - -void TestWebViewDelegate::DidFinishLoadForFrame(WebView* webview, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didFinishLoadForFrame\n", - GetFrameDescription(frame).c_str()); - } - - UpdateAddressBar(webview); - LocationChangeDone(frame->GetDataSource()); -} - -void TestWebViewDelegate::DidFailLoadWithError(WebView* webview, - const WebError& error, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didFailLoadWithError\n", - GetFrameDescription(frame).c_str()); - } - - LocationChangeDone(frame->GetDataSource()); -} - -void TestWebViewDelegate::DidFinishDocumentLoadForFrame(WebView* webview, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didFinishDocumentLoadForFrame\n", - GetFrameDescription(frame).c_str()); - } -} - -void TestWebViewDelegate::DidHandleOnloadEventsForFrame(WebView* webview, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didHandleOnloadEventsForFrame\n", - GetFrameDescription(frame).c_str()); - } -} - -void TestWebViewDelegate::DidChangeLocationWithinPageForFrame( - WebView* webview, WebFrame* frame, bool is_new_navigation) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didChangeLocationWithinPageForFrame\n", - GetFrameDescription(frame).c_str()); - } - - UpdateForCommittedLoad(frame, is_new_navigation); -} - -void TestWebViewDelegate::DidReceiveIconForFrame(WebView* webview, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didReceiveIconForFrame\n", - GetFrameDescription(frame).c_str()); - } -} - -void TestWebViewDelegate::WillPerformClientRedirect( - WebView* webview, WebFrame* frame, const std::wstring& dest_url, - unsigned int delay_seconds, unsigned int fire_date) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - // TODO: prettyprint the url? - printf("%S - willPerformClientRedirectToURL: %S\n", - GetFrameDescription(frame).c_str(), dest_url.c_str()); - } -} - -void TestWebViewDelegate::DidCancelClientRedirect(WebView* webview, - WebFrame* frame) { - if (shell_->ShouldDumpFrameLoadCallbacks()) { - printf("%S - didCancelClientRedirectForFrame\n", - GetFrameDescription(frame).c_str()); - } -} - -void TestWebViewDelegate::AddMessageToConsole(WebView* webview, - const std::wstring& message, - unsigned int line_no, - const std::wstring& source_id) { - if (shell_->interactive()) { - logging::LogMessage("CONSOLE", 0).stream() << "\"" - << message.c_str() - << ",\" source: " - << source_id.c_str() - << "(" - << line_no - << ")"; - } else { - // This matches win DumpRenderTree's UIDelegate.cpp. - std::wstring new_message = message; - if (!message.empty()) { - new_message = message; - size_t file_protocol = new_message.find(L"file://"); - if (file_protocol != std::wstring::npos) { - new_message = new_message.substr(0, file_protocol) + new_message; - // UrlSuitableForTestResult(new_message); - } - } - - std::string utf8 = WideToUTF8(new_message); - printf("CONSOLE MESSAGE: line %d: %s\n", line_no, utf8.c_str()); - } -} - -void TestWebViewDelegate::RunJavaScriptAlert(WebView* webview, - const std::wstring& message) { - if (shell_->interactive()) { - NSString *text = - [NSString stringWithUTF8String:WideToUTF8(message).c_str()]; - NSAlert *alert = [NSAlert alertWithMessageText:@"JavaScript Alert" - defaultButton:@"OK" - alternateButton:nil - otherButton:nil - informativeTextWithFormat:text]; - [alert runModal]; - } else { - std::string utf8 = WideToUTF8(message); - printf("ALERT: %s\n", utf8.c_str()); - } -} - -bool TestWebViewDelegate::RunJavaScriptConfirm(WebView* webview, - const std::wstring& message) { - if (!shell_->interactive()) { - // When running tests, write to stdout. - std::string utf8 = WideToUTF8(message); - printf("CONFIRM: %s\n", utf8.c_str()); - return true; - } - return false; -} - -bool TestWebViewDelegate::RunJavaScriptPrompt(WebView* webview, - const std::wstring& message, const std::wstring& default_value, - std::wstring* result) { - if (!shell_->interactive()) { - // When running tests, write to stdout. - std::string utf8_message = WideToUTF8(message); - std::string utf8_default_value = WideToUTF8(default_value); - printf("PROMPT: %s, default text: %s\n", utf8_message.c_str(), - utf8_default_value.c_str()); - return true; - } - return false; -} - -void TestWebViewDelegate::StartDragging(WebView* webview, - const WebDropData& drop_data) { -#if 0 -// TODO(pinkerton): fill in drag&drop code later. - if (!drag_delegate_) - drag_delegate_ = new TestDragDelegate(shell_->webViewWnd(), - shell_->webView()); - if (webkit_glue::IsLayoutTestMode()) { - if (shell_->layout_test_controller()->ShouldAddFileToPasteboard()) { - // Add a file called DRTFakeFile to the drag&drop clipboard. - // AddDRTFakeFileToDataObject(drop_data.data_object); - } - - // When running a test, we need to fake a drag drop operation otherwise - // Windows waits for real mouse events to know when the drag is over. - EventSendingController::DoDragDrop(drop_data.data_object); - } else { - // Process a real drag and drop - } - webview->DragSourceSystemDragEnded(); -#endif -} - -void TestWebViewDelegate::ShowContextMenu(WebView* webview, - ContextNode::Type type, - int x, - int y, - const GURL& link_url, - const GURL& image_url, - const GURL& page_url, - const GURL& frame_url, - const std::wstring& selection_text, - const std::wstring& misspelled_word, - int edit_flags, - const std::string& security_info) { - CapturedContextMenuEvent context(type, x, y); - captured_context_menu_events_.push_back(context); -} - -// The output from these methods in non-interactive mode should match that -// expected by the layout tests. See EditingDelegate.m in DumpRenderTree. -bool TestWebViewDelegate::ShouldBeginEditing(WebView* webview, - std::wstring range) { - if (shell_->ShouldDumpEditingCallbacks()) { - std::string utf8 = WideToUTF8(range); - printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n", - utf8.c_str()); - } - return shell_->AcceptsEditing(); -} - -bool TestWebViewDelegate::ShouldEndEditing(WebView* webview, - std::wstring range) { - if (shell_->ShouldDumpEditingCallbacks()) { - std::string utf8 = WideToUTF8(range); - printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n", - utf8.c_str()); - } - return shell_->AcceptsEditing(); -} - -bool TestWebViewDelegate::ShouldInsertNode(WebView* webview, - std::wstring node, - std::wstring range, - std::wstring action) { - if (shell_->ShouldDumpEditingCallbacks()) { - std::string utf8_node = WideToUTF8(node); - std::string utf8_range = WideToUTF8(range); - std::string utf8_action = WideToUTF8(action); - printf("EDITING DELEGATE: shouldInsertNode:%s " - "replacingDOMRange:%s givenAction:%s\n", - utf8_node.c_str(), utf8_range.c_str(), utf8_action.c_str()); - } - return shell_->AcceptsEditing(); -} - -bool TestWebViewDelegate::ShouldInsertText(WebView* webview, - std::wstring text, - std::wstring range, - std::wstring action) { - if (shell_->ShouldDumpEditingCallbacks()) { - std::string utf8_text = WideToUTF8(text); - std::string utf8_range = WideToUTF8(range); - std::string utf8_action = WideToUTF8(action); - printf("EDITING DELEGATE: shouldInsertText:%s " - "replacingDOMRange:%s givenAction:%s\n", - utf8_text.c_str(), utf8_range.c_str(), utf8_action.c_str()); - } - return shell_->AcceptsEditing(); -} - -bool TestWebViewDelegate::ShouldChangeSelectedRange(WebView* webview, - std::wstring fromRange, - std::wstring toRange, - std::wstring affinity, - bool stillSelecting) { - if (shell_->ShouldDumpEditingCallbacks()) { - std::string utf8_from = WideToUTF8(fromRange); - std::string utf8_to = WideToUTF8(toRange); - std::string utf8_affinity = WideToUTF8(affinity); - printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s " - "toDOMRange:%s affinity:%s stillSelecting:%s\n", - utf8_from.c_str(), - utf8_to.c_str(), - utf8_affinity.c_str(), - (stillSelecting ? "TRUE" : "FALSE")); - } - return shell_->AcceptsEditing(); -} - -bool TestWebViewDelegate::ShouldDeleteRange(WebView* webview, - std::wstring range) { - if (shell_->ShouldDumpEditingCallbacks()) { - std::string utf8 = WideToUTF8(range); - printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", utf8.c_str()); - } - return shell_->AcceptsEditing(); -} - -bool TestWebViewDelegate::ShouldApplyStyle(WebView* webview, - std::wstring style, - std::wstring range) { - if (shell_->ShouldDumpEditingCallbacks()) { - std::string utf8_style = WideToUTF8(style); - std::string utf8_range = WideToUTF8(range); - printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n", - utf8_style.c_str(), utf8_range.c_str()); - } - return shell_->AcceptsEditing(); -} - -bool TestWebViewDelegate::SmartInsertDeleteEnabled() { - return true; } -void TestWebViewDelegate::DidBeginEditing() { - if (shell_->ShouldDumpEditingCallbacks()) { - printf("EDITING DELEGATE: " - "webViewDidBeginEditing:WebViewDidBeginEditingNotification\n"); - } -} - -void TestWebViewDelegate::DidChangeSelection() { - if (shell_->ShouldDumpEditingCallbacks()) { - printf("EDITING DELEGATE: " - "webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n"); - } -} - -void TestWebViewDelegate::DidChangeContents() { - if (shell_->ShouldDumpEditingCallbacks()) { - printf("EDITING DELEGATE: " - "webViewDidChange:WebViewDidChangeNotification\n"); - } +void TestWebViewDelegate::ShowJavaScriptAlert(const std::wstring& message) { + NSString *text = + [NSString stringWithUTF8String:WideToUTF8(message).c_str()]; + NSAlert *alert = [NSAlert alertWithMessageText:@"JavaScript Alert" + defaultButton:@"OK" + alternateButton:nil + otherButton:nil + informativeTextWithFormat:text]; + [alert runModal]; } -void TestWebViewDelegate::DidEndEditing() { - if (shell_->ShouldDumpEditingCallbacks()) { - printf("EDITING DELEGATE: " - "webViewDidEndEditing:WebViewDidEndEditingNotification\n"); - } -} - -WebHistoryItem* TestWebViewDelegate::GetHistoryEntryAtOffset(int offset) { - TestNavigationEntry* entry = static_cast<TestNavigationEntry*>( - shell_->navigation_controller()->GetEntryAtOffset(offset)); - if (!entry) - return NULL; - - return entry->GetHistoryItem(); -} - -int TestWebViewDelegate::GetHistoryBackListCount() { - int current_index = - shell_->navigation_controller()->GetLastCommittedEntryIndex(); - return current_index; -} - -int TestWebViewDelegate::GetHistoryForwardListCount() { - int current_index = - shell_->navigation_controller()->GetLastCommittedEntryIndex(); - return shell_->navigation_controller()->GetEntryCount() - current_index - 1; -} - -void TestWebViewDelegate::SetUserStyleSheetEnabled(bool is_enabled) { - WebPreferences* prefs = shell_->GetWebPreferences(); - prefs->user_style_sheet_enabled = is_enabled; - shell_->webView()->SetPreferences(*prefs); -} - -void TestWebViewDelegate::SetUserStyleSheetLocation(const GURL& location) { - WebPreferences* prefs = shell_->GetWebPreferences(); - prefs->user_style_sheet_location = location; - shell_->webView()->SetPreferences(*prefs); -} // WebWidgetDelegate --------------------------------------------------------- -gfx::ViewHandle TestWebViewDelegate::GetContainingWindow(WebWidget* webwidget) { - if (WebWidgetHost* host = GetHostForWidget(webwidget)) - return host->window_handle(); - - return NULL; -} - -void TestWebViewDelegate::DidInvalidateRect(WebWidget* webwidget, - const gfx::Rect& rect) { - if (WebWidgetHost* host = GetHostForWidget(webwidget)) - host->DidInvalidateRect(rect); -} - -void TestWebViewDelegate::DidScrollRect(WebWidget* webwidget, int dx, int dy, - const gfx::Rect& clip_rect) { - if (WebWidgetHost* host = GetHostForWidget(webwidget)) - host->DidScrollRect(dx, dy, clip_rect); -} - void TestWebViewDelegate::Show(WebWidget* webview, WindowOpenDisposition disposition) { + NOTIMPLEMENTED(); } void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) { if (webwidget == shell_->webView()) { NSWindow *win = shell_->mainWnd(); - // Tell Cocoa to close the window. When the view is deallocated, - // the delegate (and therefore shell_) will be destroyed as well, so - // we do not need to explicitly null out the pointer shell_ is - // holding to the window. + // Tell Cocoa to close the window, which will let the window's delegate + // handle getting rid of the shell. |shell_| will still be alive for a short + // period of time after this call returns (cleanup is done after going back + // to the event loop), so we should make sure we don't leave it dangling. [win performClose:nil]; + shell_ = NULL; } else if (webwidget == shell_->popup()) { shell_->ClosePopup(); } } -void TestWebViewDelegate::Focus(WebWidget* webwidget) { - if (WebWidgetHost* host = GetHostForWidget(webwidget)) - shell_->SetFocus(host, true); -} - -void TestWebViewDelegate::Blur(WebWidget* webwidget) { - if (WebWidgetHost* host = GetHostForWidget(webwidget)) - shell_->SetFocus(host, false); -} - void TestWebViewDelegate::SetCursor(WebWidget* webwidget, const WebCursor& cursor) { //TODO: Mac cursor handling @@ -685,148 +111,19 @@ void TestWebViewDelegate::GetRootWindowRect(WebWidget* webwidget, } } -void TestWebViewDelegate::DidMove(WebWidget* webwidget, - const WebPluginGeometry& move) { - // TODO: uncomment when Mac plugins are working - // WebPluginDelegateImpl::MoveWindow( - // move.window, move.window_rect, move.clip_rect, move.visible); */ -} - -void TestWebViewDelegate::RegisterDragDrop() { - // TODO: uncomment when Mac drag and drop is working - // DCHECK(!drop_delegate_); - // drop_delegate_ = new TestDropDelegate(shell_->webViewWnd(), - // shell_->webView()); -} - void TestWebViewDelegate::RunModal(WebWidget* webwidget) { - // TODO(pinkerton): implement me -} - -bool TestWebViewDelegate::IsHidden() { - return false; + NOTIMPLEMENTED(); } // Private methods ----------------------------------------------------------- -void TestWebViewDelegate::UpdateAddressBar(WebView* webView) { - WebFrame* mainFrame = webView->GetMainFrame(); - - WebDataSource* dataSource = mainFrame->GetDataSource(); - if (!dataSource) - dataSource = mainFrame->GetProvisionalDataSource(); - if (!dataSource) - return; - - std::string frameURL = dataSource->GetRequest().GetMainDocumentURL().spec(); - NSString *address = [NSString stringWithUTF8String:frameURL.c_str()]; - [shell_->editWnd() setStringValue:address]; -} - -void TestWebViewDelegate::LocationChangeDone(WebDataSource* data_source) { - if (data_source->GetWebFrame() == top_loading_frame_) { - top_loading_frame_ = NULL; - [shell_->webViewHost()->window_handle() setNeedsDisplay:YES]; - - if (!shell_->interactive()) - shell_->layout_test_controller()->LocationChangeDone(); - } -} - -WebWidgetHost* TestWebViewDelegate::GetHostForWidget(WebWidget* webwidget) { - if (webwidget == shell_->webView()) - return shell_->webViewHost(); - if (webwidget == shell_->popup()) - return shell_->popupHost(); - return NULL; -} - -void TestWebViewDelegate::UpdateForCommittedLoad(WebFrame* frame, - bool is_new_navigation) { - WebView* webview = shell_->webView(); - - // Code duplicated from RenderView::DidCommitLoadForFrame. - const WebRequest& request = - webview->GetMainFrame()->GetDataSource()->GetRequest(); - TestShellExtraRequestData* extra_data = - static_cast<TestShellExtraRequestData*>(request.GetExtraData()); - - if (is_new_navigation) { - // New navigation. - UpdateSessionHistory(frame); - page_id_ = next_page_id_++; - } else if (extra_data && extra_data->pending_page_id != -1 && - !extra_data->request_committed) { - // This is a successful session history navigation! - UpdateSessionHistory(frame); - page_id_ = extra_data->pending_page_id; - } - - // Don't update session history multiple times. - if (extra_data) - extra_data->request_committed = true; - - UpdateURL(frame); -} - -void TestWebViewDelegate::UpdateURL(WebFrame* frame) { - WebDataSource* ds = frame->GetDataSource(); - DCHECK(ds); - - const WebRequest& request = ds->GetRequest(); - - scoped_ptr<TestNavigationEntry> entry(new TestNavigationEntry); - - // Bug 654101: the referrer will be empty on https->http transitions. It - // would be nice if we could get the real referrer from somewhere. - entry->SetPageID(page_id_); - if (ds->HasUnreachableURL()) { - entry->SetURL(GURL(ds->GetUnreachableURL())); - } else { - entry->SetURL(GURL(request.GetURL())); - } - - shell_->navigation_controller()->DidNavigateToEntry(entry.release()); - - last_page_id_updated_ = std::max(last_page_id_updated_, page_id_); -} - -void TestWebViewDelegate::UpdateSessionHistory(WebFrame* frame) { - // If we have a valid page ID at this point, then it corresponds to the page - // we are navigating away from. Otherwise, this is the first navigation, so - // there is no past session history to record. - if (page_id_ == -1) - return; - - TestNavigationEntry* entry = static_cast<TestNavigationEntry*>( - shell_->navigation_controller()->GetEntryWithPageID(page_id_)); - if (!entry) - return; - - GURL url; - std::wstring title; - std::string state; - if (!shell_->webView()->GetMainFrame()-> - GetPreviousState(&url, &title, &state)) - return; - - entry->SetURL(url); - entry->SetTitle(title); - entry->SetContentState(state); +void TestWebViewDelegate::SetPageTitle(const std::wstring& title) { + [[shell_->webViewHost()->window_handle() window] + setTitle:[NSString stringWithUTF8String:WideToUTF8(title).c_str()]]; } -std::wstring TestWebViewDelegate::GetFrameDescription(WebFrame* webframe) { - std::wstring name = webframe->GetName(); - - if (webframe == shell_->webView()->GetMainFrame()) { - if (name.length()) - return L"main frame \"" + name + L"\""; - else - return L"main frame"; - } else { - if (name.length()) - return L"frame \"" + name + L"\""; - else - return L"frame (anonymous)"; - } +void TestWebViewDelegate::SetAddressBarURL(const GURL& url) { + const char* frameURL = url.spec().c_str(); + NSString *address = [NSString stringWithUTF8String:frameURL]; + [shell_->editWnd() setStringValue:address]; } diff --git a/webkit/tools/test_shell/mac/webview_host.mm b/webkit/tools/test_shell/mac/webview_host.mm index 803555a..942f55d 100644 --- a/webkit/tools/test_shell/mac/webview_host.mm +++ b/webkit/tools/test_shell/mac/webview_host.mm @@ -29,6 +29,7 @@ WebViewHost* WebViewHost::Create(NSWindow *parent_window, // make the height and width track the window size. [host->view_ setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; [[parent_window contentView] addSubview:host->view_]; + [host->view_ release]; host->webwidget_ = WebView::Create(delegate, prefs); host->webwidget_->Resize(gfx::Size(content_rect.size.width, diff --git a/webkit/tools/test_shell/test_shell.cc b/webkit/tools/test_shell/test_shell.cc index e173f84..6c1e535 100644 --- a/webkit/tools/test_shell/test_shell.cc +++ b/webkit/tools/test_shell/test_shell.cc @@ -129,8 +129,8 @@ TestShell::~TestShell() { } void TestShell::ShutdownTestShell() { -#if defined(OS_WIN) - OleUninitialize(); +#if defined(OS_WIN) || defined(OS_MACOSX) + PlatformShutdown(); #endif SimpleResourceLoaderBridge::Shutdown(); delete window_list_; diff --git a/webkit/tools/test_shell/test_shell.h b/webkit/tools/test_shell/test_shell.h index 839d1ae..33d9d1f 100644 --- a/webkit/tools/test_shell/test_shell.h +++ b/webkit/tools/test_shell/test_shell.h @@ -231,6 +231,11 @@ public: void set_is_modal(bool value) { is_modal_ = value; } bool is_modal() const { return is_modal_; } +#if defined(OS_MACOSX) + // handle cleaning up a shell given the associated window + static void DestroyAssociatedShell(gfx::WindowHandle handle); +#endif + protected: bool Initialize(const std::wstring& startingURL); void SizeToDefault(); @@ -245,6 +250,10 @@ protected: static LRESULT CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM); #endif +#if defined(OS_WIN) || defined(OS_MACOSX) + static void PlatformShutdown(); +#endif + protected: gfx::WindowHandle m_mainWnd; gfx::EditViewHandle m_editWnd; diff --git a/webkit/tools/test_shell/test_shell_mac.mm b/webkit/tools/test_shell/test_shell_mac.mm index 71606ba..31677d2 100644 --- a/webkit/tools/test_shell/test_shell_mac.mm +++ b/webkit/tools/test_shell/test_shell_mac.mm @@ -62,10 +62,70 @@ const int kTestWindowYLocation = -14000; base::LazyInstance <std::map<gfx::WindowHandle, TestShell *> > TestShell::window_map_(base::LINKER_INITIALIZED); +// Receives notification that the window is closing so that it can start the +// tear-down process. Is responsible for deleting itself when done. +@interface WindowCloseDelegate : NSObject { +} +@end + +@implementation WindowCloseDelegate + +// Called when the window is about to close. Perform the self-destruction +// sequence by getting rid of the shell and removing it and the window from +// the various global lists. Instead of doing it here, however, we fire off +// a delayed call to |-cleanup:| to allow everything to get off the stack +// before we go deleting objects. By returning YES, we allow the window to be +// removed from the screen. +- (BOOL)windowShouldClose:(id)window { + // Try to make the window go away, but it may not when running layout + // tests due to the quirkyness of autorelease pools and having no main loop. + [window autorelease]; + + // clean ourselves up and do the work after clearing the stack of anything + // that might have the shell on it. + [self performSelectorOnMainThread:@selector(cleanup:) + withObject:window + waitUntilDone:NO]; + + return YES; +} + +// does the work of removing the window from our various bookkeeping lists +// and gets rid of the shell. +- (void)cleanup:(id)window { + BOOL found = TestShell::RemoveWindowFromList(window); + DCHECK(found); + TestShell::DestroyAssociatedShell(window); + + [self release]; +} + +@end + // Mac-specific stuff to do when the dtor is called. Nothing to do in our // case. void TestShell::PlatformCleanUp() { +} + +// static +void TestShell::DestroyAssociatedShell(gfx::WindowHandle handle) { + TestShell* shell = window_map_.Get()[handle]; + if (shell) + window_map_.Get().erase(handle); + delete shell; +} +// static +void TestShell::PlatformShutdown() { + // for each window in the window list, release it and destroy its shell + for (WindowList::iterator it = TestShell::windowList()->begin(); + it != TestShell::windowList()->end(); + ++it) { + DestroyAssociatedShell(*it); + [*it release]; + } + // assert if we have anything left over, that would be bad. + DCHECK(window_map_.Get().size() == 0); } // static @@ -109,7 +169,18 @@ bool TestShell::Initialize(const std::wstring& startingURL) { defer:NO]; [m_mainWnd setTitle:@"TestShell"]; - // create webview + // Create a window delegate to watch for when it's asked to go away. It will + // clean itself up so we don't need to hold a reference. + [m_mainWnd setDelegate:[[WindowCloseDelegate alloc] init]]; + + // Rely on the window delegate to clean us up rather than immediately + // releasing when the window gets closed. We use the delegate to do + // everything from the autorelease pool so the shell isn't on the stack + // during cleanup (ie, a window close from javascript). + [m_mainWnd setReleasedWhenClosed:NO]; + + // Create a webview. Note that |web_view| takes ownership of this shell so we + // will get cleaned up when it gets destroyed. m_webViewHost.reset( WebViewHost::Create(m_mainWnd, delegate_.get(), *TestShell::web_prefs_)); webView()->SetUseEditorDelegate(true); diff --git a/webkit/tools/test_shell/test_shell_win.cc b/webkit/tools/test_shell/test_shell_win.cc index bd0d557..70db8dc 100644 --- a/webkit/tools/test_shell/test_shell_win.cc +++ b/webkit/tools/test_shell/test_shell_win.cc @@ -92,6 +92,10 @@ void TestShell::DestroyWindow(gfx::WindowHandle windowHandle) { ::DestroyWindow(windowHandle); } +void TestShell::PlatformShutdown() { + OleUninitialize(); +} + ATOM TestShell::RegisterWindowClass() { LoadString(instance_handle_, IDS_APP_TITLE, g_windowTitle, MAX_LOADSTRING); LoadString(instance_handle_, IDC_TESTSHELL, g_windowClass, MAX_LOADSTRING); |