AXElements 0.6.0beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +20 -0
- data/LICENSE.txt +25 -0
- data/README.markdown +150 -0
- data/Rakefile +109 -0
- data/docs/AccessibilityTips.markdown +119 -0
- data/docs/Acting.markdown +340 -0
- data/docs/Debugging.markdown +326 -0
- data/docs/Inspecting.markdown +255 -0
- data/docs/KeyboardEvents.markdown +57 -0
- data/docs/NewBehaviour.markdown +151 -0
- data/docs/Notifications.markdown +271 -0
- data/docs/Searching.markdown +250 -0
- data/docs/TestingExtensions.markdown +52 -0
- data/docs/images/AX.png +0 -0
- data/docs/images/all_the_buttons.jpg +0 -0
- data/docs/images/ui_hierarchy.dot +34 -0
- data/docs/images/ui_hierarchy.png +0 -0
- data/ext/key_coder/extconf.rb +6 -0
- data/ext/key_coder/key_coder.m +77 -0
- data/lib/ax_elements/accessibility/enumerators.rb +104 -0
- data/lib/ax_elements/accessibility/language.rb +347 -0
- data/lib/ax_elements/accessibility/qualifier.rb +73 -0
- data/lib/ax_elements/accessibility.rb +164 -0
- data/lib/ax_elements/core.rb +541 -0
- data/lib/ax_elements/element.rb +593 -0
- data/lib/ax_elements/elements/application.rb +88 -0
- data/lib/ax_elements/elements/button.rb +18 -0
- data/lib/ax_elements/elements/radio_button.rb +18 -0
- data/lib/ax_elements/elements/row.rb +30 -0
- data/lib/ax_elements/elements/static_text.rb +17 -0
- data/lib/ax_elements/elements/systemwide.rb +46 -0
- data/lib/ax_elements/inspector.rb +116 -0
- data/lib/ax_elements/macruby_extensions.rb +255 -0
- data/lib/ax_elements/notification.rb +37 -0
- data/lib/ax_elements/version.rb +9 -0
- data/lib/ax_elements.rb +30 -0
- data/lib/minitest/ax_elements.rb +19 -0
- data/lib/mouse.rb +185 -0
- data/lib/rspec/expectations/ax_elements.rb +15 -0
- data/test/elements/test_application.rb +72 -0
- data/test/elements/test_row.rb +27 -0
- data/test/elements/test_systemwide.rb +38 -0
- data/test/helper.rb +119 -0
- data/test/test_accessibility.rb +127 -0
- data/test/test_blankness.rb +26 -0
- data/test/test_core.rb +448 -0
- data/test/test_element.rb +939 -0
- data/test/test_enumerators.rb +81 -0
- data/test/test_inspector.rb +121 -0
- data/test/test_language.rb +157 -0
- data/test/test_macruby_extensions.rb +303 -0
- data/test/test_mouse.rb +5 -0
- data/test/test_search_semantics.rb +143 -0
- metadata +219 -0
data/.yardopts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
--no-cache
|
2
|
+
--no-output
|
3
|
+
--verbose
|
4
|
+
--markup markdown
|
5
|
+
--markup-provider redcarpet
|
6
|
+
--asset docs/images:images
|
7
|
+
--readme README.markdown
|
8
|
+
lib/**/*.rb
|
9
|
+
ext/**/*.m
|
10
|
+
-
|
11
|
+
docs/Inspecting.markdown
|
12
|
+
docs/Acting.markdown
|
13
|
+
docs/Searching.markdown
|
14
|
+
docs/Notifications.markdown
|
15
|
+
docs/KeyboardEvents.markdown
|
16
|
+
docs/Debugging.markdown
|
17
|
+
docs/NewBehaviour.markdown
|
18
|
+
docs/AccessibilityTips.markdown
|
19
|
+
docs/TestingExtensions.markdown
|
20
|
+
LICENSE.txt
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2010-2011, Marketcircle Inc.
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of Marketcircle Inc. nor the names of its
|
12
|
+
contributors may be used to endorse or promote products derived
|
13
|
+
from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL Marketcircle Inc. BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
21
|
+
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
22
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
23
|
+
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
24
|
+
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
25
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.markdown
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# AXElements
|
2
|
+
|
3
|
+
AXElements is a DSL abstraction built on top of the Mac OS X
|
4
|
+
Accessibility and CGEvent APIs that allows code to be written in a
|
5
|
+
very natural and declarative style that describes user interactions.
|
6
|
+
|
7
|
+
The framework is optimized for writing tests that require automatic
|
8
|
+
GUI manipulation, whether it be finding controls on the screen,
|
9
|
+
typing, clicking, or other ways in which a user can interact with the
|
10
|
+
computer.
|
11
|
+
|
12
|
+
## Getting Setup
|
13
|
+
|
14
|
+
You need to have the OS X developer tools installed in build and
|
15
|
+
install AXElements (sorry). Go ahead and install the tools now if you
|
16
|
+
haven't done that yet, I'll wait.
|
17
|
+
|
18
|
+
Once, you have the developer tools, you should install MacRuby, the
|
19
|
+
latest release should be sufficient, but nightly builds are usually
|
20
|
+
safe as well. If you are on Snow Leopard, you will also need to
|
21
|
+
install the
|
22
|
+
[Bridge Support Preview](http://www.macruby.org/blog/2010/10/08/bridgesupport-preview.html).
|
23
|
+
|
24
|
+
At this point you should install development dependencies. You can do
|
25
|
+
so with `bundler` if you have it, but it will be faster to use the
|
26
|
+
`setup_dev` task that has been provided. Simply type the following in
|
27
|
+
terminal:
|
28
|
+
|
29
|
+
rake setup_dev
|
30
|
+
|
31
|
+
__NOTE__: if you are not using RVM, then you should use `macrake`
|
32
|
+
instead of `rake` for this command and anywhere else that you see
|
33
|
+
`rake` in the documentation. Also, remember that if you are not using
|
34
|
+
RVM with MacRuby but still have RVM installed then you will need to
|
35
|
+
disable RVM like so:
|
36
|
+
|
37
|
+
rvm use system
|
38
|
+
|
39
|
+
Once you are setup, you can start looking through the tutorial
|
40
|
+
documentation to show you how to use AXElements. The first tutorial is
|
41
|
+
the {file:docs/Inspecting.markdown Inspecting tutorial}. The full list
|
42
|
+
of topics include:
|
43
|
+
|
44
|
+
* {file:docs/Inspecting.markdown Inspecting}
|
45
|
+
* {file:docs/Acting.markdown Acting}
|
46
|
+
* {file:docs/Searching.markdown Searching}
|
47
|
+
* {file:docs/Notifications.markdown Notifications}
|
48
|
+
* {file:docs/KeyboardEvents.markdown Keyboard}
|
49
|
+
* {file:docs/Debugging.markdown Debugging}
|
50
|
+
* {file:docs/NewBehaviour.markdown Adding Behaviour To AXElements}
|
51
|
+
* {file:docs/AccessibilityTips.markdown Making Your Apps More Accessibile}
|
52
|
+
* {file:docs/TestingExtensions.markdown Test Suite Extensions for RSpec, Minitest, etc.}
|
53
|
+
|
54
|
+
## Documentation
|
55
|
+
|
56
|
+
AXElements is documented using YARD, and includes a few tutorials in
|
57
|
+
the `docs/` directory. If you do not want to generate the
|
58
|
+
documentation yourself then you can go to
|
59
|
+
[rdoc.info](http://rdoc.info/gems/AXElements/frames).
|
60
|
+
|
61
|
+
Though it is not required, you may want to read Apple's
|
62
|
+
[Accessibility Overview](http://developer.apple.com/library/mac/#documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXModel/OSXAXmodel.html)
|
63
|
+
as a primer on some the technical underpinnings of AXElements.
|
64
|
+
|
65
|
+
## Test Suite
|
66
|
+
|
67
|
+
Before starting development on your machine, you should run the test
|
68
|
+
suite and make sure things are kosher. The nature of this library
|
69
|
+
requires that the tests take over your computer while they run. The
|
70
|
+
tests aren't programmed to do anything destructive, but if you
|
71
|
+
interfere with them then something could go wrong.
|
72
|
+
|
73
|
+
To run the tests you simply need to run the `test` task:
|
74
|
+
|
75
|
+
rake test
|
76
|
+
|
77
|
+
__NOTE__: there may be some tests are dependent on Accessibility
|
78
|
+
features that are new in OS X Lion which will cause test failures on
|
79
|
+
OS X Snow Leopard. If you have any issues then you should look at the
|
80
|
+
output to find hints at what went wrong and/or log a bug. I will still
|
81
|
+
support Snow Leopard as long as MacRuby does, but I do not have easy
|
82
|
+
access to a Snow Leopard machine to verify that things still work.
|
83
|
+
|
84
|
+
### Benchmarks
|
85
|
+
|
86
|
+
Benchmarks are also included as part of the test suite, but they are
|
87
|
+
disabled by default. In order to enable them you need to set the
|
88
|
+
`BENCH` environment variable:
|
89
|
+
|
90
|
+
BENCH=1 rake test
|
91
|
+
|
92
|
+
Benchmarks only exist for code that is known to be slow. I'm keeping
|
93
|
+
tabs on slow code so that I be confident about getting depressed when
|
94
|
+
it gets slower. Though, there is still room for improved performance
|
95
|
+
as well.
|
96
|
+
|
97
|
+
## Road Map
|
98
|
+
|
99
|
+
There are still a bunch of things that could be done to improve
|
100
|
+
AXElements. The README only contains an idealized outline of some of
|
101
|
+
the high-level items that should get done in the next couple of
|
102
|
+
releases. Smaller items are peppered through the code base and marked
|
103
|
+
with `@todo` tags.
|
104
|
+
|
105
|
+
### 0.7 (or maybe 1.0)
|
106
|
+
|
107
|
+
- Pre-loading AX hierarchy and attribute cache from
|
108
|
+
`/System/Library/Accessibility/AccessibilityDefinitions.plist`
|
109
|
+
+ Not available on Snow Leopard, so it will have to wait anyways
|
110
|
+
+ Probably inccurs too much overhead at boot time right now
|
111
|
+
- Make a decision about NSArray#method_missing
|
112
|
+
- Merge notifications with actions as they are commonly combined
|
113
|
+
+ But how?
|
114
|
+
- Rewrite core module to handle errors more gracefully
|
115
|
+
- Mouse module cleanup and regression testing
|
116
|
+
- Test suite deduplication cleanup and better isolation
|
117
|
+
- Performance tweaks
|
118
|
+
- The OO abstraction leaks in a few places, code needs to be
|
119
|
+
refactored without hurting performance too much
|
120
|
+
- Test framework helpers
|
121
|
+
+ Minitest
|
122
|
+
+ RSpec
|
123
|
+
- Thread Safety
|
124
|
+
+ Only if it becomes an issue, otherwise it might be better to
|
125
|
+
forget thread safey to simplify and optimize existing code
|
126
|
+
|
127
|
+
### Future
|
128
|
+
|
129
|
+
- Screenshot taking and diff'ing abilities for those rare cases when
|
130
|
+
you need it
|
131
|
+
- Address Book helpers, and other friends
|
132
|
+
|
133
|
+
## Contributing to AXElements
|
134
|
+
|
135
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
136
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
137
|
+
* Fork the project
|
138
|
+
* Start a feature/bugfix branch
|
139
|
+
* Commit and push until you are happy with your contribution
|
140
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
141
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
142
|
+
|
143
|
+
## Copyright
|
144
|
+
|
145
|
+
Copyright (c) 2010-2011 Marketcircle Incorporated. All rights
|
146
|
+
reserved.
|
147
|
+
|
148
|
+
AXElements is available under the standard 3-clause BSD license. See
|
149
|
+
{file:LICENSE.txt LICENSE.txt} for further details.
|
150
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
task :default => :gem
|
4
|
+
task :clean => :clobber
|
5
|
+
|
6
|
+
def safe_require path, name
|
7
|
+
require path
|
8
|
+
yield
|
9
|
+
rescue LoadError => e
|
10
|
+
$stderr.puts "It seems as though you do not have #{name} installed."
|
11
|
+
command = ENV['RUBY_VERSION'] ? 'gem' : 'sudo macgem'
|
12
|
+
$stderr.puts "You can install it by running `#{command} install #{name}`."
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
## Documentation
|
17
|
+
|
18
|
+
safe_require 'yard', 'yard' do
|
19
|
+
YARD::Rake::YardocTask.new
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Generate Graphviz object graph'
|
23
|
+
task :garden => :yard do
|
24
|
+
sh 'yard graph --full --dependencies --dot="-Tpng:quartz" -f docs/images/AX.dot'
|
25
|
+
end
|
26
|
+
|
27
|
+
## Console
|
28
|
+
|
29
|
+
desc 'Start up irb with AXElements loaded'
|
30
|
+
task :console => :ext do
|
31
|
+
irb = ENV['RUBY_VERSION'] ? 'irb' : 'macirb'
|
32
|
+
sh "#{irb} -Ilib -Iext/key_coder -rubygems -rax_elements"
|
33
|
+
end
|
34
|
+
|
35
|
+
## Compilation
|
36
|
+
|
37
|
+
require 'rake/compiletask'
|
38
|
+
Rake::CompileTask.new
|
39
|
+
|
40
|
+
desc 'Compile C extensions'
|
41
|
+
task :ext do
|
42
|
+
Dir.chdir 'ext/key_coder' do
|
43
|
+
break if File.exists?('key_coder.bundle') && File.mtime('key_coder.bundle') > File.mtime('key_coder.m')
|
44
|
+
ruby 'extconf.rb'
|
45
|
+
sh 'make'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'Clean temporary files created by the C extension'
|
50
|
+
task :clobber_ext do
|
51
|
+
Dir.chdir 'ext/key_coder' do
|
52
|
+
['Makefile', 'key_coder.o', 'key_coder.bundle'].each do |file|
|
53
|
+
$stdout.puts "rm ext/key_coder/#{file}"
|
54
|
+
rm file
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
task :clobber => :clobber_ext
|
59
|
+
|
60
|
+
## Testing
|
61
|
+
|
62
|
+
desc 'Open the fixture app'
|
63
|
+
task :run_fixture => :fixture do
|
64
|
+
sh 'open test/fixture/Release/AXElementsTester.app'
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'Build the test fixture'
|
68
|
+
task :fixture do
|
69
|
+
sh 'cd test/AXElementsTester && xcodebuild'
|
70
|
+
end
|
71
|
+
|
72
|
+
require 'rake/testtask'
|
73
|
+
Rake::TestTask.new(:test) do |t|
|
74
|
+
t.libs << 'test' << 'ext/key_coder'
|
75
|
+
t.pattern = 'test/**/test_*.rb'
|
76
|
+
t.ruby_opts = ['-rhelper']
|
77
|
+
t.verbose = true
|
78
|
+
end
|
79
|
+
task :test => [:ext, :fixture]
|
80
|
+
|
81
|
+
## Gem Packaging
|
82
|
+
require 'rubygems/dependency_installer'
|
83
|
+
require 'rake/gempackagetask'
|
84
|
+
|
85
|
+
spec = Gem::Specification.load('AXElements.gemspec')
|
86
|
+
|
87
|
+
Rake::GemPackageTask.new(spec) { }
|
88
|
+
|
89
|
+
# This only installs this gem, it does not take deps into consideration
|
90
|
+
desc 'Build gem and install it'
|
91
|
+
task :install => :gem do
|
92
|
+
Gem::Installer.new("pkg/#{spec.file_name}").install
|
93
|
+
end
|
94
|
+
|
95
|
+
desc 'Install dependencies for a test node'
|
96
|
+
task :setup_node do
|
97
|
+
spec.runtime_dependencies.each do |dep|
|
98
|
+
puts "Installing #{dep.name}"
|
99
|
+
Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
desc 'Install dependencies for development'
|
104
|
+
task :setup_dev => :setup_node do
|
105
|
+
spec.development_dependencies.each do |dep|
|
106
|
+
puts "Installing #{dep.name}"
|
107
|
+
Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Accessibility Tips
|
2
|
+
|
3
|
+
This document includes tips for customizing accessibility in your own
|
4
|
+
applications. The goal is to inform you of pitfalls that are not
|
5
|
+
mentioned in Apple's documentation. It also includes notes on how to
|
6
|
+
avoid making decsions that will make an application incompatible with
|
7
|
+
AXElements.
|
8
|
+
|
9
|
+
@todo This document is under construction and is currently just a set
|
10
|
+
of notes and unorganized sections ripped from other documents.
|
11
|
+
|
12
|
+
## Guidelines
|
13
|
+
|
14
|
+
When implementing custom accessibility roles, you should never use a
|
15
|
+
pluralized name for the role. A role that is already pluralized will
|
16
|
+
break search.
|
17
|
+
|
18
|
+
|
19
|
+
## Adding new stuff
|
20
|
+
|
21
|
+
Adding new attributes to an object is very simple...usually. Most of
|
22
|
+
the time it is as simple as overriding two methods:
|
23
|
+
|
24
|
+
- `accessibilityAttributeNames`
|
25
|
+
- `accessibilityAttributeValue:`
|
26
|
+
|
27
|
+
`accessibilityAttributeNames` needs to return an array with the names
|
28
|
+
of available attributes. You should call `super` to get the existing
|
29
|
+
array first, and then append any custom attributes you want to
|
30
|
+
provide.
|
31
|
+
|
32
|
+
An attribute name must follow the convention of being a camel cased
|
33
|
+
string with the "AX" prefix, such as `AXTitle`. You can optionally
|
34
|
+
include an additional prefix before "AX", such as "MCAX" for
|
35
|
+
Marketcircle custom attributes. If you do not follow these rules then
|
36
|
+
attribute names will not be translated properly by AXElements.
|
37
|
+
|
38
|
+
`accessibilityAttributeValue:` is how you actually provide the value
|
39
|
+
for the attribute; the parameter for this method is the name of the
|
40
|
+
attribute fetched from calling `accessibilityAttributeNames`. You
|
41
|
+
should return the value without doing any extra work to the data; the
|
42
|
+
Accessibility interface will do any wrapping or translating for
|
43
|
+
you (e.g. CGPoint objects will have co-ordinates flipped). In the case
|
44
|
+
of a C structs you should leave them wrapped in an NSValue object.
|
45
|
+
|
46
|
+
Similarly, parameterized attributes are added using methods with
|
47
|
+
`Parameter` in the name. The method for getting the value of a
|
48
|
+
parameterized attribute will of course take an extra parameter for the
|
49
|
+
parameterized attributes parameter.
|
50
|
+
|
51
|
+
### Where To Implement The Methods
|
52
|
+
|
53
|
+
The difficulty in adding attributes lies in finding out where you need
|
54
|
+
to add the accessibility methods. Often, the class that implements
|
55
|
+
accessibility is the class that draws the user interface element. For
|
56
|
+
example, the accessibility information for a button is implemented on
|
57
|
+
the button cell and not the button itself. Since Apple is under the
|
58
|
+
delusion that you will never need to add any custom accessibility
|
59
|
+
information, they really don't document these customizations enough,
|
60
|
+
and so this document only includes caveats that have been discovered
|
61
|
+
so far.
|
62
|
+
|
63
|
+
It is often inconvenient to subclass the cell for an object just for
|
64
|
+
accessibility. In these cases Apple has provided something similar to
|
65
|
+
singleton methods, but less useful, with the
|
66
|
+
`accessibilitySetOverrideValue:forAttribute:` method. You can use the
|
67
|
+
method to override an attribute or even add a new one. The main issue
|
68
|
+
with this method is that any attribute that is overridden, or added,
|
69
|
+
will not be writable using the accessibility APIs. Another issue is
|
70
|
+
that you have to calculate the value when you override instead of when
|
71
|
+
the attribute value is queried by the client.
|
72
|
+
|
73
|
+
### Writability
|
74
|
+
|
75
|
+
In the case where it is convenient to be able to change an attribute's
|
76
|
+
value through accessibility, like the size of a window, you will also
|
77
|
+
need to implement two more methods for the attribute:
|
78
|
+
|
79
|
+
- `accessibilityIsAttributeSettable:`
|
80
|
+
- `accessibilitySetValue:forAttribute:`
|
81
|
+
|
82
|
+
`accessibilityIsAttributeSettable:` simply responds with whether or
|
83
|
+
not the attribute is writable, and
|
84
|
+
`accessibilitySetValue:forAttribute:` will be called to actually write
|
85
|
+
to the attribute.
|
86
|
+
|
87
|
+
### Remember `super`
|
88
|
+
|
89
|
+
It is important to remember that these methods are already implemented
|
90
|
+
for the built in features. When overriding, you should only implement
|
91
|
+
the custom behaviour and call `super` to handle everything else.
|
92
|
+
|
93
|
+
### Existing Definitions
|
94
|
+
|
95
|
+
When implementing custom behaviour, you should try and use
|
96
|
+
pseudoclasses that have already been defined by Apple, as well as
|
97
|
+
attributes, parameterized attributes, and other features that have
|
98
|
+
already been defined. Apple maintains the documentation for all their
|
99
|
+
definitions on
|
100
|
+
[here](http://developer.apple.com/library/mac/#documentation/UserExperience/Reference/Accessibility_RoleAttribute_Ref/Introduction.html#//apple_ref/doc/uid/TP40007870).
|
101
|
+
The documentation is fairly detailed now (moreso than before), but
|
102
|
+
still misses a few things.
|
103
|
+
|
104
|
+
|
105
|
+
## Adding Accessibility Actions
|
106
|
+
|
107
|
+
If you have access to the source code for an app, you can add more
|
108
|
+
accessibility actions. You need to override two methods, just like
|
109
|
+
with adding attributes:
|
110
|
+
|
111
|
+
– `accessibilityActionNames`
|
112
|
+
– `accessibilityPerformAction:`
|
113
|
+
|
114
|
+
These methods should be implemented in the same way that you would
|
115
|
+
implement new attributes, just as detailed in the
|
116
|
+
{file:docs/Inspecting.markdown Inspecting tutorial}. The one
|
117
|
+
difference is that `accessibilityPerformAction:` should not return
|
118
|
+
anything after it performs the action.
|
119
|
+
|