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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #import "chrome/browser/cocoa/blocked_popup_container_controller.h" 5 #import "chrome/browser/cocoa/blocked_popup_container_controller.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/sys_string_conversions.h" 8 #include "base/sys_string_conversions.h"
9 #include "chrome/browser/tab_contents/tab_contents.h" 9 #include "chrome/browser/tab_contents/tab_contents.h"
10 #include "chrome/browser/tab_contents/tab_contents_view.h" 10 #include "chrome/browser/tab_contents/tab_contents_view.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 if ((self = [super init])) { 43 if ((self = [super init])) {
44 container_ = container; 44 container_ = container;
45 bridge_.reset(new BlockedPopupContainerViewBridge(self)); 45 bridge_.reset(new BlockedPopupContainerViewBridge(self));
46 [self initPopupView]; 46 [self initPopupView];
47 } 47 }
48 return self; 48 return self;
49 } 49 }
50 50
51 - (void)dealloc { 51 - (void)dealloc {
52 [view_ removeFromSuperview]; 52 [view_ removeFromSuperview];
53 [[NSNotificationCenter defaultCenter] removeObserver:self];
53 [super dealloc]; 54 [super dealloc];
54 } 55 }
55 56
56 - (IBAction)closePopup:(id)sender { 57 - (IBAction)closePopup:(id)sender {
57 container_->set_dismissed(); 58 container_->set_dismissed();
58 container_->CloseAll(); 59 container_->CloseAll();
59 } 60 }
60 61
61 // Create and initialize the popup view and its label, close box, etc. 62 // Create and initialize the popup view and its label, close box, etc.
62 - (void)initPopupView { 63 - (void)initPopupView {
63 static const float kWidth = 200.0; 64 static const float kWidth = 200.0;
64 static const float kHeight = 20.0; 65 static const float kHeight = 20.0;
65 static const float kCloseBoxSize = 16.0; 66 static const float kCloseBoxSize = 16.0;
66 static const float kCloseBoxPaddingY = 2.0; 67 static const float kCloseBoxPaddingY = 2.0;
67 static const float kLabelPaddingX = 5.0; 68 static const float kLabelPaddingX = 5.0;
68 69
69 // Create it below the parent's bottom edge so we can animate it into place. 70 // Create it below the parent's bottom edge so we can animate it into place.
70 NSRect startFrame = NSMakeRect(0.0, -kHeight, kWidth, kHeight); 71 NSRect startFrame = NSMakeRect(0.0, -kHeight, kWidth, kHeight);
71 view_.reset([[BackgroundGradientView alloc] initWithFrame:startFrame]); 72 view_.reset([[BackgroundGradientView alloc] initWithFrame:startFrame]);
72 [view_ setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin]; 73 [view_ setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin];
73 74
74 // Create the text label and position it. We'll resize it later when the 75 // Create the text label and position it. We'll resize it later when the
75 // label gets updated. The view owns the label, we only hold a weak reference. 76 // label gets updated. The view owns the label, we only hold a weak reference.
76 NSRect labelFrame = NSMakeRect(kLabelPaddingX, 77 NSRect labelFrame = NSMakeRect(kLabelPaddingX,
77 0, 78 0,
78 startFrame.size.width - kCloseBoxSize, 79 startFrame.size.width - kCloseBoxSize,
79 startFrame.size.height); 80 startFrame.size.height);
80 label_ = [[[NSTextField alloc] initWithFrame:labelFrame] autorelease]; 81 popupButton_ = [[[NSPopUpButton alloc] initWithFrame:labelFrame] autorelease];
81 [label_ setSelectable:NO]; 82 [popupButton_ setAutoresizingMask:NSViewWidthSizable];
82 [label_ setAutoresizingMask:NSViewWidthSizable]; 83 [popupButton_ setBordered:NO];
83 [label_ setBordered:NO]; 84 [popupButton_ setBezelStyle:NSTexturedRoundedBezelStyle];
84 [label_ setBezeled:NO]; 85 [popupButton_ setPullsDown:YES];
85 [label_ setDrawsBackground:NO]; 86 // TODO(pinkerton): this doesn't work, not sure why.
86 [view_ addSubview:label_]; 87 [popupButton_ setPreferredEdge:NSMaxYEdge];
88 // TODO(pinkerton): no matter what, the arrows always draw in the middle
89 // of the button. We can turn off the arrows entirely, but then will the
90 // user ever know to click it? Leave them on for now.
91 //[[popupButton_ cell] setArrowPosition:NSPopUpNoArrow];
92 [[popupButton_ cell] setAltersStateOfSelectedItem:NO];
93 // If we don't add this, no title will ever display.
94 [popupButton_ addItemWithTitle:@"placeholder"];
95 [view_ addSubview:popupButton_];
96
97 // Register for notifications that the menu is about to display so we can
98 // fill it in lazily
99 [[NSNotificationCenter defaultCenter]
100 addObserver:self
101 selector:@selector(showMenu:)
102 name:NSPopUpButtonCellWillPopUpNotification
103 object:nil];
87 104
88 // Create the close box and position at the left of the view. 105 // Create the close box and position at the left of the view.
89 NSRect closeFrame = NSMakeRect(startFrame.size.width - kCloseBoxSize, 106 NSRect closeFrame = NSMakeRect(startFrame.size.width - kCloseBoxSize,
90 kCloseBoxPaddingY, 107 kCloseBoxPaddingY,
91 kCloseBoxSize, 108 kCloseBoxSize,
92 kCloseBoxSize); 109 kCloseBoxSize);
93 NSButton* close = [[[NSButton alloc] initWithFrame:closeFrame] autorelease]; 110 NSButton* close = [[[NSButton alloc] initWithFrame:closeFrame] autorelease];
94 [close setAutoresizingMask:NSViewMinXMargin]; 111 [close setAutoresizingMask:NSViewMinXMargin];
95 [close setImage:[NSImage imageNamed:@"close_bar"]]; 112 [close setImage:[NSImage imageNamed:@"close_bar"]];
96 [close setAlternateImage:[NSImage imageNamed:@"close_bar_p"]]; 113 [close setAlternateImage:[NSImage imageNamed:@"close_bar_p"]];
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 [[view_ animator] setFrame:frame]; 149 [[view_ animator] setFrame:frame];
133 } 150 }
134 151
135 - (void)hide { 152 - (void)hide {
136 [view_ removeFromSuperview]; 153 [view_ removeFromSuperview];
137 } 154 }
138 155
139 // Resize the view based on the new label contents. The autoresize mask will 156 // Resize the view based on the new label contents. The autoresize mask will
140 // take care of resizing everything else. 157 // take care of resizing everything else.
141 - (void)resizeWithLabel:(NSString*)label { 158 - (void)resizeWithLabel:(NSString*)label {
159 // TODO(pinkerton): fix this so that it measures the text so that it can
160 // be localized.
142 #if 0 161 #if 0
143 // TODO(pinkerton): fix this once the popup gets put in. 162 NSDictionary* attributes =
144 NSSize stringSize = [label sizeWithAttributes:nil]; 163 [NSDictionary dictionaryWithObjectsAndKeys:
164 NSFontAttributeName, [NSFont systemFontOfSize:25],
165 nil];
166 NSSize stringSize = [label sizeWithAttributes:attributes];
145 NSRect frame = [view_ frame]; 167 NSRect frame = [view_ frame];
146 float originalWidth = frame.size.width; 168 float originalWidth = frame.size.width;
147 frame.size.width = stringSize.width + 16 + 5; 169 frame.size.width = stringSize.width + 16 + 5;
148 frame.origin.x -= frame.size.width - originalWidth; 170 frame.origin.x -= frame.size.width - originalWidth;
149 [view_ setFrame:frame]; 171 [view_ setFrame:frame];
150 #endif 172 #endif
151 } 173 }
152 174
153 - (void)update { 175 - (void)update {
154 size_t blockedPopups = container_->GetBlockedPopupCount(); 176 size_t blockedPopups = container_->GetBlockedPopupCount();
155 NSString* label = nil; 177 NSString* label = nil;
156 if (blockedPopups) { 178 if (blockedPopups) {
157 label = base::SysUTF16ToNSString( 179 label = base::SysUTF16ToNSString(
158 l10n_util::GetStringFUTF16(IDS_POPUPS_BLOCKED_COUNT, 180 l10n_util::GetStringFUTF16(IDS_POPUPS_BLOCKED_COUNT,
159 UintToString16(blockedPopups))); 181 UintToString16(blockedPopups)));
160 } else { 182 } else {
161 label = base::SysUTF16ToNSString( 183 label = base::SysUTF16ToNSString(
162 l10n_util::GetStringUTF16(IDS_POPUPS_UNBLOCKED)); 184 l10n_util::GetStringUTF16(IDS_POPUPS_UNBLOCKED));
163 } 185 }
164 [self resizeWithLabel:label]; 186 [self resizeWithLabel:label];
165 [label_ setStringValue:label]; 187 [popupButton_ setTitle:label];
188 }
189
190 // Called when the user selects an item from the popup menu. The tag, if below
191 // |kImpossibleNumberOfPopups| will be the index into the container's popup
192 // array. In that case, we should display the popup. If >=
193 // |kImpossibleNumberOfPopups|, it represents a host that we should whitelist.
194 // |sender| is the NSMenuItem that was chosen.
195 - (void)menuAction:(id)sender {
196 size_t tag = static_cast<size_t>([sender tag]);
197 if (tag < BlockedPopupContainer::kImpossibleNumberOfPopups) {
198 container_->LaunchPopupAtIndex(tag);
199 } else {
200 size_t hostIndex = tag - BlockedPopupContainer::kImpossibleNumberOfPopups;
201 container_->ToggleWhitelistingForHost(hostIndex);
202 }
203 }
204
205 namespace {
206 void GetURLAndTitleForPopup(
207 const BlockedPopupContainer* container,
208 size_t index,
209 string16* url,
210 string16* title) {
211 DCHECK(url);
212 DCHECK(title);
213 TabContents* tab_contents = container->GetTabContentsAt(index);
214 const GURL& tab_contents_url = tab_contents->GetURL().GetOrigin();
215 *url = UTF8ToUTF16(tab_contents_url.possibly_invalid_spec());
216 *title = tab_contents->GetTitle();
217 }
218 } // namespace
219
220 // Build a new popup menu from scratch. The menu contains the blocked popups
221 // (tags being the popup's index), followed by the list of hosts from which
222 // the popups were blocked (tags being |kImpossibleNumberOfPopups| + host
223 // index). The hosts are used to toggle whitelisting for a site.
224 - (NSMenu*)buildMenu {
225 NSMenu* menu = [[[NSMenu alloc] init] autorelease];
226
227 // For pop-down menus, the first item is what is displayed while tracking the
228 // menu and it remains there if nothing is selected. Set it to the
229 // current title.
230 NSString* currentTitle = [popupButton_ title];
231 scoped_nsobject<NSMenuItem> dummy(
232 [[NSMenuItem alloc] initWithTitle:currentTitle
233 action:nil
234 keyEquivalent:@""]);
235 [menu addItem:dummy.get()];
236
237 // Add the list of blocked popups titles to the menu. We set the array index
238 // as the tag for use in the menu action rather than relying on the menu item
239 // index.
240 const size_t count = container_->GetBlockedPopupCount();
241 for (size_t i = 0; i < count; ++i) {
242 string16 url, title;
243 GetURLAndTitleForPopup(container_, i, &url, &title);
244 NSString* titleStr = base::SysUTF16ToNSString(
245 l10n_util::GetStringFUTF16(IDS_POPUP_TITLE_FORMAT, url, title));
246 scoped_nsobject<NSMenuItem> item(
247 [[NSMenuItem alloc] initWithTitle:titleStr
248 action:@selector(menuAction:)
249 keyEquivalent:@""]);
250 [item setTag:i];
251 [item setTarget:self];
252 [menu addItem:item.get()];
253 }
254
255 // Add the list of hosts. We begin tagging these at
256 // |kImpossibleNumberOfPopups|. If whitelisting has already been enabled
257 // for a site, mark it with a checkmark.
258 std::vector<std::string> hosts(container_->GetHosts());
259 if (!hosts.empty() && count)
260 [menu addItem:[NSMenuItem separatorItem]];
261 for (size_t i = 0; i < hosts.size(); ++i) {
262 NSString* titleStr = base::SysUTF8ToNSString(
263 l10n_util::GetStringFUTF8(IDS_POPUP_HOST_FORMAT,
264 UTF8ToUTF16(hosts[i])));
265 scoped_nsobject<NSMenuItem> item(
266 [[NSMenuItem alloc] initWithTitle:titleStr
267 action:@selector(menuAction:)
268 keyEquivalent:@""]);
269 if (container_->IsHostWhitelisted(i))
270 [item setState:NSOnState];
271 [item setTag:BlockedPopupContainer::kImpossibleNumberOfPopups + i];
272 [item setTarget:self];
273 [menu addItem:item.get()];
274 }
275
276 return menu;
277 }
278
279 // Called when the popup button is about to display the menu, giving us a
280 // chance to fill in the contents.
281 - (void)showMenu:(NSNotification*)notify {
282 NSMenu* menu = [self buildMenu];
283 [[notify object] setMenu:menu];
166 } 284 }
167 285
168 - (NSView*)view { 286 - (NSView*)view {
169 return view_.get(); 287 return view_.get();
170 } 288 }
171 289
172 - (NSView*)label { 290 - (NSPopUpButton*)popupButton {
173 return label_; 291 return popupButton_;
292 }
293
294 // Only used for testing.
295 - (void)setContainer:(BlockedPopupContainer*)container {
296 container_ = container;
174 } 297 }
175 298
176 @end 299 @end
177 300
178 //--------------------------------------------------------------------------- 301 //---------------------------------------------------------------------------
179 302
180 BlockedPopupContainerView* BlockedPopupContainerView::Create( 303 BlockedPopupContainerView* BlockedPopupContainerView::Create(
181 BlockedPopupContainer* container) { 304 BlockedPopupContainer* container) {
182 // We "leak" |blocker| for now, we'll release it when the bridge class 305 // We "leak" |blocker| for now, we'll release it when the bridge class
183 // gets a Destroy() message. 306 // gets a Destroy() message.
(...skipping 23 matching lines...) Expand all
207 [controller_ update]; 330 [controller_ update];
208 } 331 }
209 332
210 void BlockedPopupContainerViewBridge::HideView() { 333 void BlockedPopupContainerViewBridge::HideView() {
211 [controller_ hide]; 334 [controller_ hide];
212 } 335 }
213 336
214 void BlockedPopupContainerViewBridge::Destroy() { 337 void BlockedPopupContainerViewBridge::Destroy() {
215 [controller_ autorelease]; 338 [controller_ autorelease];
216 } 339 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698