forked from JuliaGizmos/Blink.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwindow.jl
199 lines (147 loc) · 4.91 KB
/
window.jl
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
using ..Blink
import Blink: js, id
import JSExpr: JSString, jsstring
import Base: position, size, close
export Window, flashframe, shell, progress, title,
centre, floating, loadurl, opentools, closetools, tools,
loadhtml, loadfile, css, front
mutable struct Window
id::Int
shell::Shell
content
end
"""
Window()
Window(electron_options::Dict; async=true)
Create and open a new Window through Electron.
If `async==false`, this function blocks until the Window is fully initialized
and ready for you to communicate with it via javascript or the Blink API.
The `electron_options` dict is used to initialize the Electron window. See here
for the full set of Electron options:
https://electronjs.org/docs/api/browser-window#new-browserwindowoptions
"""
function Window end
shell(win::Window) = win.shell
id(win::Window) = win.id
const window_defaults = @d(:url => "about:blank",
:title => "Julia",
"node-integration" => false,
"use-content-size" => true,
:icon => resolve_blink_asset("deps", "julia.png"))
raw_window(a::Electron, opts) = @js a createWindow($(merge(window_defaults, opts)))
function Window(a::Shell, opts::AbstractDict = Dict(); async=true)
# TODO: Custom urls don't support async b/c don't load Blink.js. (Same as https://github.com/JunoLab/Blink.jl/issues/150)
return haskey(opts, :url) ?
Window(raw_window(a, opts), a, nothing) :
Window(a, Page(), opts, async=async)
end
function Window(a::Shell, content::Page, opts::AbstractDict = Dict(); async=true)
url = Blink.localurl(content)
if !async
# Send the callback id as a query param in the url.
id, cond = Blink.callback!()
url *= "?callback=$id"
end
# Create the window.
opts = merge(opts, Dict(:url => url))
w = Window(raw_window(a, opts), a, content)
# If callback is requested, wait until the window has finished loading.
if !async
val = wait(cond)
if isa(val, AbstractDict) && get(val, "type", "") == "error"
err = JSError(get(val, "name", "unknown"), get(val, "message", "blank"))
throw(err)
end
end
return w
end
Window(args...; kwargs...) = Window(shell(), args...; kwargs...)
dot(a::Electron, win::Integer, code; callback = true) =
js(a, :(withwin($(win), $(jsstring(code)...))),
callback = callback)
dot(w::Window, code; callback = true) =
ifelse(callback, dot(shell(w), id(w), code, callback = callback), w)
dot_(args...) = dot(args..., callback = false)
macro dot(win, code)
:(dot($(esc(win)), $(Expr(:quote, Expr(:., :this, QuoteNode(code))))))
end
macro dot_(win, code)
:(dot_($(esc(win)), $(Expr(:quote, Expr(:., :this, QuoteNode(code))))))
end
# Window management APIs
active(s::Electron, win::Integer) =
@js s windows.hasOwnProperty($win)
active(win::Window) = active(shell(win), id(win))
flashframe(win::Window, on = true) =
@dot_ win flashFrame($on)
progress(win::Window, p = -1) =
@dot_ win setProgressBar($p)
title(win::Window, title) =
@dot_ win setTitle($title)
title(win::Window) =
@dot win getTitle()
centre(win::Window) =
@dot_ win center()
position(win::Window, x, y) =
@dot_ win setPosition($x, $y)
position(win::Window) =
@dot win getPosition()
size(win::Window, w::Integer, h::Integer) =
invoke(size, Tuple{Window, Any, Any}, win, w, h)
size(win::Window, w, h) =
@dot_ win setSize($w, $h)
size(win::Window) =
@dot win getSize()
floating(win::Window, flag) =
@dot_ win setAlwaysOnTop($flag)
floating(win::Window) =
@dot win isAlwaysOnTop()
loadurl(win::Window, url) =
@dot win loadURL($url)
loadfile(win::Window, f) =
loadurl(win, "file://$f")
"""
opentools(win::Window)
Open the Chrome Developer Tools on `win`.
See also: [`closetools`](@ref), [`tools`](@ref)
"""
opentools(win::Window) =
@dot win openDevTools()
"""
closetools(win::Window)
Close the Chrome Developer Tools on `win` if open.
See also: [`opentools`](@ref), [`tools`](@ref)
"""
closetools(win::Window) =
@dot win closeDevTools()
"""
tools(win::Window)
Toggle the Chrome Developer Tools on `win`.
See also: [`opentools`](@ref), [`closetools`](@ref)
"""
tools(win::Window) =
@dot win toggleDevTools()
front(win::Window) =
@dot win showInactive()
close(win::Window) =
@dot win close()
# Window content APIs
active(::Nothing) = false
handlers(w::Window) = handlers(w.content)
msg(win::Window, m) = msg(win.content, m)
js(win::Window, s::JSString; callback = true) =
active(win.content) ? js(win.content, s, callback = callback) :
dot(win, :(this.webContents.executeJavaScript($(s.s))), callback = callback)
const initcss = """
<style>html,body{margin:0;padding:0;border:0;text-align:center;}</style>
"""
function loadhtml(win::Window, html::AbstractString)
tmp = string(tempname(), ".html")
open(tmp, "w") do io
println(io, initcss)
println(io, html)
end
loadfile(win, tmp)
@async (sleep(1); rm(tmp))
return
end