summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-29 00:36:08 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-29 00:36:08 +0000
commitf221002832abe2c21f8b7c6a94da313b07957f50 (patch)
tree9b707ab21a3326fd9288853ef6abb3afb6d95dc2 /content
parentbae5beebbaccc8b6a6f338015784d27e5bc77929 (diff)
downloadchromium_src-f221002832abe2c21f8b7c6a94da313b07957f50.zip
chromium_src-f221002832abe2c21f8b7c6a94da313b07957f50.tar.gz
chromium_src-f221002832abe2c21f8b7c6a94da313b07957f50.tar.bz2
Content shell: Javascript dialogs, first pass, just Mac for now.
BUG=120155 TEST=javascript dialogs work on the Mac Review URL: http://codereview.chromium.org/9836127 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129537 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/content_shell.gypi4
-rw-r--r--content/shell/shell.cc10
-rw-r--r--content/shell/shell.h5
-rw-r--r--content/shell/shell_javascript_dialog.h52
-rw-r--r--content/shell/shell_javascript_dialog_creator.cc103
-rw-r--r--content/shell/shell_javascript_dialog_creator.h57
-rw-r--r--content/shell/shell_javascript_dialog_mac.mm140
7 files changed, 371 insertions, 0 deletions
diff --git a/content/content_shell.gypi b/content/content_shell.gypi
index aeecdff..49fdafb 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -79,6 +79,10 @@
'shell/shell_devtools_delegate.h',
'shell/shell_download_manager_delegate.cc',
'shell/shell_download_manager_delegate.h',
+ 'shell/shell_javascript_dialog_creator.cc',
+ 'shell/shell_javascript_dialog_creator.h',
+ 'shell/shell_javascript_dialog_mac.mm',
+ 'shell/shell_javascript_dialog.h',
'shell/shell_main_delegate.cc',
'shell/shell_main_delegate.h',
'shell/shell_messages.cc',
diff --git a/content/shell/shell.cc b/content/shell/shell.cc
index 49097bc..dff406f 100644
--- a/content/shell/shell.cc
+++ b/content/shell/shell.cc
@@ -11,6 +11,7 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/shell/shell_javascript_dialog_creator.h"
#include "content/shell/shell_messages.h"
#include "content/shell/shell_switches.h"
#include "ui/gfx/size.h"
@@ -141,6 +142,15 @@ void Shell::DidNavigateMainFramePostCommit(WebContents* tab) {
PlatformSetAddressBarURL(tab->GetURL());
}
+JavaScriptDialogCreator* Shell::GetJavaScriptDialogCreator() {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
+ return NULL;
+
+ if (!dialog_creator_.get())
+ dialog_creator_.reset(new ShellJavaScriptDialogCreator());
+ return dialog_creator_.get();
+}
+
void Shell::DidFinishLoad(int64 frame_id,
const GURL& validated_url,
bool is_main_frame) {
diff --git a/content/shell/shell.h b/content/shell/shell.h
index 93499114..0beb6dd 100644
--- a/content/shell/shell.h
+++ b/content/shell/shell.h
@@ -27,7 +27,9 @@ class GURL;
class WebContents;
namespace content {
+
class BrowserContext;
+class ShellJavaScriptDialogCreator;
class SiteInstance;
// This represents one window of the Content Shell, i.e. all the UI including
@@ -115,6 +117,7 @@ class Shell : public WebContentsDelegate,
const GURL& target_url,
WebContents* new_contents) OVERRIDE;
virtual void DidNavigateMainFramePostCommit(WebContents* tab) OVERRIDE;
+ virtual JavaScriptDialogCreator* GetJavaScriptDialogCreator() OVERRIDE;
#if defined(OS_MACOSX)
virtual void HandleKeyboardEvent(
const NativeWebKeyboardEvent& event) OVERRIDE;
@@ -143,6 +146,8 @@ class Shell : public WebContentsDelegate,
GObject*, guint, GdkModifierType);
#endif
+ scoped_ptr<ShellJavaScriptDialogCreator> dialog_creator_;
+
scoped_ptr<WebContents> web_contents_;
// layoutTestController related variables.
diff --git a/content/shell/shell_javascript_dialog.h b/content/shell/shell_javascript_dialog.h
new file mode 100644
index 0000000..32d425d
--- /dev/null
+++ b/content/shell/shell_javascript_dialog.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_SHELL_JAVASCRIPT_DIALOG_H_
+#define CONTENT_SHELL_SHELL_JAVASCRIPT_DIALOG_H_
+#pragma once
+
+#include "content/public/browser/javascript_dialogs.h"
+
+#if defined(OS_MACOSX)
+#if __OBJC__
+@class NSAlert;
+@class ShellJavaScriptDialogHelper;
+#else
+class NSAlert;
+class ShellJavaScriptDialogHelper;
+#endif // __OBJC__
+#endif // defined(OS_MACOSX)
+
+namespace content {
+
+class ShellJavaScriptDialogCreator;
+
+class ShellJavaScriptDialog {
+ public:
+ ShellJavaScriptDialog(
+ ShellJavaScriptDialogCreator* creator,
+ ui::JavascriptMessageType javascript_message_type,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const JavaScriptDialogCreator::DialogClosedCallback& callback);
+ ~ShellJavaScriptDialog();
+
+ // Called to cancel a dialog mid-flight.
+ void Cancel();
+
+ private:
+ ShellJavaScriptDialogCreator* creator_;
+ JavaScriptDialogCreator::DialogClosedCallback callback_;
+
+#if defined(OS_MACOSX)
+ ShellJavaScriptDialogHelper* helper_; // owned
+ NSAlert* alert_; // weak, owned by |helper_|.
+#endif // defined(OS_MACOSX)
+
+ DISALLOW_COPY_AND_ASSIGN(ShellJavaScriptDialog);
+};
+
+} // namespace content
+
+#endif // CONTENT_SHELL_SHELL_JAVASCRIPT_DIALOG_H_
diff --git a/content/shell/shell_javascript_dialog_creator.cc b/content/shell/shell_javascript_dialog_creator.cc
new file mode 100644
index 0000000..d6b100c
--- /dev/null
+++ b/content/shell/shell_javascript_dialog_creator.cc
@@ -0,0 +1,103 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/shell_javascript_dialog_creator.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "content/shell/shell_javascript_dialog.h"
+#include "net/base/net_util.h"
+
+namespace content {
+
+ShellJavaScriptDialogCreator::ShellJavaScriptDialogCreator() {
+}
+
+ShellJavaScriptDialogCreator::~ShellJavaScriptDialogCreator() {
+}
+
+void ShellJavaScriptDialogCreator::RunJavaScriptDialog(
+ WebContents* web_contents,
+ const GURL& origin_url,
+ const std::string& accept_lang,
+ ui::JavascriptMessageType javascript_message_type,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const DialogClosedCallback& callback,
+ bool* did_suppress_message) {
+#if defined(OS_MACOSX)
+ *did_suppress_message = false;
+
+ if (dialog_.get()) {
+ // One dialog at a time, please.
+ *did_suppress_message = true;
+ return;
+ }
+
+ string16 new_message_text = net::FormatUrl(origin_url, accept_lang) +
+ ASCIIToUTF16("\n\n") +
+ message_text;
+
+ dialog_.reset(new ShellJavaScriptDialog(this,
+ javascript_message_type,
+ new_message_text,
+ default_prompt_text,
+ callback));
+#else
+ // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
+ *did_suppress_message = true;
+ return;
+#endif
+}
+
+void ShellJavaScriptDialogCreator::RunBeforeUnloadDialog(
+ WebContents* web_contents,
+ const string16& message_text,
+ bool is_reload,
+ const DialogClosedCallback& callback) {
+#if defined(OS_MACOSX)
+ if (dialog_.get()) {
+ // Seriously!?
+ callback.Run(true, string16());
+ return;
+ }
+
+ string16 new_message_text =
+ message_text +
+ ASCIIToUTF16("\n\nIs it OK to leave/reload this page?");
+
+ dialog_.reset(new ShellJavaScriptDialog(this,
+ ui::JAVASCRIPT_MESSAGE_TYPE_CONFIRM,
+ new_message_text,
+ string16(), // default_prompt_text
+ callback));
+#else
+ // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
+ callback.Run(true, string16());
+ return;
+#endif
+}
+
+void ShellJavaScriptDialogCreator::ResetJavaScriptState(
+ WebContents* web_contents) {
+#if defined(OS_MACOSX)
+ if (dialog_.get()) {
+ dialog_->Cancel();
+ dialog_.reset();
+ }
+#else
+ // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
+#endif
+}
+
+void ShellJavaScriptDialogCreator::DialogClosed(ShellJavaScriptDialog* dialog) {
+#if defined(OS_MACOSX)
+ DCHECK_EQ(dialog, dialog_.get());
+ dialog_.reset();
+#else
+ // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
+#endif
+}
+
+} // namespace content
diff --git a/content/shell/shell_javascript_dialog_creator.h b/content/shell/shell_javascript_dialog_creator.h
new file mode 100644
index 0000000..88e5db6
--- /dev/null
+++ b/content/shell/shell_javascript_dialog_creator.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_SHELL_JAVASCRIPT_DIALOG_CREATOR_H_
+#define CONTENT_SHELL_SHELL_JAVASCRIPT_DIALOG_CREATOR_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/javascript_dialogs.h"
+
+namespace content {
+
+class ShellJavaScriptDialog;
+
+class ShellJavaScriptDialogCreator : public JavaScriptDialogCreator {
+ public:
+ ShellJavaScriptDialogCreator();
+ virtual ~ShellJavaScriptDialogCreator();
+
+ // JavaScriptDialogCreator:
+ virtual void RunJavaScriptDialog(
+ WebContents* web_contents,
+ const GURL& origin_url,
+ const std::string& accept_lang,
+ ui::JavascriptMessageType javascript_message_type,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const DialogClosedCallback& callback,
+ bool* did_suppress_message) OVERRIDE;
+
+ virtual void RunBeforeUnloadDialog(
+ WebContents* web_contents,
+ const string16& message_text,
+ bool is_reload,
+ const DialogClosedCallback& callback) OVERRIDE;
+
+ virtual void ResetJavaScriptState(WebContents* web_contents) OVERRIDE;
+
+ // Called by the ShellJavaScriptDialog when it closes.
+ void DialogClosed(ShellJavaScriptDialog* dialog);
+
+ private:
+#if defined(OS_MACOSX)
+ // The dialog being shown. No queueing.
+ scoped_ptr<ShellJavaScriptDialog> dialog_;
+#else
+ // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(ShellJavaScriptDialogCreator);
+};
+
+} // namespace content
+
+#endif // CONTENT_SHELL_SHELL_JAVASCRIPT_DIALOG_CREATOR_H_
diff --git a/content/shell/shell_javascript_dialog_mac.mm b/content/shell/shell_javascript_dialog_mac.mm
new file mode 100644
index 0000000..543bb55
--- /dev/null
+++ b/content/shell/shell_javascript_dialog_mac.mm
@@ -0,0 +1,140 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/shell_javascript_dialog.h"
+
+#import <Cocoa/Cocoa.h>
+
+#import "base/mac/cocoa_protocols.h"
+#import "base/memory/scoped_nsobject.h"
+#include "base/sys_string_conversions.h"
+#include "content/shell/shell_javascript_dialog_creator.h"
+
+// Helper object that receives the notification that the dialog/sheet is
+// going away. Is responsible for cleaning itself up.
+@interface ShellJavaScriptDialogHelper : NSObject<NSAlertDelegate> {
+ @private
+ scoped_nsobject<NSAlert> alert_;
+ NSTextField* textField_; // WEAK; owned by alert_
+
+ // Copies of the fields in ShellJavaScriptDialog because they're private.
+ content::ShellJavaScriptDialogCreator* creator_;
+ content::JavaScriptDialogCreator::DialogClosedCallback callback_;
+}
+
+- (id)initHelperWithCreator:(content::ShellJavaScriptDialogCreator*)creator
+ andCallback:(content::JavaScriptDialogCreator::DialogClosedCallback)callback;
+- (NSAlert*)alert;
+- (NSTextField*)textField;
+- (void)alertDidEnd:(NSAlert*)alert
+ returnCode:(int)returnCode
+ contextInfo:(void*)contextInfo;
+- (void)cancel;
+
+@end
+
+@implementation ShellJavaScriptDialogHelper
+
+- (id)initHelperWithCreator:(content::ShellJavaScriptDialogCreator*)creator
+ andCallback:(content::JavaScriptDialogCreator::DialogClosedCallback)callback {
+ if (self = [super init]) {
+ creator_ = creator;
+ callback_ = callback;
+ }
+
+ return self;
+}
+
+- (NSAlert*)alert {
+ alert_.reset([[NSAlert alloc] init]);
+ return alert_;
+}
+
+- (NSTextField*)textField {
+ textField_ = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 22)];
+ [[textField_ cell] setLineBreakMode:NSLineBreakByTruncatingTail];
+ [alert_ setAccessoryView:textField_];
+ [textField_ release];
+
+ return textField_;
+}
+
+- (void)alertDidEnd:(NSAlert*)alert
+ returnCode:(int)returnCode
+ contextInfo:(void*)contextInfo {
+ if (returnCode == NSRunStoppedResponse)
+ return;
+
+ bool success = returnCode == NSAlertFirstButtonReturn;
+ string16 input;
+ if (textField_)
+ input = base::SysNSStringToUTF16([textField_ stringValue]);
+
+ content::ShellJavaScriptDialog* native_dialog =
+ reinterpret_cast<content::ShellJavaScriptDialog*>(contextInfo);
+ callback_.Run(success, input);
+ creator_->DialogClosed(native_dialog);
+}
+
+- (void)cancel {
+ [NSApp endSheet:[alert_ window]];
+ alert_.reset();
+}
+
+@end
+
+namespace content {
+
+ShellJavaScriptDialog::ShellJavaScriptDialog(
+ ShellJavaScriptDialogCreator* creator,
+ ui::JavascriptMessageType javascript_message_type,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const JavaScriptDialogCreator::DialogClosedCallback& callback)
+ : creator_(creator),
+ callback_(callback) {
+ bool text_field =
+ javascript_message_type == ui::JAVASCRIPT_MESSAGE_TYPE_PROMPT;
+ bool one_button =
+ javascript_message_type == ui::JAVASCRIPT_MESSAGE_TYPE_ALERT;
+
+ helper_ =
+ [[ShellJavaScriptDialogHelper alloc] initHelperWithCreator:creator
+ andCallback:callback];
+
+ // Show the modal dialog.
+ alert_ = [helper_ alert];
+ NSTextField* field = nil;
+ if (text_field) {
+ field = [helper_ textField];
+ [field setStringValue:base::SysUTF16ToNSString(default_prompt_text)];
+ }
+ [alert_ setDelegate:helper_];
+ [alert_ setInformativeText:base::SysUTF16ToNSString(message_text)];
+ [alert_ setMessageText:@"Javascript alert"];
+ [alert_ addButtonWithTitle:@"OK"];
+ if (!one_button) {
+ NSButton* other = [alert_ addButtonWithTitle:@"Cancel"];
+ [other setKeyEquivalent:@"\e"];
+ }
+
+ [alert_
+ beginSheetModalForWindow:nil // nil here makes it app-modal
+ modalDelegate:helper_
+ didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
+ contextInfo:this];
+
+ if ([alert_ accessoryView])
+ [[alert_ window] makeFirstResponder:[alert_ accessoryView]];
+}
+
+ShellJavaScriptDialog::~ShellJavaScriptDialog() {
+ [helper_ release];
+}
+
+void ShellJavaScriptDialog::Cancel() {
+ [helper_ cancel];
+}
+
+} // namespace content