accessibility_bridge 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +9 -0
- data/History.markdown +5 -0
- data/README.markdown +39 -0
- data/Rakefile +51 -0
- data/ext/accessibility/bridge/bridge.c +490 -0
- data/ext/accessibility/bridge/extconf.rb +22 -0
- data/lib/accessibility/bridge.rb +33 -0
- data/lib/accessibility/bridge/common.rb +57 -0
- data/lib/accessibility/bridge/macruby.rb +185 -0
- data/lib/accessibility/bridge/mri.rb +121 -0
- data/lib/accessibility/bridge/version.rb +6 -0
- data/test/helper.rb +19 -0
- metadata +120 -0
data/.yardopts
ADDED
data/History.markdown
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# accessibility\_bridge
|
2
|
+
|
3
|
+
Bare minimum bridging for MRI to easily use Cocoa objects. The intended
|
4
|
+
use for this code is as a support for other gems that require some
|
5
|
+
bridging to Cocoa stuff.
|
6
|
+
|
7
|
+
This was extracted from the
|
8
|
+
[accessibility\_core](https://github.com/AXElements/accessibility_core)
|
9
|
+
project and is a work-in-progress.
|
10
|
+
|
11
|
+
|
12
|
+
## Copyright
|
13
|
+
|
14
|
+
Copyright (c)2012, Mark Rada
|
15
|
+
All rights reserved.
|
16
|
+
|
17
|
+
Redistribution and use in source and binary forms, with or without
|
18
|
+
modification, are permitted provided that the following conditions are met:
|
19
|
+
|
20
|
+
* Redistributions of source code must retain the above copyright
|
21
|
+
notice, this list of conditions and the following disclaimer.
|
22
|
+
* Redistributions in binary form must reproduce the above copyright
|
23
|
+
notice, this list of conditions and the following disclaimer in the
|
24
|
+
documentation and/or other materials provided with the distribution.
|
25
|
+
* Neither the name of Mark Rada nor the names of its
|
26
|
+
contributors may be used to endorse or promote products derived
|
27
|
+
from this software without specific prior written permission.
|
28
|
+
|
29
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
30
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
31
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
32
|
+
DISCLAIMED. IN NO EVENT SHALL Mark Rada BE LIABLE FOR ANY
|
33
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
34
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
35
|
+
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
36
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
37
|
+
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
38
|
+
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
39
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
task :default => :test
|
2
|
+
|
3
|
+
require 'rake/clean'
|
4
|
+
CLEAN.include '*.plist', '*.gch'
|
5
|
+
|
6
|
+
desc 'Run the Clang static analyzer'
|
7
|
+
task :analyze do
|
8
|
+
sh "clang --analyze ext/accessibility/bridge/bridge.c"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Startup an IRb console with accessibility-core loaded'
|
12
|
+
task :console => [:compile] do
|
13
|
+
sh 'irb -Ilib -raccessibility/bridge'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Build the test fixture'
|
17
|
+
task :fixture do
|
18
|
+
sh 'cd test/AXElementsTester && xcodebuild'
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new do |t|
|
23
|
+
t.libs << '.'
|
24
|
+
t.pattern = 'test/*_test.rb'
|
25
|
+
end
|
26
|
+
task :test => :compile
|
27
|
+
|
28
|
+
|
29
|
+
# Gem stuff
|
30
|
+
|
31
|
+
require 'rubygems/package_task'
|
32
|
+
SPEC = Gem::Specification.load('accessibility_bridge.gemspec')
|
33
|
+
|
34
|
+
Gem::PackageTask.new(SPEC) { }
|
35
|
+
|
36
|
+
desc 'Build and install gem (not including deps)'
|
37
|
+
task :install => :gem do
|
38
|
+
require 'rubygems/installer'
|
39
|
+
Gem::Installer.new("pkg/#{SPEC.file_name}").install
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# C extensions!
|
44
|
+
|
45
|
+
require 'rake/extensiontask'
|
46
|
+
|
47
|
+
Rake::ExtensionTask.new('bridge', SPEC) do |ext|
|
48
|
+
ext.ext_dir = 'ext/accessibility/bridge'
|
49
|
+
ext.lib_dir = 'lib/accessibility'
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,490 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#import <Cocoa/Cocoa.h>
|
3
|
+
|
4
|
+
#ifndef ACCESSIBILITY_BRIDGE
|
5
|
+
#define ACCESSIBILITY_BRIDGE 1
|
6
|
+
|
7
|
+
#ifdef NOT_MACRUBY
|
8
|
+
|
9
|
+
VALUE rb_mAccessibility;
|
10
|
+
VALUE rb_cElement;
|
11
|
+
VALUE rb_cCGPoint;
|
12
|
+
VALUE rb_cCGSize;
|
13
|
+
VALUE rb_cCGRect;
|
14
|
+
VALUE rb_mURI; // URI module
|
15
|
+
VALUE rb_cURI; // URI::Generic class
|
16
|
+
|
17
|
+
ID sel_x;
|
18
|
+
ID sel_y;
|
19
|
+
ID sel_width;
|
20
|
+
ID sel_height;
|
21
|
+
ID sel_origin;
|
22
|
+
ID sel_size;
|
23
|
+
ID sel_to_point;
|
24
|
+
ID sel_to_size;
|
25
|
+
ID sel_to_rect;
|
26
|
+
ID sel_to_s;
|
27
|
+
ID sel_parse;
|
28
|
+
|
29
|
+
|
30
|
+
#define WRAP_ARRAY(wrapper) do { \
|
31
|
+
CFIndex length = CFArrayGetCount(array); \
|
32
|
+
VALUE ary = rb_ary_new2(length); \
|
33
|
+
\
|
34
|
+
for (CFIndex idx = 0; idx < length; idx++) \
|
35
|
+
rb_ary_store( \
|
36
|
+
ary, \
|
37
|
+
idx, \
|
38
|
+
wrapper(CFArrayGetValueAtIndex(array, idx)) \
|
39
|
+
); \
|
40
|
+
return ary; \
|
41
|
+
} while (false);
|
42
|
+
|
43
|
+
|
44
|
+
VALUE
|
45
|
+
wrap_unknown(CFTypeRef obj)
|
46
|
+
{
|
47
|
+
// TODO: this will leak, can we use something like alloca?
|
48
|
+
CFStringRef description = CFCopyDescription(obj);
|
49
|
+
rb_raise(
|
50
|
+
rb_eRuntimeError,
|
51
|
+
"accessibility-core doesn't know how to wrap `%s` objects yet",
|
52
|
+
CFStringGetCStringPtr(description, kCFStringEncodingMacRoman)
|
53
|
+
);
|
54
|
+
return Qnil; // unreachable
|
55
|
+
}
|
56
|
+
|
57
|
+
CFTypeRef
|
58
|
+
unwrap_unknown(VALUE obj)
|
59
|
+
{
|
60
|
+
obj = rb_funcall(obj, sel_to_s, 0);
|
61
|
+
rb_raise(
|
62
|
+
rb_eRuntimeError,
|
63
|
+
"accessibility-core doesn't know how to unwrap `%s'",
|
64
|
+
StringValuePtr(obj)
|
65
|
+
);
|
66
|
+
return NULL; // unreachable
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
VALUE
|
71
|
+
wrap_point(CGPoint point)
|
72
|
+
{
|
73
|
+
return rb_struct_new(rb_cCGPoint, DBL2NUM(point.x), DBL2NUM(point.y));
|
74
|
+
}
|
75
|
+
|
76
|
+
CGPoint
|
77
|
+
unwrap_point(VALUE point)
|
78
|
+
{
|
79
|
+
point = rb_funcall(point, sel_to_point, 0);
|
80
|
+
double x = NUM2DBL(rb_struct_getmember(point, sel_x));
|
81
|
+
double y = NUM2DBL(rb_struct_getmember(point, sel_y));
|
82
|
+
return CGPointMake(x, y);
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
VALUE
|
87
|
+
wrap_size(CGSize size)
|
88
|
+
{
|
89
|
+
return rb_struct_new(rb_cCGSize, DBL2NUM(size.width), DBL2NUM(size.height));
|
90
|
+
}
|
91
|
+
|
92
|
+
CGSize
|
93
|
+
unwrap_size(VALUE size)
|
94
|
+
{
|
95
|
+
size = rb_funcall(size, sel_to_size, 0);
|
96
|
+
double width = NUM2DBL(rb_struct_getmember(size, sel_width));
|
97
|
+
double height = NUM2DBL(rb_struct_getmember(size, sel_height));
|
98
|
+
return CGSizeMake(width, height);
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
VALUE
|
103
|
+
wrap_rect(CGRect rect)
|
104
|
+
{
|
105
|
+
VALUE point = wrap_point(rect.origin);
|
106
|
+
VALUE size = wrap_size(rect.size);
|
107
|
+
return rb_struct_new(rb_cCGRect, point, size);
|
108
|
+
}
|
109
|
+
|
110
|
+
CGRect
|
111
|
+
unwrap_rect(VALUE rect)
|
112
|
+
{
|
113
|
+
rect = rb_funcall(rect, sel_to_rect, 0);
|
114
|
+
CGPoint origin = unwrap_point(rb_struct_getmember(rect, sel_origin));
|
115
|
+
CGSize size = unwrap_size(rb_struct_getmember(rect, sel_size));
|
116
|
+
return CGRectMake(origin.x, origin.y, size.width, size.height);
|
117
|
+
}
|
118
|
+
|
119
|
+
|
120
|
+
VALUE
|
121
|
+
convert_cf_range(CFRange range)
|
122
|
+
{
|
123
|
+
CFIndex end_index = range.location + range.length;
|
124
|
+
if (range.length != 0)
|
125
|
+
end_index -= 1;
|
126
|
+
return rb_range_new(INT2FIX(range.location), INT2FIX(end_index), 0);
|
127
|
+
}
|
128
|
+
|
129
|
+
CFRange
|
130
|
+
convert_rb_range(VALUE range)
|
131
|
+
{
|
132
|
+
VALUE b, e;
|
133
|
+
int exclusive;
|
134
|
+
|
135
|
+
rb_range_values(range, &b, &e, &exclusive);
|
136
|
+
|
137
|
+
int begin = NUM2INT(b);
|
138
|
+
int end = NUM2INT(e);
|
139
|
+
|
140
|
+
if (begin < 0 || end < 0)
|
141
|
+
// We don't know what the max length of the range will be, so we
|
142
|
+
// can't count backwards.
|
143
|
+
rb_raise(
|
144
|
+
rb_eArgError,
|
145
|
+
"negative values are not allowed in ranges " \
|
146
|
+
"that are converted to CFRange structures."
|
147
|
+
);
|
148
|
+
|
149
|
+
int length = exclusive ? end-begin : end-begin + 1;
|
150
|
+
return CFRangeMake(begin, length);
|
151
|
+
}
|
152
|
+
|
153
|
+
|
154
|
+
#define WRAP_VALUE(type, cookie, wrapper) do { \
|
155
|
+
type st; \
|
156
|
+
AXValueGetValue(value, cookie, &st); \
|
157
|
+
return wrapper(st); \
|
158
|
+
} while (0); \
|
159
|
+
|
160
|
+
VALUE wrap_value_point(AXValueRef value) { WRAP_VALUE(CGPoint, kAXValueCGPointType, wrap_point) }
|
161
|
+
VALUE wrap_value_size(AXValueRef value) { WRAP_VALUE(CGSize, kAXValueCGSizeType, wrap_size) }
|
162
|
+
VALUE wrap_value_rect(AXValueRef value) { WRAP_VALUE(CGRect, kAXValueCGRectType, wrap_rect) }
|
163
|
+
VALUE wrap_value_range(AXValueRef value) { WRAP_VALUE(CFRange, kAXValueCFRangeType, convert_cf_range) }
|
164
|
+
VALUE wrap_value_error(AXValueRef value) { WRAP_VALUE(AXError, kAXValueAXErrorType, INT2NUM) }
|
165
|
+
|
166
|
+
#define UNWRAP_VALUE(type, value, unwrapper) do { \
|
167
|
+
type st = unwrapper(val); \
|
168
|
+
return AXValueCreate(value, &st); \
|
169
|
+
} while(0);
|
170
|
+
|
171
|
+
AXValueRef unwrap_value_point(VALUE val) { UNWRAP_VALUE(CGPoint, kAXValueCGPointType, unwrap_point) }
|
172
|
+
AXValueRef unwrap_value_size(VALUE val) { UNWRAP_VALUE(CGSize, kAXValueCGSizeType, unwrap_size) }
|
173
|
+
AXValueRef unwrap_value_rect(VALUE val) { UNWRAP_VALUE(CGRect, kAXValueCGRectType, unwrap_rect) }
|
174
|
+
AXValueRef unwrap_value_range(VALUE val) { UNWRAP_VALUE(CFRange, kAXValueCFRangeType, convert_rb_range) }
|
175
|
+
|
176
|
+
|
177
|
+
VALUE
|
178
|
+
wrap_value(AXValueRef value)
|
179
|
+
{
|
180
|
+
switch (AXValueGetType(value))
|
181
|
+
{
|
182
|
+
case kAXValueIllegalType:
|
183
|
+
// TODO better error message
|
184
|
+
rb_raise(rb_eArgError, "herped when you should have derped");
|
185
|
+
case kAXValueCGPointType:
|
186
|
+
return wrap_value_point(value);
|
187
|
+
case kAXValueCGSizeType:
|
188
|
+
return wrap_value_size(value);
|
189
|
+
case kAXValueCGRectType:
|
190
|
+
return wrap_value_rect(value);
|
191
|
+
case kAXValueCFRangeType:
|
192
|
+
return wrap_value_range(value);
|
193
|
+
case kAXValueAXErrorType:
|
194
|
+
return wrap_value_error(value);
|
195
|
+
default:
|
196
|
+
// TODO better error message
|
197
|
+
rb_raise(
|
198
|
+
rb_eRuntimeError,
|
199
|
+
"Could not wrap You've found a bug in something...not sure who to blame"
|
200
|
+
);
|
201
|
+
}
|
202
|
+
|
203
|
+
return Qnil; // unreachable
|
204
|
+
}
|
205
|
+
|
206
|
+
AXValueRef
|
207
|
+
unwrap_value(VALUE value)
|
208
|
+
{
|
209
|
+
VALUE type = CLASS_OF(value);
|
210
|
+
if (type == rb_cCGPoint)
|
211
|
+
return unwrap_value_point(value);
|
212
|
+
else if (type == rb_cCGSize)
|
213
|
+
return unwrap_value_size(value);
|
214
|
+
else if (type == rb_cCGRect)
|
215
|
+
return unwrap_value_rect(value);
|
216
|
+
else if (type == rb_cRange)
|
217
|
+
return unwrap_value_range(value);
|
218
|
+
|
219
|
+
rb_raise(rb_eArgError, "could not wrap %s", rb_class2name(type));
|
220
|
+
return NULL; // unreachable
|
221
|
+
}
|
222
|
+
|
223
|
+
VALUE wrap_array_values(CFArrayRef array) { WRAP_ARRAY(wrap_value) }
|
224
|
+
|
225
|
+
|
226
|
+
static
|
227
|
+
void
|
228
|
+
ref_finalizer(void* obj)
|
229
|
+
{
|
230
|
+
CFRelease((CFTypeRef)obj);
|
231
|
+
}
|
232
|
+
|
233
|
+
VALUE
|
234
|
+
wrap_ref(AXUIElementRef ref)
|
235
|
+
{
|
236
|
+
return Data_Wrap_Struct(rb_cElement, NULL, ref_finalizer, (void*)ref);
|
237
|
+
}
|
238
|
+
|
239
|
+
AXUIElementRef
|
240
|
+
unwrap_ref(VALUE obj)
|
241
|
+
{
|
242
|
+
AXUIElementRef* ref;
|
243
|
+
Data_Get_Struct(obj, AXUIElementRef, ref);
|
244
|
+
// TODO we should return *ref? but that seems to fuck things up...
|
245
|
+
return (AXUIElementRef)ref;
|
246
|
+
}
|
247
|
+
|
248
|
+
VALUE wrap_array_refs(CFArrayRef array) { WRAP_ARRAY(wrap_ref) }
|
249
|
+
|
250
|
+
|
251
|
+
VALUE
|
252
|
+
wrap_string(CFStringRef string)
|
253
|
+
{
|
254
|
+
// flying by the seat of our pants here, this hasn't failed yet
|
255
|
+
// but probably will one day when I'm not looking
|
256
|
+
const char* name = CFStringGetCStringPtr(string, kCFStringEncodingMacRoman);
|
257
|
+
if (name)
|
258
|
+
return rb_str_new(name, CFStringGetLength(string));
|
259
|
+
else
|
260
|
+
// use rb_external_str_new() ? assume always UTF-8?
|
261
|
+
rb_raise(rb_eRuntimeError, "NEED TO IMPLEMNET STRING COPYING");
|
262
|
+
|
263
|
+
return Qnil; // unreachable
|
264
|
+
}
|
265
|
+
|
266
|
+
CFStringRef
|
267
|
+
unwrap_string(VALUE string)
|
268
|
+
{
|
269
|
+
return CFStringCreateWithCStringNoCopy(
|
270
|
+
NULL,
|
271
|
+
StringValueCStr(string),
|
272
|
+
0,
|
273
|
+
kCFAllocatorNull
|
274
|
+
);
|
275
|
+
/* return CFStringCreateWithCString( */
|
276
|
+
/* NULL, */
|
277
|
+
/* StringValuePtr(string), */
|
278
|
+
/* kCFStringEncodingUTF8 */
|
279
|
+
/* ); */
|
280
|
+
}
|
281
|
+
|
282
|
+
VALUE wrap_array_strings(CFArrayRef array) { WRAP_ARRAY(wrap_string) }
|
283
|
+
|
284
|
+
|
285
|
+
#define WRAP_NUM(type, cookie, macro) do { \
|
286
|
+
type value; \
|
287
|
+
if (CFNumberGetValue(num, cookie, &value)) \
|
288
|
+
return macro(value); \
|
289
|
+
rb_raise(rb_eRuntimeError, "I goofed wrapping a number"); \
|
290
|
+
return Qnil; \
|
291
|
+
} while(0);
|
292
|
+
|
293
|
+
VALUE wrap_long(CFNumberRef num) { WRAP_NUM(long, kCFNumberLongType, LONG2FIX) }
|
294
|
+
VALUE wrap_long_long(CFNumberRef num) { WRAP_NUM(long long, kCFNumberLongLongType, LL2NUM) }
|
295
|
+
VALUE wrap_float(CFNumberRef num) { WRAP_NUM(double, kCFNumberDoubleType, DBL2NUM) }
|
296
|
+
|
297
|
+
#define UNWRAP_NUM(type, cookie, macro) do { \
|
298
|
+
type base = macro(num); \
|
299
|
+
return CFNumberCreate(NULL, cookie, &base); \
|
300
|
+
} while(0);
|
301
|
+
|
302
|
+
CFNumberRef unwrap_long(VALUE num) { UNWRAP_NUM(long, kCFNumberLongType, NUM2LONG) }
|
303
|
+
CFNumberRef unwrap_long_long(VALUE num) { UNWRAP_NUM(long long, kCFNumberLongLongType, NUM2LL) }
|
304
|
+
CFNumberRef unwrap_float(VALUE num) { UNWRAP_NUM(double, kCFNumberDoubleType, NUM2DBL) }
|
305
|
+
|
306
|
+
VALUE
|
307
|
+
wrap_number(CFNumberRef number)
|
308
|
+
{
|
309
|
+
switch (CFNumberGetType(number))
|
310
|
+
{
|
311
|
+
case kCFNumberSInt8Type:
|
312
|
+
case kCFNumberSInt16Type:
|
313
|
+
case kCFNumberSInt32Type:
|
314
|
+
case kCFNumberSInt64Type:
|
315
|
+
return wrap_long(number);
|
316
|
+
case kCFNumberFloat32Type:
|
317
|
+
case kCFNumberFloat64Type:
|
318
|
+
return wrap_float(number);
|
319
|
+
case kCFNumberCharType:
|
320
|
+
case kCFNumberShortType:
|
321
|
+
case kCFNumberIntType:
|
322
|
+
case kCFNumberLongType:
|
323
|
+
return wrap_long(number);
|
324
|
+
case kCFNumberLongLongType:
|
325
|
+
return wrap_long_long(number);
|
326
|
+
case kCFNumberFloatType:
|
327
|
+
case kCFNumberDoubleType:
|
328
|
+
return wrap_float(number);
|
329
|
+
case kCFNumberCFIndexType:
|
330
|
+
case kCFNumberNSIntegerType:
|
331
|
+
return wrap_long(number);
|
332
|
+
case kCFNumberCGFloatType: // == kCFNumberMaxType
|
333
|
+
return wrap_float(number);
|
334
|
+
default:
|
335
|
+
return INT2NUM(0); // unreachable unless system goofed
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
CFNumberRef
|
340
|
+
unwrap_number(VALUE number)
|
341
|
+
{
|
342
|
+
switch (TYPE(number))
|
343
|
+
{
|
344
|
+
case T_FIXNUM:
|
345
|
+
return unwrap_long(number);
|
346
|
+
case T_FLOAT:
|
347
|
+
return unwrap_float(number);
|
348
|
+
default:
|
349
|
+
rb_raise(
|
350
|
+
rb_eRuntimeError,
|
351
|
+
"wrapping %s is not supported; log a bug?",
|
352
|
+
rb_string_value_cstr(&number)
|
353
|
+
);
|
354
|
+
return kCFNumberNegativeInfinity; // unreachable
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
VALUE wrap_array_numbers(CFArrayRef array) { WRAP_ARRAY(wrap_number) }
|
359
|
+
|
360
|
+
|
361
|
+
VALUE
|
362
|
+
wrap_url(CFURLRef url)
|
363
|
+
{
|
364
|
+
return rb_funcall(rb_mURI, sel_parse, 1, wrap_string(CFURLGetString(url)));
|
365
|
+
}
|
366
|
+
|
367
|
+
CFURLRef
|
368
|
+
unwrap_url(VALUE url)
|
369
|
+
{
|
370
|
+
url = rb_funcall(url, sel_to_s, 0);
|
371
|
+
CFStringRef string = CFStringCreateWithCString(
|
372
|
+
NULL,
|
373
|
+
StringValuePtr(url),
|
374
|
+
kCFStringEncodingUTF8
|
375
|
+
);
|
376
|
+
CFURLRef url_ref = CFURLCreateWithString(NULL, string, NULL);
|
377
|
+
CFRelease(string);
|
378
|
+
return url_ref;
|
379
|
+
}
|
380
|
+
|
381
|
+
VALUE wrap_array_urls(CFArrayRef array) { WRAP_ARRAY(wrap_url) }
|
382
|
+
|
383
|
+
VALUE
|
384
|
+
wrap_date(CFDateRef date)
|
385
|
+
{
|
386
|
+
NSTimeInterval time = [(NSDate*)date timeIntervalSince1970];
|
387
|
+
return rb_time_new((time_t)time, 0);
|
388
|
+
}
|
389
|
+
|
390
|
+
CFDateRef
|
391
|
+
unwrap_date(VALUE date)
|
392
|
+
{
|
393
|
+
struct timeval t = rb_time_timeval(date);
|
394
|
+
NSDate* ns_date = [NSDate dateWithTimeIntervalSince1970:t.tv_sec];
|
395
|
+
return (CFDateRef)ns_date;
|
396
|
+
}
|
397
|
+
|
398
|
+
VALUE wrap_array_dates(CFArrayRef array) { WRAP_ARRAY(wrap_date) }
|
399
|
+
|
400
|
+
|
401
|
+
VALUE
|
402
|
+
wrap_boolean(CFBooleanRef bool_val)
|
403
|
+
{
|
404
|
+
return (CFBooleanGetValue(bool_val) ? Qtrue : Qfalse);
|
405
|
+
}
|
406
|
+
|
407
|
+
CFBooleanRef
|
408
|
+
unwrap_boolean(VALUE bool_val)
|
409
|
+
{
|
410
|
+
return (bool_val == Qtrue ? kCFBooleanTrue : kCFBooleanFalse);
|
411
|
+
}
|
412
|
+
|
413
|
+
VALUE wrap_array_booleans(CFArrayRef array) { WRAP_ARRAY(wrap_boolean) }
|
414
|
+
|
415
|
+
|
416
|
+
VALUE
|
417
|
+
wrap_array(CFArrayRef array)
|
418
|
+
{
|
419
|
+
CFTypeRef obj = CFArrayGetValueAtIndex(array, 0);
|
420
|
+
CFTypeID di = CFGetTypeID(obj);
|
421
|
+
if (di == AXUIElementGetTypeID()) return wrap_array_refs(array);
|
422
|
+
else if (di == AXValueGetTypeID()) return wrap_array_values(array);
|
423
|
+
else if (di == CFStringGetTypeID()) return wrap_array_strings(array);
|
424
|
+
else if (di == CFNumberGetTypeID()) return wrap_array_numbers(array);
|
425
|
+
else if (di == CFBooleanGetTypeID()) return wrap_array_booleans(array);
|
426
|
+
else if (di == CFURLGetTypeID()) return wrap_array_urls(array);
|
427
|
+
else if (di == CFDateGetTypeID()) return wrap_array_dates(array);
|
428
|
+
else return wrap_unknown(obj);
|
429
|
+
}
|
430
|
+
|
431
|
+
VALUE
|
432
|
+
to_ruby(CFTypeRef obj)
|
433
|
+
{
|
434
|
+
CFTypeID di = CFGetTypeID(obj);
|
435
|
+
if (di == CFArrayGetTypeID()) return wrap_array(obj);
|
436
|
+
else if (di == AXUIElementGetTypeID()) return wrap_ref(obj);
|
437
|
+
else if (di == AXValueGetTypeID()) return wrap_value(obj);
|
438
|
+
else if (di == CFStringGetTypeID()) return wrap_string(obj);
|
439
|
+
else if (di == CFNumberGetTypeID()) return wrap_number(obj);
|
440
|
+
else if (di == CFBooleanGetTypeID()) return wrap_boolean(obj);
|
441
|
+
else if (di == CFURLGetTypeID()) return wrap_url(obj);
|
442
|
+
else if (di == CFDateGetTypeID()) return wrap_date(obj);
|
443
|
+
else return wrap_unknown(obj);
|
444
|
+
}
|
445
|
+
|
446
|
+
CFTypeRef
|
447
|
+
to_ax(VALUE obj)
|
448
|
+
{
|
449
|
+
// TODO we can better optimize this when running under MacRuby
|
450
|
+
VALUE type = CLASS_OF(obj);
|
451
|
+
if (type == rb_cElement) return unwrap_ref(obj);
|
452
|
+
else if (type == rb_cString) return unwrap_string(obj);
|
453
|
+
else if (type == rb_cStruct) return unwrap_value(obj);
|
454
|
+
else if (type == rb_cRange) return unwrap_value(obj);
|
455
|
+
else if (type == rb_cFixnum) return unwrap_number(obj);
|
456
|
+
else if (type == rb_cFloat) return unwrap_number(obj);
|
457
|
+
else if (type == rb_cTime) return unwrap_date(obj);
|
458
|
+
else if (type == rb_cURI) return unwrap_url(obj);
|
459
|
+
else if (obj == Qtrue || obj == Qfalse) return unwrap_boolean(obj);
|
460
|
+
else return unwrap_unknown(obj);
|
461
|
+
}
|
462
|
+
|
463
|
+
#endif
|
464
|
+
|
465
|
+
|
466
|
+
void
|
467
|
+
Init_bridge()
|
468
|
+
{
|
469
|
+
#ifdef NOT_MACRUBY
|
470
|
+
sel_x = rb_intern("x");
|
471
|
+
sel_y = rb_intern("y");
|
472
|
+
sel_width = rb_intern("width");
|
473
|
+
sel_height = rb_intern("height");
|
474
|
+
sel_origin = rb_intern("origin");
|
475
|
+
sel_size = rb_intern("size");
|
476
|
+
sel_to_point = rb_intern("to_point");
|
477
|
+
sel_to_size = rb_intern("to_size");
|
478
|
+
sel_to_rect = rb_intern("to_rect");
|
479
|
+
sel_to_s = rb_intern("to_s");
|
480
|
+
sel_parse = rb_intern("parse");
|
481
|
+
|
482
|
+
rb_cCGPoint = rb_const_get(rb_cObject, rb_intern("CGPoint"));
|
483
|
+
rb_cCGSize = rb_const_get(rb_cObject, rb_intern("CGSize"));
|
484
|
+
rb_cCGRect = rb_const_get(rb_cObject, rb_intern("CGRect"));
|
485
|
+
rb_mURI = rb_const_get(rb_cObject, rb_intern("URI"));
|
486
|
+
rb_cURI = rb_const_get(rb_mURI, rb_intern("Generic"));
|
487
|
+
#endif
|
488
|
+
}
|
489
|
+
|
490
|
+
#endif
|
@@ -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'
|
data/test/helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/pride'
|
3
|
+
require 'accessibility/bridge'
|
4
|
+
|
5
|
+
class MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def rand_nums count, range = 1_000
|
8
|
+
Array.new count do
|
9
|
+
rand range
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def rand_floats count, range = 1_000.0
|
14
|
+
Array.new count do
|
15
|
+
rand * range
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: accessibility_bridge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mark Rada
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: yard
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.8.3
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.8.3
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: kramdown
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.14.1
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.14.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake-compiler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.8.1
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.1
|
62
|
+
description: ! 'accessibility_bridge is a wrapper around various bits of Cocoa
|
63
|
+
|
64
|
+
so that the various accessibility projects can run on CRuby.
|
65
|
+
|
66
|
+
|
67
|
+
Originally extracted from the AXElements project.
|
68
|
+
|
69
|
+
'
|
70
|
+
email: markrada26@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions:
|
73
|
+
- ext/accessibility/bridge/extconf.rb
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/accessibility/bridge/common.rb
|
77
|
+
- lib/accessibility/bridge/macruby.rb
|
78
|
+
- lib/accessibility/bridge/mri.rb
|
79
|
+
- lib/accessibility/bridge/version.rb
|
80
|
+
- lib/accessibility/bridge.rb
|
81
|
+
- ext/accessibility/bridge/bridge.c
|
82
|
+
- ext/accessibility/bridge/extconf.rb
|
83
|
+
- Rakefile
|
84
|
+
- README.markdown
|
85
|
+
- History.markdown
|
86
|
+
- .yardopts
|
87
|
+
- test/helper.rb
|
88
|
+
homepage: http://github.com/AXElements/accessibility_bridge
|
89
|
+
licenses:
|
90
|
+
- BSD 3-clause
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
hash: -1210497514143783933
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
hash: -1210497514143783933
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.8.24
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: A library for bridging into Cocoa on OSX
|
119
|
+
test_files:
|
120
|
+
- test/helper.rb
|