sleipnir-api 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/History.txt +32 -0
  2. data/Manifest.txt +20 -3
  3. data/Rakefile +11 -1
  4. data/TODO.txt +4 -10
  5. data/bin/grepnir +1 -1
  6. data/examples/close_dup.rb +1 -1
  7. data/examples/close_err.rb +12 -0
  8. data/examples/command_list.rb +135 -0
  9. data/examples/open_last_url_by_firefox.rb +44 -0
  10. data/examples/open_selected_links.rb +40 -0
  11. data/helper/rake.rb +3 -57
  12. data/helper/rake/rake.rb +58 -0
  13. data/helper/{rake_sh_filter.rb → rake/rake_sh_filter.rb} +0 -0
  14. data/helper/{util.rb → rake/util.rb} +0 -0
  15. data/lib/sleipnir_api/cli/grepnir.rb +2 -3
  16. data/lib/sleipnir_api/command.rb +126 -0
  17. data/lib/sleipnir_api/commands.rb +264 -0
  18. data/lib/sleipnir_api/profile.rb +166 -27
  19. data/lib/sleipnir_api/profile/ini.rb +202 -0
  20. data/lib/sleipnir_api/profile/key.rb +120 -0
  21. data/lib/sleipnir_api/profile/section.rb +147 -0
  22. data/lib/sleipnir_api/profile/util.rb +82 -0
  23. data/lib/sleipnir_api/searcher.rb +133 -0
  24. data/lib/sleipnir_api/security.rb +88 -18
  25. data/lib/sleipnir_api/sleipnir.rb +91 -7
  26. data/lib/sleipnir_api/tab.rb +68 -2
  27. data/lib/sleipnir_api/tabbed_ie.rb +33 -0
  28. data/lib/sleipnir_api/util.rb +25 -0
  29. data/lib/sleipnir_api/version.rb +2 -2
  30. data/scripts/gesture2rb.rb +42 -0
  31. data/scripts/make_gesture.rb +271 -0
  32. data/scripts/subcategory.csv +253 -0
  33. data/spec/sleipnir_api/profile_mock_spec.rb +80 -6
  34. data/spec/sleipnir_api/profile_section_mock_spec.rb +143 -0
  35. data/spec/sleipnir_api/profile_spec.rb +191 -0
  36. data/spec/sleipnir_api/security_spec.rb +58 -0
  37. data/spec/sleipnir_api/tab_mock_spec.rb +0 -5
  38. data/spec/sleipnir_api/tab_spec.rb +27 -0
  39. data/spec/spec_helper.rb +20 -0
  40. metadata +22 -5
  41. data/helper/helper.rb +0 -3
@@ -30,6 +30,18 @@ module SleipnirAPI
30
30
  # # Enumerable method
31
31
  # tab.security.find_all{|e| e.disable? }
32
32
  #
33
+ # セキュリティ名は以下のシンボルを指定できます。
34
+ #
35
+ # * <tt>:javascript</tt>
36
+ # * <tt>:java</tt>
37
+ # * <tt>:run_activex</tt>
38
+ # * <tt>:download_activex</tt>
39
+ # * <tt>:picture</tt>
40
+ # * <tt>:sound</tt>
41
+ # * <tt>:video</tt>
42
+ #
43
+ # セキュリティ名の一覧は #keys で取得できます。
44
+ #
33
45
  class Security
34
46
  include Enumerable
35
47
  include SleipnirAPI::Util
@@ -43,19 +55,21 @@ module SleipnirAPI
43
55
 
44
56
  attr_reader :name
45
57
 
46
- def initialize(security, name)
58
+ def initialize(security, tab, name, method)
47
59
  @security = security
60
+ @tab = tab
48
61
  @name = name
62
+ @method = method
49
63
  end
50
64
 
51
65
  # このセキュリティ設定が有効なら true を返します。
52
66
  def enable?
53
- @security.enable?(@name)
67
+ @tab.sleipnir.api.__send__(@method, @tab.id)
54
68
  end
55
69
 
56
70
  # このセキュリティ設定が無効なら true を返します。
57
71
  def disable?
58
- @security.disable?(@name)
72
+ not enable?
59
73
  end
60
74
 
61
75
  # このセキュリティ設定の有効・無効を切り替えます。
@@ -73,7 +87,7 @@ module SleipnirAPI
73
87
  # このセキュリティ設定を有効にします。
