|  | // Copyright (c) 2012 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 <Cocoa/Cocoa.h> | 
|  |  | 
|  | #import "content/browser/accessibility/browser_accessibility_mac.h" | 
|  |  | 
|  | #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 
|  | #include "content/browser/accessibility/browser_accessibility_manager_mac.h" | 
|  | #include "ui/accessibility/ax_table_info.h" | 
|  |  | 
|  | namespace content { | 
|  |  | 
|  | // Static. | 
|  | BrowserAccessibility* BrowserAccessibility::Create() { | 
|  | return new BrowserAccessibilityMac(); | 
|  | } | 
|  |  | 
|  | BrowserAccessibilityMac::BrowserAccessibilityMac() | 
|  | : browser_accessibility_cocoa_(NULL) { | 
|  | } | 
|  |  | 
|  | bool BrowserAccessibilityMac::IsNative() const { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void BrowserAccessibilityMac::NativeReleaseReference() { | 
|  | // Detach this object from |browser_accessibility_cocoa_| so it | 
|  | // no longer has a pointer to this object. | 
|  | [browser_accessibility_cocoa_ detach]; | 
|  | // Now, release it - but at this point, other processes may have a | 
|  | // reference to the cocoa object. | 
|  | [browser_accessibility_cocoa_ release]; | 
|  | // Finally, it's safe to delete this since we've detached. | 
|  | delete this; | 
|  | } | 
|  |  | 
|  | void BrowserAccessibilityMac::OnDataChanged() { | 
|  | BrowserAccessibility::OnDataChanged(); | 
|  |  | 
|  | if (browser_accessibility_cocoa_) { | 
|  | [browser_accessibility_cocoa_ childrenChanged]; | 
|  | return; | 
|  | } | 
|  |  | 
|  | // We take ownership of the Cocoa object here. | 
|  | browser_accessibility_cocoa_ = | 
|  | [[BrowserAccessibilityCocoa alloc] initWithObject:this]; | 
|  | } | 
|  |  | 
|  | uint32_t BrowserAccessibilityMac::PlatformChildCount() const { | 
|  | uint32_t child_count = BrowserAccessibility::PlatformChildCount(); | 
|  |  | 
|  | // If this is a table, include the extra fake nodes generated by | 
|  | // AXTableInfo, for the column nodes and the table header container, all of | 
|  | // which are only important on macOS. | 
|  | ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node()); | 
|  | if (!table_info) | 
|  | return child_count; | 
|  |  | 
|  | return child_count + table_info->extra_mac_nodes.size(); | 
|  | } | 
|  |  | 
|  | BrowserAccessibility* BrowserAccessibilityMac::PlatformGetChild( | 
|  | uint32_t child_index) const { | 
|  | uint32_t child_count = BrowserAccessibility::PlatformChildCount(); | 
|  | if (child_index < child_count) | 
|  | return BrowserAccessibility::PlatformGetChild(child_index); | 
|  |  | 
|  | // If this is a table, include the extra fake nodes generated by | 
|  | // AXTableInfo, for the column nodes and the table header container, all of | 
|  | // which are only important on macOS. | 
|  | ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node()); | 
|  | if (!table_info) | 
|  | return nullptr; | 
|  |  | 
|  | child_index -= child_count; | 
|  | if (child_index < table_info->extra_mac_nodes.size()) | 
|  | return manager_->GetFromAXNode(table_info->extra_mac_nodes[child_index]); | 
|  |  | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | const BrowserAccessibilityCocoa* | 
|  | ToBrowserAccessibilityCocoa(const BrowserAccessibility* obj) { | 
|  | DCHECK(obj); | 
|  | DCHECK(obj->IsNative()); | 
|  | return static_cast<const BrowserAccessibilityMac*>(obj)->native_view(); | 
|  | } | 
|  |  | 
|  | BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa( | 
|  | BrowserAccessibility* obj) { | 
|  | DCHECK(obj); | 
|  | DCHECK(obj->IsNative()); | 
|  | return static_cast<BrowserAccessibilityMac*>(obj)->native_view(); | 
|  | } | 
|  |  | 
|  | }  // namespace content |