accessibility_core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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