aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/null-browser/extras/html.lua51
-rw-r--r--lua/null-browser/extras/statusline.lua79
-rw-r--r--lua/null-browser/extras/tabline.lua32
3 files changed, 119 insertions, 43 deletions
diff --git a/lua/null-browser/extras/html.lua b/lua/null-browser/extras/html.lua
new file mode 100644
index 0000000..d247090
--- /dev/null
+++ b/lua/null-browser/extras/html.lua
@@ -0,0 +1,51 @@
+local html = {}
+
+function html.create_el(name)
+ return function(attrs, children)
+ return { name = name, attrs = attrs, children = children }
+ end
+end
+
+function html.el(name, attrs, children)
+ return html.create_el(name)(attrs, children)
+end
+
+function html.to_string(elem)
+ if type(elem) == "string" then return html.escape_string(elem) end
+
+ if elem.raw and elem.value then return elem.value end
+
+ local attrs_str = ''
+ for key, value in pairs(elem.attrs or {}) do
+ -- TODO: html escape + quotify
+ attrs_str = attrs_str .. ' ' .. key .. '="' .. html.escape_string(value) .. '"'
+ end
+
+ local children_str = ''
+ for _, value in ipairs(elem.children or {}) do
+ children_str = children_str .. ' ' .. html.to_string(value)
+ end
+
+ return '<' .. elem.name .. attrs_str .. '>' .. children_str .. '</' .. elem.name .. '>'
+end
+
+function html.raw(value)
+ return { raw = true, value = value };
+end
+
+html.div = html.create_el('div')
+html.span = html.create_el('span')
+html.button = html.create_el('button')
+html.style = html.create_el('style')
+html.a = html.create_el('a')
+
+function html.escape_string(str)
+ str = str:gsub('&', '&amp;')
+ str = str:gsub('<', '&lt;')
+ str = str:gsub('>', '&gt;')
+ str = str:gsub('"', '&quot;')
+ str = str:gsub("'", '&apos;')
+ return str
+end
+
+return html
diff --git a/lua/null-browser/extras/statusline.lua b/lua/null-browser/extras/statusline.lua
index 33a0220..6dd70ba 100644
--- a/lua/null-browser/extras/statusline.lua
+++ b/lua/null-browser/extras/statusline.lua
@@ -1,3 +1,4 @@
+local html = require 'null-browser.extras.html'
local statusline = {}
local mode_labels = { n = 'NORMAL', i = 'INSERT' }
@@ -28,7 +29,15 @@ function statusline.show_status_in_window(win_id, decoration)
web.view.set_html(statusline.html(), { view = view })
end
- web.schedule(function() show_statusline() end)
+ web.schedule(function()
+ local view = decoration.view({ win = win_id })
+ -- FIXME: web.schedule doesn't guarantee that view will be available
+ if not view then
+ web.schedule(function() show_statusline() end)
+ else
+ show_statusline()
+ end
+ end)
web.event.add_listener({ 'ModeChanged', 'UrlChanged' }, {
callback = function(_) show_statusline() end,
})
@@ -52,40 +61,48 @@ end
function statusline.html()
local mode = web.keymap.get_mode()
local url = statusline.current_url()
- local mode_label = mode_labels[mode] or mode
- local styles = '<style>' .. statusline.css() .. '</style>'
- local mode_style = mode_styles[mode] or ''
- local html = '<div class="statusline">' ..
- '<div class="mode" style="' .. mode_style .. '">' .. mode_label .. '</div>' ..
- '<div class="url">' .. url .. '</div>' ..
- '</div>'
- return styles .. html
+ local html_elem = html.div({}, {
+ html.style({}, { html.raw(statusline.css()) }),
+ html.div({ class = 'statusline' }, {
+ html.div({ class = 'mode', style = mode_styles[mode] or '' }, {
+ mode_labels[mode] or mode,
+ }),
+ html.div({ class = 'url' }, { url }),
+ })
+ })
+ return html.to_string(html_elem)
end
function statusline.css()
return [[
- .statusline {
- width: 100%;
- height: 100vh;
- display: flex;
- justify-content: space-between;
- align-items: stretch;
- background-color: #000;
- }
- .mode {
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 0 8px;
- font-weight: bold;
- background-color: #888;
- }
- .url {
- display: flex;
- justify-content: flex-end;
- align-items: center;
- padding: 0 8px;
- }
+ html, body {
+ background: #000;
+ }
+ .statusline {
+ width: 100%;
+ height: 100vh;
+ display: flex;
+ justify-content: space-between;
+ align-items: stretch;
+ }
+ .mode {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 0 8px;
+ font-weight: bold;
+ background-color: #888;
+ }
+ .url {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ padding: 0 8px;
+ max-width: 50vw;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ text-wrap: nowrap;
+ }
]]
end
diff --git a/lua/null-browser/extras/tabline.lua b/lua/null-browser/extras/tabline.lua
index 42612e9..4548207 100644
--- a/lua/null-browser/extras/tabline.lua
+++ b/lua/null-browser/extras/tabline.lua
@@ -1,3 +1,4 @@
+local html = require 'null-browser.extras.html'
local tabline = {}
-- TODO: vertical tabs
@@ -42,19 +43,23 @@ function tabline.show_tabs_in_window(win_id, decoration)
end
function tabline.tabs_html()
- local views_html = ''
+ local tab_list = {}
for index, view in ipairs(web.view.list()) do
- -- TODO: Sanitize this stuff
- local text = index .. ': ' .. view.title .. ' (' .. view.url .. ')'
- local classes = 'tab'
- if web.view.current() == view.id then classes = classes .. ' current' end
- local onclick = '__nullbrowser.tab_select({ view: ' .. view.id .. ' })'
- local html = '<button class="' .. classes .. '" onclick="' .. onclick .. '">' .. text .. '</button>'
- views_html = views_html .. html
+ local tab = html.button({
+ class = 'tab' .. (web.view.current() == view.id and ' current' or ''),
+ onclick = '__nullbrowser.tab_select({ view: ' .. view.id .. ' })',
+ }, {
+ index .. ': ' .. view.title .. ' (' .. view.url .. ')',
+ })
+ table.insert(tab_list, tab)
end
- return '<style>' .. tabline.css() .. '</style>' ..
- '<div class="tabs">' .. views_html .. '</div>'
+ local tabs_html = html.div({}, {
+ html.style({}, { html.raw(tabline.css()) }),
+ html.div({ class = 'tabs' }, tab_list)
+ })
+
+ return html.to_string(tabs_html)
end
function tabline.css()
@@ -76,12 +81,15 @@ function tabline.css()
text-wrap: nowrap;
text-align: left;
min-width: 0;
- border-left: 1px solid white;
vertical-align: middle;
padding: 0 8px;
+ border-left: 1px solid #555;
+ }
+ .tab:first-child {
+ border: none;
}
.tab.current {
- background: #333;
+ background: #007070;
}
]]
end