AXElements 1.0.0.alpha11 → 1.0.0.beta

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 (48) hide show
  1. data/History.markdown +11 -1
  2. data/README.markdown +10 -8
  3. data/Rakefile +1 -1
  4. data/lib/accessibility/dsl.rb +5 -2
  5. data/lib/accessibility/factory.rb +134 -78
  6. data/lib/accessibility/qualifier.rb +2 -0
  7. data/lib/accessibility/system_info.rb +82 -17
  8. data/lib/accessibility/translator.rb +17 -17
  9. data/lib/accessibility/version.rb +1 -1
  10. data/lib/ax/application.rb +11 -16
  11. data/lib/ax/element.rb +21 -34
  12. data/lib/ax/systemwide.rb +2 -2
  13. data/lib/ax_elements.rb +7 -1
  14. data/lib/ax_elements/active_support_selections.rb +10 -0
  15. data/lib/ax_elements/mri.rb +57 -0
  16. data/lib/ax_elements/nsarray_compat.rb +97 -17
  17. data/rakelib/gem.rake +12 -3
  18. data/rakelib/test.rake +0 -6
  19. data/test/helper.rb +10 -20
  20. data/test/integration/accessibility/test_dsl.rb +6 -14
  21. data/test/integration/accessibility/test_enumerators.rb +0 -1
  22. data/test/integration/accessibility/test_graph.rb +1 -0
  23. data/test/integration/accessibility/test_qualifier.rb +2 -2
  24. data/test/integration/ax/test_application.rb +2 -2
  25. data/test/sanity/accessibility/test_factory.rb +2 -2
  26. data/test/sanity/accessibility/test_pretty_printer.rb +2 -2
  27. data/test/sanity/ax/test_application.rb +1 -1
  28. data/test/sanity/ax/test_element.rb +2 -2
  29. data/test/sanity/ax_elements/test_nsobject_inspect.rb +4 -2
  30. metadata +28 -36
  31. data/ext/accessibility/core/core.c +0 -26
  32. data/lib/accessibility/core.rb +0 -943
  33. data/lib/accessibility/highlighter.rb +0 -86
  34. data/lib/accessibility/statistics.rb +0 -57
  35. data/lib/ax_elements/core_graphics_workaround.rb +0 -7
  36. data/lib/ax_elements/vendor/inflection_data.rb +0 -66
  37. data/lib/ax_elements/vendor/inflections.rb +0 -176
  38. data/lib/ax_elements/vendor/inflector.rb +0 -306
  39. data/lib/minitest/ax_elements.rb +0 -180
  40. data/lib/rspec/expectations/ax_elements.rb +0 -234
  41. data/test/integration/accessibility/test_core.rb +0 -18
  42. data/test/integration/minitest/test_ax_elements.rb +0 -89
  43. data/test/integration/rspec/expectations/test_ax_elements.rb +0 -102
  44. data/test/sanity/accessibility/test_highlighter.rb +0 -56
  45. data/test/sanity/accessibility/test_statistics.rb +0 -57
  46. data/test/sanity/minitest/test_ax_elements.rb +0 -17
  47. data/test/sanity/rspec/expectations/test_ax_elements.rb +0 -15
  48. data/test/test_core.rb +0 -454
@@ -1,18 +1,16 @@
1
1
  require 'accessibility/version'
2
- require 'ax_elements/vendor/inflector'
3
-
4
- framework 'ApplicationServices'
5
-
6
- unless Object.const_defined? :KAXIdentifierAttribute
7
- ##
8
- # Added for backwards compatability with Snow Leopard.
9
- # This attribute is standard with Lion and newer. AXElements depends
10
- # on it being defined.
11
- #
12
- # @return [String]
13
- KAXIdentifierAttribute = 'AXIdentifier'
2
+ require 'active_support/inflector'
3
+ require 'ax_elements/mri'
4
+
5
+ ActiveSupport::Inflector.inflections do |inflect|
6
+ # Related to accessibility
7
+ inflect.acronym('UI')
8
+ inflect.acronym('RTF')
9
+ inflect.acronym('URL')
14
10
  end
