accessibility_core 0.3.5 → 0.4.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.
data/History.markdown CHANGED
@@ -1,3 +1,17 @@
1
+ # 0.4.0 - Fill in the gaps and other dubious requirements
2
+
3
+ * Add `Object#load_plist` to match MacRuby's `Object#load_plist`
4
+ * Add `URI::Generic#lastPathComponent` to match `NSURL#lastPathComponent`
5
+ * Add `URI::Generic#pathExtension` to match `NSURL#pathExtension`
6
+ * Add a 50% drop-in replacement for `NSData`
7
+ * Add a 50% drop-in replacement for `NSAttributedString`
8
+ * Add `Object#description` as a freedom patch on MRI
9
+ `NSObject#description` is the Objective-C equivalent to `Object#inspect` in Ruby.
10
+ While the intention is the same, the exact behaviour cannot be mimicked.
11
+
12
+ * Fixed some bugs related to converting arrays from Cocoa to Ruby
13
+
14
+
1
15
  # 0.3.5 - Add some missing bits for MRI
2
16
 
3
17
  * Add `Range#relative_to` to convert ranges to positive indicies
@@ -13,6 +13,8 @@ spin(double seconds)
13
13
 
14
14
  #ifdef NOT_MACRUBY
15
15
 
16
+ VALUE rb_cData;
17
+ VALUE rb_cAttributedString;
16
18
  VALUE rb_mAccessibility;
17
19
  VALUE rb_cElement;
18
20
  VALUE rb_cCGPoint;
@@ -255,20 +257,34 @@ VALUE wrap_array_refs(CFArrayRef array) { WRAP_ARRAY(wrap_ref) }
255
257
  VALUE
256
258
  wrap_string(CFStringRef string)
257
259
  {
258
- return wrap_nsstring((NSString*)string);
260
+ VALUE rb_str = Qnil;
261
+ CFDataRef data = CFStringCreateExternalRepresentation(
262
+ NULL,
263
+ string,
264
+ kCFStringEncodingUTF8,
265
+ 0
266
+ );
267
+ if (data) {
268
+ rb_str = rb_enc_str_new(
269
+ (char*)CFDataGetBytePtr(data),
270
+ CFDataGetLength(data),
271
+ rb_utf8_encoding()
272
+ );
273
+ CFRelease(data);
274
+ }
275
+ else {
276
+ CFRelease(data);
277
+ CFShow(string);
278
+ rb_raise(rb_eRuntimeError, "Could not convert a string to a Ruby string");
279
+ }
280
+
281
+ return rb_str;
259
282
  }
260
283
 
261
284
  VALUE
262
285
  wrap_nsstring(NSString* string)
263
286
  {
264
- // TODO: find a larger scope to apply this autoreleasepool
265
- @autoreleasepool{
266
- return rb_enc_str_new(
267
- [string UTF8String],
268
- [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding],
269
- rb_utf8_encoding()
270
- );
271
- }
287
+ return wrap_string((CFStringRef)string);
272
288
  }
273
289
 
274
290
  CFStringRef
@@ -297,6 +313,89 @@ VALUE wrap_array_nsstrings(NSArray* ary)
297
313
  }
298
314
 
299
315
 
