Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4813)

Unified Diff: chrome/browser/cocoa/blocked_popup_container_controller.mm

Issue 149145: Add remaining functionality for popup blocker: popup menu to unblock individu... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/cocoa/blocked_popup_container_controller.mm
===================================================================
--- chrome/browser/cocoa/blocked_popup_container_controller.mm (revision 19942)
+++ chrome/browser/cocoa/blocked_popup_container_controller.mm (working copy)
@@ -50,6 +50,7 @@
- (void)dealloc {
[view_ removeFromSuperview];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@@ -77,14 +78,30 @@
0,
startFrame.size.width - kCloseBoxSize,
startFrame.size.height);
- label_ = [[[NSTextField alloc] initWithFrame:labelFrame] autorelease];
- [label_ setSelectable:NO];
- [label_ setAutoresizingMask:NSViewWidthSizable];
- [label_ setBordered:NO];
- [label_ setBezeled:NO];
- [label_ setDrawsBackground:NO];
- [view_ addSubview:label_];
+ popupButton_ = [[[NSPopUpButton alloc] initWithFrame:labelFrame] autorelease];
+ [popupButton_ setAutoresizingMask:NSViewWidthSizable];
+ [popupButton_ setBordered:NO];
+ [popupButton_ setBezelStyle:NSTexturedRoundedBezelStyle];
+ [popupButton_ setPullsDown:YES];
+ // TODO(pinkerton): this doesn't work, not sure why.
+ [popupButton_ setPreferredEdge:NSMaxYEdge];
+ // TODO(pinkerton): no matter what, the arrows always draw in the middle
+ // of the button. We can turn off the arrows entirely, but then will the
+ // user ever know to click it? Leave them on for now.
+ //[[popupButton_ cell] setArrowPosition:NSPopUpNoArrow];
+ [[popupButton_ cell] setAltersStateOfSelectedItem:NO];
+ // If we don't add this, no title will ever display.
+ [popupButton_ addItemWithTitle:@"placeholder"];
+ [view_ addSubview:popupButton_];
+ // Register for notifications that the menu is about to display so we can
+ // fill it in lazily
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(showMenu:)
+ name:NSPopUpButtonCellWillPopUpNotification
+ object:nil];
+
// Create the close box and position at the left of the view.
NSRect closeFrame = NSMakeRect(startFrame.size.width - kCloseBoxSize,
kCloseBoxPaddingY,
@@ -139,9 +156,14 @@
// Resize the view based on the new label contents. The autoresize mask will
// take care of resizing everything else.
- (void)resizeWithLabel:(NSString*)label {
+// TODO(pinkerton): fix this so that it measures the text so that it can
+// be localized.
#if 0
-// TODO(pinkerton): fix this once the popup gets put in.
- NSSize stringSize = [label sizeWithAttributes:nil];
+ NSDictionary* attributes =
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ NSFontAttributeName, [NSFont systemFontOfSize:25],
+ nil];
+ NSSize stringSize = [label sizeWithAttributes:attributes];
NSRect frame = [view_ frame];
float originalWidth = frame.size.width;
frame.size.width = stringSize.width + 16 + 5;
@@ -162,17 +184,118 @@
l10n_util::GetStringUTF16(IDS_POPUPS_UNBLOCKED));
}
[self resizeWithLabel:label];
- [label_ setStringValue:label];
+ [popupButton_ setTitle:label];
}
+// Called when the user selects an item from the popup menu. The tag, if below
+// |kImpossibleNumberOfPopups| will be the index into the container's popup
+// array. In that case, we should display the popup. If >=
+// |kImpossibleNumberOfPopups|, it represents a host that we should whitelist.
+// |sender| is the NSMenuItem that was chosen.
+- (void)menuAction:(id)sender {
+ size_t tag = static_cast<size_t>([sender tag]);
+ if (tag < BlockedPopupContainer::kImpossibleNumberOfPopups) {
+ container_->LaunchPopupAtIndex(tag);
+ } else {
+ size_t hostIndex = tag - BlockedPopupContainer::kImpossibleNumberOfPopups;
+ container_->ToggleWhitelistingForHost(hostIndex);
+ }
+}
+
+namespace {
+void GetURLAndTitleForPopup(
+ const BlockedPopupContainer* container,
+ size_t index,
+ string16* url,
+ string16* title) {
+ DCHECK(url);
+ DCHECK(title);
+ TabContents* tab_contents = container->GetTabContentsAt(index);
+ const GURL& tab_contents_url = tab_contents->GetURL().GetOrigin();
+ *url = UTF8ToUTF16(tab_contents_url.possibly_invalid_spec());
+ *title = tab_contents->GetTitle();
+}
+} // namespace
+
+// Build a new popup menu from scratch. The menu contains the blocked popups
+// (tags being the popup's index), followed by the list of hosts from which
+// the popups were blocked (tags being |kImpossibleNumberOfPopups| + host
+// index). The hosts are used to toggle whitelisting for a site.
+- (NSMenu*)buildMenu {
+ NSMenu* menu = [[[NSMenu alloc] init] autorelease];
+
+ // For pop-down menus, the first item is what is displayed while tracking the
+ // menu and it remains there if nothing is selected. Set it to the
+ // current title.
+ NSString* currentTitle = [popupButton_ title];
+ scoped_nsobject<NSMenuItem> dummy(
+ [[NSMenuItem alloc] initWithTitle:currentTitle
+ action:nil
+ keyEquivalent:@""]);
+ [menu addItem:dummy.get()];
+
+ // Add the list of blocked popups titles to the menu. We set the array index
+ // as the tag for use in the menu action rather than relying on the menu item
+ // index.
+ const size_t count = container_->GetBlockedPopupCount();
+ for (size_t i = 0; i < count; ++i) {
+ string16 url, title;
+ GetURLAndTitleForPopup(container_, i, &url, &title);
+ NSString* titleStr = base::SysUTF16ToNSString(
+ l10n_util::GetStringFUTF16(IDS_POPUP_TITLE_FORMAT, url, title));
+ scoped_nsobject<NSMenuItem> item(
+ [[NSMenuItem alloc] initWithTitle:titleStr
+ action:@selector(menuAction:)
+ keyEquivalent:@""]);
+ [item setTag:i];
+ [item setTarget:self];
+ [menu addItem:item.get()];
+ }
+
+ // Add the list of hosts. We begin tagging these at
+ // |kImpossibleNumberOfPopups|. If whitelisting has already been enabled
+ // for a site, mark it with a checkmark.
+ std::vector<std::string> hosts(container_->GetHosts());
+ if (!hosts.empty() && count)
+ [menu addItem:[NSMenuItem separatorItem]];
+ for (size_t i = 0; i < hosts.size(); ++i) {
+ NSString* titleStr = base::SysUTF8ToNSString(
+ l10n_util::GetStringFUTF8(IDS_POPUP_HOST_FORMAT,
+ UTF8ToUTF16(hosts[i])));
+ scoped_nsobject<NSMenuItem> item(
+ [[NSMenuItem alloc] initWithTitle:titleStr
+ action:@selector(menuAction:)
+ keyEquivalent:@""]);
+ if (container_->IsHostWhitelisted(i))
+ [item setState:NSOnState];
+ [item setTag:BlockedPopupContainer::kImpossibleNumberOfPopups + i];
+ [item setTarget:self];
+ [menu addItem:item.get()];
+ }
+
+ return menu;
+}
+
+// Called when the popup button is about to display the menu, giving us a
+// chance to fill in the contents.
+- (void)showMenu:(NSNotification*)notify {
+ NSMenu* menu = [self buildMenu];
+ [[notify object] setMenu:menu];
+}
+
- (NSView*)view {
return view_.get();
}
-- (NSView*)label {
- return label_;
+- (NSPopUpButton*)popupButton {
+ return popupButton_;
}
+// Only used for testing.
+- (void)setContainer:(BlockedPopupContainer*)container {
+ container_ = container;
+}
+
@end
//---------------------------------------------------------------------------

Powered by Google App Engine
This is Rietveld 408576698