-
Notifications
You must be signed in to change notification settings - Fork 1
/
test_client.nim
282 lines (227 loc) · 9.19 KB
/
test_client.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
import winapi, os, strutils
import nc_menu_model, nc_process_message, nc_app, nc_client, nc_types
import nc_context_menu_params, nc_browser, nc_scheme, nc_resource_handler
import nc_request, nc_callback, nc_util, nc_response, nc_settings, nc_task
import nc_urlrequest, nc_auth_callback, nc_frame, nc_web_plugin
import nc_request_context_handler, nc_request_context
import nc_life_span_handler, nc_context_menu_handler
import test_runner, nc_resource_manager, nc_request_handler
import nc_display_handler
type
myApp = ref object of NCApp
myScheme = ref object of NCResourceHandler
mData: string
mMimeType: string
mOffset: int
myClient = ref object of NCClient
abc: int
name: string
cmh: NCContextMenuHandler
lsh: NCLifeSpanHandler
reqh: NCRequestHandler
disph: NCDisplayHandler
MENU_ID:
MY_MENU_ID
MY_QUIT_ID
MY_PLUGIN_ID
MY_SHOW_DEVTOOLS
MY_CLOSE_DEVTOOLS
MY_INSPECT_ELEMENT
MY_OTHER_TESTS
handlerImpl(NCClient)
proc showDevTool(host: NCBrowserHost; x, y: int = 0) =
let screenW = getSystemMetrics(SM_CXSCREEN)
let screenH = getSystemMetrics(SM_CYSCREEN)
let devToolW = screenW - screenW div 3
let devToolH = screenH - screenH div 3
var windowInfo: NCWindowInfo
windowInfo.style = WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_VISIBLE
windowInfo.parent_window = cef_window_handle(0)
windowInfo.x = (screenW - devToolW) div 2
windowInfo.y = (screenH - devToolH) div 2
windowInfo.width = devToolW
windowInfo.height = devToolH
var setting: NCBrowserSettings
host.showDevTools(windowInfo, NCClient.ncCreate(), setting, NCPoint(x:x, y:y))
handlerImpl(NCContextMenuHandler):
proc onBeforeContextMenu(self: NCContextMenuHandler, browser: NCBrowser,
frame: NCFrame, params: NCContextMenuParams, model: NCMenuModel) =
discard model.addSeparator()
discard model.addItem(MY_PLUGIN_ID, "Plugin Info")
discard model.addItem(MY_MENU_ID, "Hello There")
discard model.addSeparator()
discard model.addItem(MY_SHOW_DEVTOOLS, "Show DevTools")
discard model.addItem(MY_CLOSE_DEVTOOLS, "Close DevTools")
discard model.addItem(MY_INSPECT_ELEMENT, "Inspect Element")
discard model.addSeparator()
discard model.addItem(MY_OTHER_TESTS, "Other Tests")
discard model.addItem(MY_QUIT_ID, "Quit")
proc onContextMenuCommand(self: NCContextMenuHandler, browser: NCBrowser,
frame: NCFrame, params: NCContextMenuParams, command_id: cef_menu_id,
event_flags: cef_event_flags): int =
case command_id
of MY_MENU_ID:
frame.executeJavaScript("alert('Hello There Clicked!');", frame.getURL(), 0)
of MY_QUIT_ID:
var host = browser.getHost()
host.closeBrowser(true)
of MY_SHOW_DEVTOOLS:
showDevTool(browser.getHost())
of MY_CLOSE_DEVTOOLS:
browser.getHost().closeDevTools()
of MY_INSPECT_ELEMENT:
showDevTool(browser.getHost(), params.getXCoord(), params.getYCoord())
of MY_OTHER_TESTS:
browser.getMainFrame().loadURL("http://tests/other_tests")
else:
echo "unsupported MENU ID"
#if command_id == MY_PLUGIN_ID:
# echo "PLUGIN INFO"
# let visitor = makeNCWebPluginInfoVisitor(visitor_impl)
# NCVisitWebPluginInfo(visitor)
handlerImpl(myScheme):
proc processRequest(self: myScheme, request: NCRequest, callback: NCCallback): bool =
NC_REQUIRE_IO_THREAD()
var handled = false
var url = request.getURL()
if url.find("handler.html") != -1:
#Build the response html
self.mData = """<html><head><title>Client Scheme Handler</title></head>
<body bgcolor="white">
This contents of this page are served by the
myScheme object handling the client:// protocol.
<h2>Google</h2>
<a href="https://www.google.com/">https://www.google.com/</a>
<br/>You should see an image:
<br/><img src="client://tests/logo.png"><pre>"""
#Output a string representation of the request
self.mData.add dumpRequestContents(request)
self.mData.add """</pre><br/>Try the test form:
<form method="POST" action="handler.html">
<input type="text" name="field1">
<input type="text" name="field2">
<input type="submit">
</form></body></html>"""
handled = true
#Set the resulting mime type
self.mMimeType = "text/html"
elif url.find("logo.png") != -1:
#Load the response image
self.mData = readFile("resources" & DirSep & "logo.png")
handled = true
#Set the resulting mime type
self.mMimeType = "image/png"
if handled:
#Indicate the headers are available.
callback.continueCallback()
return true
result = false
proc getResponseHeaders(self: myScheme, response: NCResponse, response_length: var int64, redirectUrl: var string) =
NC_REQUIRE_IO_THREAD()
doAssert(self.mData.len != 0)
response.setMimeType(self.mMimeType)
response.setStatus(200)
#Set the resulting response length
response_length = self.mData.len
proc readResponse(self: myScheme, data_out: cstring, bytes_to_read: int, bytes_read: var int, callback: NCCallback): bool =
NC_REQUIRE_IO_THREAD()
var has_data = false
bytes_read = 0
if self.mOffset < self.mData.len:
#Copy the next block of data into the buffer.
let transfer_size = min(bytes_to_read, self.mData.len - self.mOffset)
copyMem(data_out, self.mData[self.mOffset].addr, transfer_size)
inc(self.mOffset, transfer_size)
bytes_read = transfer_size
has_data = true
result = has_data
handlerImpl(myApp):
proc onRegisterCustomSchemes*(self: myApp, registrar: NCSchemeRegistrar) =
discard registrar.addCustomScheme("client", true, false, false)
handlerImpl(NCSchemeHandlerFactory):
proc create*(self: NCSchemeHandlerFactory, browser: NCBrowser, frame: NCFrame, schemeName: string, request: NCRequest): NCResourceHandler =
NC_REQUIRE_IO_THREAD()
result = myScheme.ncCreate()
proc registerSchemeHandler() =
ncRegisterSchemeHandlerFactory("client", "tests", NCSchemeHandlerFactory.ncCreate())
handlerImpl(NCLifeSpanHandler):
proc onBeforeClose(self: NCLifeSpanHandler, browser: NCBrowser) =
ncQuitMessageLoop()
handlerImpl(NCRequestHandler):
proc onBeforeResourceLoad*(self: NCRequestHandler, browser: NCBrowser,
frame: NCFrame, request: NCRequest, callback: NCRequestCallback): cef_return_value =
NC_REQUIRE_IO_THREAD()
var resourceManager = getResourceManager()
result = resourceManager.onBeforeResourceLoad(browser, frame, request, callback)
proc getResourceHandler*(self: NCRequestHandler, browser: NCBrowser,
frame: NCFrame, request: NCRequest): NCResourceHandler =
NC_REQUIRE_IO_THREAD()
var resourceManager = getResourceManager()
result = resourceManager.getResourceHandler(browser, frame, request)
handlerImpl(NCDisplayHandler):
proc onTitleChange*(self: NCDisplayHandler, browser: NCBrowser, title: string) =
var host = browser.getHost()
var hWnd = host.getWindowHandle()
discard setWindowText(hWnd, title)
handlerImpl(myClient):
proc getContextMenuHandler*(self: myClient): NCContextMenuHandler =
return self.cmh
proc getLifeSpanHandler*(self: myClient): NCLifeSpanHandler =
return self.lsh
proc getRequestHandler*(self: myClient): NCRequestHandler =
return self.reqh
proc getDisplayHandler*(self: myClient): NCDisplayHandler =
return self.disph
proc newClient(no: int, name: string): myClient =
result = myClient.ncCreate()
result.abc = no
result.name = name
result.cmh = NCContextMenuHandler.ncCreate()
result.lsh = NCLifeSpanHandler.ncCreate()
result.reqh = NCRequestHandler.ncCreate()
result.disph = NCDisplayHandler.ncCreate()
setupResourceManager()
proc onBeforePluginLoad*(self: NCRequestContextHandler, mime_type, plugin_url, top_origin_url: string,
plugin_info: NCWebPluginInfo, plugin_policy: var cef_plugin_policy): bool =
# Always allow the PDF plugin to load.
if plugin_policy != PLUGIN_POLICY_ALLOW and mime_type == "application/pdf":
plugin_policy = PLUGIN_POLICY_ALLOW
return true
result = false
proc main() =
# Main args.
var mainArgs = makeNCMainArgs()
var app = myApp.ncCreate()
var code = ncExecuteProcess(mainArgs, app)
if code >= 0:
echo "failure execute process ", code
quit(code)
var settings: NCSettings
settings.no_sandbox = true
discard ncInitialize(mainArgs, settings, app)
var windowInfo: NCWindowInfo
windowInfo.style = WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_VISIBLE or WS_MAXIMIZE
windowInfo.parent_window = cef_window_handle(0)
windowInfo.x = 0
windowInfo.y = 0
windowInfo.width = getSystemMetrics(SM_CXSCREEN)
windowInfo.height = getSystemMetrics(SM_CYSCREEN)
registerSchemeHandler()
#Initial url.
#let cwd = getCurrentDir()
#let url = "file://$1/example.html" % [cwd]
let url = "client://tests/handler.html"
#Browser settings.
#It is mandatory to set the "size" member.
var browserSettings: NCBrowserSettings
#browserSettings.plugins = STATE_ENABLED
var client = newClient(123, "myClient")
#var rch = makeNCRequestContextHandler(rch_impl)
#var rcsetting: NCRequestContextSettings
#var ctx = NCRequestContextCreateContext(rcsetting, rch)
# Create browser.
discard ncBrowserHostCreateBrowser(windowInfo, client, url, browserSettings)
# Message loop.
ncRunMessageLoop()
ncShutdown()
main()