316
+ VALUE
317
+ wrap_attributed_string(CFAttributedStringRef string)
318
+ {
319
+ return wrap_nsattributed_string((NSAttributedString*)string);
320
+ }
321
+
322
+ VALUE
323
+ wrap_nsattributed_string(NSAttributedString* obj)
324
+ {
325
+ WRAP_OBJC(rb_cAttributedString, objc_finalizer);
326
+ }
327
+
328
+ CFAttributedStringRef
329
+ unwrap_attributed_string(VALUE string)
330
+ {
331
+ return (CFAttributedStringRef)unwrap_nsattributed_string(string);
332
+ }
333
+
334
+ NSAttributedString*
335
+ unwrap_nsattributed_string(VALUE obj)
336
+ {
337
+ UNWRAP_OBJC(NSAttributedString);
338
+ }
339
+
340
+ VALUE
341
+ wrap_array_attributed_strings(CFArrayRef array)
342
+ {
343
+ WRAP_ARRAY(wrap_attributed_string);
344
+ }
345
+
346
+ VALUE wrap_array_nsattributed_strings(NSArray* ary)
347
+ {
348
+ CFArrayRef array = (CFArrayRef)ary;
349
+ WRAP_ARRAY(wrap_nsattributed_string);
350
+ }
351
+
352
+ static
353
+ VALUE
354
+ rb_astring_alloc(VALUE self)
355
+ {
356
+ return wrap_nsattributed_string([NSAttributedString alloc]);
357
+ }
358
+
359
+ static
360
+ VALUE
361
+ rb_astring_init_with_string(int argc, VALUE* argv, VALUE self)
362
+ {
363
+ if (!argc)
364
+ rb_raise(rb_eArgError, "wrong number of arguments (0 for 1+)");
365
+
366
+ NSString* nsstring = unwrap_nsstring(argv[0]);
367
+ NSAttributedString* old_astring = unwrap_nsattributed_string(self);
368
+ NSAttributedString* new_astring = [old_astring initWithString:nsstring];
369
+ [nsstring release];
370
+ if (old_astring == new_astring)
371
+ return self;
372
+ return wrap_nsattributed_string(new_astring);
373
+ }
374
+
375
+ static
376
+ VALUE
377
+ rb_astring_string(VALUE self)
378
+ {
379
+ NSString* string = [unwrap_nsattributed_string(self) string];
380
+ VALUE rb_str = wrap_nsstring(string);
381
+ return rb_str;
382
+ }
383
+
384
+ static
385
+ VALUE
386
+ rb_astring_length(VALUE self)
387
+ {
388
+ return ULONG2NUM([unwrap_nsattributed_string(self) length]);
389
+ }
390
+
391
+ static
392
+ VALUE
393
+ rb_astring_equality(VALUE self, VALUE other)
394
+ {
395
+ OBJC_EQUALITY(rb_cAttributedString, unwrap_nsattributed_string);
396
+ }
397
+
398
+
300
399
  #define WRAP_NUM(type, cookie, macro) do { \
301
400
  type value; \
302
401
  if (CFNumberGetValue(num, cookie, &value)) \
@@ -456,16 +555,21 @@ VALUE wrap_array_booleans(CFArrayRef array) { WRAP_ARRAY(wrap_boolean) }
456
555
  VALUE
457
556
  wrap_array(CFArrayRef array)
458
557
  {
459
- CFTypeRef obj = CFArrayGetValueAtIndex(array, 0);
460
- CFTypeID di = CFGetTypeID(obj);
461
- if (di == AXUIElementGetTypeID()) return wrap_array_refs(array);
462
- else if (di == AXValueGetTypeID()) return wrap_array_values(array);
463
- else if (di == CFStringGetTypeID()) return wrap_array_strings(array);
464
- else if (di == CFNumberGetTypeID()) return wrap_array_numbers(array);
465
- else if (di == CFBooleanGetTypeID()) return wrap_array_booleans(array);
466
- else if (di == CFURLGetTypeID()) return wrap_array_urls(array);
467
- else if (di == CFDateGetTypeID()) return wrap_array_dates(array);
468
- else return wrap_unknown(obj);
558
+ CFIndex length = CFArrayGetCount(array);
559
+ if (length) {
560
+ CFTypeRef obj = CFArrayGetValueAtIndex(array, 0);
561
+ CFTypeID di = CFGetTypeID(obj);
562
+ if (di == AXUIElementGetTypeID()) return wrap_array_refs(array);
563
+ else if (di == AXValueGetTypeID()) return wrap_array_values(array);
564
+ else if (di == CFStringGetTypeID()) return wrap_array_strings(array);
565
+ else if (di == CFNumberGetTypeID()) return wrap_array_numbers(array);
566
+ else if (di == CFBooleanGetTypeID()) return wrap_array_booleans(array);
567
+ else if (di == CFURLGetTypeID()) return wrap_array_urls(array);
568
+ else if (di == CFDateGetTypeID()) return wrap_array_dates(array);
569
+ else if (di == CFDictionaryGetTypeID()) return wrap_array_dictionaries(array);
570
+ else return wrap_unknown(obj);
571
+ }
572
+ return rb_ary_new();
469
573
  }
