-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathbrowser.js
More file actions
120 lines (96 loc) · 3.6 KB
/
Copy pathbrowser.js
File metadata and controls
120 lines (96 loc) · 3.6 KB
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
#!/usr/bin/env node
/*
* A basic node-gtk WebKit based browser example, built with libadwaita (GTK 4).
*
* Usage:
* node examples/browser.js [url] [dark]
*
* e.g. node examples/browser.js github.com dark
*/
const gi = require('../lib/')
const GLib = gi.require('GLib', '2.0')
const Gtk = gi.require('Gtk', '4.0')
const Adw = gi.require('Adw', '1')
const WebKit = gi.require('WebKit', '6.0')
const loop = GLib.MainLoop.new(null, false)
const app = new Adw.Application('com.github.romgrk.node-gtk.browser', 0)
app.on('activate', onActivate)
gi.startLoop()
const status = app.run([])
console.log('Finished with status:', status)
function onActivate() {
// Optional dark theme (gotta love it!)
if (process.argv.some(arg => arg === 'dark'))
Adw.StyleManager.getDefault().setColorScheme(Adw.ColorScheme.FORCE_DARK)
const window = new Adw.ApplicationWindow(app)
window.setTitle('node-gtk Browser')
window.setDefaultSize(1024, 720)
window.on('close-request', onQuit)
// WebKit2 browser wrapper. It scrolls internally, so no ScrolledWindow needed.
const webView = new WebKit.WebView({ vexpand: true, hexpand: true })
const settings = webView.getSettings()
settings.setEnableDeveloperExtras(true)
// Navigation buttons, grouped with the "linked" style so they read as a unit.
const backButton = new Gtk.Button({ 'icon-name': 'go-previous-symbolic', sensitive: false })
const forwardButton = new Gtk.Button({ 'icon-name': 'go-next-symbolic', sensitive: false })
const navBox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL })
navBox.addCssClass('linked')
navBox.append(backButton)
navBox.append(forwardButton)
const refreshButton = new Gtk.Button({ 'icon-name': 'view-refresh-symbolic' })
// The URL bar lives in the header bar's title slot and doubles as a
// progress indicator while a page loads.
const urlBar = new Gtk.Entry({ hexpand: true })
urlBar.setInputPurpose(Gtk.InputPurpose.URL)
const header = new Adw.HeaderBar()
header.packStart(navBox)
header.packStart(refreshButton)
header.setTitleWidget(urlBar)
// ToolbarView is the canonical Adwaita way to stack a header bar over content.
const view = new Adw.ToolbarView()
view.addTopBar(header)
view.setContent(webView)
window.setContent(view)
/*
* Event handlers
*/
webView.on('load-changed', (loadEvent) => {
if (loadEvent === WebKit.LoadEvent.COMMITTED)
urlBar.setText(webView.getUri() || '')
backButton.setSensitive(webView.canGoBack())
forwardButton.setSensitive(webView.canGoForward())
})
// Drive the entry's progress bar from the load estimate; clear it when done.
webView.on('notify::estimated-load-progress', () => {
const progress = webView.getEstimatedLoadProgress()
urlBar.setProgressFraction(progress < 1 ? progress : 0)
})
webView.on('notify::title', () => {
window.setTitle(webView.getTitle() || 'node-gtk Browser')
})
backButton.on('clicked', () => webView.goBack())
forwardButton.on('clicked', () => webView.goForward())
refreshButton.on('clicked', () => webView.reload())
urlBar.on('activate', () => {
const href = url(urlBar.getText())
urlBar.setText(href)
webView.loadUri(href)
})
// Open the first non-flag argument, or Google by default.
const urlArg = process.argv.slice(2).find(arg => arg !== 'dark')
webView.loadUri(url(urlArg || 'google.com'))
window.present()
loop.run()
}
function onQuit() {
loop.quit()
app.quit()
return false
}
/*
* Helpers
*/
// If the link doesn't have a protocol, prefix it with http://
function url(href) {
return /^([a-z]{2,}):/.test(href) ? href : ('http://' + href)
}