Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
JankyBrowser

JankyBrowser

The only cross-platform browser that fits in a Gist!

One line install. Works on Linux, MacOSX and Windows.

Local Install

$> npm install http://gist.github.com/morganrallen/f07f59802884bcdcad4a/download
$> node node_modules/jankybrowser

Global Install

$> npm install -g http://gist.github.com/morganrallen/f07f59802884bcdcad4a/download
$> jankybrowser

JankyBrowser is based on Thrust

html, body {
font: 13px normal "Roboto", Arial;
width: 100%;
height: 100%;
overflow: hidden;
-webkit-font-smoothing: antialiased;
}
html, body,
header {
clear: both;
margin: 0;
padding: 0;
width: 100%;
}
header {
height: 40px;
font-size: 14px;
line-height: 1em;
background: #f9f9f9;
border-bottom: 3px solid #d5d5d5;
-webkit-user-select: none;
}
header * {
-webkit-box-sizing: border-box;
}
header input {
background: #fff;
padding: 0 12px;
border: none;
height: 100%;
}
#nav {
float: left;
height: 100%;
}
#nav .forward,
#nav .backward {
height: 100%;
float: left;
padding: 10px;
padding-top: 15px;
color: #d5d5d5;
cursor: pointer;
}
#nav .forward:hover,
#nav .backward:hover {
color: hsl(200, 50%, 50%);
}
#nav .forward:active,
#nav .backward:active {
background: #f3f3f3;
}
#new {
float: right;
position: absolute;
right: 0;
text-align: center;
top: 0;
padding: 10px;
padding-top: 14px;
z-index: 1000;
color: #d5d5d5;
cursor: pointer;
}
#new:hover {
color: hsl(100, 50%, 50%);
}
#new:active {
background: #f3f3f3;
}
#tabs-wrapper {
height: 40px;
overflow: hidden;
}
.tabs {
height: 100%;
list-style: none;
margin: 0;
padding: 0;
overflow: hidden;
width: 100%;
}
.tabs li {
float: left;
padding: 15px;
border-bottom: 3px solid #d5d5d5;
cursor: default;
}
.tabs li.active {
background-color: #f3f3f3;
border-bottom: 3px solid #0b0909;
}
.tab .tab-close {
cursor: pointer;
float: right;
margin-left: 10px;
opacity: 0;
}
.tab:hover .tab-close {
opacity: 1;
}
#page-content {
height: calc(100% - 44px);
width: 100%;
}
#page-content .page {
height: calc(100% - 44px);
transition: left 0.4s ease-in-out;
position: absolute;
left: -100%;
width: 100%;
}
#page-content .page.active {
left: 0;
}
<html>
<head>
<link rel="stylesheet" href="//brick.a.ssl.fastly.net/Roboto:200,300,400,500,700,900">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="/browser.css" rel="stylesheet" />
<script src="/browser.js"></script>
</head>
<body>
<header>
<div id="nav">
<div class="backward"><i class="fa fa-chevron-left"></i></div>
<div class="forward"><i class="fa fa-chevron-right"></i></div>
<input id="location" />
</div>
<div id="tabs-wrapper">
<ul class="tabs"></ul>
<div id="new"><i class="fa fa-plus"></i></div>
</div>
</header>
<div id="page-content"></div>
</body>
</html>
"use strict";
function urlToTtile(url) {
var a = document.createElement("a");
a.href = url;
var hostname = a.hostname;
hostname = hostname.split(".").slice(-2).join(".");
return hostname;
}
var loc;
var tabs;
var newTab;
var pageContent;
var navForward;
var navBackward;
var activePage;
var activeTab;
var activeWV;
function activate(page, tab) {
if(activePage && activePage !== page) {
activePage.classList.remove("active");
}
if(activeTab && activeTab !== tab) {
activeTab.classList.remove("active");
}
activePage = page;
activeTab = tab;
activeWV = page.firstElementChild;
activePage.classList.add("active");
activeTab.classList.add("active");
loc.value = activeWV.src;
}
window.onload = function() {
var $ = document.querySelector.bind(document);
loc = $("header input");
tabs = $("ul.tabs");
newTab = $("#new");
pageContent = $("#page-content");
navForward = $("#nav .forward");
navBackward = $("#nav .backward");
function openNewTab(url) {
var page = document.createElement("div");
page.className = "page";
var webview = document.createElement("webview");
page.appendChild(webview);
pageContent.appendChild(page);
if(url) {
webview.src = url;
}
var tab = document.createElement("li");
tab.className = "tab";
var label = document.createTextNode(urlToTtile(url));
tab.appendChild(label);
var close = document.createElement("i");
close.className = "tab-close fa fa-times";
tab.appendChild(close);
tabs.appendChild(tab);
function handleTabClick() {
console.log("clicking tab");
activate(page, tab);
}
function handleCloseClick(evt) {
console.log("closing tab");
tab.removeEventListener(handleTabClick);
webview.removeEventListener(handleTabClick);
close.removeEventListener(handleCloseClick);
tab.parentNode.removeChild(tab);
webview.parentNode.removeChild(webview);
evt.stopPropagation();
}
tab.addEventListener("click", handleTabClick, false);
close.addEventListener("click", handleCloseClick, true);
webview.addEventListener("title-set", function(evt) {
label.textContent = evt.title;
}, false);
activate(page, tab);
}
loc.addEventListener("keypress", function(evt) {
if(evt.keyCode === 13) {
console.log("changing location " + loc.value);
activeWV.src = loc.value;
}
}, false);
newTab.addEventListener("click", function() {
openNewTab("http://www.google.com");
}, false);
navBackward.addEventListener("click", function() {
activeWV.back();
});
navForward.addEventListener("click", function() {
activeWV.forward();
});
openNewTab("http://www.google.com");
};
"use strict";
var argv = require('minimist')(process.argv.slice(2));
var async = require('async');
var api = null;
var window = null;
var url = __dirname + "/test.html";
var fs = require("fs");
var http = require("http");
var port = 21024;
async.series([
function(cb) {
var server = http.createServer(function(req, res) {
if(req.url === "/") {
req.url = "/browser.html";
}
req.url = __dirname + req.url;
console.log("attempting to load %s", req.url);
fs.createReadStream(req.url).pipe(res);
});
server.listen(port, '127.0.0.1', function() {
console.log("listening on %s", port);
cb(null);
});
},
function(cb_) {
require('node-thrust')(function(err, a) {
api = a;
return cb_(err);
}, argv.thrust_path || null);
},
function(cb_) {
var root = "http://127.0.0.1:" + port;
if(argv.ext) root += ("/" + argv.ext);
window = api.window({
root_url: root,
size: {
width: 1024,
height: 768
}
});
window.on("closed", function() {
process.exit(0);
});
return cb_();
},
function(cb_) {
window.show(cb_);
}
], function(err) {
if(err) {
console.log('FAILED');
console.error(err);
}
console.log('OK');
});
#!/usr/bin/env node
require("./");
{
"name": "jankybrowser",
"version": "1.2.0",
"description": "",
"bin": {
"jankybrowser": "jankybrowser"
},
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"async": "^0.9.0",
"minimist": "^1.1.0",
"node-thrust": "*"
}
}
@spolu

This comment has been minimized.

Copy link

@spolu spolu commented Nov 25, 2014

This is awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.