sleipnir-api 0.3.0 → 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.
@@ -1,52 +1,84 @@
1
+ == 0.4.0 / 2007-10-28
2
+
3
+ === New API:
4
+
5
+ * SleipnirAPI::Sleipnir
6
+ +bring_window_to_top+:: brings the Sleipnir window to the top of the Z order.
7
+ +save_active_tab+:: protect actived tab.
8
+ +capture_browser+:: capture sleipnir window.
9
+
10
+ * SleipnirAPI::Tab
11
+ +capture_page+:: save screenshot to specified file.
12
+ +sleipnir_ieview_hwnd+:: get Sleipnir_IEView window handle.
13
+ +embedding_ie_hwnd+:: get Internet Explorer_Server window handle.
14
+ +client_area+:: return body.clientLeft, body.clientTop, body.clientWidth, body.clientHeight
15
+ +embedding_ie_area+:: return browser width, height including scrollbar and border.
16
+ +compatible_mode+:: new method to get compatMode.
17
+ <tt>compatible_mode?</tt>:: new method to return whether documet is compatMode or not.
18
+ +get_elements_by_tag+:: wrapper of getElementsByTag.
19
+ <tt>closed?</tt>:: return true closed tab.
20
+
21
+
1
22
  == 0.3.0 / 2007-09-23
2
23
 
3
- * API changes:
4
- * SleipnirAPI::Tab
5
- +search+:: support Sleipnir 2.x.
6
- * SleipnirAPI::Security
7
- +enable?+:: support multiple arguments.
8
- +disable?+:: ditto.
9
- * SleipnirAPI::Sleipnir
10
- +profile+:: support default keyword arguments.
11
- +exec_command+:: support SleipnirAPI::Command object.
12
- * New API:
13
- * SleipnirAPI::Command
14
- * new class to represent Sleipnir menu commands.
15
- it can specify SleipnirAPI::Sleipnir#exec_command.
16
- * SleipnirAPI::Profile::Ini
17
- * new class to represent ini file.
18
- * SleipnirAPI::Profile::Seciton
19
- * new class to represent ini section.
20
- * SleipnirAPI::Profile::Key
21
- * new class to represent ini section key.
22
- * SleipnirAPI::Profile
23
- +ini+:: get SleipnirAPI::Profile::Ini object.
24
- * SleipnirAPI::Tab
25
- +watir+:: get Watir object [experimental].
26
- +elem_by_tag+:: get IHTMLElement. (shortcut of document.getElementsByTagName).
27
- +base_uri+:: get document base (<base> or location.href).
28
- +base_uris+:: get base uri in <head>.
29
- * SleipnirAPI::Security
30
- +enable!+:: set security config.
31
- +disable!+:: ditto.
24
+ === API changes:
25
+
26
+ * SleipnirAPI::Tab
27
+ +search+:: support Sleipnir 2.x.
28
+ * SleipnirAPI::Security
29
+ <tt>enable?</tt>:: support multiple arguments.
30
+ <tt>disable?</tt>:: ditto.
31
+ * SleipnirAPI::Sleipnir
32
+ +profile+:: support default keyword arguments.
33
+ +exec_command+:: support SleipnirAPI::Command object.
34
+
35
+ === New API:
36
+
37
+ * SleipnirAPI::Command
38
+ * new class to represent Sleipnir menu commands.
39
+ it can specify SleipnirAPI::Sleipnir#exec_command.
40
+ * SleipnirAPI::Profile::Ini
41
+ * new class to represent ini file.
42
+ * SleipnirAPI::Profile::Section
43
+ * new class to represent ini section.
44
+ * SleipnirAPI::Profile::Key
45
+ * new class to represent ini section key.
46
+ * SleipnirAPI::Profile
47
+ +ini+:: get SleipnirAPI::Profile::Ini object.
48
+ * SleipnirAPI::Tab
49
+ +watir+:: get Watir object [experimental].
50
+ +elem_by_tag+:: get IHTMLElement. (shortcut of document.getElementsByTagName).
51
+ +base_uri+:: get document base (<base> or location.href).
52
+ +base_uris+:: get base uri in <head>.
53
+ * SleipnirAPI::Security
54
+ +enable!+:: set security config.
55
+ +disable!+:: ditto.
56
+
32
57
 
