diff options
| -rw-r--r-- | TODO.org | 8 | ||||
| -rw-r--r-- | doc/symbols.json | 1 | ||||
| -rw-r--r-- | init.lua | 9 | ||||
| -rw-r--r-- | ldoc_json_filter.lua | 37 | ||||
| -rw-r--r-- | lua/null-browser/api.lua | 27 | ||||
| -rw-r--r-- | src/schemes/NullSchemeHandler.cpp | 46 | ||||
| -rw-r--r-- | src/schemes/NullSchemeHandler.hpp | 30 | ||||
| -rw-r--r-- | src/schemes/schemes.hpp | 13 | ||||
| -rw-r--r-- | src/widgets/BrowserApp.cpp | 2 |
9 files changed, 169 insertions, 4 deletions
@@ -14,12 +14,13 @@ - [X] Callback for result of run_js - [X] Generate docs for api - [X] Any hint action/generic (currently only url open) +- [X] Embed docs in app (`null:/docs`) +- [X] web.decorations.*.set_size() +- [X] Vertical tabline ui - [ ] Document events and event opts -- [ ] Embed docs in app (`null:/docs`) - [ ] Update all api to use opts table pattern -- [X] web.decorations.*.set_size() +- [ ] Install doc/ in build - [ ] web.keymap.configure_mode(modename, { passthrough = false }) -- [X] Vertical tabline ui - [ ] Fullscreen - [ ] Zoom in/out/reset - [ ] Remove unwanted "async"-ness in lua calls @@ -28,6 +29,7 @@ - [ ] json encode/decode ** Bugs +- [ ] Closing webview should close devtools window - [ ] INVESTIGATE: Check why urlchanged doesnt fire for first url open sometimes - [ ] INVESTIGATE: Segfault on close sometimes - [ ] API's don't validate types. (invalid type conversion segfaults) diff --git a/doc/symbols.json b/doc/symbols.json new file mode 100644 index 0000000..8766314 --- /dev/null +++ b/doc/symbols.json @@ -0,0 +1 @@ +["_G.__internals","schedule","web.keymap.set","web.keymap.set_mode","web.keymap.get_mode","web.view.close","web.view.create","web.view.current","web.view.list","web.view.select","web.view.set_url","web.view.set_html","web.view.run_js","web.view.reload","web.view.expose","web.view.open_devtools","web.view.current_index","web.event.add_listener","set","get","WebOpts","opts","web.history.back","web.history.forward","web.search.set_text","web.search.reset","web.search.get_text","web.search.next","web.search.previous","web.view.scroll","web.view.scroll_to_top","web.view.scroll_to_bottom","uv","inspect","web.utils.string_trim","web.utils.table_merge","web.utils.table_keys","web.utils.equals","web.utils.table_contains"]
\ No newline at end of file @@ -64,6 +64,15 @@ require 'null-browser.extras.statusline'.init { decoration = web.decorations.bottom, } + +web.keymap.set('n', '<c-h>', function() + local symbols = web.help.get_items() + menu:select(symbols, { select_last_line = true }, function(err, selection) + if err then return end + web.help.show(web.utils.string_trim(selection)) + end) +end) + local hints = require 'null-browser.extras.hints' hints.init() web.keymap.set('n', 'f', function() hints.start('a[href], button', hints.action.open_in_view) end) diff --git a/ldoc_json_filter.lua b/ldoc_json_filter.lua new file mode 100644 index 0000000..33141cb --- /dev/null +++ b/ldoc_json_filter.lua @@ -0,0 +1,37 @@ +local function get_labels(items) + local labels = {} + for _, item in ipairs(items) do + if item.items then + for _, label in ipairs(get_labels(item.items)) do + table.insert(labels, label) + end + else + local label = table.concat(item.names_hierarchy, '.') + table.insert(labels, label) + end + end + return labels +end + +local function get_dir() + local dir = './doc' + for index, a in ipairs(arg) do + if a == '--dir' or a == '-d' then + dir = arg[index + 1] + end + end + return dir +end + +return { + lua = function(doc) + local labels = get_labels(doc) + local file_path = get_dir() .. '/symbols.json' + local file, _ = io.open(file_path, 'w+') + if file then + local symbols = require 'dkjson'.encode(labels, { indent = true }) + assert(file:write(symbols)) + end + return false + end, +} diff --git a/lua/null-browser/api.lua b/lua/null-browser/api.lua index 4054895..4da1124 100644 --- a/lua/null-browser/api.lua +++ b/lua/null-browser/api.lua @@ -12,6 +12,7 @@ web.view = web.view or {} web.history = web.history or {} web.event = web.event or {} web.decorations = web.decorations or {} +web.help = web.help or {} require 'null-browser.utils' @@ -357,3 +358,29 @@ web.decorations.top = create_decoration_api('top') web.decorations.bottom = create_decoration_api('bottom') web.decorations.left = create_decoration_api('left') web.decorations.right = create_decoration_api('right') + +--- Get a list of items for help +function web.help.get_items() + -- TODO: Use proper path from build + local file, _ = io.open('./doc/symbols.json', 'r') + if file then + local contents, _ = file:read('a') + return web.json.decode(contents) + end + return {} +end + +--- Open help docs for a given item +--- +--- @param item string? +--- @param opts table? +--- @param opts.view number? +function web.help.show(item, opts) + opts = opts or {} + local url = 'null://docs/api#' .. (item or '') + if opts.view ~= nil then + web.view.set_url(url, opts.view) + else + web.view.create(url) + end +end diff --git a/src/schemes/NullSchemeHandler.cpp b/src/schemes/NullSchemeHandler.cpp new file mode 100644 index 0000000..203e673 --- /dev/null +++ b/src/schemes/NullSchemeHandler.cpp @@ -0,0 +1,46 @@ +#include "NullSchemeHandler.hpp" +#include <qstringview.h> +#include <qwebengineurlrequestjob.h> + +void NullSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job) { + auto url = job->requestUrl(); + + if (url.host() == "docs") { + QBuffer *buffer = new QBuffer(job); + buffer->setData(read_static_docs_file(url.path())); + buffer->open(QIODevice::ReadOnly); + job->reply(get_content_type(url.path()), buffer); + } else { + job->reply("text/html", new QBuffer(job)); + } +} + +QByteArray NullSchemeHandler::read_static_docs_file(const QString &path) { + QFile file(NULL_DOCS_DIR + path); + if (!file.exists()) + return read_index_html(); + + if (file.open(QIODevice::ReadOnly)) { + auto contents = file.readAll(); + file.close(); + return contents; + } + return QByteArray{}; +} + +QByteArray NullSchemeHandler::read_index_html() { + QFile file(NULL_DOCS_DIR + QString("/index.html")); + qDebug() << ":::" << file.exists(); + if (file.open(QIODevice::ReadOnly)) { + auto contents = file.readAll(); + file.close(); + return contents; + } + return QByteArray{}; +} + +QByteArray NullSchemeHandler::get_content_type(const QString &path) { + if (path.endsWith(".css")) + return "text/css"; + return "text/html"; +} diff --git a/src/schemes/NullSchemeHandler.hpp b/src/schemes/NullSchemeHandler.hpp new file mode 100644 index 0000000..bc05076 --- /dev/null +++ b/src/schemes/NullSchemeHandler.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include <QWebEngineUrlRequestJob> +#include <QWebEngineUrlSchemeHandler> +#include <QtCore> +#include <qcontainerfwd.h> +#include <qdebug.h> +#include <qurlquery.h> + +// TODO: Install doc dir and pass this path during build +#define NULL_DOCS_DIR "./doc" + +class NullSchemeHandler : public QWebEngineUrlSchemeHandler { + Q_OBJECT + +public: + static NullSchemeHandler &instance() { + static NullSchemeHandler handler; + return handler; + } + + void requestStarted(QWebEngineUrlRequestJob *job) override; + +private: + NullSchemeHandler() = default; + + QByteArray read_static_docs_file(const QString &path); + QByteArray read_index_html(); + QByteArray get_content_type(const QString &path); +}; diff --git a/src/schemes/schemes.hpp b/src/schemes/schemes.hpp index f33d74b..439519c 100644 --- a/src/schemes/schemes.hpp +++ b/src/schemes/schemes.hpp @@ -13,4 +13,15 @@ void register_nullrpc_scheme() { QWebEngineUrlScheme::registerScheme(scheme); } -void register_all_schemes() { register_nullrpc_scheme(); } +void register_null_scheme() { + QWebEngineUrlScheme scheme("null"); + scheme.setSyntax(QWebEngineUrlScheme::Syntax::Host); + scheme.setFlags(QWebEngineUrlScheme::SecureScheme | QWebEngineUrlScheme::LocalScheme | + QWebEngineUrlScheme::LocalAccessAllowed); + QWebEngineUrlScheme::registerScheme(scheme); +} + +void register_all_schemes() { + register_nullrpc_scheme(); + register_null_scheme(); +} diff --git a/src/widgets/BrowserApp.cpp b/src/widgets/BrowserApp.cpp index c3c2313..e57b923 100644 --- a/src/widgets/BrowserApp.cpp +++ b/src/widgets/BrowserApp.cpp @@ -8,6 +8,7 @@ #include "events/NotificationReceivedEvent.hpp" #include "events/WinCreatedEvent.hpp" #include "schemes/NullRpcSchemeHandler.hpp" +#include "schemes/NullSchemeHandler.hpp" #include "widgets/BrowserWindow.hpp" #include "widgets/BrowserApp.hpp" @@ -59,6 +60,7 @@ void BrowserApp::setup_profile(QWebEngineProfile *profile) { }); profile->setPersistentPermissionsPolicy(configuration.permission_persistance_policy()); profile->installUrlSchemeHandler("nullrpc", &NullRPCSchemeHandler::instance()); + profile->installUrlSchemeHandler("null", &NullSchemeHandler::instance()); } BrowserWindow *BrowserApp::create_window(const QStringList &urls) { |
