accessibility_core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.yardopts +9 -0
  2. data/History.markdown +36 -0
  3. data/README.markdown +66 -0
  4. data/Rakefile +72 -0
  5. data/ext/accessibility/bridge/ext/accessibility/bridge/bridge.c +490 -0
  6. data/ext/accessibility/bridge/ext/accessibility/bridge/extconf.rb +22 -0
  7. data/ext/accessibility/bridge/lib/accessibility/bridge.rb +33 -0
  8. data/ext/accessibility/bridge/lib/accessibility/bridge/common.rb +57 -0
  9. data/ext/accessibility/bridge/lib/accessibility/bridge/macruby.rb +185 -0
  10. data/ext/accessibility/bridge/lib/accessibility/bridge/mri.rb +121 -0
  11. data/ext/accessibility/bridge/lib/accessibility/bridge/version.rb +6 -0
  12. data/ext/accessibility/bridge/test/array_test.rb +31 -0
  13. data/ext/accessibility/bridge/test/boxed_test.rb +23 -0
  14. data/ext/accessibility/bridge/test/cfrange_test.rb +21 -0
  15. data/ext/accessibility/bridge/test/cgpoint_test.rb +54 -0
  16. data/ext/accessibility/bridge/test/cgrect_test.rb +60 -0
  17. data/ext/accessibility/bridge/test/cgsize_test.rb +54 -0
  18. data/ext/accessibility/bridge/test/helper.rb +19 -0
  19. data/ext/accessibility/bridge/test/nsstring_test.rb +22 -0
  20. data/ext/accessibility/bridge/test/nsurl_test.rb +17 -0
  21. data/ext/accessibility/bridge/test/object_test.rb +19 -0
  22. data/ext/accessibility/bridge/test/range_test.rb +16 -0
  23. data/ext/accessibility/bridge/test/string_test.rb +35 -0
  24. data/ext/accessibility/bridge/test/uri_test.rb +15 -0
  25. data/ext/accessibility/core/bridge.h +1 -0
  26. data/ext/accessibility/core/core.c +705 -0
  27. data/ext/accessibility/core/extconf.rb +22 -0
  28. data/ext/accessibility/highlighter/extconf.rb +22 -0
  29. data/ext/accessibility/highlighter/highlighter.c +7 -0
  30. data/lib/accessibility/core.rb +12 -0
  31. data/lib/accessibility/core/core_ext/common.rb +57 -0
  32. data/lib/accessibility/core/core_ext/macruby.rb +140 -0
  33. data/lib/accessibility/core/core_ext/mri.rb +121 -0
  34. data/lib/accessibility/core/macruby.rb +858 -0
  35. data/lib/accessibility/core/version.rb +6 -0
  36. data/test/helper.rb +48 -0
  37. metadata +158 -0