74
88
  #
75
89
  # 複数のセキュリティ設定を更新する場合は、
76
- # このメソッドを利用せず SleipnirAPI::Security#set_security を利用して
90
+ # このメソッドを利用せず SleipnirAPI::Security#enable! を利用して
77
91
  # 一括設定してください。
78
92
  def enable!
79
93
  self.enable = true
@@ -82,7 +96,7 @@ module SleipnirAPI
82
96
  # このセキュリティ設定を無効にします。
83
97
  #
84
98
  # 複数のセキュリティ設定を更新する場合は、
85
- # このメソッドを利用せず SleipnirAPI::Security#set_security を利用して
99
+ # このメソッドを利用せず SleipnirAPI::Security#disable! を利用して
86
100
  # 一括設定してください。
87
101
  def disable!
88
102
  self.enable = false
@@ -128,14 +142,14 @@ module SleipnirAPI
128
142
 
129
143
  def initialize(tab)
130
144
  @tab = tab
131
- keys.each do |name|
132
- instance_variable_set("@#{name}", Config.new(self, name))
145
+ NAME2API.each do |name, api|
146
+ instance_variable_set("@#{name}", Config.new(self, tab, name, api))
133
147
  end
134
148
  end
135
149
 
136
150
  # セキュリティ設定の名前 (シンボル) を配列で返します。
137
151
  #
138
- # この名前は #[], #set_security, #enable?, #disable? に指定できます。
152
+ # この名前は [], #set_security, #enable?, #disable? などに指定できます。
139
153
  #
140
154
  # pnir.active_tab.security.keys
141
155
  # #=> [:javascript, :java, :run_activex, :download_activex, :picture, :sound, :video]
@@ -178,6 +192,7 @@ module SleipnirAPI
178
192
  keys.map{|e| self[e] }.each(&block)
179
193
  end
180
194
 
195
+
181
196
  # call-seq:
182
197
  # set_security(:javascript => true_or_false,
183
198
  # :java => true_or_false,
@@ -197,23 +212,78 @@ module SleipnirAPI
197
212
 
198
213
  # セキュリティ設定をハッシュで取得します。
199
214
  def get_security
200
- NAME2API.inject({}) do |h, pair|
201
- h[pair[0]] = api.__send__(pair[1], @tab.id)
202
- h
203
- end
215
+ inject({}) {|h,conf| h[conf.name] = conf.enable?; h }
204
216
  end
205
217
  alias to_hash get_security
206
218
 
207
- # 指定された名前のセキュリティ設定が有効なら true を返します。
208
- def enable?(name)
209
- api.__send__(NAME2API.assoc(name.to_sym)[1], @tab.id)
219
+ # 指定された名前のセキュリティ設定がすべて有効なら true を返します。
220
+ #
221
+ # 引数に :all を指定するとすべてのセキュリティ設定が有効なら true を返します。
222
+ #
223
+ # tab.security.enable?(:javascript)
224
+ # tab.security.enable?(:picture, :sound, :video)
225
+ # tab.security.enable?(:all)
226
+ #
227
+ def enable?(*names)
228
+ names = parse_name(*names)
229
+ names.all?{|name| self[name].enable? }
210
230
  end
211
231
 
212
- # 指定された名前のセキュリティ設定が無効なら true を返します。
213
- def disable?(name)
214
- not enable?(name)
232
+ # 指定された名前のセキュリティ設定がすべて無効なら true を返します。
233
+ #
234
+ # 引数に :all を指定するとすべてのセキュリティ設定が無効なら true を返します。
235
+ #
236
+ # tab.security.disable?(:javascript)
237
+ # tab.security.disable?(:picture, :sound, :video)
238
+ # tab.security.disable?(:all)
239
+ #
240
+ def disable?(*names)
241
+ names = parse_name(*names)
242
+ names.all?{|name| self[name].disable? }
215
243
  end
216
244
 