470
574
 
471
575
 
@@ -481,22 +585,25 @@ wrap_dictionary(NSDictionary* dict)
481
585
  return hash;
482
586
  }
483
587
 
588
+ VALUE wrap_array_dictionaries(CFArrayRef array) { WRAP_ARRAY(wrap_dictionary); }
484
589
 
485
590
 
486
591
  VALUE
487
592
  to_ruby(CFTypeRef obj)
488
593
  {
489
594
  CFTypeID di = CFGetTypeID(obj);
490
- if (di == CFArrayGetTypeID()) return wrap_array(obj);
491
- else if (di == AXUIElementGetTypeID()) return wrap_ref(obj);
492
- else if (di == AXValueGetTypeID()) return wrap_value(obj);
493
- else if (di == CFStringGetTypeID()) return wrap_string(obj);
494
- else if (di == CFNumberGetTypeID()) return wrap_number(obj);
495
- else if (di == CFBooleanGetTypeID()) return wrap_boolean(obj);
496
- else if (di == CFURLGetTypeID()) return wrap_url(obj);
497
- else if (di == CFDateGetTypeID()) return wrap_date(obj);
498
- else if (di == CFDictionaryGetTypeID()) return wrap_dictionary(obj);
499
- else return wrap_unknown(obj);
595
+ if (di == CFArrayGetTypeID()) return wrap_array(obj);
596
+ else if (di == AXUIElementGetTypeID()) return wrap_ref(obj);
597
+ else if (di == AXValueGetTypeID()) return wrap_value(obj);
598
+ else if (di == CFStringGetTypeID()) return wrap_string(obj);
599
+ else if (di == CFNumberGetTypeID()) return wrap_number(obj);
600
+ else if (di == CFBooleanGetTypeID()) return wrap_boolean(obj);
601
+ else if (di == CFURLGetTypeID()) return wrap_url(obj);
602
+ else if (di == CFDateGetTypeID()) return wrap_date(obj);
603
+ else if (di == CFDataGetTypeID()) return wrap_data(obj);
604
+ else if (di == CFAttributedStringGetTypeID()) return wrap_attributed_string(obj);
605
+ else if (di == CFDictionaryGetTypeID()) return wrap_dictionary(obj);
606
+ else return wrap_unknown(obj);
500
607
  }
501
608
 
502
609
  CFTypeRef
@@ -513,8 +620,9 @@ to_ax(VALUE obj)
513
620
  case T_FLOAT:
514
621
  return unwrap_number(obj);
515
622
  case T_TRUE:
623
+ return kCFBooleanTrue;
516
624
  case T_FALSE:
517
- return unwrap_boolean(obj);
625
+ return kCFBooleanFalse;
518
626
  }
519
627
 
520
628
  VALUE type = CLASS_OF(obj);
@@ -522,6 +630,10 @@ to_ax(VALUE obj)
522
630
  return unwrap_date(obj);
523
631
  else if (type == rb_cRange)
524
632
  return unwrap_value_range(obj);
633
+ else if (type == rb_cAttributedString)
634
+ return unwrap_attributed_string(obj);
635
+ else if (type == rb_cData)
636
+ return unwrap_data(obj);
525
637
 
526
638
  if (rb_obj_is_kind_of(obj, rb_cURI))
527
639
  return unwrap_url(obj);
@@ -531,8 +643,114 @@ to_ax(VALUE obj)
531
643
  }
532
644
 