33
58
  == 0.2.1 / 2007-07-30
34
59
 
35
- * grepnir:
36
- * minor bug fix.
60
+ === command:
61
+
62
+ * minor bug fix.
63
+
37
64
 
38
65
  == 0.2.0 / 2007-07-29
39
66
 
67
+ === command:
68
+
40
69
  * Added grepnir command to search Sleipnir tab.
41
- * API changes:
42
- * SleipnirAPI::Tab
43
- +window+:: support block argument.
44
- +document+:: ditto.
45
- +browser+:: ditto.
46
- +location+:: ditto.
47
- +close+:: now take +force+ optional argument to close navigate locked tab.
48
- +hilight+:: support multiple keywords.
49
- +selection_text+:: add new method to get selected text.
70
+
71
+ === API changes:
72
+
73
+ * SleipnirAPI::Tab
74
+ +window+:: support block argument.
75
+ +document+:: ditto.
76
+ +browser+:: ditto.
77
+ +location+:: ditto.
78
+ +close+:: now take +force+ optional argument to close navigate locked tab.
79
+ +hilight+:: support multiple keywords.
80
+ +selection_text+:: add new method to get selected text.
81
+
50
82
 
51
83
  == 0.1.0 / 2007-07-22
52
84
 
@@ -11,16 +11,24 @@ examples/command_list.rb
11
11
  examples/open_last_url_by_firefox.rb
12
12
  examples/open_selected_links.rb
13
13
  examples/reload.rb
14
+ examples/screenshot.rb
14
15
  helper/rake.rb
15
16
  helper/rake/rake.rb
16
17
  helper/rake/rake_sh_filter.rb
17
18
  helper/rake/util.rb
18
19
  lib/sleipnir_api.rb
20
+ lib/sleipnir_api/bitmap.rb
19
21
  lib/sleipnir_api/cli/base.rb
20
22
  lib/sleipnir_api/cli/grepnir.rb
21
23
  lib/sleipnir_api/command.rb
22
24
  lib/sleipnir_api/commands.rb
23
25
  lib/sleipnir_api/dialog.rb
26
+ lib/sleipnir_api/ffi.rb
27
+ lib/sleipnir_api/ffi/base.rb
28
+ lib/sleipnir_api/ffi/gdi32.rb
29
+ lib/sleipnir_api/ffi/kernel32.rb
30
+ lib/sleipnir_api/ffi/struct.rb
31
+ lib/sleipnir_api/ffi/user32.rb
24
32
  lib/sleipnir_api/key_state.rb
25
33
  lib/sleipnir_api/output.rb
26
34
  lib/sleipnir_api/process.rb
@@ -30,6 +38,7 @@ lib/sleipnir_api/profile/key.rb
30
38
  lib/sleipnir_api/profile/section.rb
31
39
  lib/sleipnir_api/profile/util.rb
32
40
  lib/sleipnir_api/registry.rb
41
+ lib/sleipnir_api/screen_captor.rb
33
42
  lib/sleipnir_api/searcher.rb
34
43
  lib/sleipnir_api/security.rb
35
44
  lib/sleipnir_api/sleipnir.rb
@@ -37,7 +46,6 @@ lib/sleipnir_api/tab.rb
37
46
  lib/sleipnir_api/tabbed_ie.rb
38
47
  lib/sleipnir_api/util.rb
39
48
  lib/sleipnir_api/version.rb
40
- lib/sleipnir_api/win32api.rb
41
49
  scripts/gesture2rb.rb
42
50
  scripts/make_gesture.rb
43
51
  scripts/rdoc_filter.rb
@@ -48,6 +56,7 @@ spec/matchers/exit_with.rb
48
56
  spec/matchers/path_eql.rb