245
+ # 指定された名前のセキュリティ設定をすべて有効にします。
246
+ #
247
+ # 引数に :all を指定するとすべてのセキュリティ設定を有効にします。
248
+ #
249
+ # tab.security.enable!(:javascript)
250
+ # tab.security.enable!(:picture, :sound, :video)
251
+ # tab.security.enable!(:all)
252
+ #
253
+ def enable!(*names)
254
+ set!(true, *names)
255
+ end
256
+
257
+ # 指定された名前のセキュリティ設定をすべて無効にします。
258
+ #
259
+ # 引数に :all を指定するとすべてのセキュリティ設定を無効にします。
260
+ #
261
+ # tab.security.disable!(:javascript)
262
+ # tab.security.disable!(:picture, :sound, :video)
263
+ # tab.security.disable!(:all)
264
+ #
265
+ def disable!(*names)
266
+ set!(false, *names)
267
+ end
268
+
269
+ def set!(enable, *names)
270
+ names = parse_name(*names)
271
+ set_security(names.inject({}){|h,k| h[k] = enable; h})
272
+ end
273
+ private :set!
274
+
275
+ def parse_name(*names)
276
+ names = names.flatten.map{|e| e.to_sym }
277
+ invalid = names - keys - [:all]
278
+ unless invalid.empty?
279
+ raise ArgumentError, "invalid security name #{invalid.inspect}"
280
+ end
281
+ names = keys if names.include?(:all)
282
+ names
283
+ end
284
+ private :parse_name
285
+
286
+
217
287
  def inspect
218
288
  "#<%s:0x%x %s>" % [self.class, self.object_id << 1, to_hash.inspect ]
219
289
  end
@@ -4,6 +4,7 @@ require "sleipnir_api/output"
4
4
  require "sleipnir_api/profile"
5
5
  require "sleipnir_api/key_state"
6
6
  require "sleipnir_api/dialog"
7
+ require "sleipnir_api/command"
7
8
 
8
9
  module SleipnirAPI
9
10
 
@@ -55,6 +56,7 @@ module SleipnirAPI
55
56
 
56
57
  # Sleipnir のウィンドウハンドル
57
58
  attr_reader :handle
59
+ alias hwnd handle
58
60
 
59
61
  # Sleipnir のバージョン
60
62
  attr_reader :version
@@ -194,6 +196,21 @@ module SleipnirAPI
194
196
  tabs.each(&block)
195
197
  end
196
198
 
199
+ # call-seq:
200
+ # each_eval{ ... }
201
+ #
202
+ # すべてのタブで指定された block を評価します。
203
+ # block は SleipnirAPI::Tab のコンテキストで評価されます (self が SleipnirAPI::Tab です)
204
+ #
205
+ # pnir.each_eval do
206
+ # if location.href =~ /workspace/
207
+ # self.navigate_lock = true
208
+ # end
209
+ # end
210
+ #
211
+ def each_eval(&block)
212
+ each {|tab| tab.instance_eval(&block) }
213
+ end
197
214
 
198
215
  # アクティブなドキュメントのタブ位置を取得します。
199
216
  def active_index
@@ -331,10 +348,36 @@ module SleipnirAPI
331
348
  api.AddSearchBarHistory
332
349
  end
333
350
 
334
- # Sleipnir の任意のメニューを <tt>cmdid</tt> で指定して実行します。
335
- # <tt>cmdid</tt> はマウスジェスチャー (Gesture.ini) 等から参照してください。
336
- def exec_command(cmdid)
337
- api.ExecCommand(cmdid)
351
+ # Sleipnir の任意のメニューを <tt>command</tt> で指定して実行します。
352
+ #
353
+ # command には以下の値を指定可能です。
354
+ #
355
+ # * SleipnirAPI::Command オブジェクト
356
+ # * 文字列 or 配列 (メニュー文字列)
357
+ # * メニュー文字列のエンコーディングは Shift_JIS です
358
+ # * 数値 (コマンド番号)
359
+ #
360
+ # 例:
361
+ #
362
+ # pnir = SleipnirAPI.connect
363
+ # pnir.exec_command(57664)
364
+ # pnir.exec_command("バージョン情報")
365
+ # pnir.exec_command(SleipnirAPI::Command["バージョン情報"])
366
+ # pnir.exec_command(["Netscape ブックマーク", "インポート"])
367
+ #
368
+ def exec_command(command)
369
+ case command
370
+ when String, Array
371
+ c = SleipnirAPI::Command[*Array(command)]
372
+ raise ArgumentError, "No such command: #{command}" unless c
373
+ exec_command(c.command_id)
374
+ when SleipnirAPI::Command
375
+ exec_command(command.command_id)
376
+ when Integer
377
+ api.ExecCommand(command)
378
+ else
379
+ raise ArgumentError, "Illegal command: #{command.inspect}"
380
+ end
338
381
  end
