sleipnir-api 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;