~sql в пузыре кодоблока, кликабельные имена и пути
- renderSqlBlock: та же рамка что у кода (Telegram-пузырь), таблица светлым по тёмно-синему, кнопка копирования запроса - Имя файла (title) — ссылка flora://open (новая вкладка рядом); путь — ссылка flora://copycode/spath_N (клик копирует путь) - Database::filePathForTitle: резолв имени в путь (пусто при отсутствии/неоднозначности) - Тесты пузыря, open/copy ссылок и резолва
This commit is contained in:
+49
-5
@@ -4,6 +4,7 @@
|
||||
#include <QTemporaryDir>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QUrl>
|
||||
#include <cstdio>
|
||||
|
||||
#include "core/Frontmatter.h"
|
||||
@@ -193,9 +194,11 @@ int main(int argc, char *argv[])
|
||||
if (blocks[1].toMap().value("type").toString() != "html")
|
||||
return fail("sql type", blocks[1].toMap().value("type").toString());
|
||||
const QString html = blocks[1].toMap().value("html").toString();
|
||||
// title = имя файла без расширения
|
||||
if (!html.contains("<table") || !html.contains(">a</td>") || !html.contains(">b</td>"))
|
||||
// title = имя файла без расширения; пузырь кодоблока; имена — ссылки
|
||||
if (!html.contains("<table") || !html.contains(">a</a>") || !html.contains(">b</a>"))
|
||||
return fail("sql table", html.left(300));
|
||||
if (!html.contains("#2e4d6a"))
|
||||
return fail("sql bubble", html.left(200));
|
||||
// plain render тоже таблицей
|
||||
const QString h = p.render("```~sql\nSELECT title FROM files\n```\n", vault, vault);
|
||||
if (!h.contains("<table"))
|
||||
@@ -316,16 +319,57 @@ int main(int argc, char *argv[])
|
||||
if (r.value("rows").toList().value(0).toList().value(0).toString() != "0")
|
||||
return fail("isolate c");
|
||||
}
|
||||
// ~sql внутри index.md видит другие файлы (и не видит изолят)
|
||||
// filePathForTitle: точное имя → путь, нет/несколько → пусто
|
||||
{
|
||||
if (db2.filePathForTitle("a") != v2 + "/a.md")
|
||||
return fail("title lookup", db2.filePathForTitle("a"));
|
||||
if (!db2.filePathForTitle("нет-такого").isEmpty())
|
||||
return fail("title missing");
|
||||
}
|
||||
// ~sql внутри index.md видит другие файлы (и не видит изолят).
|
||||
// Имена — ссылки flora://open, пути — flora://copycode (клик = в буфер).
|
||||
{
|
||||
MdParser p;
|
||||
p.setDatabaseForVault(v2, &db2);
|
||||
const QVariantList blocks = p.parseBlocks(
|
||||
"```~sql\nSELECT title, path FROM files WHERE title IN ('a','b','c') ORDER BY title\n```\n",
|
||||
v2, v2);
|
||||
if (blocks.size() != 1 || blocks[0].toMap().value("type").toString() != "html")
|
||||
return fail("xfile type");
|
||||
const QString h = blocks[0].toMap().value("html").toString();
|
||||
if (!h.contains("#2e4d6a"))
|
||||
return fail("xfile bubble", h.left(200));
|
||||
// имя a открывает файл
|
||||
const QString openA = "flora://open/" + QString::fromLatin1(QUrl::toPercentEncoding(v2 + "/a.md"));
|
||||
if (!h.contains(openA))
|
||||
return fail("xfile open link", h.left(500));
|
||||
// путь a копируется (spath_* зарегистрирован)
|
||||
if (!h.contains("flora://copycode/spath_"))
|
||||
return fail("xfile copy link", h.left(500));
|
||||
if (p.getCodeBlock("spath_0") != v2 + "/a.md"
|
||||
&& p.getCodeBlock("spath_1") != v2 + "/a.md"
|
||||
&& p.getCodeBlock("spath_2") != v2 + "/a.md")
|
||||
return fail("xfile copy target");
|
||||
// изолят c тоже в выдаче (запрос его выбрал), но имя так же кликабельно
|
||||
if (!h.contains(">c</a>"))
|
||||
return fail("xfile c link", h.left(500));
|
||||
// title без path в строке резолвится через базу
|
||||
const QVariantList b2 = p.parseBlocks("```~sql\nSELECT title FROM files WHERE title='b'\n```\n", v2, v2);
|
||||
const QString h2 = b2[0].toMap().value("html").toString();
|
||||
const QString openB = "flora://open/" + QString::fromLatin1(QUrl::toPercentEncoding(v2 + "/b.md"));
|
||||
if (!h2.contains(openB))
|
||||
return fail("xfile title lookup", h2.left(500));
|
||||
}
|
||||
// Рендер index.md целиком: таблица есть, изолята нет, шапки нет
|
||||
{
|
||||
MdParser p;
|
||||
p.setDatabaseForVault(v2, &db2);
|
||||
QFile f(v2 + "/index.md");
|
||||
f.open(QIODevice::ReadOnly);
|
||||
const QString h = p.render(QString::fromUtf8(f.readAll()), v2, v2);
|
||||
if (!h.contains(">a</td>") || !h.contains(">b</td>"))
|
||||
if (!h.contains(">a</a>") || !h.contains(">b</a>"))
|
||||
return fail("xfile table", h.left(300));
|
||||
if (h.contains(">c</td>"))
|
||||
if (h.contains(">c</td>") || h.contains(">c</a>"))
|
||||
return fail("xfile leak isolate");
|
||||
if (h.contains("тип: хаб"))
|
||||
return fail("xfile fm leak");
|
||||
|
||||
Reference in New Issue
Block a user