339
382
 
340
383
 
@@ -345,11 +388,52 @@ module SleipnirAPI
345
388
  SleipnirAPI::Output.new(self)
346
389
  end
347
390
 
391
+ # call-seq:
392
+ # profile()
393
+ # profile(ini_filename)
394
+ # profile(:default => "default value")
395
+ # profile(:cipher => true)
396
+ # profile(:cipher => true, :default => "default value")
397
+ # profile(:ini => ini_filename, :default => "default value")
398
+ # profile(:ini => ini_filename, :cipher => true)
399
+ # profile(:ini => ini_filename, :cipher => true, :default => "default value")
400
+ #
348
401
  # ini ファイルを操作するオブジェクトを取得します。
349
402
  #
350
- # See Also: SleipnirAPI::Profile
351
- def profile
352
- SleipnirAPI::Profile.new(self)
403
+ # 引数には ini ファイル名、SleipnirAPI::Profile#get_string などに指定するオプションの
404
+ # デフォルト値を指定します。
405
+ # ここで指定したオプションは各メソッドの引数で上書きすることができます。
406
+ #
407
+ # なお、SleipnirAPI::Profile#delete はオプション引数を取らないので
408
+ # ここで指定した値は完全に無視されます。
409
+ #
410
+ # ini ファイル名を指定した場合、SleipnirAPI::Profile::Ini オブジェクトを返します。
411
+ # 指定しない場合は SleipnirAPI::Profile オブジェクトを返します。
412
+ #
413
+ # ex)
414
+ # prof = pnir.profile #=> #<SleipnirAPI::Profile:0xdeadbeaf ...>
415
+ # proxy = pnir.profile("Proxy.ini") #=> #<SleipnirAPI::Profile::Ini:0xdeadbeaf: Proxy.ini, opts={}>
416
+ #
417
+ # See Also: SleipnirAPI::Profile, SleipnirAPI::Profile::Ini
418
+ def profile(ini = nil, opts = nil)
419
+ if ini
420
+ case ini
421
+ when Hash
422
+ t = ini.delete(:ini)
423
+ ini, opts = t, ini
424
+ when String, Symbol
425
+ ini = ini.to_s
426
+ else
427
+ raise ArgumentError, "Invalid ini filename `#{ini.inspect}':#{ini.class} (expected String or Symbol)"
428
+ end
429
+ end
430
+
431
+ r = SleipnirAPI::Profile.new(self, opts)
432
+ if ini
433
+ r.ini(ini)
434
+ else
435
+ r
436
+ end
353
437
  end
354
438
 
355
439
  end
@@ -2,6 +2,8 @@ require "sleipnir_api/util"
2
2
  require "sleipnir_api/key_state"
3
3
  require "sleipnir_api/dialog"
4
4
  require "sleipnir_api/security"
5
+ require "sleipnir_api/tabbed_ie"
6
+ require "sleipnir_api/searcher"
5
7
 
6
8
  module SleipnirAPI
7
9
 
@@ -38,6 +40,7 @@ module SleipnirAPI
38
40
  def initialize(sleipnir, id)
39
41
  @sleipnir = sleipnir
40
42
  @id = id
43
+ @searcher = SleipnirAPI::Searcher.new(self)
41
44
  end
42
45
 
43
46
  # call-seq:
@@ -109,6 +112,46 @@ module SleipnirAPI
109
112
  end
110
113
  end
111
114
 
115
+ # call-seq:
116
+ # elem_by_tag(tag, parent=nil) -> Array of IHTMLElement
117
+ # elem_by_tag(tag, index=0, parent=nil) -> IHTMLElement
118
+ #
119
+ # 指定された +tag+ 名の IHTMLElement を取得します。
120
+ #
121
+ # * +index+ を指定した場合、+index+ 番目の IHTMLElement を返します。
122
+ # 指定しない場合は IHTMLElement の配列を返します。
123
+ # * +parent+ を指定した場合は、+parent+ 配下から指定されたタグを探します。
124
+ # 指定しない場合はドキュメント全体から探します。
125
+ #
126
+ def elem_by_tag(tag, index=nil, parent=nil)
127
+ parent ||= document
128
+ tags = parent.getElementsByTagName(tag)
129
+ return unless tags
130
+ return tags unless index
131
+ tags.extend(Enumerable).to_a[index]
132
+ end
133
+
134
+ # このタブの base URI を返します。
135
+ #
136
+ # * <head> 内に <base> タグがあれば、最後の <base> タグの href 属性を返します。
137
+ # * <base> タグがなければこのドキュメントの URL を返します。
138
+ # * <body> 内の <base> タグは無視されます。
139
+ def base_uri
140
+ # document.baseUrl does not work :-(
141
+ base_uris.last || location.href
142
+ end
143
+
144
+ # <head> 内に <base> タグの配列を返します。
145
+ #
146
+ # <base> タグがなければ空の配列を返します。
147
+ def base_uris
148
+ head = elem_by_tag("head", 0)
149
+ return [] unless head
150
+ base = elem_by_tag("base", nil, head)
151
+ return [] unless base
152
+ base.extend(Enumerable).map{|e| e.href }
153
+ end
154
+
112
155
  # このタブで選択しているテキストを取得します。