49
57
  spec/sleipnir_api/cli/grepnir_spec.rb
50
58
  spec/sleipnir_api/dialog_mock_spec.rb
59
+ spec/sleipnir_api/ffi_spec.rb
51
60
  spec/sleipnir_api/key_state_mock_spec.rb
52
61
  spec/sleipnir_api/output_spec.rb
53
62
  spec/sleipnir_api/profile_mock_spec.rb
data/README.txt CHANGED
@@ -6,6 +6,7 @@ sleipnir-api は {Sleipnir}[http://www.fenrir.co.jp/sleipnir2-the-world/] の
6
6
  COM サーバ (Sleipnir.API) を操作するための Ruby ライブラリです。
7
7
 
8
8
  WIN32OLE オブジェクトをラップし、Ruby らしいインターフェイスを提供します。
9
+ また、Sleipnir ウィンドウのスクリーンショットを保存することができます。
9
10
 
10
11
  API 仕様は SleipnirAPI を参照してください。
11
12
 
@@ -46,6 +47,15 @@ sleipnir-api は _grepnir_ コマンドが付属しています。
46
47
  * Sleipnir 2.xx でのテストはあまりしていません。
47
48
 
48
49
 
50
+ === ACKNOWLEDGMENTS
51
+
52
+ * スクリーンショットの取得周りのコードの多くは Perl の
53
+ {Win32::CaptureIE}[http://search.cpan.org/~psme/Win32-CaptureIE/]
54
+ および
55
+ {Win32::Screenshot}[http://search.cpan.org/~psme/Win32-Screenshot/]
56
+ を参考にさせていただきました。
57
+
58
+
49
59
  === COPYRIGHT
50
60
 
51
61
  Copyright (c) 2007 MIYAMUKO Katsuyuki.
data/TODO.txt CHANGED
@@ -1,5 +1,7 @@
1
1
  == TODO
2
2
 
3
+ * スクロール位置が移動しないリロード
4
+ * exec_command じゃタブごとにできない
3
5
  * hilight を自前で実装する
4
6
  * Sleipnir 2.x じゃサポートしていない
5
7
  * 1.66 で hilight を同じページに対して何回も実行するとだんだん重くなる
@@ -9,10 +11,9 @@
9
11
  * sleipnir shell
10
12
  * JavaScript の実行
11
13
  * Sleipnir の起動・終了を WMI を使わずに実装。
12
- * Sleipnir の終了時に Window Handle をちゃんと見る。
13
- * Sleipnir の IE コンポーネント部分の Window Handle の取得。
14
- * Internet Explorer_Server
15
- * ウィンドウの screen shot
14
+ * screen shot
15
+ * ページごと
16
+ * ImageMagik
16
17
  * Sleipnir.API proxy interface
17
18
  * JSON-RPC
18
19
  * XML-RPC
@@ -0,0 +1,33 @@
1
+ require "thread"
2
+ require "digest"
3
+
4
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "../lib")
5
+ require "sleipnir_api"
6
+
7
+ lock = Mutex.new
8
+ pnir = SleipnirAPI.connect
9
+
10
+ worker = ARGV.collect {|url|
11
+ Thread.start {
12
+ tab = lock.synchronize {
13
+ if url =~ /[a-z]+:\/\//
14
+ pnir.new_tab(url)
15
+ else
16
+ pnir.new_tab("file://#{File.expand_path(url)}")
17
+ end
18
+ }
19
+ sleep 0.1 while tab.busy?
20
+ sleep 1 # �ꉞ
21
+ lock.synchronize {
22
+ digest = Digest::MD5.hexdigest(url)
23
+ filename = "#{digest}.bmp"
24
+ puts "#{url} => #{filename}"
25
+ tab.capture_page(filename)
26
+ }
27
+ tab.close
28
+ }
29
+ }
30
+
31
+ worker.each do |t|
32
+ t.join
33
+ end
@@ -131,7 +131,7 @@ module SleipnirAPI
131
131
  unless SleipnirAPI::Process.exist?
132
132
  SleipnirAPI::Process.create
133
133
  end
134
- connect(quit_on_finish, &block)
134
+ connect0(quit_on_finish, &block)
135
135
  end
136
136
 
137
137
  #
@@ -154,10 +154,14 @@ module SleipnirAPI
154
154
  # puts tab.document.location.href
155
155
  # end
156
156
  #
157
- def connect(quit_on_finish = false)
157
+ def connect(quit_on_finish = false, &block)
158
158
  unless SleipnirAPI::Process.exist?
159
159
  raise SleipnirAPI::ConnectError, "Sleipnir.API does not running"
160
160
  end
161
+ connect0(quit_on_finish, &block)
162
+ end
163
+
164
+ def connect0(quit_on_finish) #:nodoc:
161
165
  pnir = SleipnirAPI::Sleipnir.new(create_sleipnir_ole_object)
162
166
  return pnir unless block_given?
163
167
 
@@ -0,0 +1,113 @@
1
+ require "sleipnir_api/ffi"
2
+
3
+ module SleipnirAPI
4
+
5
+ class BitMapSizeError < StandardError #:nodoc:
6
+ end
7
+
8
+ class BitMap #:nodoc:
9
+ include SleipnirAPI::FFI::GDI32
10
+
11
+ attr_reader :width, :height
12
+ def initialize(width, height)
13
+ @width = width
14
+ @height = height
15
+ @data = nil
16
+ end
17
+
18
+ def header_size
19
+ BITMAPINFOHEADER.packed_size + BITMAPFILEHEADER.packed_size
20
+ end
21
+
22
+ def data_size
23
+ width * height * 4
24
+ end
25
+
26
+ def data
27
+ @data ||= "\0" * data_size
28
+ end
29
+
30
+ def rows
31
+ (0..height).map{|i| data[i * width * 4, width * 4] }
32
+ end
33
+
34
+ def replace(bmp)
35
+ @width = bmp.width
36
+ @height = bmp.height
37
+ @data = bmp.data
38
+ end
39
+
40
+
41
+ def concat_bottom!(bmp)
42
+ if width.zero?
43
+ replace(bmp)
44
+ else
45
+ check_bitmap_size(:width, @width, bmp.width)
46
+ @data << bmp.data
47
+ @height += bmp.height
48
+ end
49
+ end
50
+ alias << concat_bottom!
51
+
52
+ def concat_right!(bmp)
53
+ if height.zero?
54
+ replace(bmp)
55
+ else
56
+ check_bitmap_size(:height, @height, bmp.height)
57
+ @data = rows.zip(bmp.rows).flatten.join
58
+ @width += bmp.width
59
+ end
60
+ end
61
+
62
+ def check_bitmap_size(key, expected, actual)
63
+ if expected != actual
64
+ raise BitMapSizeError, "wrong bitmap #{key}: expected #{expected}px, but was #{actual}px."
65
+ end
66
+ end
67
+ private :check_bitmap_size
68
+
69
+
70
+ def create_bitmapfileheader
71
+ header = BITMAPFILEHEADER.new
72
+ header.bfType = "BM".unpack("S")[0]
73
+ header.bfSize = header_size + data_size
74
+ header.bfOffBits = header_size
75
+ header
76
+ end
77
+ alias header create_bitmapfileheader
78
+
79
+ def create_bitmapinfo
80
+ info = BITMAPINFO.new
81
+ info.bmiHeader.biSize = BITMAPINFOHEADER.packed_size
82
+ info.bmiHeader.biWidth = width
83
+ info.bmiHeader.biHeight = -height # negative because we want top-down bitmap
84
+ info.bmiHeader.biPlanes = 1
85
+ info.bmiHeader.biBitCount = 32 # we want RGBQUAD data
86
+ info.bmiHeader.biCompression = BI_RGB
87
+ info
88
+ end
89
+ alias info create_bitmapinfo
90
+
91
+ def save(filename)
92
+ open(filename, "wb") do |w|
93
+ pack {|data|
94
+ w.write data
95
+ }
96
+ end
97
+ end
98
+
99
+ def pack(&block)
100
+ v = [create_bitmapfileheader.pack, create_bitmapinfo.bmiHeader.pack, @data]
101
+ if block
102
+ v.each(&block)
103
+ else
104
+ v.join
105
+ end
106
+ end
107
+
108
+ def inspect
109
+ "#<%s:0x%x @width=%d @height=%d @data=...>" % [self.class, self.object_id << 1, @height, @width]
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,4 @@
1
+ require "sleipnir_api/ffi/struct"
2
+ require "sleipnir_api/ffi/kernel32"
3
+ require "sleipnir_api/ffi/user32"
4
+ require "sleipnir_api/ffi/gdi32"
@@ -0,0 +1,22 @@
1
+ require "Win32API"
2
+
3
+ module SleipnirAPI
4
+ module FFI #:nodoc:
5
+ end
6
+
7
+ class Win32APIError < StandardError #:nodoc:
8
+ end
9
+ end
10
+
11
+ module SleipnirAPI::FFI
12
+ module Base #:nodoc:
13
+ def define_ffi_entry(const, args, ret, lib, entry=const.to_s)
14
+ api = ::Win32API.new(lib, entry, args, ret)
15
+ const_set(const, api)
16
+ define_method(const) do |*args|
17
+ api.call(*args)
18
+ end
19
+ module_function const
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,165 @@
1
+ require "sleipnir_api/ffi/base"
2
+ require "sleipnir_api/ffi/struct"
3
+
4
+ module SleipnirAPI::FFI
5
+ module GDI32 #:nodoc:
6
+ extend SleipnirAPI::FFI::Base
7
+ extend SleipnirAPI::FFI::CStruct
8
+
9
+ define_c_type(:uint8, :BYTE)
10
+ define_c_type(:uint16, :WORD)
11
+ define_c_type(:uint32, :DWORD)
12
+ define_c_type(:int32, :LONG)
13
+
14
+ define_c_struct(:RGBQUAD) {
15
+ BYTE :rgbBlue
16
+ BYTE :rgbGreen
17
+ BYTE :rgbRed
18
+ BYTE :rgbReserved
19
+ }
20
+
21
+ define_c_struct(:BITMAPINFOHEADER) {
22
+ DWORD :biSize
23
+ LONG :biWidth
24
+ LONG :biHeight
25
+ WORD :biPlanes
26
+ WORD :biBitCount
27
+ DWORD :biCompression
28
+ DWORD :biSizeImage
29
+ LONG :biXPelsPerMeter
30
+ LONG :biYPelsPerMeter
31
+ DWORD :biClrUsed
32
+ DWORD :biClrImportant
33
+ }
34
+
35
+ define_c_struct(:BITMAPINFO) {
36
+ BITMAPINFOHEADER :bmiHeader
37
+ RGBQUAD :bmiColors, :dim => 1
38
+ }
39
+
40
+ define_c_struct(:BITMAPFILEHEADER) {
41
+ WORD :bfType
42
+ DWORD :bfSize, :offset => 2
43
+ WORD :bfReserved1
44
+ WORD :bfReserved2
45
+ DWORD :bfOffBits, :offset => 10
46
+ }
47
+
48
+ DRIVERVERSION = 0
49
+ TECHNOLOGY = 2
50
+ HORZSIZE = 4
51
+ VERTSIZE = 6
52
+ HORZRES = 8
53
+ VERTRES = 10
54
+ BITSPIXEL = 12
55
+ PLANES = 14
56
+ NUMBRUSHES = 16
57
+ NUMPENS = 18
58
+ NUMMARKERS = 20
59
+ NUMFONTS = 22
60
+ NUMCOLORS = 24
61
+ PDEVICESIZE = 26
62
+ CURVECAPS = 28
63
+ LINECAPS = 30
64
+ POLYGONALCAPS = 32
65
+ TEXTCAPS = 34
66
+ CLIPCAPS = 36
67
+ RASTERCAPS = 38
68
+ ASPECTX = 40
69
+ ASPECTY = 42
70
+ ASPECTXY = 44
71
+
72
+ DIB_RGB_COLORS = 0
73
+ DIB_PAL_COLORS = 1
74
+
75
+ # Raster operations
76
+ SRCCOPY = 0x00CC0020
77
+ SRCPAINT = 0x00EE0086
78
+ SRCAND = 0x008800C6
79
+ SRCINVERT = 0x00660046
80
+ SRCERASE = 0x00440328
81
+ NOTSRCCOPY = 0x00330008
82
+ NOTSRCERASE = 0x001100A6
83
+ MERGECOPY = 0x00C000CA
84
+ MERGEPAINT = 0x00BB0226
85
+ PATCOPY = 0x00F00021
86
+ PATPAINT = 0x00FB0A09
87
+ PATINVERT = 0x005A0049
88
+ DSTINVERT = 0x00550009
89
+ BLACKNESS = 0x00000042
90
+ WHITENESS = 0x00FF0062
91
+
92
+ # constants for the biCompression field
93
+ BI_RGB = 0
94
+ BI_RLE8 = 1
95
+ BI_RLE4 = 2
96
+ BI_BITFIELDS = 3
97
+ BI_JPEG = 4
98
+ BI_PNG = 5
99
+
100
+ define_ffi_entry(:BitBlt, 'LIIIILIIL', 'B', 'gdi32')
101
+ define_ffi_entry(:CreateCompatibleDC, 'L', 'L', 'gdi32')
102
+ define_ffi_entry(:CreateCompatibleBitmap, 'LII', 'L', 'gdi32')
103
+ define_ffi_entry(:DeleteDC, 'L', 'B', 'gdi32')
104
+ define_ffi_entry(:DeleteObject, 'L', 'B', 'gdi32')
105
+ define_ffi_entry(:GetDIBits, 'LLIIPPI', 'I', 'gdi32')
106
+ define_ffi_entry(:SelectObject, 'LL', 'L', 'gdi32')
107
+
108
+ module_function
109
+
110
+ def with_delete_dc(hdc)
111
+ begin
112
+ yield hdc
113
+ ensure
114
+ DeleteDC(hdc)
115
+ end
116
+ end
117
+
118
+ def with_delete_object(obj)
119
+ begin
120
+ yield obj
121
+ ensure
122
+ DeleteObject(obj)
123
+ end
124
+ end
125
+
126
+ end
127
+ end
128
+
129
+
130
+ __END__
131
+ from WinGDI.h
132
+
133
+ typedef struct tagBITMAPINFOHEADER{
134
+ DWORD biSize;
135
+ LONG biWidth;
136
+ LONG biHeight;
137
+ WORD biPlanes;
138
+ WORD biBitCount;
139
+ DWORD biCompression;
140
+ DWORD biSizeImage;
141
+ LONG biXPelsPerMeter;
142
+ LONG biYPelsPerMeter;
143
+ DWORD biClrUsed;
144
+ DWORD biClrImportant;
145
+ } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
146
+
147
+ typedef struct tagRGBQUAD {
148
+ BYTE rgbBlue;
149
+ BYTE rgbGreen;
150
+ BYTE rgbRed;
151
+ BYTE rgbReserved;
152
+ } RGBQUAD;
153
+
154
+ typedef struct tagBITMAPINFO {
155
+ BITMAPINFOHEADER bmiHeader;
156
+ RGBQUAD bmiColors[1];
157
+ } BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;
158
+
159
+ typedef struct tagBITMAPFILEHEADER {
160
+ WORD bfType;
161
+ DWORD bfSize;
162
+ WORD bfReserved1;
163
+ WORD bfReserved2;
164
+ DWORD bfOffBits;
165
+ } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;