|
54 | 54 | #include "feedlistwidget.h"
|
55 | 55 | #include "ui_rsswidget.h"
|
56 | 56 |
|
| 57 | +namespace |
| 58 | +{ |
| 59 | + void convertRelativeUrlToAbsolute(QString &html, const QString &baseUrl) |
| 60 | + { |
| 61 | + const QRegularExpression rx {uR"(((<a\s+[^>]*?href|<img\s+[^>]*?src)\s*=\s*["'])((https?|ftp):)?(\/\/[^\/]*)?(\/?[^\/"].*?)(["']))"_s |
| 62 | + , QRegularExpression::CaseInsensitiveOption}; |
| 63 | + |
| 64 | + const QString normalizedBaseUrl = baseUrl.endsWith(u'/') ? baseUrl : (baseUrl + u'/'); |
| 65 | + const QUrl url {normalizedBaseUrl}; |
| 66 | + const QString defaultScheme = url.scheme(); |
| 67 | + QRegularExpressionMatchIterator iter = rx.globalMatch(html); |
| 68 | + |
| 69 | + while (iter.hasNext()) |
| 70 | + { |
| 71 | + const QRegularExpressionMatch match = iter.next(); |
| 72 | + const QString scheme = match.captured(4); |
| 73 | + const QString host = match.captured(5); |
| 74 | + if (!scheme.isEmpty()) |
| 75 | + { |
| 76 | + if (host.isEmpty()) |
| 77 | + break; // invalid URL, should never happen |
| 78 | + |
| 79 | + // already absolute URL |
| 80 | + continue; |
| 81 | + } |
| 82 | + |
| 83 | + QString relativePath = match.captured(6); |
| 84 | + if (relativePath.startsWith(u'/')) |
| 85 | + relativePath = relativePath.mid(1); |
| 86 | + |
| 87 | + const QString absoluteUrl = !host.isEmpty() |
| 88 | + ? QString(defaultScheme + u':' + host) : (normalizedBaseUrl + relativePath); |
| 89 | + const QString fullMatch = match.captured(0); |
| 90 | + const QString prefix = match.captured(1); |
| 91 | + const QString suffix = match.captured(7); |
| 92 | + |
| 93 | + html.replace(fullMatch, (prefix + absoluteUrl + suffix)); |
| 94 | + } |
| 95 | + } |
| 96 | +} |
| 97 | + |
| 98 | + |
57 | 99 | RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
|
58 | 100 | : GUIApplicationComponent(app, parent)
|
59 | 101 | , m_ui {new Ui::RSSWidget}
|
@@ -605,6 +647,11 @@ void RSSWidget::renderArticle(const RSS::Article *article) const
|
605 | 647 |
|
606 | 648 | html += u"<pre>" + description + u"</pre>";
|
607 | 649 | }
|
| 650 | + |
| 651 | + // Supplement relative URLs to absolute ones |
| 652 | + const QUrl url {article->link()}; |
| 653 | + const QString baseUrl = url.toString(QUrl::RemovePath | QUrl::RemoveQuery); |
| 654 | + convertRelativeUrlToAbsolute(html, baseUrl); |
608 | 655 | html += u"</div>";
|
609 | 656 | m_ui->textBrowser->setHtml(html);
|
610 | 657 | }
|
0 commit comments