Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #import "mozActionElements.h"
8 #import "MacUtils.h"
9 #include "Accessible-inl.h"
10 #include "DocAccessible.h"
11 #include "XULTabAccessible.h"
13 #include "nsDeckFrame.h"
14 #include "nsObjCExceptions.h"
16 using namespace mozilla::a11y;
18 enum CheckboxValue {
19 // these constants correspond to the values in the OS
20 kUnchecked = 0,
21 kChecked = 1,
22 kMixed = 2
23 };
25 @implementation mozButtonAccessible
27 - (NSArray*)accessibilityAttributeNames
28 {
29 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
31 static NSArray *attributes = nil;
32 if (!attributes) {
33 attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
34 NSAccessibilityRoleAttribute, // required
35 NSAccessibilityRoleDescriptionAttribute,
36 NSAccessibilityPositionAttribute, // required
37 NSAccessibilitySizeAttribute, // required
38 NSAccessibilityWindowAttribute, // required
39 NSAccessibilityPositionAttribute, // required
40 NSAccessibilityTopLevelUIElementAttribute, // required
41 NSAccessibilityHelpAttribute,
42 NSAccessibilityEnabledAttribute, // required
43 NSAccessibilityFocusedAttribute, // required
44 NSAccessibilityTitleAttribute, // required
45 NSAccessibilityDescriptionAttribute,
46 #if DEBUG
47 @"AXMozDescription",
48 #endif
49 nil];
50 }
51 return attributes;
53 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
54 }
56 - (id)accessibilityAttributeValue:(NSString *)attribute
57 {
58 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
60 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
61 return nil;
62 if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
63 if ([self isTab])
64 return utils::LocalizedString(NS_LITERAL_STRING("tab"));
66 return NSAccessibilityRoleDescription([self role], nil);
67 }
69 return [super accessibilityAttributeValue:attribute];
71 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
72 }
74 - (BOOL)accessibilityIsIgnored
75 {
76 return !mGeckoAccessible;
77 }
79 - (NSArray*)accessibilityActionNames
80 {
81 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
83 if ([self isEnabled])
84 return [NSArray arrayWithObject:NSAccessibilityPressAction];
86 return nil;
88 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
89 }
91 - (NSString*)accessibilityActionDescription:(NSString*)action
92 {
93 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
95 if ([action isEqualToString:NSAccessibilityPressAction]) {
96 if ([self isTab])
97 return utils::LocalizedString(NS_LITERAL_STRING("switch"));
99 return @"press button"; // XXX: localize this later?
100 }
102 return nil;
104 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
105 }
107 - (void)accessibilityPerformAction:(NSString*)action
108 {
109 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
111 if ([action isEqualToString:NSAccessibilityPressAction])
112 [self click];
114 NS_OBJC_END_TRY_ABORT_BLOCK;
115 }
117 - (void)click
118 {
119 // both buttons and checkboxes have only one action. we should really stop using arbitrary
120 // arrays with actions, and define constants for these actions.
121 mGeckoAccessible->DoAction(0);
122 }
124 - (BOOL)isTab
125 {
126 return (mGeckoAccessible && (mGeckoAccessible->Role() == roles::PAGETAB));
127 }
129 @end
131 @implementation mozCheckboxAccessible
133 - (NSString*)accessibilityActionDescription:(NSString*)action
134 {
135 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
137 if ([action isEqualToString:NSAccessibilityPressAction]) {
138 if ([self isChecked] != kUnchecked)
139 return @"uncheck checkbox"; // XXX: localize this later?
141 return @"check checkbox"; // XXX: localize this later?
142 }
144 return nil;
146 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
147 }
149 - (int)isChecked
150 {
151 uint64_t state = mGeckoAccessible->NativeState();
153 // check if we're checked or in a mixed state
154 if (state & states::CHECKED) {
155 return (state & states::MIXED) ? kMixed : kChecked;
156 }
158 return kUnchecked;
159 }
161 - (id)value
162 {
163 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
165 return [NSNumber numberWithInt:[self isChecked]];
167 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
168 }
170 @end
172 @implementation mozPopupButtonAccessible
174 - (NSArray *)accessibilityAttributeNames
175 {
176 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
178 static NSArray *attributes = nil;
180 if (!attributes) {
181 attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
182 NSAccessibilityPositionAttribute, // required
183 NSAccessibilityRoleAttribute, // required
184 NSAccessibilitySizeAttribute, // required
185 NSAccessibilityWindowAttribute, // required
186 NSAccessibilityTopLevelUIElementAttribute, // required
187 NSAccessibilityHelpAttribute,
188 NSAccessibilityEnabledAttribute, // required
189 NSAccessibilityFocusedAttribute, // required
190 NSAccessibilityTitleAttribute, // required for popupmenus, and for menubuttons with a title
191 NSAccessibilityChildrenAttribute, // required
192 NSAccessibilityDescriptionAttribute, // required if it has no title attr
193 #if DEBUG
194 @"AXMozDescription",
195 #endif
196 nil];
197 }
198 return attributes;
200 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
201 }
203 - (id)accessibilityAttributeValue:(NSString *)attribute
204 {
205 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
207 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
208 return [super children];
209 }
210 return [super accessibilityAttributeValue:attribute];
212 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
213 }
215 - (NSArray *)accessibilityActionNames
216 {
217 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
219 if ([self isEnabled]) {
220 return [NSArray arrayWithObjects:NSAccessibilityPressAction,
221 NSAccessibilityShowMenuAction,
222 nil];
223 }
224 return nil;
226 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
227 }
229 - (NSString *)accessibilityActionDescription:(NSString *)action
230 {
231 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
233 if ([action isEqualToString:NSAccessibilityShowMenuAction])
234 return @"show menu";
235 return [super accessibilityActionDescription:action];
237 NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
238 }
240 - (void)accessibilityPerformAction:(NSString *)action
241 {
242 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
244 // both the ShowMenu and Click action do the same thing.
245 if ([self isEnabled]) {
246 // TODO: this should bring up the menu, but currently doesn't.
247 // once msaa and atk have merged better, they will implement
248 // the action needed to show the menu.
249 [super click];
250 }
252 NS_OBJC_END_TRY_ABORT_BLOCK;
253 }
255 @end
257 @implementation mozTabsAccessible
259 - (void)dealloc
260 {
261 [mTabs release];
263 [super dealloc];
264 }
266 - (NSArray*)accessibilityAttributeNames
267 {
268 // standard attributes that are shared and supported by root accessible (AXMain) elements.
269 static NSMutableArray* attributes = nil;
271 if (!attributes) {
272 attributes = [[super accessibilityAttributeNames] mutableCopy];
273 [attributes addObject:NSAccessibilityContentsAttribute];
274 [attributes addObject:NSAccessibilityTabsAttribute];
275 }
277 return attributes;
278 }
280 - (id)accessibilityAttributeValue:(NSString *)attribute
281 {
282 if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
283 return [super children];
284 if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
285 return [self tabs];
287 return [super accessibilityAttributeValue:attribute];
288 }
290 /**
291 * Returns the selected tab (the mozAccessible)
292 */
293 - (id)value
294 {
295 if (!mGeckoAccessible)
296 return nil;
298 Accessible* accessible = mGeckoAccessible->GetSelectedItem(0);
299 if (!accessible)
300 return nil;
302 mozAccessible* nativeAcc = nil;
303 nsresult rv = accessible->GetNativeInterface((void**)&nativeAcc);
304 NS_ENSURE_SUCCESS(rv, nil);
306 return nativeAcc;
307 }
309 /**
310 * Return the mozAccessibles that are the tabs.
311 */
312 - (id)tabs
313 {
314 if (mTabs)
315 return mTabs;
317 NSArray* children = [self children];
318 NSEnumerator* enumerator = [children objectEnumerator];
319 mTabs = [[NSMutableArray alloc] init];
321 id obj;
322 while ((obj = [enumerator nextObject]))
323 if ([obj isTab])
324 [mTabs addObject:obj];
326 return mTabs;
327 }
329 - (void)invalidateChildren
330 {
331 [super invalidateChildren];
333 [mTabs release];
334 mTabs = nil;
335 }
337 @end
339 @implementation mozPaneAccessible
341 - (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
342 {
343 if (!mGeckoAccessible)
344 return 0;
346 // By default this calls -[[mozAccessible children] count].
347 // Since we don't cache mChildren. This is faster.
348 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
349 return mGeckoAccessible->ChildCount() ? 1 : 0;
351 return [super accessibilityArrayAttributeCount:attribute];
352 }
354 - (NSArray*)children
355 {
356 if (!mGeckoAccessible)
357 return nil;
359 nsDeckFrame* deckFrame = do_QueryFrame(mGeckoAccessible->GetFrame());
360 nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
362 Accessible* selectedAcc = nullptr;
363 if (selectedFrame) {
364 nsINode* node = selectedFrame->GetContent();
365 selectedAcc = mGeckoAccessible->Document()->GetAccessible(node);
366 }
368 if (selectedAcc) {
369 mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
370 if (curNative)
371 return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
372 }
374 return nil;
375 }
377 @end