533
645
 
646
+ VALUE
647
+ wrap_data(CFDataRef data)
648
+ {
649
+ return wrap_nsdata((NSData*)data);
650
+ }
651
+
652
+ VALUE
653
+ wrap_nsdata(NSData* obj)
654
+ {
655
+ WRAP_OBJC(rb_cData, objc_finalizer);
656
+ }
657
+
658
+ VALUE wrap_array_data(CFArrayRef array) { WRAP_ARRAY(wrap_data); }
659
+ VALUE
660
+ wrap_array_nsdata(NSArray* ary)
661
+ {
662
+ CFArrayRef array = (CFArrayRef)ary;
663
+ WRAP_ARRAY(wrap_data);
664
+ }
665
+
666
+ CFDataRef
667
+ unwrap_data(VALUE data)
668
+ {
669
+ return (CFDataRef)unwrap_nsdata(data);
670
+ }
671
+
672
+ NSData*
673
+ unwrap_nsdata(VALUE obj)
674
+ {
675
+ UNWRAP_OBJC(NSData);
676
+ }
677
+
678
+
679
+ static
680
+ VALUE
681
+ rb_data_data(VALUE self)
682
+ {
683
+ return wrap_nsdata([NSData data]);
684
+ }
685
+
686
+ static
687
+ VALUE
688
+ rb_data_with_contents_of_url(VALUE self, VALUE url)
689
+ {
690
+ NSData* data = [NSData dataWithContentsOfURL:unwrap_nsurl(url)];
691
+ if (data)
692
+ return wrap_nsdata(data);
693
+ return Qnil;
694
+ }
695
+
696
+ static
697
+ VALUE
698
+ rb_data_length(VALUE self)
699
+ {
700
+ return ULONG2NUM([unwrap_nsdata(self) length]);
701
+ }
702
+
703
+ static
704
+ VALUE
705
+ rb_data_equality(VALUE self, VALUE other)
706
+ {
707
+ OBJC_EQUALITY(rb_cData, unwrap_nsdata);
708
+ }
709
+
534
710
  static
535
711
  VALUE
712
+ rb_data_write_to_file(int argc, VALUE* argv, VALUE self)
713
+ {
714
+ if (argc < 2)
715
+ rb_raise(
716
+ rb_eArgError,
717
+ "wrong number of arguments, got %d, expected 2",
718
+ argc
719
+ );
720
+
721
+ NSString* path = unwrap_nsstring(argv[0]);
722
+ BOOL result = [unwrap_nsdata(self) writeToFile:path
723
+ atomically:(argv[1] == Qtrue)];
724
+
725
+ [path release];
726
+
727
+ return (result ? Qtrue : Qfalse);
728
+ }
729
+
730
+
731
+ static
732
+ VALUE
733
+ rb_data_to_str(VALUE self)
734
+ {
735
+ NSData* data = unwrap_nsdata(self);
736
+ const void* bytes = [data bytes];
737
+ NSUInteger length = [data length];
738
+ return rb_enc_str_new(bytes, length, rb_utf8_encoding());
739
+ }
740
+
741
+ static
742
+ VALUE
743
+ rb_str_to_data(VALUE self)
744
+ {
745
+ NSData* data = [NSData dataWithBytes:(void*)StringValuePtr(self)
746
+ length:RSTRING_LEN(self)];
747
+ if (data)
748
+ return wrap_nsdata(data);
749
+ return Qnil; // I don't think this is possible except in case of ENOMEM
750
+ }
751
+
752
+
753
+ static VALUE
536
754
  rb_spin(int argc, VALUE* argv, VALUE self)
537
755
  {
538
756
  if (argc == 0)
@@ -570,6 +788,67 @@ Init_bridge()
570
788
  rb_mURI = rb_const_get(rb_cObject, rb_intern("URI"));
571
789
  rb_cURI = rb_const_get(rb_mURI, rb_intern("Generic"));
572
790
 
791
+
792
+ /*
793
+ * Document-class: NSAttributedString
794
+ *
795
+ * A 90% drop-in replacement for Cocoa's `NSAttributedString` class. The most likely
796
+ * to use methods have been bridged. Remaining methods can be bridged upon request.
797
+ *
798
+ * See [Apple's Developer Reference](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSAttributedString_Class/Reference/Reference.html)
799
+ * for documentation on the methods available in this class.
800
+ */
801
+ rb_cAttributedString = rb_define_class("NSAttributedString", rb_cObject);
802
+
803
+ // LOL, but required to be a drop-in replacement
804
+ rb_define_singleton_method(rb_cAttributedString, "alloc", rb_astring_alloc, 0);
805
+
806
+ // TODO: all these methods :(
807
+ rb_define_method(rb_cAttributedString, "initWithString", rb_astring_init_with_string, -1);
808
+ /* rb_define_method(rb_cAttributedString, "initWithAttributedString", rb_astring_init_with_astring, 2); */
809
+ rb_define_method(rb_cAttributedString, "string", rb_astring_string, 0);
810
+ rb_define_method(rb_cAttributedString, "length", rb_astring_length, 0);
811
+ /* rb_define_method(rb_cAttributedString, "attributesAtIndex", rb_astring_attrs_at_index, -1); */
812
+ rb_define_method(rb_cAttributedString, "isEqualToAttributedString", rb_astring_equality, 1);
813
+ /* rb_define_method(rb_cAttributedString, "attributedSubstringFromRange", rb_astring_astring_from_range, 1); */
814
+
815
+ rb_define_alias(rb_cAttributedString, "to_s", "string");
816
+ rb_define_alias(rb_cAttributedString, "to_str", "string");
817
+ rb_define_alias(rb_cAttributedString, "==", "isEqualToAttributedString");
818
+
819
+
820
+ /*
821
+ * Document-class: NSData
822
+ *
823
+ * A 50% drop-in replacement for Cocoa's `NSData` class. Almost all
824
+ * non-deprecated methods have been bridged.
825
+ *
826
+ * See [Apple's Developer Reference](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html)
827
+ * for documentation on the methods available in this class.
828
+ */
829
+ rb_cData = rb_define_class("NSData", rb_cObject);
830
+
831
+ // TODO: implement commented out methods
832
+ rb_define_singleton_method(rb_cData, "data", rb_data_data, 0);
833
+ //rb_define_singleton_method(rb_cData, "dataWithBytes", rb_data_with_bytes, 2);
834
+ //rb_define_singleton_method(rb_cData, "dataWithContentsOfFile", rb_data_with_contents_of_file, 1);
835
+ rb_define_singleton_method(rb_cData, "dataWithContentsOfURL", rb_data_with_contents_of_url, 1);
836
+ //rb_define_singleton_method(rb_cData, "dataWithData", rb_data_with_data, 1);
837
+
838
+ //rb_define_method(rb_cData, "bytes", rb_data_bytes, 0);
839
+ //rb_define_method(rb_cData, "description", rb_data_description, 0);
840
+ //rb_define_method(rb_cData, "subdataWithRange", rb_data_subrange, 1);
841
+ rb_define_method(rb_cData, "isEqualToData", rb_data_equality, 1);
842
+ rb_define_method(rb_cData, "length", rb_data_length, 0);
843
+ rb_define_method(rb_cData, "writeToFile", rb_data_write_to_file, -1);
844
+ //rb_define_method(rb_cData, "writeToURL", rb_data_write_to_url, -1);
845
+ rb_define_method(rb_cData, "to_str", rb_data_to_str, 0);
846
+
847
+ rb_define_alias(rb_cData, "==", "isEqualToData");
848
+
849
+
850
+ // misc freedom patches
851
+ rb_define_method(rb_cString, "to_data", rb_str_to_data, 0);
573
852
  rb_define_method(rb_cObject, "spin", rb_spin, -1); // semi-private method
574
853
  #endif
575
854
  }
