| Index: ui/views/attributes.cc | 
| diff --git a/ui/views/attributes.cc b/ui/views/attributes.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..16440eed437203cfcf5211cce3238c926e006f90 | 
| --- /dev/null | 
| +++ b/ui/views/attributes.cc | 
| @@ -0,0 +1,58 @@ | 
| +// Copyright (c) 2016 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. | 
| + | 
| +#include "ui/views/attributes.h" | 
| + | 
| +namespace views { | 
| + | 
| +AttributeId Attribute::Identity() const { | 
| +  return GetAttributeId<Attribute>(); | 
| +} | 
| + | 
| +AttributeContainer::AttributeContainer(View* view) : view_(view) {} | 
| + | 
| +AttributeContainer::AttributeContainer() : view_(nullptr) {} | 
| + | 
| +AttributeContainer::~AttributeContainer() {} | 
| + | 
| +bool AttributeContainer::Remove(const AttributeId attributeId) { | 
| +  AttributeMap::const_iterator it = map_.find(attributeId); | 
| +  bool canRemove = it != map_.cend(); | 
| +  if (canRemove) { | 
| +    Notification(Attribute::NotifyType::AttributeRemoved, it->second.get()); | 
| +    it->second.get()->RemovedFromView(); | 
| +    map_.erase(it); | 
| +  } | 
| +  return canRemove; | 
| +} | 
| + | 
| +void AttributeContainer::Notification(Attribute::NotifyType type, | 
| +                                      Attribute* attribute) { | 
| +  for (AttributeMap::const_iterator a = map_.cbegin(); a != map_.cend(); a++) { | 
| +    Attribute* attr = a->second.get(); | 
| +    if (attr != attribute) | 
| +      attr->Notification(type, attribute); | 
| +  } | 
| +} | 
| + | 
| +void AttributeContainer::ViewNotification(View* view) { | 
| +  for (AttributeMap::const_iterator a = map_.cbegin(); a != map_.cend(); a++) | 
| +    a->second.get()->ViewNotification(view); | 
| +} | 
| + | 
| +AttributeIdFactory::AttributeIdMap AttributeIdFactory::map_; | 
| + | 
| +AttributeId AttributeIdFactory::GetAttributeId(const char* typeName) { | 
| +  std::string type_name = typeName; | 
| +  AttributeIdMap::const_iterator it = map_.find(type_name); | 
| +  if (it == map_.cend()) { | 
| +    std::unique_ptr<AttributeIdHolder> holder = | 
| +        base::WrapUnique(new AttributeIdHolder()); | 
| +    it = map_.insert(AttributeIdMap::value_type(type_name, std::move(holder))) | 
| +             .first; | 
| +  } | 
| +  return it->second.get()->GetAttributeId(); | 
| +} | 
| + | 
| +}  // namespace views | 
|  |