113
156
  #
114
157
  # 選択していない場合は空文字列を返します。
@@ -122,6 +165,30 @@ module SleipnirAPI
122
165
  SleipnirAPI::Security.new(self)
123
166
  end
124
167
 
168
+ # このタブを操作する Watir オブジェクトを取得します。
169
+ #
170
+ # pnir = SleipnirAPI.connect
171
+ # ie = pnir.open("http://www.google.com").watir
172
+ # ie.text_field(:name, "q").set("Sleipnir")
173
+ # ie.button(:name, "btnG").click
174
+ #
175
+ def watir
176
+ begin
177
+ require "watir"
178
+ rescue LoadError
179
+ retry if require "rubygems"
180
+ raise
181
+ end
182
+
183
+ ie = SleipnirAPI::TabbedIE.new(self)
184
+ ::Watir::IE.new(true).instance_eval {
185
+ @ie = ie
186
+ set_defaults
187
+ self
188
+ }
189
+ end
190
+
191
+
125
192
  # このタブのタブ位置を取得します。
126
193
  def index
127
194
  self.api.GetIndex(self.id)
@@ -146,7 +213,7 @@ module SleipnirAPI
146
213
  # このメソッドを呼ぶたびにキーワードにマッチした次の位置に移動します。
147
214
  # キーワードが発見できない、または先頭のキーワードに戻ってきた場合 false を返します。
148
215
  def search(keyword)
149
- self.api.Search(self.id, keyword)
216
+ @searcher.find_text(keyword, :select, :scroll)
150
217
  end
151
218
 
152
219
  # 指定されたキーワードにマッチする部分をハイライトします。
@@ -416,4 +483,3 @@ __END__
416
483
  [戻り値]
417
484
   自動更新の時間(単位 = 秒)
418
485
 
419
-
@@ -0,0 +1,33 @@
1
+ require "forwardable"
2
+
3
+ module SleipnirAPI
4
+
5
+ class TabbedIE #:nodoc:
6
+ extend Forwardable
7
+
8
+ attr_accessor :visible
9
+
10
+ def initialize(tab)
11
+ @tab = tab
12
+ @browser = tab.browser
13
+ @visible = false
14
+ end
15
+
16
+ def quit
17
+ @tab.close
18
+ end
19
+
20
+ def statusBar
21
+ false
22
+ end
23
+
24
+ def statusText
25
+ nil
26
+ end
27
+
28
+ def method_missing(method, *args, &block)
29
+ @browser.__send__(method, *args, &block)
30
+ end
31
+ end
32
+
33
+ end
@@ -17,4 +17,29 @@ module SleipnirAPI
17
17
  end
18
18
 
19
19
  end
20
+
21
+ module OptionUtil #:nodoc:
22
+ module_function
23
+
24
+ def parse_option_arguments(*options)
25
+ result = {}
26
+ rest = []
27
+ options.flatten.compact.map{|e| Symbol === e ? e.to_s : e }.each do |opt|
28
+ case opt
29
+ when /\A(?:no|without)_(.+)/
30
+ result[$1.to_sym] = false
31
+ when /\A(?:with)_(.+)/
32
+ result[$1.to_sym] = true
33
+ when /(.+)/
34
+ result[$1.to_sym] = true
35
+ when Hash
36
+ result.update(opt)
37
+ else
38
+ rest << opt
39
+ end
40
+ end
41
+ [result, rest]
42
+ end
43
+ end
44
+
20
45
  end