@@ -11,6 +11,8 @@ void Init_bridge();
11
11
 
12
12
  #ifdef NOT_MACRUBY
13
13
 
14
+ extern VALUE rb_cData;
15
+ extern VALUE rb_cAttributedString;
14
16
  extern VALUE rb_mAccessibility;
15
17
  extern VALUE rb_cElement;
16
18
  extern VALUE rb_cCGPoint;
@@ -43,6 +45,13 @@ extern ID sel_parse;
43
45
  return unwrapped; \
44
46
  } while (false);
45
47
 
48
+ #define OBJC_EQUALITY(type, unwrapper) do { \
49
+ if (CLASS_OF(other) == type) \
50
+ if ([unwrapper(self) isEqual:unwrapper(other)]) \
51
+ return Qtrue; \
52
+ return Qfalse; \
53
+ } while (false);
54
+
46
55
  #define WRAP_ARRAY(wrapper) do { \
47
56
  CFIndex length = CFArrayGetCount(array); \
48
57
  VALUE ary = rb_ary_new2(length); \
@@ -129,11 +138,17 @@ VALUE wrap_boolean(CFBooleanRef bool_val);
129
138
  VALUE wrap_array_booleans(CFArrayRef array);
130
139
  CFBooleanRef unwrap_boolean(VALUE bool_val);
131
140
 
141
+ VALUE wrap_data(CFDataRef data);
142
+ VALUE wrap_nsdata(NSData* data);
143
+ CFDataRef unwrap_data(VALUE data);
144
+ NSData* unwrap_nsdata(VALUE data);
145
+
132
146
  // this function assumes that arrays are homogeneous;
133
147
  // which is usually the case coming from the CF world
134
148
  VALUE wrap_array(CFArrayRef array);
135
149
 
136
150
  VALUE wrap_dictionary(NSDictionary* dict);
151
+ VALUE wrap_array_dictionaries(CFArrayRef array);
137
152
 
138
153
  VALUE to_ruby(CFTypeRef obj);
139
154
  CFTypeRef to_ax(VALUE obj);
@@ -142,4 +157,18 @@ VALUE wrap_screen(NSScreen* screen);
142
157
  VALUE wrap_array_screens(CFArrayRef array);
143
158
  NSScreen* unwrap_screen(VALUE screen);
144
159
 
160
+ VALUE wrap_attributed_string(CFAttributedStringRef string);
161
+ VALUE wrap_nsattributed_string(NSAttributedString* string);
162
+ VALUE wrap_array_attributed_strings(CFArrayRef array);
163
+ VALUE wrap_array_nsattributed_strings(NSArray* ary);
164
+ CFAttributedStringRef unwrap_attributed_string(VALUE string);
165
+ NSAttributedString* unwrap_nsattributed_string(VALUE string);
166
+
167
+ VALUE wrap_data(CFDataRef data);
168
+ VALUE wrap_nsdata(NSData* data);
169
+ VALUE wrap_array_data(CFArrayRef array);
170
+ VALUE wrap_array_nsdata(NSArray* array);
171
+ CFDataRef unwrap_data(VALUE data);
172
+ NSData* unwrap_nsdata(VALUE data);
173
+
145
174
  #endif
@@ -444,6 +444,29 @@ rb_bundle_object_for_info_dict_key(VALUE self, VALUE key)
444
444
  }
445
445
 
446
446
 
447
+ static
448
+ VALUE
449
+ rb_load_plist(VALUE self, VALUE plist_data)
450
+ {
451
+ NSData* data = [NSData dataWithBytes:(void*)StringValueCStr(plist_data)
452
+ length:RSTRING_LEN(plist_data)];
453
+ NSError* err = nil;
454
+ id plist = [NSPropertyListSerialization propertyListWithData:data
455
+ options:0
456
+ format:nil
457
+ error:&err];
458
+ [data release];
459
+ if (plist) {
460
+ VALUE list = to_ruby(plist);
461
+ [plist release];
462
+ return list;
463
+ }
464
+
465
+ rb_raise(rb_eArgError, "error loading property list: '%s'",
466
+ [[err localizedDescription] UTF8String]);
467
+ return Qnil; // unreachable
468
+ }
469
+
447
470
  VALUE wrap_screen(NSScreen* obj) { WRAP_OBJC(rb_cScreen, NULL); }