15
11
 
12
+ framework 'ApplicationServices' if on_macruby?
13
+
16
14
 
17
15
  ##
18
16
  # Maintain all the rules for transforming Cocoa constants into something
@@ -142,7 +140,7 @@ class Accessibility::Translator
142
140
  placeholder: KAXPlaceholderValueAttribute,
143
141
  # workarounds for known case where AX uses "Is" for a boolean attribute
144
142
  application_running: KAXIsApplicationRunningAttribute,
145
- application_running?: KAXIsApplicationRunningAttribute
143
+ application_running?: KAXIsApplicationRunningAttribute,
146
144
  }
147
145
  end
148
146
 
@@ -156,7 +154,7 @@ class Accessibility::Translator
156
154
  # @return [Hash{String=>Symbol}]
157
155
  def init_rubyisms
158
156
  @rubyisms = Hash.new do |hash, key|
159
- hash[key] = [Accessibility::Inflector.underscore(@unprefixes[key]).to_sym]
157
+ hash[key] = [ActiveSupport::Inflector.underscore(@unprefixes[key]).to_sym]
160
158
  end
161
159
  preloads.each_pair do |k,v| @rubyisms[v] << k end
162
160
  end
@@ -164,7 +162,9 @@ class Accessibility::Translator
164
162
  # @return [Hash{Symbol=>String}]
165
163
  def init_cocoaifications
166
164
  @cocoaifications = Hash.new do |hash, key|
167
- hash[key] = "AX#{Accessibility::Inflector.camelize(key.chomp QUESTION_MARK)}"
165
+ str_key = key.to_s
166
+ str_key.chomp! QUESTION_MARK
167
+ hash[key] = "AX#{ActiveSupport::Inflector.camelize(str_key)}"
168
168
  end
169
169
  preloads.each_pair do |k, v| @cocoaifications[k] = v end
170
170
  end
@@ -172,14 +172,14 @@ class Accessibility::Translator
172
172
  # @return [Hash{String=>String}]
173
173
  def init_classifications
174
174
  @classifications = Hash.new do |hash, key|
175
- hash[key] = Accessibility::Inflector.classify(key)
175
+ hash[key] = ActiveSupport::Inflector.classify(key)
176
176
  end
177
177
  end
178
178
 
179
179
  # @return [Hash{String=>String}]
180
180
  def init_singularizations
181
181
  @singularizations = Hash.new do |hash, key|
182
- hash[key] = Accessibility::Inflector.singularize(key)
182
+ hash[key] = ActiveSupport::Inflector.singularize(key)
183
183
  end
184
184
  end
185
185
 
@@ -4,7 +4,7 @@
4
4
  # The main AXElements namespace.
5
5
  module Accessibility
6
6
  # @return [String]
7
- VERSION = '1.0.0.alpha11'
7
+ VERSION = '1.0.0.beta'
8
8
 
9
9
  # @return [String]
10
10
  CODE_NAME = 'ルナトーン'
@@ -19,7 +19,7 @@ class AX::Application < AX::Element
19
19
  # @return [Boolean]
20
20
  def launch bundle
21
21
  NSWorkspace.sharedWorkspace.launchAppWithBundleIdentifier bundle,
22
- options: NSWorkspaceLaunchAsync,
22
+ options: NSWorkspace::NSWorkspaceLaunchAsync,
23
23
  additionalEventParamDescriptor: nil,
24
24
  launchIdentifier: nil
25
25
  end
@@ -121,7 +121,7 @@ class AX::Application < AX::Element
121
121
  app.first
122
122
 