@@ -0,0 +1,22 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << ' -std=c99 -Wall -Werror -pedantic -ObjC'
4
+ $LIBS << ' -framework CoreFoundation -framework ApplicationServices -framework Cocoa'
5
+ $LIBS << ' -framework CoreGraphics' unless `sw_vers -productVersion`.to_f == 10.7
6
+
7
+ if RUBY_ENGINE == 'macruby'
8
+ $CFLAGS << ' -fobjc-gc'
9
+ else
10
+ unless RbConfig::CONFIG["CC"].match /clang/
11
+ clang = `which clang`.chomp
12
+ if clang.empty?
13
+ raise "Clang not installed. Cannot build C extension"
14
+ else
15
+ RbConfig::MAKEFILE_CONFIG["CC"] = clang
16
+ RbConfig::MAKEFILE_CONFIG["CXX"] = clang
17
+ end
18
+ end
19
+ $CFLAGS << ' -DNOT_MACRUBY'
20
+ end
21
+
22
+ create_makefile 'accessibility/bridge'
@@ -0,0 +1,33 @@
1
+ require 'accessibility/bridge/version'
2
+
3
+ if RUBY_ENGINE == 'macruby'
4
+
5
+ ##
6
+ # Whether or not we are running on MacRuby
7
+ def on_macruby?
8
+ true
9
+ end
10
+
11
+ framework 'Cocoa'
12
+
13
+ # A workaround that guarantees that `CGPoint` is defined
14
+ unless defined? MOUNTAIN_LION_APPKIT_VERSION
15
+ MOUNTAIN_LION_APPKIT_VERSION = 1187
16
+ end
17
+
18
+ if NSAppKitVersionNumber >= MOUNTAIN_LION_APPKIT_VERSION
19
+ framework '/System/Library/Frameworks/CoreGraphics.framework'
20
+ end
21
+
22
+ require 'accessibility/bridge/macruby'
23
+
24
+ else
25
+
26
+ def on_macruby?
27
+ false
28
+ end
29
+
30
+ require 'accessibility/bridge/mri'
31
+
32
+ end
33
+
@@ -0,0 +1,57 @@
1
+ class CGPoint
2
+ ##
3
+ # Returns the receiver, since the receiver is already a {CGPoint}
4
+ #
5
+ # @return [CGPoint]
6
+ def to_point
7
+ self
8
+ end
9
+ end
10
+
11
+ class CGSize
12
+ ##
13
+ # Returns the receiver, since the receiver is already a {CGSize}
14
+ #
15
+ # @return [CGSize]
16
+ def to_size
17
+ self
18
+ end
19
+ end
20
+
21
+ class CGRect
22
+ ##
23
+ # Returns the receiver, since the receiver is already a {CGRect}
24
+ #
25
+ # @return [CGRect]
26
+ def to_rect
27
+ self
28
+ end
29
+ end
30
+
31
+ ##
32
+ # accessibility-core extensions to `Array`
33
+ class Array
34
+ ##
35
+ # Coerce the first two elements of the receiver into a {CGPoint}
36
+ #
37
+ # @return [CGPoint]
38
+ def to_point
39
+ CGPoint.new self[0], self[1]
40
+ end
41
+
42
+ ##
43
+ # Coerce the first two elements of the receiver into a {CGSize}
44
+ #
45
+ # @return [CGSize]
46
+ def to_size
47
+ CGSize.new self[0], self[1]
48
+ end
49
+
50
+ ##
51
+ # Coerce the first four elements of the receiver into a {CGRect}
52
+ #
53
+ # @return [CGRect]
54
+ def to_rect
55
+ CGRect.new CGPoint.new(self[0], self[1]), CGSize.new(self[2], self[3])
56
+ end
57
+ end
@@ -0,0 +1,185 @@
1
+ require 'accessibility/bridge/common'
2
+
3
+ ##
4
+ # accessibility-core extensions for `NSURL`
5
+ class NSURL
6
+ ##
7
+ # Return the reciver, for the receiver is already a URL object
8
+ #
9
+ # @return [NSURL]
10
+ def to_url
11
+ self
12
+ end
13
+
14
+ # because printing is easier this way
15
+ alias_method :to_s, :inspect
16
+ end
17
+
18
+ ##
19
+ # accessibility-core extensions for `NSString`
20
+ class NSString
21
+ ##
22
+ # Create an NSURL using the receiver as the initialization string
23
+ #
24
+ # If the receiver is not a valid URL then `nil` will be returned.
25
+ #
26
+ # This exists because of
27
+ # [rdar://11207662](http://openradar.appspot.com/11207662).
28
+ #
29
+ # @return [NSURL,nil]
30
+ def to_url
31
+ NSURL.URLWithString self
32
+ end
33
+ end
34
+
35
+ ##
36
+ # `accessibility-core` extensions for `NSObject`
37
+ class NSObject
38
+ ##
39
+ # Return an object safe for passing to AXAPI
40
+ def to_ax
41
+ self
42
+ end
43
+
44
+ ##
45
+ # Return a usable object from an AXAPI pointer
46
+ def to_ruby
47
+ self
48
+ end
49
+ end
50
+
51
+ ##
52
+ # `accessibility-core` extensions for `CFRange`
53
+ class CFRange
54
+ ##
55
+ # Convert the {CFRange} to a Ruby {Range} object
56
+ #
57
+ # @return [Range]
58
+ def to_ruby
59
+ Range.new location, (location + length - 1)
60
+ end
61
+ end
62
+
63
+ ##
64
+ # `accessibility-core` extensions for `Range`
65
+ class Range
66
+ # @return [AXValueRef]
67
+ def to_ax
68
+ raise ArgumentError, "can't convert negative index" if last < 0 || first < 0
69
+ length = if exclude_end?
70
+ last - first
71
+ else
72
+ last - first + 1
73
+ end
74
+ CFRange.new(first, length).to_ax
75
+ end
76
+ end
77
+
78
+ ##
79
+ # AXElements extensions to the `Boxed` class
80
+ #
81
+ # The `Boxed` class is simply an abstract base class for structs that
82
+ # MacRuby can use via bridge support.
83
+ class Boxed
84
+ ##
85
+ # Returns the number that AXAPI uses in order to know how to wrap
86
+ # a struct.
87
+ #
88
+ # @return [Number]
89
+ def self.ax_value
90
+ raise NotImplementedError, "#{inspect}:#{self.class} cannot be wrapped"
91
+ end
92
+
93
+ ##
94
+ # Create an `AXValueRef` from the `Boxed` instance. This will only
95
+ # work if for the most common boxed types, you will need to check
96
+ # the AXAPI documentation for an up to date list.
97
+ #
98
+ # @example
99
+ #
100
+ # CGPoint.new(12, 34).to_ax # => #<AXValueRef:0x455678e2>
101
+ # CGSize.new(56, 78).to_ax # => #<AXValueRef:0x555678e2>
102
+ #
103
+ # @return [AXValueRef]
104
+ def to_ax
105
+ klass = self.class
106
+ ptr = Pointer.new klass.type
107
+ ptr.assign self
108
+ AXValueCreate(klass.ax_value, ptr)
109
+ end
110
+ end
111
+
112
+ # `accessibility-core` extensions for `CFRange`'s metaclass
113
+ class << CFRange
114
+ # (see Boxed.ax_value)
115
+ def ax_value; KAXValueCFRangeType end
116
+ end
117
+ # `accessibility-core` extensions for `CGSize`'s metaclass
118
+ class << CGSize
119
+ # (see Boxed.ax_value)
120
+ def ax_value; KAXValueCGSizeType end
121
+ end
122
+ # `accessibility-core` extensions for `CGRect`'s metaclass
123
+ class << CGRect
124
+ # (see Boxed.ax_value)
125
+ def ax_value; KAXValueCGRectType end
126
+ end
127
+ # `accessibility-core` extensions for `CGPoint`'s metaclass
128
+ class << CGPoint
129
+ # (see Boxed.ax_value)
130
+ def ax_value; KAXValueCGPointType end
131
+ end
132
+
133
+ ##
134
+ # Mixin for the special hidden class in MacRuby that represents `AXValueRef`
135
+ #
136
+ # This module adds a `#to_ruby` method that actually unwraps the object from
137
+ # the `AXValueRef` to some sort of {Boxed} object, such as a {CGPoint} or a
138
+ # {Range}.
139
+ module ValueWrapper
140
+
141
+
142
+ ##
143
+ # Map of type encodings used for unwrapping structs wrapped in an `AXValueRef`
144
+ #
145
+ # The list is order sensitive, which is why we unshift nil, but
146
+ # should probably be more rigorously defined at runtime.
147
+ #
148
+ # @return [String,nil]
149
+ BOX_TYPES = [CGPoint, CGSize, CGRect, CFRange].map!(&:type).unshift(nil)
150
+
151
+ ##
152
+ # Unwrap an `AXValueRef` into the `Boxed` instance that it is supposed
153
+ # to be. This will only work for the most common boxed types, you will
154
+ # need to check the AXAPI documentation for an up to date list.
155
+ #
156
+ # @example
157
+ #
158
+ # wrapped_point.to_ruby # => #<CGPoint x=44.3 y=99.0>
159
+ # wrapped_range.to_ruby # => #<CFRange begin=7 length=100>
160
+ # wrapped_thing.to_ruby # => wrapped_thing
161
+ #
162
+ # @return [Boxed]
163
+ def to_ruby
164
+ type = AXValueGetType(self)
165
+ return self if type.zero?
166
+
167
+ ptr = Pointer.new BOX_TYPES[type]
168
+ AXValueGetValue(self, type, ptr)
169
+ ptr.value.to_ruby
170
+ end
171
+
172
+ # hack to find the __NSCFType class and mix things in
173
+ klass = AXUIElementCreateSystemWide().class
174
+ klass.send :include, self
175
+
176
+ end
177
+
178
+ ##
179
+ # `accessibility-core` extensions to `NSArray`
180
+ class NSArray
181
+ # @return [Array]
182
+ def to_ruby
183
+ map do |obj| obj.to_ruby end
184
+ end
185
+ end
@@ -0,0 +1,121 @@
1
+ ##
2
+ # A structure that contains a point in a two-dimensional coordinate system
3
+ CGPoint = Struct.new(:x, :y) do
4
+
5
+ # @param x [Number]
6
+ # @param y [Number]
7
+ def initialize x = 0.0, y = 0.0
8
+ super
9
+ end
10
+
11
+ # @!attribute [rw] x
12
+ # The `x` co-ordinate of the screen point
13
+ # @return [Number]
14
+
15
+ # @!attribute [rw] y
16
+ # The `y` co-ordinate of the screen point
17
+ # @return [Number]
18
+
19
+ ##
20
+ # Return a nice string representation of the point
21
+ #
22
+ # Overrides `Object#inspect` to more closely mimic MacRuby `Boxed#inspect`.
23
+ #
24
+ # @return [String]
25
+ def inspect
26
+ "#<CGPoint x=#{self.x.to_f} y=#{self.y.to_f}>"
27
+ end
28
+
29
+ end
30
+
31
+
32
+ ##
33
+ # A structure that contains the size of a rectangle in a 2D co-ordinate system
34
+ CGSize = Struct.new(:width, :height) do
35
+
36
+ # @param width [Number]
37
+ # @param height [Number]
38
+ def initialize width = 0.0, height = 0.0
39
+ super
40
+ end
41
+
42
+ # @!attribute [rw] width
43
+ # The `width` of the box
44
+ # @return [Number]
45
+
46
+ # @!attribute [rw] height
47
+ # The `heighth` of the box
48
+ # @return [Number]
49
+
50
+ ##
51
+ # Return a nice string representation of the size
52
+ #
53
+ # Overrides `Object#inspect` to more closely mimic MacRuby `Boxed#inspect`.
54
+ #
55
+ # @return [String]
56
+ def inspect
57
+ "#<CGSize width=#{self.width.to_f} height=#{self.height.to_f}>"
58
+ end
59
+
60
+ end
61
+
62
+
63
+ ##
64
+ # Complete definition of a rectangle in a 2D coordinate system
65
+ CGRect = Struct.new(:origin, :size) do
66
+
67
+ # @param origin [CGPoint,#to_point]
68
+ # @param size [CGSize,#to_size]
69
+ def initialize origin = CGPoint.new, size = CGSize.new
70
+ super(origin.to_point, size.to_size)
71
+ end
72
+
73
+ # @!attribute [rw] origin
74
+ # The `origin` point
75
+ # @return [CGPoint,#to_point]
76
+
77
+ # @!attribute [rw] size
78
+ # The `size` of the rectangle
79
+ # @return [CGSize,#to_size]
80
+
81
+ ##
82
+ # Return a nice string representation of the rectangle
83
+ #
84
+ # Overrides `Object#inspect` to more closely mimic MacRuby `Boxed#inspect`.
85
+ #
86
+ # @return [String]
87
+ def inspect
88
+ "#<CGRect origin=#{self.origin.inspect} size=#{self.size.inspect}>"
89
+ end
90
+
91
+ end
92
+
93
+
94
+ require 'uri'
95
+
96
+ ##
97
+ # `accessibility-core` extensions to the `URI` family of classes
98
+ class URI::Generic
99
+ ##
100
+ # Returns the receiver (since the receiver is already a `URI` object)
101
+ #
102
+ # @return [URI::Generic]
103
+ def to_url
104
+ self
105
+ end
106
+ end
107
+
108
+ ##
109
+ # `accessibility-core` extensions to the `String` class
110
+ class String
111
+ ##
112
+ # Parse the receiver into a `URI` object
113
+ #
114
+ # @return [URI::Generic]
115
+ def to_url
116
+ URI.parse self
117
+ end
118
+ end
119
+
120
+
121
+ require 'accessibility/bridge/common'
@@ -0,0 +1,6 @@
1
+ module Accessibility
2
+ module Bridge
3
+ # @return [String]
4
+ VERSION = '0.1.0'
5
+ end
6
+ end
@@ -0,0 +1,31 @@
1
+ require 'test/helper'
2
+
3
+ class ArrayTest < MiniTest::Unit::TestCase
4
+
5
+ def test_to_point
6
+ x, y = rand_nums 2
7
+ p = [x, y].to_point
8
+ assert_kind_of CGPoint, p
9
+ assert_equal x, p.x
10
+ assert_equal y, p.y
11
+ end
12
+
13
+ def test_to_size
14
+ w, h = rand_nums 2
15
+ s = [w, h].to_size
16
+ assert_kind_of CGSize, s
17
+ assert_equal w, s.width
18
+ assert_equal h, s.height
19
+ end
20
+
21
+ def test_to_rect
22
+ x, y, w, h = rand_nums 4
23
+ r = [x, y, w, h].to_rect
24
+ assert_kind_of CGRect, r
25
+ assert_equal x, r.origin.x
26
+ assert_equal y, r.origin.y
27
+ assert_equal w, r.size.width
28
+ assert_equal h, r.size.height
29
+ end
30
+
31
+ end