448
471
  VALUE wrap_array_screens(CFArrayRef array) { WRAP_ARRAY(wrap_screen); }
449
472
  NSScreen* unwrap_screen(VALUE obj) { UNWRAP_OBJC(NSScreen); }
@@ -837,6 +860,9 @@ Init_extras()
837
860
  rb_define_singleton_method(rb_cBundle, "bundleWithURL", rb_bundle_with_url, 1);
838
861
  rb_define_method(rb_cBundle, "infoDictionary", rb_bundle_info_dict, 0);
839
862
  rb_define_method(rb_cBundle, "objectForInfoDictionaryKey", rb_bundle_object_for_info_dict_key, 1);
863
+
864
+
865
+ rb_define_method(rb_cObject, "load_plist", rb_load_plist, 1);
840
866
  #endif
841
867
 
842
868
 
@@ -106,6 +106,39 @@ class URI::Generic
106
106
  def to_url
107
107
  self
108
108
  end
109
+
110
+ ##
111
+ # Return the last component of the path of the URL
112
+ #
113
+ # This is intended to help make {URI::Generic} closer to being
114
+ # a drop-in replacement for {NSURL}.
115
+ #
116
+ # @example
117
+ #
118
+ # url = "https://macruby.macosforge.org/files/nightlies/macruby_nightly-latest.pkg"
119
+ # URI.parse(url).lastPathComponent # => "macruby_nightly-latest.pkg"
120
+ #
121
+ # @return [String]
122
+ def lastPathComponent
123
+ self.path.split(%r{/+}).last
124
+ end
125
+
126
+ ##
127
+ # Returns the path extension of a file URL
128
+ #
129
+ # This is intended to help make {URI::Generic} closer to being
130
+ # a drop-in replacement for {NSURL}.
131
+ #
132
+ # @example
133
+ #
134
+ # url = "https://macruby.macosforge.org/files/nightlies/macruby_nightly-latest.pkg"
135
+ # URI.parse(url).pathExtension # => "pkg"
136
+ #
137
+ # @return [String]
138
+ def pathExtension
139
+ split = self.path.split '.', -1
140
+ split.size > 1 ? split.last : ''
141
+ end
109
142
  end
110
143
 
111
144
  ##
@@ -137,6 +170,17 @@ class Object
137
170
  def NSContainsRect outer, inner
138
171
  outer.to_rect.contains? inner
139
172
  end
173
+
174
+ ##
175
+ # An alias for `Object#inspect`
176
+ #
177
+ # This exists to help make code more compatible between MacRuby
178
+ # and CRuby.
179
+ #
180
+ # @return [String]
181
+ def description
182
+ inspect
183
+ end
140
184
  end
141
185
 
142
186
  ##
@@ -6,6 +6,6 @@ module Accessibility
6
6
  # Namespace for `accessibility_core` specific classes
7
7
  module Core
8
8
  # return [String]
9
- VERSION = '0.3.5'
9
+ VERSION = '0.4.0'
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: accessibility_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-27 00:00:00.000000000 Z
12
+ date: 2013-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard
@@ -107,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
107
  version: '0'
108
108
  segments:
109
109
  - 0
110
- hash: 865923332438012461
110
+ hash: -989078667386493475
111
111
  required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  none: false
113
113
  requirements:
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
116
  version: '0'
117
117
  segments:
118
118
  - 0
119
- hash: 865923332438012461
119
+ hash: -989078667386493475
120
120
  requirements: []
121
121
  rubyforge_project:
122
122
  rubygems_version: 1.8.24