summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/scoped_vector.h10
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field.mm40
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell.h59
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell.mm164
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm26
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_editor.mm25
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm2
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_unittest.mm14
-rw-r--r--chrome/browser/cocoa/extension_installed_bubble_controller.mm4
-rw-r--r--chrome/browser/cocoa/location_bar_view_mac.h62
-rw-r--r--chrome/browser/cocoa/location_bar_view_mac.mm104
11 files changed, 328 insertions, 182 deletions
diff --git a/base/scoped_vector.h b/base/scoped_vector.h
index 0c7449d..c007ce4 100644
--- a/base/scoped_vector.h
+++ b/base/scoped_vector.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -17,6 +17,9 @@ class ScopedVector {
public:
typedef typename std::vector<T*>::iterator iterator;
typedef typename std::vector<T*>::const_iterator const_iterator;
+ typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
+ typedef typename std::vector<T*>::const_reverse_iterator
+ const_reverse_iterator;
ScopedVector() {}
~ScopedVector() { reset(); }
@@ -29,6 +32,11 @@ class ScopedVector {
bool empty() const { return v.empty(); }
size_t size() const { return v.size(); }
+ reverse_iterator rbegin() { return v.rbegin(); }
+ const_reverse_iterator rbegin() const { return v.rbegin(); }
+ reverse_iterator rend() { return v.rend(); }
+ const_reverse_iterator rend() const { return v.rend(); }
+
iterator begin() { return v.begin(); }
const_iterator begin() const { return v.begin(); }
iterator end() { return v.end(); }
diff --git a/chrome/browser/cocoa/autocomplete_text_field.mm b/chrome/browser/cocoa/autocomplete_text_field.mm
index 2f263f7..488a8f2 100644
--- a/chrome/browser/cocoa/autocomplete_text_field.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -115,21 +115,12 @@
return;
}
- // If the user clicked the security hint icon in the cell, display the page
- // info window.
- const NSRect hintIconFrame = [cell securityImageFrameForFrame:bounds];
- if (NSMouseInRect(location, hintIconFrame, flipped)) {
- [cell onSecurityIconMousePressed];
- return;
- }
-
+ // If the user clicked on one of the icons (security icon, Page Actions, etc),
+ // let the icon handle the click.
const BOOL ctrlKey = ([theEvent modifierFlags] & NSControlKeyMask) != 0;
- // If the user left-clicked a Page Action icon, execute its action.
- const size_t pageActionCount = [cell pageActionCount];
- for (size_t i = 0; i < pageActionCount; ++i) {
- NSRect pageActionFrame = [cell pageActionFrameForIndex:i inFrame:bounds];
- if (NSMouseInRect(location, pageActionFrame, flipped) && !ctrlKey) {
- [cell onPageActionMousePressedIn:pageActionFrame forIndex:i];
+ for (AutocompleteTextFieldIcon* icon in [cell layedOutIcons:bounds]) {
+ if (NSMouseInRect(location, [icon rect], flipped) && !ctrlKey) {
+ [icon view]->OnMousePressed([icon rect]);
return;
}
}
@@ -204,14 +195,8 @@
[self addCursorRect:fieldBounds cursor:[NSCursor IBeamCursor]];
AutocompleteTextFieldCell* cell = [self autocompleteTextFieldCell];
- NSRect iconRect = [cell securityImageFrameForFrame:fieldBounds];
- [self addCursorRect:iconRect cursor:[NSCursor arrowCursor]];
-
- const size_t pageActionCount = [cell pageActionCount];
- for (size_t i = 0; i < pageActionCount; ++i) {
- iconRect = [cell pageActionFrameForIndex:i inFrame:fieldBounds];
- [self addCursorRect:iconRect cursor:[NSCursor arrowCursor]];
- }
+ for (AutocompleteTextFieldIcon* icon in [cell layedOutIcons:fieldBounds])
+ [self addCursorRect:[icon rect] cursor:[NSCursor arrowCursor]];
}
- (void)updateCursorAndToolTipRects {
@@ -226,14 +211,13 @@
[currentToolTips_ removeAllObjects];
AutocompleteTextFieldCell* cell = [self autocompleteTextFieldCell];
- const size_t pageActionCount = [cell pageActionCount];
- for (size_t i = 0; i < pageActionCount; ++i) {
- NSRect iconRect = [cell pageActionFrameForIndex:i inFrame:[self bounds]];
- NSString* tooltip = [cell pageActionToolTipForIndex:i];
+ for (AutocompleteTextFieldIcon* icon in [cell layedOutIcons:[self bounds]]) {
+ NSRect iconRect = [icon rect];
+ NSString* tooltip = [icon view]->GetToolTip();
if (!tooltip)
continue;
- // -[NSView addToolTipRect:owner:userData] does _not_ retain the owner!
+ // -[NSView addToolTipRect:owner:userData] does _not_ retain its |owner:|.
// Put the string in a collection so it can't be dealloced while in use.
[currentToolTips_ addObject:tooltip];
[self addToolTipRect:iconRect owner:tooltip userData:nil];
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.h b/chrome/browser/cocoa/autocomplete_text_field_cell.h
index bcd595e..3763e2c 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.h
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -11,6 +11,24 @@
class ExtensionAction;
+// Holds a |LocationBarImageView| and its current rect. Do not keep references
+// to this object, only use it directly after calling |-layedOutIcons:|.
+@interface AutocompleteTextFieldIcon : NSObject {
+ // The frame rect of |view_|.
+ NSRect rect_;
+
+ // weak, owned by LocationBarViewMac.
+ LocationBarViewMac::LocationBarImageView* view_;
+}
+
+// Returns a new AutocompleteTextFieldIcon object.
++ (AutocompleteTextFieldIcon*)
+ iconWithRect:(NSRect)rect
+ view:(LocationBarViewMac::LocationBarImageView*)view;
+@property(assign, nonatomic) NSRect rect;
+@property(assign, nonatomic) LocationBarViewMac::LocationBarImageView* view;
+@end
+
// AutocompleteTextFieldCell extends StyledTextFieldCell to provide support for
// certain decorations to be applied to the field. These are the search hint
// ("Type to search" on the right-hand side), the keyword hint ("Press [Tab] to
@@ -35,6 +53,9 @@ class ExtensionAction;
// Display is exclusive WRT the |hintString_| and |keywordString_|.
// This may be NULL during testing.
LocationBarViewMac::PageActionViewList* page_action_views_;
+
+ // List of content blocked icons. This may be NULL during testing.
+ LocationBarViewMac::ContentBlockedViews* content_blocked_views_;
}
// Chooses |partialString| if |width| won't fit |fullString|. Strings
@@ -58,34 +79,21 @@ class ExtensionAction;
- (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view;
- (void)setPageActionViewList:(LocationBarViewMac::PageActionViewList*)list;
+- (void)setContentBlockedViewList:
+ (LocationBarViewMac::ContentBlockedViews*)views;
-// Returns the total number of installed Page Actions, visible or not.
-- (size_t)pageActionCount;
+// Returns an array of the visible AutocompleteTextFieldIcon objects. Returns
+// only visible icons.
+- (NSArray*)layedOutIcons:(NSRect)cellFrame;
-// Called when the security icon is visible and clicked. Passed through to the
-// security_image_view_ to handle the click (i.e., show the page info dialog).
-- (void)onSecurityIconMousePressed;
-
-// Returns the portion of the cell to use for displaying the security (SSL lock)
-// icon, leaving space for its label if any.
-- (NSRect)securityImageFrameForFrame:(NSRect)cellFrame;
// Returns the portion of the cell to use for displaying the Page Action icon
// at the given index. May be NSZeroRect if the index's action is not visible.
+// This does a linear walk over all page actions, so do not call this in a loop
+// to get the position of all page actions. Use |-layedOutIcons:| instead in that
+// case.
- (NSRect)pageActionFrameForIndex:(size_t)index inFrame:(NSRect)cellFrame;
-// Returns the string to be shown on hover for the Page Action icon at the
-// given index.
-- (NSString*)pageActionToolTipForIndex:(size_t)index;
-
-// Returns a pointer to the ExtensionAction object that the view at the
-// specified index represents.
-- (ExtensionAction*)pageActionForIndex:(size_t)index;
-
-// Called when the Page Action at the given index, whose icon is drawn in the
-// iconFrame, is visible and clicked. Passed through to the list of views to
-// handle the click.
-- (void)onPageActionMousePressedIn:(NSRect)iconFrame forIndex:(size_t)index;
@end
@@ -96,4 +104,11 @@ class ExtensionAction;
@property(readonly) NSAttributedString* hintString;
@property(readonly) NSAttributedString* hintIconLabel;
+// Returns the total number of installed Page Actions, visible or not.
+- (size_t)pageActionCount;
+
+// Returns the portion of the cell to use for displaying the security (SSL lock)
+// icon, leaving space for its label if any.
+- (NSRect)securityImageFrameForFrame:(NSRect)cellFrame;
+
@end
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
index 8558b80..8772f5a 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -57,6 +57,22 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
} // namespace
+@implementation AutocompleteTextFieldIcon
+
+@synthesize rect = rect_;
+@synthesize view = view_;
+
++ (AutocompleteTextFieldIcon*)
+ iconWithRect:(NSRect)rect
+ view:(LocationBarViewMac::LocationBarImageView*)view {
+ AutocompleteTextFieldIcon* result = [[AutocompleteTextFieldIcon alloc] init];
+ [result setRect:rect];
+ [result setView:view];
+ return [result autorelease];
+}
+
+@end
+
@implementation AutocompleteTextFieldCell
// @synthesize doesn't seem to compile for this transition.
@@ -202,12 +218,9 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
security_image_view_ = view;
}
-- (void)onSecurityIconMousePressed {
- security_image_view_->OnMousePressed();
-}
-
-- (void)onPageActionMousePressedIn:(NSRect)iconFrame forIndex:(size_t)index {
- page_action_views_->OnMousePressed(iconFrame, index);
+- (void)setContentBlockedViewList:
+ (LocationBarViewMac::ContentBlockedViews*)views {
+ content_blocked_views_ = views;
}
// Overriden to account for the hint strings and hint icons.
@@ -235,32 +248,15 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame);
}
} else {
- // Account for the lock icon, if any, and any visible Page Action icons.
+ // Leave room for images on the right (lock icon etc).
+ NSArray* iconFrames = [self layedOutIcons:cellFrame];
CGFloat width = 0;
- const size_t iconCount = [self pageActionCount];
- for (size_t i = 0; i < iconCount; ++i) {
- LocationBarViewMac::PageActionImageView* view =
- page_action_views_->ViewAt(i);
- NSImage* image = view->GetImage();
- if (image && view->IsVisible()) {
- width += [image size].width + kIconHorizontalPad;
- }
- }
-
- if (security_image_view_ && security_image_view_->IsVisible()) {
- width += [security_image_view_->GetImage() size].width +
- kIconHorizontalPad;
- NSAttributedString* label = security_image_view_->GetLabel();
- if (label) {
- width += ceil([label size].width) + kHintXOffset;
- }
- }
+ if ([iconFrames count] > 0)
+ width = NSMaxX(cellFrame) - NSMinX([[iconFrames lastObject] rect]);
if (width > 0)
width += kIconHorizontalPad;
-
- if (width < NSWidth(cellFrame)) {
+ if (width < NSWidth(cellFrame))
textFrame.size.width -= width;
- }
}
return textFrame;
@@ -308,53 +304,21 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
- (NSRect)pageActionFrameForIndex:(size_t)index inFrame:(NSRect)cellFrame {
LocationBarViewMac::PageActionImageView* view =
page_action_views_->ViewAt(index);
- const NSImage* icon = view->GetImage();
// If we are calculating space for a preview page action, the icon is still
// loading. We use this function only to get the correct x value for the
// extension installed bubble arrow.
if (!view->preview_enabled() &&
- (!icon || !view->IsVisible())) {
+ (!view->GetImage() || !view->IsVisible())) {
return NSZeroRect;
}
- // Compute the amount of space used by this icon plus any other icons to its
- // right. It's terribly inefficient to do this anew every time, but easy to
- // understand. It should be fine for 5 or 10 installed Page Actions, perhaps
- // too slow for 100.
- // TODO(pamg): Refactor to avoid this if performance is a problem.
- const NSRect securityIconRect = [self securityImageFrameForFrame:cellFrame];
- CGFloat widthUsed = 0.0;
- if (NSWidth(securityIconRect) > 0) {
- widthUsed += NSMaxX(cellFrame) - NSMinX(securityIconRect);
+ for (AutocompleteTextFieldIcon* icon in [self layedOutIcons:cellFrame]) {
+ if (view == [icon view])
+ return [icon rect];
}
- for (size_t i = 0; i <= index; ++i) {
- view = page_action_views_->ViewAt(i);
- if (view->IsVisible()) {
- NSImage* image = view->GetImage();
- if (image) {
- // Page Action icons don't have labels. Don't compute space for them.
- widthUsed += [image size].width + kIconHorizontalPad;
- }
- }
- }
- widthUsed += kIconHorizontalPad;
-
- // If we are calculating frame space for a preview, the icon is still
- // loading -- use maximum size as a placeholder.
- NSSize iconSize = view->GetImageSize();
-
- return [self rightJustifyImage:iconSize
- inRect:cellFrame
- withMargin:widthUsed];
-}
-
-- (NSString*)pageActionToolTipForIndex:(size_t)index {
- return page_action_views_->ViewAt(index)->GetToolTip();
-}
-
-- (ExtensionAction*)pageActionForIndex:(size_t)index {
- return page_action_views_->ViewAt(index)->page_action();
+ NOTREACHED();
+ return NSZeroRect;
}
- (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
@@ -430,25 +394,65 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
} else if (keywordString_) {
[self drawKeywordWithFrame:cellFrame inView:controlView];
} else {
- if (security_image_view_ && security_image_view_->IsVisible()) {
- [self drawImageView:security_image_view_
- inFrame:[self securityImageFrameForFrame:cellFrame]
+ for (AutocompleteTextFieldIcon* icon in [self layedOutIcons:cellFrame]) {
+ [self drawImageView:[icon view]
+ inFrame:[icon rect]
inView:controlView];
}
+ }
- const size_t pageActionCount = [self pageActionCount];
- for (size_t i = 0; i < pageActionCount; ++i) {
- LocationBarViewMac::PageActionImageView* view =
- page_action_views_->ViewAt(i);
- if (view && view->IsVisible()) {
- [self drawImageView:view
- inFrame:[self pageActionFrameForIndex:i inFrame:cellFrame]
- inView:controlView];
- }
+ [super drawInteriorWithFrame:cellFrame inView:controlView];
+}
+
+- (NSArray*)layedOutIcons:(NSRect)cellFrame {
+ NSMutableArray* result = [NSMutableArray arrayWithCapacity:0];
+ NSRect iconFrame = cellFrame;
+ if (security_image_view_ && security_image_view_->IsVisible()) {
+ NSRect securityImageFrame = [self securityImageFrameForFrame:iconFrame];
+ [result addObject:
+ [AutocompleteTextFieldIcon iconWithRect:securityImageFrame
+ view:security_image_view_]];
+ iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(securityImageFrame);
+ }
+
+ const size_t pageActionCount = [self pageActionCount];
+ for (size_t i = 0; i < pageActionCount; ++i) {
+ LocationBarViewMac::PageActionImageView* view =
+ page_action_views_->ViewAt(i);
+ if (view->preview_enabled() || (view->GetImage() && view->IsVisible())) {
+ NSSize iconSize = view->GetImageSize();
+ NSRect pageActionFrame =
+ [self rightJustifyImage:iconSize
+ inRect:iconFrame
+ withMargin:kIconHorizontalPad + iconSize.width];
+ [result addObject:
+ [AutocompleteTextFieldIcon iconWithRect:pageActionFrame view:view]];
+ iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(pageActionFrame);
}
}
- [super drawInteriorWithFrame:cellFrame inView:controlView];
+ if (content_blocked_views_) {
+ // We use a reverse_iterator here because we're laying out the views from
+ // right to left but in the vector they're ordered left to right.
+ for (LocationBarViewMac::ContentBlockedViews::const_reverse_iterator
+ it(content_blocked_views_->rbegin());
+ it != const_cast<const LocationBarViewMac::ContentBlockedViews*>(
+ content_blocked_views_)->rend();
+ ++it) {
+ if ((*it)->IsVisible()) {
+ NSImage* image = (*it)->GetImage();
+ NSRect blockedContentFrame =
+ [self rightJustifyImage:[image size]
+ inRect:iconFrame
+ withMargin:[image size].width + kIconHorizontalPad];
+ [result addObject:
+ [AutocompleteTextFieldIcon iconWithRect:blockedContentFrame
+ view:*it]];
+ iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(blockedContentFrame);
+ }
+ }
+ }
+ return result;
}
@end
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
index a83cdab..9023d4b 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
@@ -284,14 +284,12 @@ TEST_F(AutocompleteTextFieldCellTest, SecurityImageFrame) {
LocationBarViewMac::SecurityImageView::LOCK);
security_image_view_.SetVisible(false);
- NSRect iconRect = [cell securityImageFrameForFrame:bounds];
- EXPECT_TRUE(NSIsEmptyRect(iconRect));
-
- // Save the starting frame for after clear.
- const NSRect originalIconRect(iconRect);
+ EXPECT_EQ(0u, [[cell layedOutIcons:bounds] count]);
security_image_view_.SetVisible(true);
- iconRect = [cell securityImageFrameForFrame:bounds];
+ NSArray* icons = [cell layedOutIcons:bounds];
+ ASSERT_EQ(1u, [icons count]);
+ NSRect iconRect = [[icons objectAtIndex:0] rect];
EXPECT_FALSE(NSIsEmptyRect(iconRect));
EXPECT_TRUE(NSContainsRect(bounds, iconRect));
@@ -308,7 +306,9 @@ TEST_F(AutocompleteTextFieldCellTest, SecurityImageFrame) {
NSFont* font = [NSFont controlContentFontOfSize:12.0];
NSColor* color = [NSColor blackColor];
security_image_view_.SetLabel(@"Label", font, color);
- iconRect = [cell securityImageFrameForFrame:bounds];
+ icons = [cell layedOutIcons:bounds];
+ ASSERT_EQ(1u, [icons count]);
+ iconRect = [[icons objectAtIndex:0] rect];
EXPECT_FALSE(NSIsEmptyRect(iconRect));
EXPECT_TRUE(NSContainsRect(bounds, iconRect));
@@ -323,9 +323,7 @@ TEST_F(AutocompleteTextFieldCellTest, SecurityImageFrame) {
// Make sure we clear correctly.
security_image_view_.SetVisible(false);
- iconRect = [cell securityImageFrameForFrame:bounds];
- EXPECT_TRUE(NSEqualRects(iconRect, originalIconRect));
- EXPECT_TRUE(NSIsEmptyRect(iconRect));
+ EXPECT_EQ(0u, [[cell layedOutIcons:bounds] count]);
}
// Test Page Action counts.
@@ -382,6 +380,7 @@ TEST_F(AutocompleteTextFieldCellTest, PageActionImageFrame) {
EXPECT_TRUE(NSIsEmptyRect([cell pageActionFrameForIndex:2 inFrame:bounds]));
preview_view.set_preview_enabled(true);
EXPECT_FALSE(NSIsEmptyRect([cell pageActionFrameForIndex:2 inFrame:bounds]));
+ preview_view.set_preview_enabled(false);
// One page action, no security icon.
page_action_view.SetVisible(true);
@@ -401,9 +400,14 @@ TEST_F(AutocompleteTextFieldCellTest, PageActionImageFrame) {
// Two page actions plus a security icon.
page_action_view2.SetVisible(true);
security_image_view_.SetVisible(true);
+ NSArray* icons = [cell layedOutIcons:bounds];
+ EXPECT_EQ(3u, [icons count]);
iconRect0 = [cell pageActionFrameForIndex:0 inFrame:bounds];
NSRect iconRect1 = [cell pageActionFrameForIndex:1 inFrame:bounds];
- NSRect lockRect = [cell securityImageFrameForFrame:bounds];
+ NSRect lockRect = [[icons objectAtIndex:0] rect];
+
+ EXPECT_TRUE(NSEqualRects(iconRect0, [[icons objectAtIndex:1] rect]));
+ EXPECT_TRUE(NSEqualRects(iconRect1, [[icons objectAtIndex:2] rect]));
// Make sure they're all in the expected order, and right of the |drawingRect|
// and |textFrame|.
diff --git a/chrome/browser/cocoa/autocomplete_text_field_editor.mm b/chrome/browser/cocoa/autocomplete_text_field_editor.mm
index b4e0a5e..7eb8b93 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_editor.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_editor.mm
@@ -13,7 +13,6 @@
#import "chrome/browser/cocoa/autocomplete_text_field.h"
#import "chrome/browser/cocoa/autocomplete_text_field_cell.h"
#import "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/extensions/extension_action_context_menu.h"
#import "chrome/browser/cocoa/toolbar_controller.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/common/extensions/extension_action.h"
@@ -96,25 +95,13 @@ class Extension;
AutocompleteTextField* field = (AutocompleteTextField*)[self delegate];
NSRect bounds([field bounds]);
AutocompleteTextFieldCell* cell = [field autocompleteTextFieldCell];
- const size_t pageActionCount = [cell pageActionCount];
BOOL flipped = [self isFlipped];
- if (!profile_)
- return [self defaultMenuForEvent:event];
-
- ExtensionsService* service = profile_->GetExtensionsService();
- if (!service)
- return [self defaultMenuForEvent:event];
-
- for (size_t i = 0; i < pageActionCount; ++i) {
- NSRect pageActionFrame = [cell pageActionFrameForIndex:i inFrame:bounds];
- if (NSMouseInRect(location, pageActionFrame, flipped)) {
- Extension* extension = service->GetExtensionById(
- [cell pageActionForIndex:i]->extension_id(), false);
- DCHECK(extension);
- if (!extension)
- break;
- return [[[ExtensionActionContextMenu alloc]
- initWithExtension:extension profile:profile_] autorelease];
+
+ for (AutocompleteTextFieldIcon* icon in [cell layedOutIcons:bounds]) {
+ if (NSMouseInRect(location, [icon rect], flipped)) {
+ NSMenu* menu = [icon view]->GetMenu();
+ if (menu)
+ return menu;
}
}
diff --git a/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm
index 40a1838..29d87ec 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
diff --git a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm
index 4adfa6a..b2f1f2d 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm
@@ -27,7 +27,12 @@ class MockSecurityImageView : public LocationBarViewMac::SecurityImageView {
ToolbarModel* model)
: LocationBarViewMac::SecurityImageView(owner, profile, model) {}
- MOCK_METHOD0(OnMousePressed, bool());
+ // We can't use gmock's MOCK_METHOD macro, because it doesn't like the
+ // NSRect argument to OnMousePressed.
+ virtual void OnMousePressed(NSRect bounds) {
+ mouse_was_pressed_ = true;
+ }
+ bool mouse_was_pressed_;
};
class MockPageActionImageView : public LocationBarViewMac::PageActionImageView {
@@ -37,9 +42,8 @@ class MockPageActionImageView : public LocationBarViewMac::PageActionImageView {
// We can't use gmock's MOCK_METHOD macro, because it doesn't like the
// NSRect argument to OnMousePressed.
- virtual bool OnMousePressed(NSRect bounds) {
+ virtual void OnMousePressed(NSRect bounds) {
mouse_was_pressed_ = true;
- return true;
}
bool MouseWasPressed() { return mouse_was_pressed_; }
@@ -585,8 +589,8 @@ TEST_F(AutocompleteTextFieldObserverTest, SecurityIconMouseDown) {
NSPoint location(NSMakePoint(NSMidX(iconFrame), NSMidY(iconFrame)));
NSEvent* event(Event(field_, location, NSLeftMouseDown, 1));
- EXPECT_CALL(security_image_view, OnMousePressed());
[field_ mouseDown:event];
+ EXPECT_TRUE(security_image_view.mouse_was_pressed_);
}
// Clicking a Page Action icon should call its OnMousePressed.
@@ -657,8 +661,8 @@ TEST_F(AutocompleteTextFieldObserverTest, PageActionMouseDown) {
location = NSMakePoint(NSMidX(iconFrame), NSMidY(iconFrame));
event = Event(field_, location, NSLeftMouseDown, 1);
- EXPECT_CALL(security_image_view, OnMousePressed());
[field_ mouseDown:event];
+ EXPECT_TRUE(security_image_view.mouse_was_pressed_);
}
// Verify that -setAttributedStringValue: works as expected when
diff --git a/chrome/browser/cocoa/extension_installed_bubble_controller.mm b/chrome/browser/cocoa/extension_installed_bubble_controller.mm
index f1d4761..677e55c 100644
--- a/chrome/browser/cocoa/extension_installed_bubble_controller.mm
+++ b/chrome/browser/cocoa/extension_installed_bubble_controller.mm
@@ -200,9 +200,7 @@ class ExtensionLoadedNotificationObserver : public NotificationObserver {
pageActionFrameForIndex:index inFrame:[field frame]];
NSRect boundsrect = [browserContentWindow convertRect:iconRect
fromView:[field superview]];
- arrowPoint =
- NSMakePoint(NSMinX(boundsrect) - NSWidth(boundsrect) / 2 - 1,
- NSMinY(boundsrect));
+ arrowPoint = NSMakePoint(NSMidX(boundsrect) + 1, NSMinY(boundsrect));
break;
}
default: {
diff --git a/chrome/browser/cocoa/location_bar_view_mac.h b/chrome/browser/cocoa/location_bar_view_mac.h
index 19d88d1..75241f8 100644
--- a/chrome/browser/cocoa/location_bar_view_mac.h
+++ b/chrome/browser/cocoa/location_bar_view_mac.h
@@ -13,11 +13,13 @@
#include "base/scoped_nsobject.h"
#include "base/scoped_ptr.h"
+#include "base/scoped_vector.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h"
#include "chrome/browser/extensions/image_loading_tracker.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/toolbar_model.h"
+#include "chrome/common/content_settings_types.h"
#include "third_party/skia/include/core/SkBitmap.h"
@class AutocompleteTextField;
@@ -150,6 +152,15 @@ class LocationBarViewMac : public AutocompleteEditController,
const NSAttributedString* GetLabel() const { return label_; }
bool IsVisible() const { return visible_; }
+ // Returns the tooltip for this image view or |nil| if there is none.
+ virtual const NSString* GetToolTip() { return nil; }
+
+ // Called on mouse down.
+ virtual void OnMousePressed(NSRect bounds) {}
+
+ // Called to get the icon's context menu. Return |nil| for no menu.
+ virtual NSMenu* GetMenu() { return nil; }
+
private:
scoped_nsobject<NSImage> image_;
@@ -178,8 +189,8 @@ class LocationBarViewMac : public AutocompleteEditController,
// Sets the image to the appropriate icon.
void SetImageShown(Image image);
- // Shows the page info dialog. Virtual so it can be overridden for testing.
- virtual bool OnMousePressed();
+ // Shows the page info dialog.
+ virtual void OnMousePressed(NSRect bounds);
private:
// The lock icon shown when using HTTPS. Loaded lazily, the first time it's
@@ -223,8 +234,7 @@ class LocationBarViewMac : public AutocompleteEditController,
virtual NSSize GetImageSize();
// Either notify listeners or show a popup depending on the Page Action.
- // Virtual so it can be overridden for testing.
- virtual bool OnMousePressed(NSRect bounds);
+ virtual void OnMousePressed(NSRect bounds);
// Overridden from ImageLoadingTracker.
virtual void OnImageLoaded(SkBitmap* image, size_t index);
@@ -239,7 +249,10 @@ class LocationBarViewMac : public AutocompleteEditController,
void SetToolTip(std::string tooltip);
// Returns the tooltip for this Page Action image or |nil| if there is none.
- const NSString* GetToolTip();
+ virtual const NSString* GetToolTip();
+
+ // Overridden to return a menu.
+ virtual NSMenu* GetMenu();
protected:
// For unit testing only.
@@ -293,6 +306,38 @@ class LocationBarViewMac : public AutocompleteEditController,
DISALLOW_COPY_AND_ASSIGN(PageActionImageView);
};
+ // ContentBlockedImageView is used to display the content settings images
+ // when types of contents are blocked on the current page.
+ class ContentBlockedImageView : public LocationBarImageView {
+ public:
+ ContentBlockedImageView(ContentSettingsType settings_type,
+ LocationBarViewMac* owner,
+ Profile* profile);
+ virtual ~ContentBlockedImageView();
+
+ // Shows a content settings bubble.
+ void OnMousePressed(NSRect bounds);
+
+ // Returns the settings type this shows up for.
+ ContentSettingsType settings_type() { return settings_type_; }
+
+ // Returns the tooltip for this Page Action image or |nil| if there is none.
+ virtual const NSString* GetToolTip();
+
+ private:
+ void SetToolTip(NSString* tooltip);
+
+ // The type of content handled by this view.
+ ContentSettingsType settings_type_;
+
+ LocationBarViewMac* owner_;
+ Profile* profile_;
+ scoped_nsobject<NSString> tooltip_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentBlockedImageView);
+ };
+ typedef ScopedVector<ContentBlockedImageView> ContentBlockedViews;
+
class PageActionViewList {
public:
PageActionViewList(LocationBarViewMac* location_bar,
@@ -341,6 +386,10 @@ class LocationBarViewMac : public AutocompleteEditController,
// Posts |notification| to the default notification center.
void PostNotification(const NSString* notification);
+ // Updates visibility of the content blocked icons based on the current
+ // tab contents state.
+ void RefreshContentBlockedViews();
+
scoped_ptr<AutocompleteEditViewMac> edit_view_;
CommandUpdater* command_updater_; // Weak, owned by Browser.
@@ -361,6 +410,9 @@ class LocationBarViewMac : public AutocompleteEditController,
// Any installed Page Actions.
PageActionViewList page_action_views_;
+ // The content blocked views.
+ ContentBlockedViews content_blocked_views_;
+
Profile* profile_;
Browser* browser_;
diff --git a/chrome/browser/cocoa/location_bar_view_mac.mm b/chrome/browser/cocoa/location_bar_view_mac.mm
index afcf1b0..88fcc89 100644
--- a/chrome/browser/cocoa/location_bar_view_mac.mm
+++ b/chrome/browser/cocoa/location_bar_view_mac.mm
@@ -6,6 +6,7 @@
#include "app/l10n_util_mac.h"
#include "app/resource_bundle.h"
+#include "base/nsimage_cache_mac.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
@@ -17,6 +18,7 @@
#import "chrome/browser/cocoa/autocomplete_text_field.h"
#import "chrome/browser/cocoa/autocomplete_text_field_cell.h"
#include "chrome/browser/cocoa/event_utils.h"
+#import "chrome/browser/cocoa/extensions/extension_action_context_menu.h"
#import "chrome/browser/cocoa/extensions/extension_popup_controller.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
@@ -99,9 +101,18 @@ LocationBarViewMac::LocationBarViewMac(
browser_(browser),
toolbar_model_(toolbar_model),
transition_(PageTransition::TYPED) {
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ ContentBlockedImageView* content_blocked_view =
+ new ContentBlockedImageView(static_cast<ContentSettingsType>(i), this,
+ profile_);
+ content_blocked_views_.push_back(content_blocked_view);
+ content_blocked_view->SetVisible(false);
+ }
+
AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
[cell setSecurityImageView:&security_image_view_];
[cell setPageActionViewList:&page_action_views_];
+ [cell setContentBlockedViewList:&content_blocked_views_];
registrar_.Add(this,
NotificationType::EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
@@ -123,6 +134,7 @@ WindowOpenDisposition LocationBarViewMac::GetWindowOpenDisposition() const {
return disposition_;
}
+// TODO(thakis): Ping shess to verify what he wants to verify.
// TODO(shess): Verify that this TODO is TODONE.
// TODO(rohitrao): Fix this to return different types once autocomplete and
// the onmibar are implemented. For now, any URL that comes from the
@@ -152,7 +164,9 @@ void LocationBarViewMac::FocusSearch() {
}
void LocationBarViewMac::UpdateContentBlockedIcons() {
- // TODO(pkasting): Implement.
+ RefreshContentBlockedViews();
+ [field_ updateCursorAndToolTipRects];
+ [field_ setNeedsDisplay:YES];
}
void LocationBarViewMac::UpdatePageActions() {
@@ -187,6 +201,7 @@ void LocationBarViewMac::Update(const TabContents* contents,
bool should_restore_state) {
SetSecurityIcon(toolbar_model_->GetIcon());
page_action_views_.RefreshViews();
+ RefreshContentBlockedViews();
// AutocompleteEditView restores state if the tab is non-NULL.
edit_view_->Update(should_restore_state ? contents : NULL);
}
@@ -497,6 +512,16 @@ void LocationBarViewMac::PostNotification(const NSString* notification) {
object:[NSValue valueWithPointer:this]];
}
+void LocationBarViewMac::RefreshContentBlockedViews() {
+ const TabContents* tab_contents = browser_->GetSelectedTabContents();
+ for (ContentBlockedViews::iterator it(content_blocked_views_.begin());
+ it != content_blocked_views_.end();
+ ++it) {
+ (*it)->SetVisible((!toolbar_model_->input_in_progress() && tab_contents) ?
+ tab_contents->IsContentBlocked((*it)->settings_type()) : false);
+ }
+}
+
// LocationBarImageView---------------------------------------------------------
void LocationBarViewMac::LocationBarImageView::SetImage(NSImage* image) {
@@ -568,15 +593,14 @@ void LocationBarViewMac::SecurityImageView::SetImageShown(Image image) {
}
}
-bool LocationBarViewMac::SecurityImageView::OnMousePressed() {
+void LocationBarViewMac::SecurityImageView::OnMousePressed(NSRect bounds) {
TabContents* tab = owner_->GetTabContents();
NavigationEntry* nav_entry = tab->controller().GetActiveEntry();
if (!nav_entry) {
NOTREACHED();
- return true;
+ return;
}
tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true);
- return true;
}
// PageActionImageView----------------------------------------------------------
@@ -632,12 +656,12 @@ NSSize LocationBarViewMac::PageActionImageView::GetImageSize() {
// Overridden from LocationBarImageView. Either notify listeners or show a
// popup depending on the Page Action.
-bool LocationBarViewMac::PageActionImageView::OnMousePressed(NSRect bounds) {
+void LocationBarViewMac::PageActionImageView::OnMousePressed(NSRect bounds) {
if (current_tab_id_ < 0) {
NOTREACHED() << "No current tab.";
// We don't want other code to try and handle this click. Returning true
// prevents this by indicating that we handled it.
- return true;
+ return;
}
if (page_action_->HasPopup(current_tab_id_)) {
@@ -662,7 +686,6 @@ bool LocationBarViewMac::PageActionImageView::OnMousePressed(NSRect bounds) {
current_tab_id_, current_url_.spec(),
1);
}
- return true;
}
void LocationBarViewMac::PageActionImageView::OnImageLoaded(SkBitmap* image,
@@ -763,6 +786,21 @@ const NSString* LocationBarViewMac::PageActionImageView::GetToolTip() {
return tooltip_.get();
}
+NSMenu* LocationBarViewMac::PageActionImageView::GetMenu() {
+ if (!profile_)
+ return nil;
+ ExtensionsService* service = profile_->GetExtensionsService();
+ if (!service)
+ return nil;
+ Extension* extension = service->GetExtensionById(
+ page_action_->extension_id(), false);
+ DCHECK(extension);
+ if (!extension)
+ return nil;
+ return [[[ExtensionActionContextMenu alloc]
+ initWithExtension:extension profile:profile_] autorelease];
+}
+
void LocationBarViewMac::PageActionImageView::Observe(
NotificationType type,
const NotificationSource& source,
@@ -781,6 +819,58 @@ void LocationBarViewMac::PageActionImageView::Observe(
}
}
+// ContentSettingsImageView-----------------------------------------------------
+
+LocationBarViewMac::ContentBlockedImageView::ContentBlockedImageView(
+ ContentSettingsType settings_type,
+ LocationBarViewMac* owner,
+ Profile* profile)
+ : settings_type_(settings_type),
+ owner_(owner),
+ profile_(profile) {
+ // TODO(thakis): We should use pdfs for these icons on OSX.
+ // http://crbug.com/35847
+ static const int kIconIDs[] = {
+ IDR_BLOCKED_COOKIES,
+ IDR_BLOCKED_IMAGES,
+ IDR_BLOCKED_JAVASCRIPT,
+ IDR_BLOCKED_PLUGINS,
+ IDR_BLOCKED_POPUPS,
+ };
+ DCHECK_EQ(arraysize(kIconIDs),
+ static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ SetImage(rb.GetNSImageNamed(kIconIDs[settings_type]));
+
+ static const int kTooltipIDs[] = {
+ IDS_BLOCKED_COOKIES_TITLE,
+ IDS_BLOCKED_IMAGES_TITLE,
+ IDS_BLOCKED_JAVASCRIPT_TITLE,
+ IDS_BLOCKED_PLUGINS_TITLE,
+ IDS_BLOCKED_POPUPS_TOOLTIP,
+ };
+ DCHECK_EQ(arraysize(kTooltipIDs),
+ static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
+ SetToolTip(l10n_util::GetNSStringWithFixup(kTooltipIDs[settings_type]));
+}
+
+LocationBarViewMac::ContentBlockedImageView::~ContentBlockedImageView() {}
+
+void LocationBarViewMac::ContentBlockedImageView::OnMousePressed(NSRect bounds)
+ {
+ // TODO(thakis): Implement.
+ NOTIMPLEMENTED();
+}
+
+const NSString* LocationBarViewMac::ContentBlockedImageView::GetToolTip() {
+ return tooltip_.get();
+}
+
+void LocationBarViewMac::ContentBlockedImageView::SetToolTip(NSString* tooltip)
+ {
+ tooltip_.reset([tooltip retain]);
+}
+
// PageActionViewList-----------------------------------------------------------
void LocationBarViewMac::PageActionViewList::DeleteAll() {