Use CSS classes on html list items for checkbox support
If we replace the bullet character with a UC checkbox character, it looks ok in a browser, and the HTML parser can recover the BlockMarker attribute from the css class. [ChangeLog][QtGui][Text] Checkbox list items can now be read and written in both HTML and Markdown, including conversions. Task-number: QTBUG-103714 Change-Id: Ic6b74512075cd4ac16d6f80fdf55b221447491a9 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit eee9d252028c4b3b743c77a406cd6939eda3962f) Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
91cb059e3d
commit
e58a29bdae
@ -2372,6 +2372,8 @@ QString QTextHtmlExporter::toHtml(ExportMode mode)
|
||||
html += "<style type=\"text/css\">\n"_L1;
|
||||
html += "p, li { white-space: pre-wrap; }\n"_L1;
|
||||
html += "hr { height: 1px; border-width: 0; }\n"_L1;
|
||||
html += "li.unchecked::marker { content: \"\\2610\"; }\n"_L1;
|
||||
html += "li.checked::marker { content: \"\\2612\"; }\n"_L1;
|
||||
html += "</style>"_L1;
|
||||
html += "</head><body"_L1;
|
||||
|
||||
@ -3038,7 +3040,7 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
|
||||
|
||||
html += " style=\""_L1;
|
||||
html += styleString;
|
||||
html += "\">"_L1;
|
||||
html += "\">\n"_L1;
|
||||
}
|
||||
|
||||
html += "<li"_L1;
|
||||
@ -3051,6 +3053,18 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
|
||||
|
||||
defaultCharFormat.merge(block.charFormat());
|
||||
}
|
||||
if (block.blockFormat().hasProperty(QTextFormat::BlockMarker)) {
|
||||
switch (block.blockFormat().marker()) {
|
||||
case QTextBlockFormat::MarkerType::Checked:
|
||||
html += " class=\"checked\""_L1;
|
||||
break;
|
||||
case QTextBlockFormat::MarkerType::Unchecked:
|
||||
html += " class=\"unchecked\""_L1;
|
||||
break;
|
||||
case QTextBlockFormat::MarkerType::NoMarker:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QTextBlockFormat blockFormat = block.blockFormat();
|
||||
|
@ -1636,6 +1636,14 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Html_li:
|
||||
if (key == "class"_L1) {
|
||||
if (value == "unchecked"_L1)
|
||||
node->blockFormat.setMarker(QTextBlockFormat::MarkerType::Unchecked);
|
||||
else if (value == "checked"_L1)
|
||||
node->blockFormat.setMarker(QTextBlockFormat::MarkerType::Checked);
|
||||
}
|
||||
break;
|
||||
case Html_a:
|
||||
if (key == "href"_L1)
|
||||
node->charFormat.setAnchorHref(value);
|
||||
|
@ -274,6 +274,8 @@ void tst_QTextDocument::init()
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"hr { height: 1px; border-width: 0; }\n"
|
||||
"li.unchecked::marker { content: \"\\2610\"; }\n"
|
||||
"li.checked::marker { content: \"\\2612\"; }\n"
|
||||
"</style></head>"
|
||||
"<body style=\" font-family:'%1'; font-size:%2; font-weight:%3; font-style:%4;\">\n");
|
||||
htmlHead = htmlHead.arg(defaultFont.family())
|
||||
@ -1371,7 +1373,7 @@ void tst_QTextDocument::toHtml_data()
|
||||
QTest::newRow("lists") << QTextDocumentFragment(&doc)
|
||||
<<
|
||||
QString("EMPTYBLOCK") +
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\"><li DEFAULTBLOCKSTYLE>Blubb</li>\n<li DEFAULTBLOCKSTYLE>Blah</li></ul>");
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\">\n<li DEFAULTBLOCKSTYLE>Blubb</li>\n<li DEFAULTBLOCKSTYLE>Blah</li></ul>");
|
||||
}
|
||||
|
||||
{
|
||||
@ -1394,7 +1396,7 @@ void tst_QTextDocument::toHtml_data()
|
||||
QTest::newRow("charfmt-for-list-item") << QTextDocumentFragment(&doc)
|
||||
<<
|
||||
QString("EMPTYBLOCK") +
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\"><li DEFAULTBLOCKSTYLE>Blubb</li>\n<li style=\" color:#0000ff;\" DEFAULTBLOCKSTYLE><span style=\" color:#ff0000;\">Blah</span></li></ul>");
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\">\n<li DEFAULTBLOCKSTYLE>Blubb</li>\n<li style=\" color:#0000ff;\" DEFAULTBLOCKSTYLE><span style=\" color:#ff0000;\">Blah</span></li></ul>");
|
||||
}
|
||||
|
||||
{
|
||||
@ -1424,7 +1426,7 @@ void tst_QTextDocument::toHtml_data()
|
||||
QTest::newRow("list-indent") << QTextDocumentFragment(&doc)
|
||||
<<
|
||||
QString("EMPTYBLOCK") +
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 4;\"><li DEFAULTBLOCKSTYLE>Blah</li></ul>");
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 4;\">\n<li DEFAULTBLOCKSTYLE>Blah</li></ul>");
|
||||
}
|
||||
|
||||
{
|
||||
@ -1712,7 +1714,7 @@ void tst_QTextDocument::toHtml_data()
|
||||
|
||||
QTest::newRow("list-ul-margin") << QTextDocumentFragment(&doc)
|
||||
<< QString("EMPTYBLOCK") +
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\"><li DEFAULTBLOCKSTYLE>Blah</li></ul>");
|
||||
QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\">\n<li DEFAULTBLOCKSTYLE>Blah</li></ul>");
|
||||
}
|
||||
{
|
||||
CREATE_DOC_AND_CURSOR();
|
||||
@ -1722,12 +1724,12 @@ void tst_QTextDocument::toHtml_data()
|
||||
cursor.insertHtml(listHtml);
|
||||
|
||||
QTest::newRow("nested-lists-one") << QTextDocumentFragment(&doc)
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\"><li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\">\n<li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
|
||||
"item-1</li>\n<li DEFAULTBLOCKSTYLE>item-2\n<ul DEFAULTULSTYLE 2;\"><li "
|
||||
"item-1</li>\n<li DEFAULTBLOCKSTYLE>item-2\n<ul DEFAULTULSTYLE 2;\">\n<li "
|
||||
"DEFAULTBLOCKSTYLE>item-2.1</li>\n<li DEFAULTBLOCKSTYLE>item-2.2\n<ul "
|
||||
"DEFAULTULSTYLE 3;\"><li DEFAULTBLOCKSTYLE>item-2.2.1</li></ul></li>\n"
|
||||
"<li DEFAULTBLOCKSTYLE>item-2.3\n<ul DEFAULTULSTYLE 3;\"><li DEFAULTBLOCKSTYLE>"
|
||||
"DEFAULTULSTYLE 3;\">\n<li DEFAULTBLOCKSTYLE>item-2.2.1</li></ul></li>\n"
|
||||
"<li DEFAULTBLOCKSTYLE>item-2.3\n<ul DEFAULTULSTYLE 3;\">\n<li DEFAULTBLOCKSTYLE>"
|
||||
"item-2.3.1</li></ul></li></ul></li>\n<li DEFAULTLASTLISTYLE>item-3</li></ul>");
|
||||
}
|
||||
{
|
||||
@ -1736,9 +1738,9 @@ void tst_QTextDocument::toHtml_data()
|
||||
cursor.insertHtml(listHtml);
|
||||
|
||||
QTest::newRow("nested-lists-two") << QTextDocumentFragment(&doc)
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\"><li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\">\n<li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
|
||||
"item-1</li>\n<li DEFAULTLASTLISTYLE>item-2\n<ul DEFAULTULSTYLE 2;\"><li "
|
||||
"item-1</li>\n<li DEFAULTLASTLISTYLE>item-2\n<ul DEFAULTULSTYLE 2;\">\n<li "
|
||||
"DEFAULTBLOCKSTYLE>item-2.1</li></ul></li></ul>");
|
||||
}
|
||||
{
|
||||
@ -1748,9 +1750,9 @@ void tst_QTextDocument::toHtml_data()
|
||||
cursor.insertHtml(listHtml);
|
||||
|
||||
QTest::newRow("nested-lists-three") << QTextDocumentFragment(&doc)
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\"><li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\">\n<li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
|
||||
"item-1</li>\n<li DEFAULTLASTLISTYLE>item-2\n<ul DEFAULTULSTYLE 2;\"><li "
|
||||
"item-1</li>\n<li DEFAULTLASTLISTYLE>item-2\n<ul DEFAULTULSTYLE 2;\">\n<li "
|
||||
"DEFAULTBLOCKSTYLE>item-2.1</li>\n<li DEFAULTBLOCKSTYLE>item-2.2</li></ul>"
|
||||
"</li></ul>");
|
||||
}
|
||||
@ -1761,12 +1763,23 @@ void tst_QTextDocument::toHtml_data()
|
||||
cursor.insertHtml(listHtml);
|
||||
|
||||
QTest::newRow("not-nested-list") << QTextDocumentFragment(&doc)
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\"><li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
<< QString("<ul DEFAULTULSTYLE 1;\">\n<li style=\" margin-top:12px; margin-bottom:0px; "
|
||||
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
|
||||
"item-1.1</li>\n<li DEFAULTBLOCKSTYLE>item-1.2</li></ul>\n<ul DEFAULTULSTYLE 1;\">"
|
||||
"item-1.1</li>\n<li DEFAULTBLOCKSTYLE>item-1.2</li></ul>\n<ul DEFAULTULSTYLE 1;\">\n"
|
||||
"<li style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; "
|
||||
"margin-right:0px; -qt-block-indent:0; text-indent:0px;\">item-2.1</li></ul>");
|
||||
}
|
||||
{
|
||||
CREATE_DOC_AND_CURSOR();
|
||||
const QString listHtml = "<ul><li>bullet</li><li class=\"unchecked\">unchecked item</li><li class=\"checked\">checked item</li></ul>";
|
||||
cursor.insertHtml(listHtml);
|
||||
|
||||
QTest::newRow("list with and without checkboxes") << QTextDocumentFragment(&doc)
|
||||
<< QString("<ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\">\n"
|
||||
"<li style=\" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">bullet</li>\n"
|
||||
"<li class=\"unchecked\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">unchecked item</li>\n"
|
||||
"<li class=\"checked\" style=\" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">checked item</li></ul>");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTextDocument::toHtml()
|
||||
|
@ -502,6 +502,9 @@ void tst_QTextMarkdownWriter::fromHtml_data()
|
||||
QTest::newRow("preformats with embedded backticks") <<
|
||||
"<pre>none `one` ``two``</pre>plain<pre>```three``` ````four````</pre>plain" <<
|
||||
"```\nnone `one` ``two``\n\n```\nplain\n\n```\n```three``` ````four````\n\n```\nplain\n\n";
|
||||
QTest::newRow("list items with and without checkboxes") <<
|
||||
"<ul><li>bullet</li><li class=\"unchecked\">unchecked item</li><li class=\"checked\">checked item</li></ul>" <<
|
||||
"- bullet\n- [ ] unchecked item\n- [x] checked item\n";
|
||||
}
|
||||
|
||||
void tst_QTextMarkdownWriter::fromHtml()
|
||||
|
Loading…
x
Reference in New Issue
Block a user