WebKitAuthenticationWidget.cpp [plain text]
#include "config.h"
#include "WebKitAuthenticationWidget.h"
#include "CredentialBackingStore.h"
#include "GtkVersioning.h"
#include <glib/gi18n-lib.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/text/CString.h>
using namespace WebCore;
struct _WebKitAuthenticationWidgetPrivate {
AuthenticationChallenge challenge;
CredentialStorageMode credentialStorageMode;
GtkWidget* loginEntry;
GtkWidget* passwordEntry;
GtkWidget* rememberCheckButton;
};
G_DEFINE_TYPE(WebKitAuthenticationWidget, webkit_authentication_widget, GTK_TYPE_BOX)
static const int gLayoutColumnSpacing = 12;
static const int gLayoutRowSpacing = 6;
static const int gButtonSpacing = 5;
#ifdef GTK_API_VERSION_2
static void packTwoColumnLayoutInBox(GtkWidget* box, ...)
{
va_list argumentList;
va_start(argumentList, box);
GtkWidget* table = gtk_table_new(1, 2, FALSE);
gtk_table_set_col_spacings(GTK_TABLE(table), gLayoutColumnSpacing);
gtk_table_set_row_spacings(GTK_TABLE(table), gLayoutRowSpacing);
GtkWidget* firstColumnWidget = va_arg(argumentList, GtkWidget*);
int rowNumber = 0;
while (firstColumnWidget) {
if (rowNumber)
gtk_table_resize(GTK_TABLE(table), rowNumber + 1, 2);
GtkWidget* secondColumnWidget = va_arg(argumentList, GtkWidget*);
GtkAttachOptions attachOptions = static_cast<GtkAttachOptions>(GTK_EXPAND | GTK_FILL);
gtk_table_attach(
GTK_TABLE(table), firstColumnWidget,
0, secondColumnWidget ? 1 : 2,
rowNumber, rowNumber + 1,
attachOptions, attachOptions,
0, 0);
gtk_widget_show(firstColumnWidget);
if (secondColumnWidget) {
gtk_table_attach_defaults(GTK_TABLE(table), secondColumnWidget, 1, 2, rowNumber, rowNumber + 1);
gtk_widget_show(secondColumnWidget);
}
firstColumnWidget = va_arg(argumentList, GtkWidget*);
rowNumber++;
}
va_end(argumentList);
gtk_box_pack_start(GTK_BOX(box), table, FALSE, FALSE, 0);
gtk_widget_show(table);
}
#else
static void packTwoColumnLayoutInBox(GtkWidget* box, ...)
{
va_list argumentList;
va_start(argumentList, box);
GtkWidget* grid = gtk_grid_new();
gtk_grid_set_column_spacing(GTK_GRID(grid), gLayoutRowSpacing);
gtk_grid_set_row_spacing(GTK_GRID(grid), gLayoutRowSpacing);
gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
GtkWidget* firstColumnWidget = va_arg(argumentList, GtkWidget*);
int rowNumber = 0;
while (firstColumnWidget) {
GtkWidget* secondColumnWidget = va_arg(argumentList, GtkWidget*);
int firstWidgetWidth = secondColumnWidget ? 1 : 2;
gtk_grid_attach(GTK_GRID(grid), firstColumnWidget, 0, rowNumber, firstWidgetWidth, 1);
gtk_widget_set_hexpand(firstColumnWidget, TRUE);
gtk_widget_set_vexpand(firstColumnWidget, TRUE);
gtk_widget_show(firstColumnWidget);
if (secondColumnWidget) {
gtk_grid_attach(GTK_GRID(grid), secondColumnWidget, 1, rowNumber, 1, 1);
gtk_widget_set_hexpand(secondColumnWidget, TRUE);
gtk_widget_set_vexpand(secondColumnWidget, TRUE);
gtk_widget_show(secondColumnWidget);
}
firstColumnWidget = va_arg(argumentList, GtkWidget*);
rowNumber++;
}
va_end(argumentList);
gtk_box_pack_start(GTK_BOX(box), grid, FALSE, FALSE, 0);
gtk_widget_show(grid);
}
#endif
static GtkWidget* createLabel(const char* labelString, int horizontalPadding = 0)
{
GtkWidget* label = gtk_label_new(labelString);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
if (horizontalPadding)
gtk_misc_set_padding(GTK_MISC(label), 0, horizontalPadding);
return label;
}
static GtkWidget* createEntry(GtkWidget** member)
{
*member = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(*member), TRUE);
return *member;
}
static void webkitAuthenticationWidgetInitialize(WebKitAuthenticationWidget* authWidget)
{
gtk_orientable_set_orientation(GTK_ORIENTABLE(authWidget), GTK_ORIENTATION_HORIZONTAL);
gtk_box_set_spacing(GTK_BOX(authWidget), gLayoutColumnSpacing);
gtk_container_set_border_width(GTK_CONTAINER(authWidget), gButtonSpacing);
GtkWidget* icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0.0);
gtk_box_pack_start(GTK_BOX(authWidget), icon, FALSE, FALSE, 0);
gtk_widget_show(icon);
WebKitAuthenticationWidgetPrivate* priv = authWidget->priv;
GOwnPtr<char> prompt(g_strdup_printf(
_("The site %s:%i requests a username and password"),
priv->challenge.protectionSpace().host().utf8().data(),
priv->challenge.protectionSpace().port()));
priv->rememberCheckButton = gtk_check_button_new_with_mnemonic(_("_Remember password"));
gtk_label_set_line_wrap(GTK_LABEL(gtk_bin_get_child(GTK_BIN(priv->rememberCheckButton))), TRUE);
String realm = authWidget->priv->challenge.protectionSpace().realm();
if (!realm.isEmpty()) {
packTwoColumnLayoutInBox(
GTK_WIDGET(authWidget),
createLabel(prompt.get(), gLayoutRowSpacing), NULL,
createLabel(_("Server message:")), createLabel(realm.utf8().data()),
createLabel(_("Username:")), createEntry(&priv->loginEntry),
createLabel(_("Password:")), createEntry(&priv->passwordEntry),
priv->rememberCheckButton, NULL,
NULL);
} else {
packTwoColumnLayoutInBox(
GTK_WIDGET(authWidget),
createLabel(prompt.get(), gLayoutRowSpacing), NULL,
createLabel(_("Username:")), createEntry(&priv->loginEntry),
createLabel(_("Password:")), createEntry(&priv->passwordEntry),
priv->rememberCheckButton, NULL, NULL,
NULL);
}
gtk_entry_set_visibility(GTK_ENTRY(priv->passwordEntry), FALSE);
gtk_widget_set_visible(priv->rememberCheckButton, priv->credentialStorageMode != DisallowPersistentStorage);
const Credential& credentialFromPersistentStorage = priv->challenge.proposedCredential();
if (!credentialFromPersistentStorage.isEmpty()) {
gtk_entry_set_text(GTK_ENTRY(priv->loginEntry), credentialFromPersistentStorage.user().utf8().data());
gtk_entry_set_text(GTK_ENTRY(priv->passwordEntry), credentialFromPersistentStorage.password().utf8().data());
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->rememberCheckButton), TRUE);
}
gtk_widget_grab_focus(priv->loginEntry);
}
static void webkitAuthenticationWidgetFinalize(GObject* object)
{
WEBKIT_AUTHENTICATION_WIDGET(object)->priv->~WebKitAuthenticationWidgetPrivate();
G_OBJECT_CLASS(webkit_authentication_widget_parent_class)->finalize(object);
}
static void webkit_authentication_widget_init(WebKitAuthenticationWidget* authWidget)
{
WebKitAuthenticationWidgetPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(authWidget, WEBKIT_TYPE_AUTHENTICATION_WIDGET, WebKitAuthenticationWidgetPrivate);
new (priv) WebKitAuthenticationWidgetPrivate();
authWidget->priv = priv;
}
static void webkit_authentication_widget_class_init(WebKitAuthenticationWidgetClass* klass)
{
GObjectClass* objectClass = G_OBJECT_CLASS(klass);
objectClass->finalize = webkitAuthenticationWidgetFinalize;
g_type_class_add_private(objectClass, sizeof(WebKitAuthenticationWidgetPrivate));
}
GtkWidget* webkitAuthenticationWidgetNew(const AuthenticationChallenge& challenge, CredentialStorageMode mode)
{
WebKitAuthenticationWidget* authWidget = WEBKIT_AUTHENTICATION_WIDGET(g_object_new(WEBKIT_TYPE_AUTHENTICATION_WIDGET, NULL));
authWidget->priv->challenge = challenge;
authWidget->priv->credentialStorageMode = mode;
webkitAuthenticationWidgetInitialize(authWidget);
return GTK_WIDGET(authWidget);
}
Credential webkitAuthenticationWidgetCreateCredential(WebKitAuthenticationWidget* authWidget)
{
const char* username = gtk_entry_get_text(GTK_ENTRY(authWidget->priv->loginEntry));
const char* password = gtk_entry_get_text(GTK_ENTRY(authWidget->priv->passwordEntry));
bool rememberPassword = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(authWidget->priv->rememberCheckButton));
CredentialPersistence persistence;
if (rememberPassword && authWidget->priv->credentialStorageMode == AllowPersistentStorage)
persistence = CredentialPersistencePermanent;
else
persistence = CredentialPersistenceForSession;
return Credential(String::fromUTF8(username), String::fromUTF8(password), persistence);
}
AuthenticationChallenge& webkitAuthenticationWidgetGetChallenge(WebKitAuthenticationWidget* authWidget)
{
return authWidget->priv->challenge;
}