📄 accessibilityobjectwrapper.mm
字号:
/* * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#import "config.h"#import "AccessibilityObjectWrapper.h"#if HAVE(ACCESSIBILITY)#import "AXObjectCache.h"#import "AccessibilityListBox.h"#import "AccessibilityList.h"#import "AccessibilityRenderObject.h"#import "AccessibilityTable.h"#import "AccessibilityTableCell.h"#import "AccessibilityTableRow.h"#import "AccessibilityTableColumn.h"#import "ColorMac.h"#import "Frame.h"#import "HTMLAnchorElement.h"#import "HTMLAreaElement.h"#import "HTMLImageElement.h"#import "HTMLInputElement.h"#import "HTMLTextAreaElement.h"#import "LocalizedStrings.h"#import "RenderTextControl.h"#import "RenderView.h"#import "RenderWidget.h"#import "SelectionController.h"#import "SimpleFontData.h"#import "TextIterator.h"#import "WebCoreFrameView.h"#import "WebCoreObjCExtras.h"#import "WebCoreViewFactory.h"#import "htmlediting.h"#import "visible_units.h"#import <runtime/InitializeThreading.h>using namespace WebCore;using namespace HTMLNames;using namespace std;// Cell Tables#ifndef NSAccessibilitySelectedCellsAttribute#define NSAccessibilitySelectedCellsAttribute @"AXSelectedCells"#endif#ifndef NSAccessibilityVisibleCellsAttribute#define NSAccessibilityVisibleCellsAttribute @"AXVisibleCells"#endif#ifndef NSAccessibilityRowHeaderUIElementsAttribute#define NSAccessibilityRowHeaderUIElementsAttribute @"AXRowHeaderUIElements"#endif#ifndef NSAccessibilityRowIndexRangeAttribute#define NSAccessibilityRowIndexRangeAttribute @"AXRowIndexRange"#endif#ifndef NSAccessibilityColumnIndexRangeAttribute#define NSAccessibilityColumnIndexRangeAttribute @"AXColumnIndexRange"#endif#ifndef NSAccessibilityCellForColumnAndRowParameterizedAttribute#define NSAccessibilityCellForColumnAndRowParameterizedAttribute @"AXCellForColumnAndRow"#endif#ifndef NSAccessibilityCellRole#define NSAccessibilityCellRole @"AXCell"#endif// Lists#ifndef NSAccessibilityContentListSubrole#define NSAccessibilityContentListSubrole @"AXContentList"#endif#ifndef NSAccessibilityDefinitionListSubrole#define NSAccessibilityDefinitionListSubrole @"AXDefinitionList"#endif// Miscellaneous#ifndef NSAccessibilityBlockQuoteLevelAttribute#define NSAccessibilityBlockQuoteLevelAttribute @"AXBlockQuoteLevel"#endif#ifndef NSAccessibilityAccessKeyAttribute#define NSAccessibilityAccessKeyAttribute @"AXAccessKey"#endif#ifdef BUILDING_ON_TIGERtypedef unsigned NSUInteger;#endif@interface NSObject (WebKitAccessibilityArrayCategory)- (NSUInteger)accessibilityIndexOfChild:(id)child;- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute;- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;@end@implementation AccessibilityObjectWrapper+ (void)initialize{ JSC::initializeThreading();#ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self);#endif}- (id)initWithAccessibilityObject:(AccessibilityObject*)axObject{ [super init]; m_object = axObject; return self;}- (void)unregisterUniqueIdForUIElement{ [[WebCoreViewFactory sharedFactory] unregisterUniqueIdForUIElement:self];}- (void)detach{ // Send unregisterUniqueIdForUIElement unconditionally because if it is // ever accidently not done (via other bugs in our AX implementation) you // end up with a crash like <rdar://problem/4273149>. It is safe and not // expensive to send even if the object is not registered. [self unregisterUniqueIdForUIElement]; m_object = 0;}- (AccessibilityObject*)accessibilityObject{ return m_object;}- (NSView*)attachmentView{ ASSERT(m_object->isAttachment()); Widget* widget = m_object->widgetForAttachmentView(); if (!widget) return nil; return widget->platformWidget();}static WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition& visiblePos){ if (visiblePos.isNull()) return nil; Position deepPos = visiblePos.deepEquivalent(); Node* domNode = deepPos.node(); ASSERT(domNode); if (!domNode) return nil; if (domNode->isHTMLElement()) { InputElement* inputElement = toInputElement(static_cast<Element*>(domNode)); if (inputElement && inputElement->isPasswordField()) return nil; } // locate the renderer, which must exist for a visible dom node RenderObject* renderer = domNode->renderer(); ASSERT(renderer); // find or create an accessibility object for this renderer AXObjectCache* cache = renderer->document()->axObjectCache(); RefPtr<AccessibilityObject> obj = cache->getOrCreate(renderer); // create a text marker, adding an ID for the AccessibilityObject if needed TextMarkerData textMarkerData; // The compiler can add padding to this struct. // This memory must be bzero'd so instances of TextMarkerData can be tested for byte-equivalence. bzero(&textMarkerData, sizeof(TextMarkerData)); textMarkerData.axID = obj.get()->axObjectID(); textMarkerData.node = domNode; textMarkerData.offset = deepPos.offset(); textMarkerData.affinity = visiblePos.affinity(); return [[WebCoreViewFactory sharedFactory] textMarkerWithBytes:&textMarkerData length:sizeof(textMarkerData)];}static VisiblePosition visiblePositionForTextMarker(WebCoreTextMarker* textMarker){ TextMarkerData textMarkerData; if (![[WebCoreViewFactory sharedFactory] getBytes:&textMarkerData fromTextMarker:textMarker length:sizeof(textMarkerData)]) return VisiblePosition(); VisiblePosition visiblePos = VisiblePosition(textMarkerData.node, textMarkerData.offset, textMarkerData.affinity); Position deepPos = visiblePos.deepEquivalent(); if (deepPos.isNull()) return VisiblePosition(); RenderObject* renderer = deepPos.node()->renderer(); if (!renderer) return VisiblePosition(); AXObjectCache* cache = renderer->document()->axObjectCache(); if (!cache->isIDinUse(textMarkerData.axID)) return VisiblePosition(); if (deepPos.node() != textMarkerData.node || deepPos.offset() != textMarkerData.offset) return VisiblePosition(); return visiblePos;}static VisiblePosition visiblePositionForStartOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange){ return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]);}static VisiblePosition visiblePositionForEndOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange){ return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]);}static WebCoreTextMarkerRange* textMarkerRangeFromMarkers(WebCoreTextMarker* textMarker1, WebCoreTextMarker* textMarker2){ if (!textMarker1 || !textMarker2) return nil; return [[WebCoreViewFactory sharedFactory] textMarkerRangeWithStart:textMarker1 end:textMarker2];}static void AXAttributeStringSetFont(NSMutableAttributedString* attrString, NSString* attribute, NSFont* font, NSRange range){ NSDictionary* dict; if (font) { dict = [NSDictionary dictionaryWithObjectsAndKeys: [font fontName] , NSAccessibilityFontNameKey, [font familyName] , NSAccessibilityFontFamilyKey, [font displayName] , NSAccessibilityVisibleNameKey, [NSNumber numberWithFloat:[font pointSize]] , NSAccessibilityFontSizeKey, nil]; [attrString addAttribute:attribute value:dict range:range]; } else [attrString removeAttribute:attribute range:range]; }static CGColorRef CreateCGColorIfDifferent(NSColor* nsColor, CGColorRef existingColor){ // get color information assuming NSDeviceRGBColorSpace NSColor* rgbColor = [nsColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; if (rgbColor == nil) rgbColor = [NSColor blackColor]; CGFloat components[4]; [rgbColor getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]]; // create a new CGColorRef to return CGColorSpaceRef cgColorSpace = CGColorSpaceCreateDeviceRGB(); CGColorRef cgColor = CGColorCreate(cgColorSpace, components); CGColorSpaceRelease(cgColorSpace); // check for match with existing color if (existingColor && CGColorEqualToColor(cgColor, existingColor)) { CGColorRelease(cgColor); cgColor = 0; } return cgColor;}static void AXAttributeStringSetColor(NSMutableAttributedString* attrString, NSString* attribute, NSColor* color, NSRange range){ if (color) { CGColorRef existingColor = (CGColorRef) [attrString attribute:attribute atIndex:range.location effectiveRange:nil]; CGColorRef cgColor = CreateCGColorIfDifferent(color, existingColor); if (cgColor) { [attrString addAttribute:attribute value:(id)cgColor range:range]; CGColorRelease(cgColor); } } else [attrString removeAttribute:attribute range:range];}static void AXAttributeStringSetNumber(NSMutableAttributedString* attrString, NSString* attribute, NSNumber* number, NSRange range){ if (number) [attrString addAttribute:attribute value:number range:range]; else [attrString removeAttribute:attribute range:range];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -