diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2024-02-28 16:36:02 -0700 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-03-02 03:29:52 +0000 |
commit | d91d5d3abe64c61d157a1d7456ef622ac759cfd3 (patch) | |
tree | 98cd5364891daf95f9d3ffc9d69224eb888c3a24 | |
parent | b8ed5def06efc1af6cb9d50af6712572e738c99b (diff) |
QTextHtmlImporter: don't forget to appendBlock after block tag closed
If we see a closing tag that really demands a new block after it,
like </ul>, that needs to be done even if some ignorable whitespace
and "inline" tags come after it. Don't get distracted by those.
Also add a comment in QTextDocument::setHtml() to remind the reader that
HTML parsing is a two-pass algorithm.
Fixes: QTBUG-81662
Change-Id: If723c9d3c211a684725055a06bcf87be4e38923a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit 60aeeb0e92762d57c208e4212374d30be6490611)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit f0713117d6d0b77c5903ffe9ce3a7d5317021691)
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentfragment.cpp | 4 | ||||
-rw-r--r-- | tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp | 22 |
3 files changed, 27 insertions, 1 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 44e9c79948..5ca32e5c4f 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1267,6 +1267,8 @@ void QTextDocument::setHtml(const QString &html) d->enableUndoRedo(false); d->beginEditBlock(); d->clear(); + // ctor calls parse() to build up QTextHtmlParser::nodes list + // then import() populates the QTextDocument from those QTextHtmlImporter(this, html, QTextHtmlImporter::ImportToDocument).import(); d->endEditBlock(); d->enableUndoRedo(previousState); diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index 9e99992929..5d3b1f7f1f 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -488,7 +488,8 @@ void QTextHtmlImporter::import() * means there was a tag closing in the input html */ if (currentNodeIdx > 0 && (currentNode->parent != currentNodeIdx - 1)) { - blockTagClosed = closeTag(); + const bool lastBlockTagClosed = closeTag(); + blockTagClosed = blockTagClosed || lastBlockTagClosed; // visually collapse subsequent block tags, but if the element after the closed block tag // is for example an inline element (!isBlock) we have to make sure we start a new paragraph by setting // hasBlock to false. @@ -540,6 +541,7 @@ void QTextHtmlImporter::import() appendBlock(block, currentNode->charFormat); + blockTagClosed = false; hasBlock = true; } diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp index ca23c56b3e..425b22f335 100644 --- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp +++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp @@ -16,6 +16,8 @@ #include <qtextcursor.h> +using namespace Qt::StringLiterals; + QT_FORWARD_DECLARE_CLASS(QTextDocument) class tst_QTextDocumentFragment : public QObject @@ -245,6 +247,7 @@ private slots: void html_fromFirefox(); void html_emptyInlineInsideBlock(); void css_fontAndWordSpacing(); + void html_brWithWhitespaceAfterList(); private: inline void setHtml(const QString &html) @@ -4320,5 +4323,24 @@ void tst_QTextDocumentFragment::css_fontAndWordSpacing() } } +void tst_QTextDocumentFragment::html_brWithWhitespaceAfterList() // QTBUG-81662 +{ + setHtml(QString::fromLatin1("<ul><li>one</li><li>two</li></ul>\n <br/>\nhello")); + + QCOMPARE(doc->blockCount(), 3); + + QTextBlock block = doc->begin(); + QVERIFY(block.textList()); + + block = block.next(); + QVERIFY(block.textList()); + + block = block.next(); + QCOMPARE(block.text(), u"\u2028hello"_s); + + block = block.next(); + QVERIFY(block.text().isEmpty()); +} + QTEST_MAIN(tst_QTextDocumentFragment) #include "tst_qtextdocumentfragment.moc" |