| Index: chrome/browser/cocoa/view_id_util.mm | 
| diff --git a/chrome/browser/cocoa/view_id_util.mm b/chrome/browser/cocoa/view_id_util.mm | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..cf61e9cf80549012d6525a66163d8c6215846d2f | 
| --- /dev/null | 
| +++ b/chrome/browser/cocoa/view_id_util.mm | 
| @@ -0,0 +1,87 @@ | 
| +// 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. | 
| + | 
| +#import "chrome/browser/cocoa/view_id_util.h" | 
| + | 
| +#import <Cocoa/Cocoa.h> | 
| + | 
| +#include <map> | 
| +#include <utility> | 
| + | 
| +#include "base/logging.h" | 
| +#include "base/singleton.h" | 
| +#import "chrome/browser/cocoa/browser_window_controller.h" | 
| +#import "chrome/browser/cocoa/tab_strip_controller.h" | 
| + | 
| +namespace { | 
| + | 
| +// TODO(suzhe): After migrating to Mac OS X 10.6, we may use Objective-C's new | 
| +// "Associative References" feature to attach the ViewID to the view directly | 
| +// rather than using a separated map. | 
| +typedef std::map<NSView*, ViewID> ViewIDMap; | 
| + | 
| +// Returns the view's nearest descendant (including itself) with a specific | 
| +// ViewID, or nil if no subview has that ViewID. | 
| +NSView* FindViewWithID(NSView* view, ViewID viewID) { | 
| +  if ([view viewID] == viewID) | 
| +    return view; | 
| + | 
| +  for (NSView* subview in [view subviews]) { | 
| +    NSView* result = FindViewWithID(subview, viewID); | 
| +    if (result != nil) | 
| +      return result; | 
| +  } | 
| +  return nil; | 
| +} | 
| + | 
| +}  // anonymous namespace | 
| + | 
| +namespace view_id_util { | 
| + | 
| +void SetID(NSView* view, ViewID viewID) { | 
| +  DCHECK(view); | 
| +  DCHECK(viewID != VIEW_ID_NONE); | 
| +  // We handle VIEW_ID_TAB_0 to VIEW_ID_TAB_LAST in GetView() function directly. | 
| +  DCHECK(!((viewID >= VIEW_ID_TAB_0) && (viewID <= VIEW_ID_TAB_LAST))); | 
| +  (*Singleton<ViewIDMap>::get())[view] = viewID; | 
| +} | 
| + | 
| +void UnsetID(NSView* view) { | 
| +  DCHECK(view); | 
| +  Singleton<ViewIDMap>::get()->erase(view); | 
| +} | 
| + | 
| +NSView* GetView(NSWindow* window, ViewID viewID) { | 
| +  DCHECK(viewID != VIEW_ID_NONE); | 
| +  DCHECK(window); | 
| + | 
| +  // As tabs can be created, destroyed or rearranged dynamically, we handle them | 
| +  // here specially. | 
| +  if (viewID >= VIEW_ID_TAB_0 && viewID <= VIEW_ID_TAB_LAST) { | 
| +    BrowserWindowController* windowController = [window windowController]; | 
| +    DCHECK([windowController isKindOfClass:[BrowserWindowController class]]); | 
| +    TabStripController* tabStripController = | 
| +        [windowController tabStripController]; | 
| +    DCHECK(tabStripController); | 
| +    NSUInteger count = [tabStripController viewsCount]; | 
| +    DCHECK(count); | 
| +    NSUInteger index = | 
| +        (viewID == VIEW_ID_TAB_LAST ? count - 1 : viewID - VIEW_ID_TAB_0); | 
| +    return index < count ? [tabStripController viewAtIndex:index] : nil; | 
| +  } | 
| + | 
| +  return FindViewWithID([[window contentView] superview], viewID); | 
| +} | 
| + | 
| +}  // namespace view_id_util | 
| + | 
| +@implementation NSView (ViewID) | 
| + | 
| +- (ViewID)viewID { | 
| +  ViewIDMap* map = Singleton<ViewIDMap>::get(); | 
| +  ViewIDMap::const_iterator iter = map->find(self); | 
| +  return iter != map->end() ? iter->second : VIEW_ID_NONE; | 
| +} | 
| + | 
| +@end | 
|  |