123
123
  ) || (
124
- spin_run_loop
124
+ spin
125
125
  NSWorkspace.sharedWorkspace.runningApplications.find { |app|
126
126
  app.localizedName == arg
127
127
  }
@@ -129,7 +129,7 @@ class AX::Application < AX::Element
129
129
  ) || (
130
130
  count ||= 0
131
131
  if AX::Application.launch arg
132
- sleep 1
132
+ spin 1
133
133
  count += 1
134
134
  raise "#{arg} failed to launch in time" if count == 10
135
135
  else
@@ -172,7 +172,7 @@ class AX::Application < AX::Element
172
172
  # to the dynamic `#focused?` method, but might make more sense to use
173
173
  # in some cases.
174
174
  def active?
175
- spin_run_loop
175
+ spin
176
176
  @app.active?
177
177
  end
178
178
  alias_method :focused, :active?
@@ -181,14 +181,14 @@ class AX::Application < AX::Element
181
181
  ##
182
182
  # Ask the app whether or not it is hidden.
183
183
  def hidden?
184
- spin_run_loop
184
+ spin
185
185
  @app.hidden?
186
186
  end
187
187
 
188
188
  ##
189
189
  # Ask the app whether or not it is still running.
190
190
  def terminated?
191
- spin_run_loop
191
+ spin
192
192
  @app.terminated?
193
193
  end
194
194
 
@@ -292,17 +292,17 @@ class AX::Application < AX::Element
292
292
  case name
293
293
  when :terminate
294
294
  return true if terminated?
295
- @app.terminate; sleep 0.2; terminated?
295
+ @app.terminate; spin 0.25; terminated?
296
296
  when :force_terminate
297
297
  return true if terminated?
298
- @app.forceTerminate; sleep 0.2; terminated?
298
+ @app.forceTerminate; spin 0.25; terminated?
299
299
  when :hide
300
300
  return true if hidden?
301
- @app.hide; sleep 0.2; hidden?
301
+ @app.hide; spin 0.25; hidden?
302
302
  when :unhide
303
303
  return true if active?
304
- @app.activateWithOptions(NSApplicationActivateIgnoringOtherApps)
305
- sleep 0.2; active?
304
+ @app.activateWithOptions(NSRunningApplication::NSApplicationActivateIgnoringOtherApps)
305
+ spin 0.25; active?
306
306
  else
307
307
  super
308
308
  end
@@ -432,11 +432,6 @@ class AX::Application < AX::Element
432
432
 
433
433
  private
434
434
 
435
- # @return [nil]
436
- def spin_run_loop
437
- NSRunLoop.currentRunLoop.runUntilDate Time.now
438
- end
439
-
440
435
  # @return [NSBundle]
441
436
  def bundle
442
437
  @bundle ||= NSBundle.bundleWithURL @app.bundleURL
data/lib/ax/element.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ require 'active_support/core_ext/object/blank'
3
4
  require 'accessibility/core'
4
5
  require 'accessibility/factory'
5
6
  require 'accessibility/translator'
@@ -54,7 +55,7 @@ class AX::Element
54
55
  #
55
56
  # @param attr [#to_sym]
56
57
  def attribute attr
57
- @ref.attribute TRANSLATOR.cocoaify(attr)
58
+ @ref.attribute(TRANSLATOR.cocoaify(attr)).to_ruby
58
59
  end
59
60
 
60
61
  ##
@@ -65,7 +66,7 @@ class AX::Element
65
66
  #
66
67
  # @return [String]
67
68
  def description
68
- attribute :description
69
+ attribute(:description).to_ruby
69
70
  end
70
71
 
71
72
  ##
@@ -73,12 +74,12 @@ class AX::Element
73
74
  #
74
75
  # @return [Array<AX::Element>]
75
76
  def children
76
- @ref.children
77
+ @ref.children.to_ruby
77
78
  end
78
79
 
79
80
  ##
80
81
  # Get a list of elements, starting with the receiver and riding
81
- # the hierarchy up to the top level object (i.e. the {AX::Application}).
82
+ # the hierarchy up to the top level object (i.e. the {AX::Application})
82
83
  #
83
84
  # @example
84
85
  #
@@ -87,15 +88,16 @@ class AX::Element
87
88
  # # => [#<AX::ApplicationDockItem...>, #<AX::List...>, #<AX::Application...>]
88
89
  #
89
90
  # @return [Array<AX::Element>]
90
- def ancestry *elements
91
- elements = [self] if elements.empty?
91
+ def ancestry elements = self
92
+ elements = Array(elements)
92
93
  element = elements.last
93
94
  if element.attributes.include? :parent
94
- ancestry(elements << element.parent)
95
+ ancestry(elements << element.attribute(:parent))
95
96
  else
96
97
  elements
97
98
  end
98
99
  end
100
+ alias_method :lineage, :ancestry
99
101
 
100
102
  ##
101
103
  # Get the process identifier for the application that the element
@@ -186,7 +188,7 @@ class AX::Element
186
188
  # @param param [Object]
187
189
  def parameterized_attribute attr, param
188
190
  param = param.relative_to(@ref.value.size) if value.kind_of? Range
189
- @ref.parameterized_attribute TRANSLATOR.cocoaify(attr), param
191
+ @ref.parameterized_attribute(TRANSLATOR.cocoaify(attr), param).to_ruby
190
192
  end
191
193
 
192
194
 
@@ -456,11 +458,17 @@ class AX::Element
456
458
  @ref.invalid?
457
459
  end
458
460
 
459
- ##
460
- # Like {#respond_to?}, this is overriden to include attribute methods.
461
- # Though, it does include dynamic predicate methods at the moment.
462
- def methods include_super = true, include_objc_super = false
463
- super.concat(attributes).concat(parameterized_attributes)
461
+ if on_macruby?
462
+ ##
463
+ # Like {#respond_to?}, this is overriden to include attribute methods.
464
+ # Though, it does include dynamic predicate methods at the moment.
465
+ def methods include_super = true, include_objc_super = false
466
+ super.concat(attributes).concat(parameterized_attributes)
467
+ end
468
+ else
469
+ def methods include_super = true
470
+ super.concat(attributes).concat(parameterized_attributes)
471
+ end
464
472
  end
465
473
 
466
474
  ##
@@ -485,24 +493,3 @@ class AX::Element
485
493
  TRANSLATOR = Accessibility::Translator.instance
486
494
 
487
495
  end
488
-
489
-
490
- # Extensions so checking `#blank?` on search result "just works".
491
- class NSArray
492
- # (see NilClass#blank?)
493
- alias_method :blank?, :empty?
494
- end
495
-
496
- # Extensions so checking `#blank?` on search result "just works".
497
- class NilClass
498
- ##
499
- # Whether or not the object is "blank". The concept of blankness
500
- # borrowed from `Active Support` and is true if the object is falsey
501
- # or `#empty?`.
502
- #
503
- # This method is used by implicit searching in AXElements to
504
- # determine if searches yielded responses.
505
- def blank?
506
- true
507
- end
508
- end
data/lib/ax/systemwide.rb CHANGED
@@ -13,7 +13,7 @@ class AX::SystemWide < AX::Element
13
13
 
14
14
  class << self
15
15
  ##
16
- # Find and return the group that represents the dock
16
+ # Find and return the group that represents the desktop
17
17
  #
18
18
  # @return [AX::Group]
19
19
  def desktop
@@ -41,7 +41,7 @@ class AX::SystemWide < AX::Element
41
41
  ##
42
42
  # Overridden since there is only one way to get the element ref.
43
43
  def initialize
44
- super AXUIElementCreateSystemWide()
44
+ super Accessibility::Element.system_wide
45
45
  end
46
46
 
47
47
  ##
data/lib/ax_elements.rb CHANGED
@@ -1,3 +1,7 @@
1
+ require 'ax_elements/active_support_selections'
2
+ require 'accessibility/bridge'
3
+ require 'ax_elements/mri' unless on_macruby?
4
+
1
5
  # Mix the language methods into the TopLevel
2
6
  require 'accessibility/dsl'
3
7
  include Accessibility::DSL
@@ -5,10 +9,12 @@ include Accessibility::DSL
5
9
  require 'accessibility/system_info'
6
10
 
7
11
  ##
12
+ # @deprecated Please use {AX::Application.dock} instead
13
+ #
8
14
  # The Mac OS X dock application.
9
15
  #
10
16
  # @return [AX::Application]
11
- AX::DOCK = AX::Application.new('com.apple.dock')
17
+ AX::DOCK = AX::Application.dock
12
18
 
13
19
  # Load explicitly defined elements that are optional
14
20
  require 'ax/button'
@@ -0,0 +1,10 @@
1
+ # this is just a list of core extensions from Active Support
2
+ # that I would like to have loaded by default
3
+
4
+ require 'active_support/core_ext/numeric'
5
+ require 'active_support/core_ext/date/calculations'
6
+ require 'active_support/core_ext/date/conversions'
7
+ require 'active_support/core_ext/time/calculations'
8
+ require 'active_support/core_ext/time/conversions'
9
+ require 'active_support/core_ext/date_time/calculations'
10
+ require 'active_support/core_ext/date_time/conversions'
@@ -0,0 +1,57 @@
1
+ unless on_macruby?
2
+
3
+ KAXChildrenAttribute = 'AXChildren'
4
+ KAXRoleAttribute = 'AXRole'
5
+ KAXSubroleAttribute = 'AXSubrole'
6
+ KAXIdentifierAttribute = 'AXIdentifier'
7
+ KAXWindowCreatedNotification = 'AXWindowCreated'
8
+ KAXMainWindowAttribute = 'AXMainWindow'
9
+ KAXFocusedAttribute = 'AXFocused'
10
+ KAXValueChangedNotification = 'AXValueChanged'
11
+ KAXTitleAttribute = 'AXTitle'
12
+ KAXURLAttribute = 'AXURL'
13
+ KAXTitleUIElementAttribute = 'AXTitleUIElement'
14
+ KAXPlaceholderValueAttribute = 'AXPlaceholderValue'
15
+ KAXWindowRole = 'AXWindow'
16
+ KAXCloseButtonSubrole = 'AXCloseButton'
17
+ KAXTrashDockItemSubrole = 'AXTrashDockItem'
18
+ KAXRTFForRangeParameterizedAttribute = 'AXRTFForRange'
19
+ KAXIsApplicationRunningAttribute = 'AXIsApplicationRunning'
20
+ KAXStringForRangeParameterizedAttribute = 'AXStringForRange'
21
+
22
+ unless defined? NSString
23
+ NSString = String
24
+ end
25
+
26
+ unless defined? NSDictionary
27
+ NSDictionary = Hash
28
+ end
29
+
30
+ unless defined? NSArray
31
+ NSArray = Array
32
+ end
33
+
34
+ unless defined? NSDate
35
+ NSDate = Time
36
+ end
37
+
38
+ class Symbol
39
+
40
+ def chomp suffix
41
+ to_s.chomp suffix
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+ unless defined? KAXIdentifierAttribute
49
+ ##
50
+ # Added for backwards compatability with Snow Leopard.
51
+ # This attribute is standard with Lion and newer. AXElements depends
52
+ # on it being defined.
53
+ #
54
+ # @return [String]
55
+ KAXIdentifierAttribute = 'AXIdentifier'
56
+ end
57
+
@@ -1,5 +1,6 @@
1
1
  require 'ax/element'
2
2
  require 'accessibility/translator'
3
+ require 'active_support/core_ext/array/access'
3
4
 
4
5
  ##
5
6
  # An old hack on arrays that allows you to map a single method across
@@ -11,18 +12,6 @@ require 'accessibility/translator'
11
12
  # on this and so I will just keep it around for backwards compatability.
12
13
  module Accessibility::NSArrayCompat
13
14
 
14
- ##
15
- # Equivalent to `#at(1)`
16
- def second
17
- at(1)
18
- end
19
-
20
- ##
21
- # Equivalent to `#at(2)`
22
- def third
23
- at(2)
24
- end
25
-
26
15
  ##
27
16
  # @note Debatably bad idea. Maintained for backwards compatibility.
28
17
  #
@@ -40,11 +29,11 @@ module Accessibility::NSArrayCompat
40
29
  # outline.rows.text_fields.values # all at once
41
30
  #
42
31
  def method_missing method, *args
43
- smethod = TRANSLATOR.singularize(method.chomp('?'))
32
+ smethod = TRANSLATOR.singularize(method.to_s.chomp('?'))
44
33
  map do |x|
45
- if !x.kind_of? AX::Element then super
46
- elsif x.respond_to? method then x.send method, *args
47
- else x.send smethod, *args
34
+ if !x.kind_of?(AX::Element) then super
35
+ elsif x.respond_to? method then x.send method, *args
36
+ else x.send smethod, *args
48
37
  end
49
38
  end
50
39
  end
@@ -58,8 +47,99 @@ module Accessibility::NSArrayCompat
58
47
 
59
48
  end
60
49
 
50
+ unless defined? NSArray
51
+ NSArray = Array
52
+ end
61
53
 
62
- # AXElements extensions for `NSArray`.
54
+ ##
55
+ # AXElements extensions for `NSArray`
63
56
  class NSArray
64
57
  include Accessibility::NSArrayCompat
58
+
59
+ if on_macruby?
60
+
61
+ ##
62
+ # Returns the tail of the array from `position`
63
+ #
64
+ # @example
65
+ #
66
+ # [1, 2, 3, 4].from(0) # => [1, 2, 3, 4]
67
+ # [1, 2, 3, 4].from(2) # => [3, 4]
68
+ # [1, 2, 3, 4].from(10) # => []
69
+ # [].from(0) # => []
70
+ #
71
+ # @param position [Fixnum]
72
+ # @return [Array]
73
+ def from position
74
+ self[position, length] || []
75
+ end
76
+
77
+ ##
78
+ # Returns the beginning of the array up to `position`
79
+ #
80
+ # [1, 2, 3, 4].to(0) # => [1]
81
+ # [1, 2, 3, 4].to(2) # => [1, 2, 3]
82
+ # [1, 2, 3, 4].to(10) # => [1, 2, 3, 4]
83
+ # [].to(0) # => []
84
+ #
85
+ # @param count [Fixnum]
86
+ # @return [Array]
87
+ def to count
88
+ take count + 1
89
+ end
90
+
91
+ ##
92
+ # Equal to `self[1]`
93
+ def second
94
+ self[1]
95
+ end
96
+
97
+ ##
98
+ # Equal to `self[2]`
99
+ def third
100
+ self[2]
101
+ end
102
+
103
+ ##
104
+ # Equal to `self[3]`
105
+ def fourth
106
+ self[3]
107
+ end
108
+
109
+ ##
110
+ # Equal to `self[4]`
111
+ def fifth
112
+ self[4]
113
+ end
114
+
115
+ ##
116
+ # Equal to `self[41]`
117
+ #
118
+ # Also known as accessing "the reddit".
119
+ def forty_two
120
+ self[41]
121
+ end
122
+
123
+ else
124
+
125
+ ##
126
+ # Create a new array with the same contents as the given array
127
+ #
128
+ # @param ary [Array]
129
+ def self.arrayWithArray ary
130
+ ary.dup
131
+ end
132
+
133
+ ##
134
+ # Create and return a new empty array
135
+ #
136
+ # @return [Array]
137
+ def self.array
138
+ []
139
+ end
140
+
141
+ end
142
+
143
+ alias_method :the_reddit, :forty_two
144
+
65
145
  end