Skip to content

Instantly share code, notes, and snippets.

@SuborbitalPigeon
Last active December 1, 2019 17:47
Show Gist options
  • Save SuborbitalPigeon/5398109 to your computer and use it in GitHub Desktop.
Save SuborbitalPigeon/5398109 to your computer and use it in GitHub Desktop.
A web browser, in JavaScript.
#!/usr/bin/gjs
// TODO
// Proper actions
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const WebKit2 = imports.gi.WebKit2;
//const MainToolbar = imports.mainToolbar;
var MainToolbar = GObject.registerClass(
class MainToolbar extends Gtk.Toolbar
{
_init(webView)
{
super._init()
this._webView = webView;
this.get_style_context().add_class("primary-toolbar");
/* Back/forward box */
let backForwardBox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL });
backForwardBox.get_style_context().add_class("linked");
/* Back */
this._backButton = this._createToolButton("go-previous-symbolic");
this._backButton.connect("clicked", () => {
this._webView.go_back();
});
backForwardBox.add(this._backButton);
/* Forward */
this._forwardButton = this._createToolButton("go-next-symbolic");
this._forwardButton.connect("clicked", () => {
this._webView.go_forward();
});
backForwardBox.add(this._forwardButton);
// Back/forward item
let backForwardItem = this._createToolItem(backForwardBox);
this.add(backForwardItem);
/* Refresh */
let refButton = this._createToolButton("view-refresh-symbolic");
refButton.connect("clicked", () => {
this._webView.reload();
});
let refItem = this._createToolItem(refButton);
this.add(refItem);
/* Entry */
this.entry = new Gtk.Entry();
this.entry.connect("activate", this._entryActivate.bind(this));
let locItem = this._createToolItem(this.entry);
locItem.set_expand(true);
this.add(locItem);
}
_createToolButton(iconName)
{
let image = new Gtk.Image({ icon_name: iconName });
let button = new Gtk.Button({ image: image});
button.get_style_context().add_class("raised");
return button;
}
_createToolItem(child)
{
let item = new Gtk.ToolItem();
item.add(child);
return item;
}
_entryActivate()
{
let text = this._toolbar.entry.text;
let uri;
//FIXME JS17
//if(text.startsWith("http://"))
if(text.startsWith("http://"))
uri = text;
else
uri = "http://" + text;
this._webView.load_uri(uri);
}
get backButton()
{
return this._backButton;
}
get forwardButton()
{
return this._forwardButton;
}
});
class WebBrowser
{
//create the application
constructor()
{
this.application = new Gtk.Application({
application_id: 'uk.me.bcowan.gjsbrowser',
flags: Gio.ApplicationFlags.FLAGS_NONE
});
//connect to 'activate' and 'startup' signals to the callback functions
this.application.connect('activate', this._onActivate.bind(this));
this.application.connect('startup', this._onStartup.bind(this));
}
//callback function for 'activate' signal
_onActivate()
{
this._initMenus();
this._window.show_all();
}
//callback function for 'startup' signal
_onStartup()
{
this._window = new Gtk.ApplicationWindow({ application: this.application,
window_position: Gtk.WindowPosition.CENTER,
title: "GJS Browser" });
let grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
this._window.add(grid);
this._webView = new WebKit2.WebView();
this._webView.load_uri("http://webkitgtk.org");
this._webView.set_size_request(800, 600);
this._webView.connect("notify::estimated_load_progress", this._notifyLoadProgress.bind(this));
this._webView.connect("notify::title", this._notifyTitle.bind(this));
this._webView.connect("load_changed", this._loadChanged.bind(this));
this._toolbar = new MainToolbar(this._webView);
this._toolbar.set_hexpand(true);
grid.add(this._toolbar);
grid.add(this._webView);
}
_initMenus()
{
let menu = new Gio.Menu();
menu.append("About", "app.about");
menu.append("Quit", "app.quit");
this.application.set_app_menu(menu);
let aboutAction = new Gio.SimpleAction({ name: "about" });
aboutAction.connect("activate", this._showAbout.bind(this));
this.application.add_action(aboutAction);
let quitAction = new Gio.SimpleAction({ name: "quit" });
quitAction.connect("activate", () => {
this._window.destroy();
});
this.application.add_action(quitAction);
}
_showAbout()
{
let authors = ["Bruce Cowan"];
let aboutDialog = new Gtk.AboutDialog({ program_name: "GJS Browser",
copyright : "Copyright © 2013 Bruce Cowan",
authors : authors,
license_type: Gtk.License.MIT_X11 });
aboutDialog.modal = true;
aboutDialog.transient_for = this._window;
aboutDialog.show();
aboutDialog.connect("response", () => {
aboutDialog.destroy();
});
}
// FIXME This never gets called
_notifyLoadProgress(webView, pspec)
{
let progress = this._webview.estimated_load_progress;
if (progress < 1)
this._toolbar.entry.progress_fraction = progress;
else
this._toolbar.entry.progress_fraction = 0;
}
_notifyTitle(webView, pspec)
{
let title = this._webView.title;
this._window.title = title + " - GJS Browser";
}
_loadChanged(webView, loadEvent)
{
if (loadEvent == WebKit2.LoadEvent.COMMITTED)
{
this._toolbar.entry.text = this._webView.uri;
let list = webView.get_back_forward_list();
let back = list.get_back_item();
let forwards = list.get_forward_item();
if (back)
this._toolbar.backButton.sensitive = true;
else
this._toolbar.backButton.sensitive = false;
if (forwards)
this._toolbar.forwardButton.sensitive = true;
else
this._toolbar.forwardButton.sensitive = false;
}
}
};
//run the application
let app = new WebBrowser();
app.application.run(ARGV);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment