diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index b4824aeca..0c41c837a 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -7,9 +7,10 @@ body:
- type: markdown
attributes:
value: |
- Dear RSS Guard contributor, please RESPECT this template. You might be interested in reading [www.chiark.greenend.org.uk](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
- Also, ALWAYS, ALWAYS, ALWAYS attach DEBUG LOG to your bug report!!!
+ Dear RSS Guard contributor, ALWAYS, ALWAYS, ALWAYS attach DEBUG LOG to your bug report!!!
How to generate it see [here](https://github.com/martinrotter/rssguard/blob/master/resources/docs/Documentation.md#reprt).
+
+ Please, RESPECT this template. You might be interested in reading [www.chiark.greenend.org.uk](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
- type: textarea
attributes:
label: Brief description of the issue
@@ -39,10 +40,10 @@ body:
required: true
- type: textarea
attributes:
- label: Other information
- description: Write any other supplementary information here.
+ label: Debug log
+ description: Paste debug log contents here.
validations:
- required: false
+ required: true
- type: textarea
attributes:
label: Operating system and version
diff --git a/.github/workflows/rssguard.yml b/.github/workflows/rssguard.yml
index 1b9b1c0f5..322e6b891 100644
--- a/.github/workflows/rssguard.yml
+++ b/.github/workflows/rssguard.yml
@@ -3,7 +3,7 @@ name: rssguard
on:
push:
- branches: ["master", "version-4"]
+ branches: ["*"]
tags: ["*"]
jobs:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a4fb61bf5..82a00b962 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,7 +68,7 @@ set(APP_URL_ISSUES_NEW "https://github.com/martinrotter/rssguard/issues/new/choo
set(TYPEINFO "????")
-project(rssguard VERSION ${APP_VERSION} LANGUAGES CXX)
+project(rssguard VERSION ${APP_VERSION} LANGUAGES CXX C)
# Basic C++ related behavior of cmake.
set(CMAKE_CXX_STANDARD 17)
diff --git a/README.md b/README.md
index 4700354ef..34371fbc9 100644
--- a/README.md
+++ b/README.md
@@ -10,16 +10,14 @@ RSS Guard
### [Discord server](https://discord.gg/7xbVMPPNqH) | [Downloads](https://github.com/martinrotter/rssguard/releases) | [Development builds](https://github.com/martinrotter/rssguard/releases/tag/devbuild) | [Documentation](https://github.com/martinrotter/rssguard/blob/master/resources/docs/Documentation.md)
RSS Guard is simple RSS/ATOM feed reader for Windows, Linux, BSD, OS/2 or macOS which can work with RSS/ATOM/JSON feeds and also supports many online feed services:
-* [Tiny Tiny RSS](https://tt-rss.org),
-* [Inoreader](https://www.inoreader.com) (via Google Reader API plugin),
-* [Nextcloud News](https://apps.nextcloud.com/apps/news),
+* [Feedly](https://feedly.com),
* [Gmail](https://developers.google.com/gmail/api),
-* [FreshRSS](https://freshrss.org) (via Google Reader API plugin),
-* [The Old Reader](https://theoldreader.com) (via Google Reader API plugin),
-* [Bazqux](https://bazqux.com) (via Google Reader API plugin),
-* [Reedah](http://reedah.com) (via Google Reader API plugin),
-* [Feedly](https://feedly.com).
+* Google Reader API ([Bazqux](https://bazqux.com), [FreshRSS](https://freshrss.org), [Inoreader](https://www.inoreader.com), [Reedah](http://reedah.com), [The Old Reader](https://theoldreader.com) and others),
+* [Nextcloud News](https://apps.nextcloud.com/apps/news),
+* [Tiny Tiny RSS](https://tt-rss.org).

-Application icon was kindly contributed by Siddharth Yadav - @Siddharth_yd (Instagram), illustrationdesignsid@gmail.com (e-mail). Flag icons were provided by [IconDrawer](http://www.icondrawer.com).
+Contributed graphics:
+* RSS Guard logo - [Siddharth Yadav](mailto:illustrationdesignsid@gmail.com), [@Siddharth_yd](https://www.instagram.com/siddharth_yd/).
+* Flag icons - [IconDrawer](http://www.icondrawer.com).
diff --git a/localization/rssguard_de.ts b/localization/rssguard_de.ts
index c51f56260..d8d614b89 100644
--- a/localization/rssguard_de.ts
+++ b/localization/rssguard_de.ts
@@ -875,12 +875,12 @@ Status: %3
Feeds search box
-
+ Suchfeld für Feeds
Search feeds (regex only)
-
+ Feeds durchsuchen (nur Regex)
@@ -1103,7 +1103,7 @@ or this functionality is not implemented yet.
Database location
-
+ Speicherort der Datenbank
@@ -2375,7 +2375,7 @@ or this functionality is not implemented yet.
New article filter
-
+ Neuer Artikel-Filter
@@ -2421,7 +2421,7 @@ or this functionality is not implemented yet.
Article filters
-
+ Artikel-Filter
@@ -2457,7 +2457,7 @@ or this functionality is not implemented yet.
Title of article filter
-
+ Titel des Artikel-Filters
@@ -3564,7 +3564,7 @@ Ablauf des Login tokens: %2
Important articles
-
+ Wichtige Artikel
@@ -3786,7 +3786,7 @@ Ablauf des Login tokens: %2
Date
-
+ Datum
@@ -3884,7 +3884,7 @@ Ablauf des Login tokens: %2
Date
-
+ Datum
@@ -3939,7 +3939,7 @@ Ablauf des Login tokens: %2
Creation date of the article.
-
+ Erstellungsdatum des Artikels.
@@ -4062,7 +4062,7 @@ Ablauf des Login tokens: %2
Search articles (regex only)
-
+ Artikel durchsuchen (nur Regex)
diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml
index 265e13e2f..9edaf09d6 100644
--- a/resources/desktop/com.github.rssguard.appdata.xml
+++ b/resources/desktop/com.github.rssguard.appdata.xml
@@ -26,7 +26,7 @@
https://github.com/sponsors/martinrotter
-
+
none
diff --git a/resources/docs/Documentation.md b/resources/docs/Documentation.md
index 8649c1a9d..7ffdfb70b 100644
--- a/resources/docs/Documentation.md
+++ b/resources/docs/Documentation.md
@@ -426,18 +426,12 @@ RSS Guard stores its data and settings in single folder. What exact folder it is
### Built-in Web Browser with AdBlock
RSS Guard is distributed in two variants:
-* **Standard package with WebEngine-based bundled article viewer**: This variant displays messages/articles with their full formatting and layout in embedded Chromium-based web viewer. This variant of RSS Guard should be nice for everyone. Also, installation packages are relatively big.
+* **Standard package with WebEngine-based bundled article viewer**: This variant displays messages/articles with their full formatting and layout in embedded Chromium-based web browser. This variant of RSS Guard should be nice for everyone. Also, installation packages are relatively big.
-
-
-* **Lite package with simple text-based article viewer**: This variant displays message/article in much simpler and more lightweight text-based component. All packages of this variant have `nowebengine` keyword in their names. Layout and formatting of displayed message is simplified, no big external web viewers are used, which results in much smaller installation packages, much smaller memory footprint and increased privacy of the user, because many web resources are not downloaded by default like pictures, JavaScript and so on. This variant of RSS Guard is meant for advanced users.
-
-
-
-If you're not sure which version to use, **use the WebEngine-based RSS Guard**.
+* **Lite package with simple text-based article viewer**: This variant displays article in much simpler and much more lightweight web viewer component. All packages of this variant have `nowebengine` keyword in their names. This variant of RSS Guard uses [litehtml](https://github.com/litehtml/litehtml) to render HTML/CSS layout of your articles. This component does NOT include JavaScript and is meant to be here for people who value their privacy.
#### AdBlock
-[Web-based variant](#webb) of RSS Guard offers ad-blocking functionality via [Adblocker](https://github.com/cliqz-oss/adblocker). Adblocker offers similar performance to [uBlock Origin](https://github.com/gorhill/uBlock).
+Both variants of RSS Guard offer ad-blocking functionality via [Adblocker](https://github.com/cliqz-oss/adblocker). Adblocker offers similar performance to [uBlock Origin](https://github.com/gorhill/uBlock).
If you want to use AdBlock, you need to have [Node.js](#node) installed.
@@ -461,9 +455,9 @@ You can right click on any item in embedded web browser and hit `Save as` button
You can download up to 6 files simultaneously.
### Node.js
-RSS Guard integrates [`Node.js`](https://nodejs.org). Go to `Node.js` section of `Settings` dialog to see more.
+RSS Guard integrates [Node.js](https://nodejs.org). Go to `Node.js` section of `Settings` dialog to see more.
-`Node.js` is used for some advanced functionality like [AdBlock](#adbl).
+Node.js is used for some advanced functionality like [AdBlock](#adbl).
### Labels
diff --git a/resources/docs/images/nonwebengine-view.png b/resources/docs/images/nonwebengine-view.png
deleted file mode 100644
index 5cc04957e..000000000
Binary files a/resources/docs/images/nonwebengine-view.png and /dev/null differ
diff --git a/resources/docs/images/webengine-view.png b/resources/docs/images/webengine-view.png
deleted file mode 100644
index 517cae4d0..000000000
Binary files a/resources/docs/images/webengine-view.png and /dev/null differ
diff --git a/resources/icons.qrc b/resources/icons.qrc
index 8b4a8422e..db31a46ea 100644
--- a/resources/icons.qrc
+++ b/resources/icons.qrc
@@ -29,6 +29,7 @@
./graphics/Breeze/actions/32/edit-reset.svg
./graphics/Breeze/actions/22/edit-select-all.svg
./graphics/Breeze/actions/22/edit-select-none.svg
+ ./graphics/Breeze/emblems/22/emblem-favorite.svg
./graphics/Breeze/emblems/22/emblem-shared.svg
./graphics/Breeze/places/96/folder.svg
./graphics/Breeze/actions/22/format-indent-more.svg
@@ -49,6 +50,7 @@
./graphics/Breeze/actions/22/list-add.svg
./graphics/Breeze/actions/22/list-remove.svg
./graphics/Breeze/actions/32/mail-attachment.svg
+ ./graphics/Breeze/actions/32/mail-forward.svg
./graphics/Breeze/actions/symbolic/mail-inbox-symbolic.svg
./graphics/Breeze/actions/32/mail-mark-important.svg
./graphics/Breeze/actions/32/mail-mark-junk.svg
@@ -69,6 +71,7 @@
./graphics/Breeze/mimetypes/64/text-html.svg
./graphics/Breeze/places/96/user-trash.svg
./graphics/Breeze/actions/22/view-fullscreen.svg
+ ./graphics/Breeze/actions/22/viewimage.svg
./graphics/Breeze/actions/32/view-list-details.svg
./graphics/Breeze/actions/32/view-refresh.svg
./graphics/Breeze/actions/22/view-restore.svg
@@ -103,6 +106,7 @@
./graphics/Breeze Dark/actions/32/edit-reset.svg
./graphics/Breeze Dark/actions/22/edit-select-all.svg
./graphics/Breeze Dark/actions/22/edit-select-none.svg
+ ./graphics/Breeze Dark/emblems/22/emblem-favorite.svg
./graphics/Breeze Dark/emblems/22/emblem-shared.svg
./graphics/Breeze Dark/places/96/folder.svg
./graphics/Breeze Dark/actions/22/format-indent-more.svg
@@ -123,6 +127,7 @@
./graphics/Breeze Dark/actions/22/list-add.svg
./graphics/Breeze Dark/actions/22/list-remove.svg
./graphics/Breeze Dark/actions/32/mail-attachment.svg
+ ./graphics/Breeze Dark/actions/32/mail-forward.svg
./graphics/Breeze Dark/actions/symbolic/mail-inbox-symbolic.svg
./graphics/Breeze Dark/actions/32/mail-mark-important.svg
./graphics/Breeze Dark/actions/32/mail-mark-junk.svg
@@ -143,6 +148,7 @@
./graphics/Breeze Dark/mimetypes/64/text-html.svg
./graphics/Breeze Dark/places/96/user-trash.svg
./graphics/Breeze Dark/actions/22/view-fullscreen.svg
+ ./graphics/Breeze Dark/actions/22/viewimage.svg
./graphics/Breeze Dark/actions/32/view-list-details.svg
./graphics/Breeze Dark/actions/32/view-refresh.svg
./graphics/Breeze Dark/actions/22/view-restore.svg
@@ -174,6 +180,7 @@
./graphics/Faenza/actions/64/edit-copy.png
./graphics/Faenza/actions/64/edit-select-all.png
./graphics/Faenza/emblems/64/emblem-downloads.png
+ ./graphics/Faenza/emblems/64/emblem-favorite.png
./graphics/Faenza/emblems/64/emblem-shared.png
./graphics/Faenza/emblems/64/emblem-system.png
./graphics/Faenza/places/64/folder.png
@@ -195,6 +202,7 @@
./graphics/Faenza/actions/64/list-add.png
./graphics/Faenza/actions/64/list-remove.png
./graphics/Faenza/actions/64/mail-attachment.png
+ ./graphics/Faenza/actions/64/mail-forward.png
./graphics/Faenza/actions/64/mail-inbox.png
./graphics/Faenza/actions/64/mail-mark-important.png
./graphics/Faenza/actions/64/mail-mark-junk.png
@@ -252,6 +260,7 @@
./graphics/Numix/22/actions/edit-copy.svg
./graphics/Numix/22/actions/edit-select-all.svg
./graphics/Numix/22/emblems/emblem-downloads.svg
+ ./graphics/Numix/22/emblems/emblem-favorite.svg
./graphics/Numix/22/emblems/emblem-shared.svg
./graphics/Numix/22/emblems/emblem-system.svg
./graphics/Numix/22/places/folder.svg
@@ -273,6 +282,7 @@
./graphics/Numix/22/actions/list-add.svg
./graphics/Numix/22/actions/list-remove.svg
./graphics/Numix/22/actions/mail-attachment.svg
+ ./graphics/Numix/22/actions/mail-forward.svg
./graphics/Numix/22/places/mail-inbox.svg
./graphics/Numix/22/actions/mail-mark-important.svg
./graphics/Numix/22/actions/mail-mark-junk.svg
@@ -295,6 +305,7 @@
./graphics/Numix/22/actions/up.svg
./graphics/Numix/22/places/user-trash.svg
./graphics/Numix/22/actions/view-fullscreen.svg
+ ./graphics/Numix/22/actions/viewimage.svg
./graphics/Numix/22/actions/view-list-details.svg
./graphics/Numix/22/actions/view-refresh.svg
./graphics/Numix/22/actions/view-restore.svg
diff --git a/resources/scripts/github-actions/build-linux-mac.sh b/resources/scripts/github-actions/build-linux-mac.sh
index bbc27fef0..83d8a842a 100755
--- a/resources/scripts/github-actions/build-linux-mac.sh
+++ b/resources/scripts/github-actions/build-linux-mac.sh
@@ -50,7 +50,7 @@ git_tag=$(git describe --tags $(git rev-list --tags --max-count=1))
git_revision=$(git rev-parse --short HEAD)
mkdir rssguard-build && cd rssguard-build
-cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DREVISION_FROM_GIT=ON -DUSE_WEBENGINE="$webengine" -DFEEDLY_CLIENT_ID="$FEEDLY_CLIENT_ID" -DFEEDLY_CLIENT_SECRET="$FEEDLY_CLIENT_SECRET" -DGMAIL_CLIENT_ID="$GMAIL_CLIENT_ID" -DGMAIL_CLIENT_SECRET="$GMAIL_CLIENT_SECRET" -DINOREADER_CLIENT_ID="$INOREADER_CLIENT_ID" -DINOREADER_CLIENT_SECRET="$INOREADER_CLIENT_SECRET"
+cmake .. -G Ninja -DCMAKE_BUILD_TYPE="MinSizeRel" -DCMAKE_INSTALL_PREFIX="$prefix" -DREVISION_FROM_GIT="ON" -DUSE_WEBENGINE="$webengine" -DFEEDLY_CLIENT_ID="$FEEDLY_CLIENT_ID" -DFEEDLY_CLIENT_SECRET="$FEEDLY_CLIENT_SECRET" -DGMAIL_CLIENT_ID="$GMAIL_CLIENT_ID" -DGMAIL_CLIENT_SECRET="$GMAIL_CLIENT_SECRET" -DINOREADER_CLIENT_ID="$INOREADER_CLIENT_ID" -DINOREADER_CLIENT_SECRET="$INOREADER_CLIENT_SECRET"
cmake --build .
cmake --install . --prefix "$prefix"
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/GUMBO-AUTHORS.txt b/src/librssguard/3rd-party/qlitehtml/3rdparty/GUMBO-AUTHORS.txt
new file mode 100644
index 000000000..54ec74b8b
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/GUMBO-AUTHORS.txt
@@ -0,0 +1,2 @@
+Copyright 2010, 2011 Google Inc.
+Copyright 2008-2009 Bjoern Hoehrmann
\ No newline at end of file
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/LICENSE b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/LICENSE
new file mode 100644
index 000000000..601e1c712
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2013, Yuri Kobets (tordex)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/README.md b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/README.md
new file mode 100644
index 000000000..c5df6b2d1
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/README.md
@@ -0,0 +1,38 @@
+# What is litehtml?
+
+**litehtml** is the lightweight HTML rendering engine with CSS2/CSS3 support. Note that **litehtml** itself does not draw any text, pictures or other graphics and that **litehtml** does not depend on any image/draw/font library. You are free to use any library to draw images, fonts and any other graphics. **litehtml** just parses HTML/CSS and places the HTML elements into the correct positions (renders HTML). To draw the HTML elements you have to implement the simple callback interface [document_container](https://github.com/litehtml/litehtml/wiki/document_container). This interface is really simple, check it out! The [document_container](https://github.com/litehtml/litehtml/wiki/document_container) implementation is required to render HTML correctly.
+
+# Where litehtml can be used
+
+**litehtml** can be used when you need to show HTML formatted text or even to create a mini-browser, but using it as a full-featured HTML engine is not recommended. Usually you don't need something like WebKit to show simple HTML tooltips or HTML-formatted text, **litehtml** is much better for these as it's more lightweight and easier to integrate into your application.
+
+## HTML Parser
+
+**litehtml** uses the [gumbo-parser](https://github.com/google/gumbo-parser) to parse HTML. Gumbo is an implementation of the HTML5 parsing algorithm implemented as a pure C99 library with no outside dependencies. It's designed to serve as a building block for other tools and libraries such as linters, validators, templating languages, and refactoring and analysis tools.
+
+## Compatibility
+
+**litehtml** is compatible with any platform suported by C++ and STL. For Windows MS Visual Studio 2013 is recommended. **litehtml** supports both UTF-8 and Unicode strings on Windows and UTF-8 strings on Linux and Haiku.
+
+## Support for HTML and CSS standards
+
+Unfortunately **litehtml** is not fully compatible with HTML/CSS standards. There is lots of work to do to make **litehtml** work as well as modern browsers. But **litehtml** supports most HTML tags and CSS properties. You can find the list of supported CSS properties in [this table](https://docs.google.com/spreadsheet/ccc?key=0AvHXl5n24PuhdHdELUdhaUl4OGlncXhDcDJuM1JpMnc&usp=sharing). For most simple usecases the HTML/CSS features supported by **litehtml** are enough. Right now **litehtml** supports even some pages with very complex HTML/CSS designs. As an example the pages created with [bootstrap framework](http://getbootstrap.com/) are usually well formatted by **litehtml**.
+
+## Testing litehtml
+
+You can [download the simple browser](http://www.litehtml.com/download.html) (**litebrowser**) to test the **litehtml** rendering engine.
+
+The litebrowser source codes are available on GitHub:
+ * [For Windows](https://github.com/litehtml/litebrowser)
+ * [For Linux](https://github.com/litehtml/litebrowser-linux)
+ * [For Haiku](https://github.com/adamfowleruk/litebrowser-haiku)
+
+## License
+
+**litehtml** is distributed under [New BSD License](https://opensource.org/licenses/BSD-3-Clause).
+The **gumbo-parser** is disributed under [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+## Links
+
+ * [source code](https://github.com/litehtml/litehtml)
+ * [website](http://www.litehtml.com/)
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml.h
new file mode 100644
index 000000000..98a24e0da
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml.h
@@ -0,0 +1,10 @@
+#ifndef LITEHTML_H
+#define LITEHTML_H
+
+#include
+#include
+#include
+#include
+#include
+
+#endif // LITEHTML_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/attributes.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/attributes.h
new file mode 100644
index 000000000..98487f02e
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/attributes.h
@@ -0,0 +1,35 @@
+#ifndef LH_ATTRIBUTES_H
+#define LH_ATTRIBUTES_H
+
+namespace litehtml
+{
+ struct attr_color
+ {
+ unsigned char rgbBlue;
+ unsigned char rgbGreen;
+ unsigned char rgbRed;
+ unsigned char rgbAlpha;
+ attr_color()
+ {
+ rgbAlpha = 255;
+ rgbBlue = 0;
+ rgbGreen = 0;
+ rgbRed = 0;
+ }
+ };
+
+ struct attr_border
+ {
+ style_border border;
+ int width;
+ attr_color color;
+
+ attr_border()
+ {
+ border = borderNone;
+ width = 0;
+ }
+ };
+}
+
+#endif // LH_ATTRIBUTES_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/background.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/background.h
new file mode 100644
index 000000000..35b022b3c
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/background.h
@@ -0,0 +1,58 @@
+#ifndef LH_BACKGROUND_H
+#define LH_BACKGROUND_H
+
+#include "types.h"
+#include "attributes.h"
+#include "css_length.h"
+#include "css_position.h"
+#include "web_color.h"
+#include "borders.h"
+
+namespace litehtml
+{
+ class background
+ {
+ public:
+ tstring m_image;
+ tstring m_baseurl;
+ web_color m_color;
+ background_attachment m_attachment;
+ css_position m_position;
+ background_repeat m_repeat;
+ background_box m_clip;
+ background_box m_origin;
+ css_border_radius m_radius;
+
+ public:
+ background();
+ background(const background& val);
+ ~background() = default;
+
+ background& operator=(const background& val);
+ };
+
+ class background_paint
+ {
+ public:
+ tstring image;
+ tstring baseurl;
+ background_attachment attachment;
+ background_repeat repeat;
+ web_color color;
+ position clip_box;
+ position origin_box;
+ position border_box;
+ border_radiuses border_radius;
+ size image_size;
+ int position_x;
+ int position_y;
+ bool is_root;
+ public:
+ background_paint();
+ background_paint(const background_paint& val);
+ background_paint& operator=(const background& val);
+ };
+
+}
+
+#endif // LH_BACKGROUND_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/borders.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/borders.h
new file mode 100644
index 000000000..72618670d
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/borders.h
@@ -0,0 +1,305 @@
+#ifndef LH_BORDERS_H
+#define LH_BORDERS_H
+
+#include "css_length.h"
+#include "types.h"
+
+namespace litehtml
+{
+ struct css_border
+ {
+ css_length width;
+ border_style style;
+ web_color color;
+
+ css_border()
+ {
+ style = border_style_none;
+ }
+
+ css_border(const css_border& val)
+ {
+ width = val.width;
+ style = val.style;
+ color = val.color;
+ }
+
+ css_border& operator=(const css_border& val)
+ {
+ width = val.width;
+ style = val.style;
+ color = val.color;
+ return *this;
+ }
+ };
+
+ struct border
+ {
+ int width;
+ border_style style;
+ web_color color;
+
+ border()
+ {
+ width = 0;
+ }
+ border(const border& val)
+ {
+ width = val.width;
+ style = val.style;
+ color = val.color;
+ }
+ border(const css_border& val)
+ {
+ width = (int) val.width.val();
+ style = val.style;
+ color = val.color;
+ }
+ border& operator=(const border& val)
+ {
+ width = val.width;
+ style = val.style;
+ color = val.color;
+ return *this;
+ }
+ border& operator=(const css_border& val)
+ {
+ width = (int) val.width.val();
+ style = val.style;
+ color = val.color;
+ return *this;
+ }
+ };
+
+ struct border_radiuses
+ {
+ int top_left_x;
+ int top_left_y;
+
+ int top_right_x;
+ int top_right_y;
+
+ int bottom_right_x;
+ int bottom_right_y;
+
+ int bottom_left_x;
+ int bottom_left_y;
+
+ border_radiuses()
+ {
+ top_left_x = 0;
+ top_left_y = 0;
+ top_right_x = 0;
+ top_right_y = 0;
+ bottom_right_x = 0;
+ bottom_right_y = 0;
+ bottom_left_x = 0;
+ bottom_left_y = 0;
+ }
+ border_radiuses(const border_radiuses& val)
+ {
+ top_left_x = val.top_left_x;
+ top_left_y = val.top_left_y;
+ top_right_x = val.top_right_x;
+ top_right_y = val.top_right_y;
+ bottom_right_x = val.bottom_right_x;
+ bottom_right_y = val.bottom_right_y;
+ bottom_left_x = val.bottom_left_x;
+ bottom_left_y = val.bottom_left_y;
+ }
+ border_radiuses& operator = (const border_radiuses& val)
+ {
+ top_left_x = val.top_left_x;
+ top_left_y = val.top_left_y;
+ top_right_x = val.top_right_x;
+ top_right_y = val.top_right_y;
+ bottom_right_x = val.bottom_right_x;
+ bottom_right_y = val.bottom_right_y;
+ bottom_left_x = val.bottom_left_x;
+ bottom_left_y = val.bottom_left_y;
+ return *this;
+ }
+ void operator += (const margins& mg)
+ {
+ top_left_x += mg.left;
+ top_left_y += mg.top;
+ top_right_x += mg.right;
+ top_right_y += mg.top;
+ bottom_right_x += mg.right;
+ bottom_right_y += mg.bottom;
+ bottom_left_x += mg.left;
+ bottom_left_y += mg.bottom;
+ fix_values();
+ }
+ void operator -= (const margins& mg)
+ {
+ top_left_x -= mg.left;
+ top_left_y -= mg.top;
+ top_right_x -= mg.right;
+ top_right_y -= mg.top;
+ bottom_right_x -= mg.right;
+ bottom_right_y -= mg.bottom;
+ bottom_left_x -= mg.left;
+ bottom_left_y -= mg.bottom;
+ fix_values();
+ }
+ void fix_values()
+ {
+ if (top_left_x < 0) top_left_x = 0;
+ if (top_left_y < 0) top_left_y = 0;
+ if (top_right_x < 0) top_right_x = 0;
+ if (top_right_y < 0) top_right_y = 0;
+ if (bottom_right_x < 0) bottom_right_x = 0;
+ if (bottom_right_y < 0) bottom_right_y = 0;
+ if (bottom_left_x < 0) bottom_left_x = 0;
+ if (bottom_left_y < 0) bottom_left_y = 0;
+ }
+ };
+
+ struct css_border_radius
+ {
+ css_length top_left_x;
+ css_length top_left_y;
+
+ css_length top_right_x;
+ css_length top_right_y;
+
+ css_length bottom_right_x;
+ css_length bottom_right_y;
+
+ css_length bottom_left_x;
+ css_length bottom_left_y;
+
+ css_border_radius()
+ {
+
+ }
+
+ css_border_radius(const css_border_radius& val)
+ {
+ top_left_x = val.top_left_x;
+ top_left_y = val.top_left_y;
+ top_right_x = val.top_right_x;
+ top_right_y = val.top_right_y;
+ bottom_left_x = val.bottom_left_x;
+ bottom_left_y = val.bottom_left_y;
+ bottom_right_x = val.bottom_right_x;
+ bottom_right_y = val.bottom_right_y;
+ }
+
+ css_border_radius& operator=(const css_border_radius& val)
+ {
+ top_left_x = val.top_left_x;
+ top_left_y = val.top_left_y;
+ top_right_x = val.top_right_x;
+ top_right_y = val.top_right_y;
+ bottom_left_x = val.bottom_left_x;
+ bottom_left_y = val.bottom_left_y;
+ bottom_right_x = val.bottom_right_x;
+ bottom_right_y = val.bottom_right_y;
+ return *this;
+ }
+ border_radiuses calc_percents(int width, int height)
+ {
+ border_radiuses ret;
+ ret.bottom_left_x = bottom_left_x.calc_percent(width);
+ ret.bottom_left_y = bottom_left_y.calc_percent(height);
+ ret.top_left_x = top_left_x.calc_percent(width);
+ ret.top_left_y = top_left_y.calc_percent(height);
+ ret.top_right_x = top_right_x.calc_percent(width);
+ ret.top_right_y = top_right_y.calc_percent(height);
+ ret.bottom_right_x = bottom_right_x.calc_percent(width);
+ ret.bottom_right_y = bottom_right_y.calc_percent(height);
+ return ret;
+ }
+ };
+
+ struct css_borders
+ {
+ css_border left;
+ css_border top;
+ css_border right;
+ css_border bottom;
+ css_border_radius radius;
+
+ css_borders() = default;
+
+ bool is_visible() const
+ {
+ return left.width.val() != 0 || right.width.val() != 0 || top.width.val() != 0 || bottom.width.val() != 0;
+ }
+
+ css_borders(const css_borders& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ radius = val.radius;
+ }
+
+ css_borders& operator=(const css_borders& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ radius = val.radius;
+ return *this;
+ }
+ };
+
+ struct borders
+ {
+ border left;
+ border top;
+ border right;
+ border bottom;
+ border_radiuses radius;
+
+ borders() = default;
+
+ borders(const borders& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ radius = val.radius;
+ }
+
+ borders(const css_borders& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ }
+
+ bool is_visible() const
+ {
+ return left.width != 0 || right.width != 0 || top.width != 0 || bottom.width != 0;
+ }
+
+ borders& operator=(const borders& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ radius = val.radius;
+ return *this;
+ }
+
+ borders& operator=(const css_borders& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ return *this;
+ }
+ };
+}
+
+#endif // LH_BORDERS_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/box.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/box.h
new file mode 100644
index 000000000..32c674e7a
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/box.h
@@ -0,0 +1,120 @@
+#ifndef LH_BOX_H
+#define LH_BOX_H
+
+namespace litehtml
+{
+ class html_tag;
+
+ enum box_type
+ {
+ box_block,
+ box_line
+ };
+
+ class box
+ {
+ public:
+ typedef std::unique_ptr ptr;
+ typedef std::vector< box::ptr > vector;
+ protected:
+ int m_box_top;
+ int m_box_left;
+ int m_box_right;
+ public:
+ box(int top, int left, int right)
+ {
+ m_box_top = top;
+ m_box_left = left;
+ m_box_right = right;
+ }
+ virtual ~box() = default;
+
+ int bottom() const { return m_box_top + height(); }
+ int top() const { return m_box_top; }
+ int right() const { return m_box_left + width(); }
+ int left() const { return m_box_left; }
+
+ virtual litehtml::box_type get_type() const = 0;
+ virtual int height() const = 0;
+ virtual int width() const = 0;
+ virtual void add_element(const element::ptr &el) = 0;
+ virtual bool can_hold(const element::ptr &el, white_space ws) const = 0;
+ virtual void finish(bool last_box = false) = 0;
+ virtual bool is_empty() const = 0;
+ virtual int baseline() const = 0;
+ virtual void get_elements(elements_vector& els) = 0;
+ virtual int top_margin() const = 0;
+ virtual int bottom_margin() const = 0;
+ virtual void y_shift(int shift) = 0;
+ virtual void new_width(int left, int right, elements_vector& els) = 0;
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+
+ class block_box : public box
+ {
+ element::ptr m_element;
+ public:
+ block_box(int top, int left, int right) : box(top, left, right)
+ {
+ m_element = nullptr;
+ }
+
+ litehtml::box_type get_type() const override;
+ int height() const override;
+ int width() const override;
+ void add_element(const element::ptr &el) override;
+ bool can_hold(const element::ptr &el, white_space ws) const override;
+ void finish(bool last_box = false) override;
+ bool is_empty() const override;
+ int baseline() const override;
+ void get_elements(elements_vector& els) override;
+ int top_margin() const override;
+ int bottom_margin() const override;
+ void y_shift(int shift) override;
+ void new_width(int left, int right, elements_vector& els) override;
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+
+ class line_box : public box
+ {
+ elements_vector m_items;
+ int m_height;
+ int m_width;
+ int m_line_height;
+ font_metrics m_font_metrics;
+ int m_baseline;
+ text_align m_text_align;
+ public:
+ line_box(int top, int left, int right, int line_height, font_metrics& fm, text_align align) : box(top, left, right)
+ {
+ m_height = 0;
+ m_width = 0;
+ m_font_metrics = fm;
+ m_line_height = line_height;
+ m_baseline = 0;
+ m_text_align = align;
+ }
+
+ litehtml::box_type get_type() const override;
+ int height() const override;
+ int width() const override;
+ void add_element(const element::ptr &el) override;
+ bool can_hold(const element::ptr &el, white_space ws) const override;
+ void finish(bool last_box = false) override;
+ bool is_empty() const override;
+ int baseline() const override;
+ void get_elements(elements_vector& els) override;
+ int top_margin() const override;
+ int bottom_margin() const override;
+ void y_shift(int shift) override;
+ void new_width(int left, int right, elements_vector& els) override;
+
+ private:
+ bool have_last_space() const;
+ bool is_break_only() const;
+ };
+}
+
+#endif // LH_BOX_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/codepoint.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/codepoint.h
new file mode 100644
index 000000000..0bd7906b7
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/codepoint.h
@@ -0,0 +1,51 @@
+// Copyright (C) 2020-2021 Primate Labs Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the names of the copyright holders nor the names of their
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef LITEHTML_CODEPOINT_H__
+#define LITEHTML_CODEPOINT_H__
+
+#include
+
+#include "litehtml/os_types.h"
+
+namespace litehtml {
+
+bool is_ascii_codepoint(litehtml::tchar_t c);
+
+// Returns true if the codepoint is a reserved codepoint for URLs.
+// https://datatracker.ietf.org/doc/html/rfc3986#section-2.2
+bool is_url_reserved_codepoint(litehtml::tchar_t c);
+
+// Returns true if the codepoint is a scheme codepoint for URLs.
+// https://datatracker.ietf.org/doc/html/rfc3986#section-3.1
+bool is_url_scheme_codepoint(litehtml::tchar_t c);
+
+} // namespace litehtml
+
+#endif // LITEHTML_CODEPOINT_H__
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/context.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/context.h
new file mode 100644
index 000000000..b6450f8f5
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/context.h
@@ -0,0 +1,20 @@
+#ifndef LH_CONTEXT_H
+#define LH_CONTEXT_H
+
+#include "stylesheet.h"
+
+namespace litehtml
+{
+ class context
+ {
+ litehtml::css m_master_css;
+ public:
+ void load_master_stylesheet(const tchar_t* str);
+ litehtml::css& master_css()
+ {
+ return m_master_css;
+ }
+ };
+}
+
+#endif // LH_CONTEXT_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_length.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_length.h
new file mode 100644
index 000000000..13a3d77b7
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_length.h
@@ -0,0 +1,135 @@
+#ifndef LH_CSS_LENGTH_H
+#define LH_CSS_LENGTH_H
+
+#include "types.h"
+
+namespace litehtml
+{
+ class css_length
+ {
+ union
+ {
+ float m_value;
+ int m_predef;
+ };
+ css_units m_units;
+ bool m_is_predefined;
+ public:
+ css_length();
+ css_length(const css_length& val);
+
+ css_length& operator=(const css_length& val);
+ css_length& operator=(float val);
+ bool is_predefined() const;
+ void predef(int val);
+ int predef() const;
+ void set_value(float val, css_units units);
+ float val() const;
+ css_units units() const;
+ int calc_percent(int width) const;
+ void fromString(const tstring& str, const tstring& predefs = _t(""), int defValue = 0);
+ };
+
+ // css_length inlines
+
+ inline css_length::css_length()
+ {
+ m_value = 0;
+ m_predef = 0;
+ m_units = css_units_none;
+ m_is_predefined = false;
+ }
+
+ inline css_length::css_length(const css_length& val)
+ {
+ if(val.is_predefined())
+ {
+ m_predef = val.m_predef;
+ } else
+ {
+ m_value = val.m_value;
+ }
+ m_units = val.m_units;
+ m_is_predefined = val.m_is_predefined;
+ }
+
+ inline css_length& css_length::operator=(const css_length& val)
+ {
+ if(val.is_predefined())
+ {
+ m_predef = val.m_predef;
+ } else
+ {
+ m_value = val.m_value;
+ }
+ m_units = val.m_units;
+ m_is_predefined = val.m_is_predefined;
+ return *this;
+ }
+
+ inline css_length& css_length::operator=(float val)
+ {
+ m_value = val;
+ m_units = css_units_px;
+ m_is_predefined = false;
+ return *this;
+ }
+
+ inline bool css_length::is_predefined() const
+ {
+ return m_is_predefined;
+ }
+
+ inline void css_length::predef(int val)
+ {
+ m_predef = val;
+ m_is_predefined = true;
+ }
+
+ inline int css_length::predef() const
+ {
+ if(m_is_predefined)
+ {
+ return m_predef;
+ }
+ return 0;
+ }
+
+ inline void css_length::set_value(float val, css_units units)
+ {
+ m_value = val;
+ m_is_predefined = false;
+ m_units = units;
+ }
+
+ inline float css_length::val() const
+ {
+ if(!m_is_predefined)
+ {
+ return m_value;
+ }
+ return 0;
+ }
+
+ inline css_units css_length::units() const
+ {
+ return m_units;
+ }
+
+ inline int css_length::calc_percent(int width) const
+ {
+ if(!is_predefined())
+ {
+ if(units() == css_units_percentage)
+ {
+ return (int) ((double) width * (double) m_value / 100.0);
+ } else
+ {
+ return (int) val();
+ }
+ }
+ return 0;
+ }
+}
+
+#endif // LH_CSS_LENGTH_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_margins.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_margins.h
new file mode 100644
index 000000000..def378a52
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_margins.h
@@ -0,0 +1,36 @@
+#ifndef LH_CSS_MARGINS_H
+#define LH_CSS_MARGINS_H
+
+#include "css_length.h"
+
+namespace litehtml
+{
+ struct css_margins
+ {
+ css_length left;
+ css_length right;
+ css_length top;
+ css_length bottom;
+
+ css_margins() = default;
+
+ css_margins(const css_margins& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ }
+
+ css_margins& operator=(const css_margins& val)
+ {
+ left = val.left;
+ right = val.right;
+ top = val.top;
+ bottom = val.bottom;
+ return *this;
+ }
+ };
+}
+
+#endif // LH_CSS_MARGINS_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_offsets.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_offsets.h
new file mode 100644
index 000000000..abeddfb6c
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_offsets.h
@@ -0,0 +1,36 @@
+#ifndef LH_CSS_OFFSETS_H
+#define LH_CSS_OFFSETS_H
+
+#include "css_length.h"
+
+namespace litehtml
+{
+ struct css_offsets
+ {
+ css_length left;
+ css_length top;
+ css_length right;
+ css_length bottom;
+
+ css_offsets() = default;
+
+ css_offsets(const css_offsets& val)
+ {
+ left = val.left;
+ top = val.top;
+ right = val.right;
+ bottom = val.bottom;
+ }
+
+ css_offsets& operator=(const css_offsets& val)
+ {
+ left = val.left;
+ top = val.top;
+ right = val.right;
+ bottom = val.bottom;
+ return *this;
+ }
+ };
+}
+
+#endif // LH_CSS_OFFSETS_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_position.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_position.h
new file mode 100644
index 000000000..1f884121b
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_position.h
@@ -0,0 +1,36 @@
+#ifndef LH_CSS_POSITION_H
+#define LH_CSS_POSITION_H
+
+#include "css_length.h"
+
+namespace litehtml
+{
+ struct css_position
+ {
+ css_length x;
+ css_length y;
+ css_length width;
+ css_length height;
+
+ css_position() = default;
+
+ css_position(const css_position& val)
+ {
+ x = val.x;
+ y = val.y;
+ width = val.width;
+ height = val.height;
+ }
+
+ css_position& operator=(const css_position& val)
+ {
+ x = val.x;
+ y = val.y;
+ width = val.width;
+ height = val.height;
+ return *this;
+ }
+ };
+}
+
+#endif // LH_CSS_POSITION_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_selector.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_selector.h
new file mode 100644
index 000000000..da64df091
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/css_selector.h
@@ -0,0 +1,278 @@
+#ifndef LH_CSS_SELECTOR_H
+#define LH_CSS_SELECTOR_H
+
+#include "style.h"
+#include "media_query.h"
+
+namespace litehtml
+{
+ //////////////////////////////////////////////////////////////////////////
+
+ struct selector_specificity
+ {
+ int a;
+ int b;
+ int c;
+ int d;
+
+ explicit selector_specificity(int va = 0, int vb = 0, int vc = 0, int vd = 0)
+ {
+ a = va;
+ b = vb;
+ c = vc;
+ d = vd;
+ }
+
+ void operator += (const selector_specificity& val)
+ {
+ a += val.a;
+ b += val.b;
+ c += val.c;
+ d += val.d;
+ }
+
+ bool operator==(const selector_specificity& val) const
+ {
+ if(a == val.a && b == val.b && c == val.c && d == val.d)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ bool operator!=(const selector_specificity& val) const
+ {
+ if(a != val.a || b != val.b || c != val.c || d != val.d)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ bool operator > (const selector_specificity& val) const
+ {
+ if(a > val.a)
+ {
+ return true;
+ } else if(a < val.a)
+ {
+ return false;
+ } else
+ {
+ if(b > val.b)
+ {
+ return true;
+ } else if(b < val.b)
+ {
+ return false;
+ } else
+ {
+ if(c > val.c)
+ {
+ return true;
+ } else if(c < val.c)
+ {
+ return false;
+ } else
+ {
+ if(d > val.d)
+ {
+ return true;
+ } else if(d < val.d)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ bool operator >= (const selector_specificity& val) const
+ {
+ if((*this) == val) return true;
+ if((*this) > val) return true;
+ return false;
+ }
+
+ bool operator <= (const selector_specificity& val) const
+ {
+ if((*this) > val)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ bool operator < (const selector_specificity& val) const
+ {
+ if((*this) <= val && (*this) != val)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+
+ enum attr_select_condition
+ {
+ select_exists,
+ select_equal,
+ select_contain_str,
+ select_start_str,
+ select_end_str,
+ select_pseudo_class,
+ select_pseudo_element,
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+
+ struct css_attribute_selector
+ {
+ typedef std::vector vector;
+
+ tstring attribute;
+ tstring val;
+ string_vector class_val;
+ attr_select_condition condition;
+
+ css_attribute_selector()
+ {
+ condition = select_exists;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+
+ class css_element_selector
+ {
+ public:
+ tstring m_tag;
+ css_attribute_selector::vector m_attrs;
+ public:
+
+ void parse(const tstring& txt);
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+
+ enum css_combinator
+ {
+ combinator_descendant,
+ combinator_child,
+ combinator_adjacent_sibling,
+ combinator_general_sibling
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+
+ class css_selector
+ {
+ public:
+ typedef std::shared_ptr ptr;
+ typedef std::vector vector;
+ public:
+ selector_specificity m_specificity;
+ css_element_selector m_right;
+ css_selector::ptr m_left;
+ css_combinator m_combinator;
+ tstring m_style;
+ int m_order;
+ media_query_list::ptr m_media_query;
+ tstring m_baseurl;
+ public:
+ explicit css_selector(const media_query_list::ptr& media, const tstring& baseurl)
+ {
+ m_media_query = media;
+ m_baseurl = baseurl;
+ m_combinator = combinator_descendant;
+ m_order = 0;
+ }
+
+ ~css_selector() = default;
+
+ css_selector(const css_selector& val)
+ {
+ m_right = val.m_right;
+ if(val.m_left)
+ {
+ m_left = std::make_shared(*val.m_left);
+ } else
+ {
+ m_left = nullptr;
+ }
+ m_combinator = val.m_combinator;
+ m_specificity = val.m_specificity;
+ m_order = val.m_order;
+ m_media_query = val.m_media_query;
+ }
+
+ bool parse(const tstring& text);
+ void calc_specificity();
+ bool is_media_valid() const;
+ void add_media_to_doc(document* doc) const;
+ };
+
+ inline bool css_selector::is_media_valid() const
+ {
+ if(!m_media_query)
+ {
+ return true;
+ }
+ return m_media_query->is_used();
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+
+ inline bool operator > (const css_selector& v1, const css_selector& v2)
+ {
+ if(v1.m_specificity == v2.m_specificity)
+ {
+ return (v1.m_order > v2.m_order);
+ }
+ return (v1.m_specificity > v2.m_specificity);
+ }
+
+ inline bool operator < (const css_selector& v1, const css_selector& v2)
+ {
+ if(v1.m_specificity == v2.m_specificity)
+ {
+ return (v1.m_order < v2.m_order);
+ }
+ return (v1.m_specificity < v2.m_specificity);
+ }
+
+ inline bool operator >(const css_selector::ptr& v1, const css_selector::ptr& v2)
+ {
+ return (*v1 > *v2);
+ }
+
+ inline bool operator < (const css_selector::ptr& v1, const css_selector::ptr& v2)
+ {
+ return (*v1 < *v2);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+
+ class used_selector
+ {
+ public:
+ typedef std::unique_ptr ptr;
+ typedef std::vector vector;
+
+ css_selector::ptr m_selector;
+ bool m_used;
+
+ used_selector(const css_selector::ptr& selector, bool used)
+ {
+ m_used = used;
+ m_selector = selector;
+ }
+ };
+}
+
+#endif // LH_CSS_SELECTOR_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/document.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/document.h
new file mode 100644
index 000000000..1fd8dab89
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/document.h
@@ -0,0 +1,117 @@
+#ifndef LH_DOCUMENT_H
+#define LH_DOCUMENT_H
+
+#include "style.h"
+#include "types.h"
+#include "context.h"
+
+namespace litehtml
+{
+ struct css_text
+ {
+ typedef std::vector vector;
+
+ tstring text;
+ tstring baseurl;
+ tstring media;
+
+ css_text() = default;
+
+ css_text(const tchar_t* txt, const tchar_t* url, const tchar_t* media_str)
+ {
+ text = txt ? txt : _t("");
+ baseurl = url ? url : _t("");
+ media = media_str ? media_str : _t("");
+ }
+
+ css_text(const css_text& val)
+ {
+ text = val.text;
+ baseurl = val.baseurl;
+ media = val.media;
+ }
+ };
+
+ class html_tag;
+
+ class document : public std::enable_shared_from_this
+ {
+ public:
+ typedef std::shared_ptr ptr;
+ typedef std::weak_ptr weak_ptr;
+ private:
+ std::shared_ptr m_root;
+ document_container* m_container;
+ fonts_map m_fonts;
+ css_text::vector m_css;
+ litehtml::css m_styles;
+ litehtml::web_color m_def_color;
+ litehtml::context* m_context;
+ litehtml::size m_size;
+ position::vector m_fixed_boxes;
+ media_query_list::vector m_media_lists;
+ element::ptr m_over_element;
+ elements_vector m_tabular_elements;
+ media_features m_media;
+ tstring m_lang;
+ tstring m_culture;
+ public:
+ document(litehtml::document_container* objContainer, litehtml::context* ctx);
+ virtual ~document();
+
+ litehtml::document_container* container() { return m_container; }
+ uint_ptr get_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm);
+ int render(int max_width, render_type rt = render_all);
+ void draw(uint_ptr hdc, int x, int y, const position* clip);
+ web_color get_def_color() { return m_def_color; }
+ int cvt_units(const tchar_t* str, int fontSize, bool* is_percent = nullptr) const;
+ int cvt_units(css_length& val, int fontSize, int size = 0) const;
+ int width() const;
+ int height() const;
+ void add_stylesheet(const tchar_t* str, const tchar_t* baseurl, const tchar_t* media);
+ bool on_mouse_over(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);
+ bool on_lbutton_down(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);
+ bool on_lbutton_up(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);
+ bool on_mouse_leave(position::vector& redraw_boxes);
+ litehtml::element::ptr create_element(const tchar_t* tag_name, const string_map& attributes);
+ element::ptr root();
+ void get_fixed_boxes(position::vector& fixed_boxes);
+ void add_fixed_box(const position& pos);
+ void add_media_list(const media_query_list::ptr& list);
+ bool media_changed();
+ bool lang_changed();
+ bool match_lang(const tstring & lang);
+ void add_tabular(const element::ptr& el);
+ element::const_ptr get_over_element() const { return m_over_element; }
+
+ void append_children_from_string(element& parent, const tchar_t* str);
+ void append_children_from_utf8(element& parent, const char* str);
+
+ static litehtml::document::ptr createFromString(const tchar_t* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr);
+ static litehtml::document::ptr createFromUTF8(const char* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr);
+
+ private:
+ litehtml::uint_ptr add_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm);
+
+ void create_node(void* gnode, elements_vector& elements, bool parseTextNode);
+ bool update_media_lists(const media_features& features);
+ void fix_tables_layout();
+ void fix_table_children(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str);
+ void fix_table_parent(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str);
+ };
+
+ inline element::ptr document::root()
+ {
+ return m_root;
+ }
+ inline void document::add_tabular(const element::ptr& el)
+ {
+ m_tabular_elements.push_back(el);
+ }
+ inline bool document::match_lang(const tstring & lang)
+ {
+ return lang == m_lang || lang == m_culture;
+ }
+}
+
+#endif // LH_DOCUMENT_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_anchor.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_anchor.h
new file mode 100644
index 000000000..b33794c52
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_anchor.h
@@ -0,0 +1,18 @@
+#ifndef LH_EL_ANCHOR_H
+#define LH_EL_ANCHOR_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_anchor : public html_tag
+ {
+ public:
+ explicit el_anchor(const std::shared_ptr& doc);
+
+ void on_click() override;
+ void apply_stylesheet(const litehtml::css& stylesheet) override;
+ };
+}
+
+#endif // LH_EL_ANCHOR_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_base.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_base.h
new file mode 100644
index 000000000..d7efb8064
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_base.h
@@ -0,0 +1,17 @@
+#ifndef LH_EL_BASE_H
+#define LH_EL_BASE_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_base : public html_tag
+ {
+ public:
+ explicit el_base(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+ };
+}
+
+#endif // LH_EL_BASE_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_before_after.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_before_after.h
new file mode 100644
index 000000000..34554c5b8
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_before_after.h
@@ -0,0 +1,40 @@
+#ifndef LH_EL_BEFORE_AFTER_H
+#define LH_EL_BEFORE_AFTER_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_before_after_base : public html_tag
+ {
+ public:
+ el_before_after_base(const std::shared_ptr& doc, bool before);
+
+ void add_style(const tstring& style, const tstring& baseurl) override;
+ void apply_stylesheet(const litehtml::css& stylesheet) override;
+ private:
+ void add_text(const tstring& txt);
+ void add_function(const tstring& fnc, const tstring& params);
+ static tstring convert_escape(const tchar_t* txt);
+ };
+
+ class el_before : public el_before_after_base
+ {
+ public:
+ explicit el_before(const std::shared_ptr& doc) : el_before_after_base(doc, true)
+ {
+
+ }
+ };
+
+ class el_after : public el_before_after_base
+ {
+ public:
+ explicit el_after(const std::shared_ptr& doc) : el_before_after_base(doc, false)
+ {
+
+ }
+ };
+}
+
+#endif // LH_EL_BEFORE_AFTER_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_body.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_body.h
new file mode 100644
index 000000000..fb30e0c51
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_body.h
@@ -0,0 +1,17 @@
+#ifndef LH_EL_BODY_H
+#define LH_EL_BODY_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_body : public html_tag
+ {
+ public:
+ explicit el_body(const std::shared_ptr& doc);
+
+ bool is_body() const override;
+ };
+}
+
+#endif // LH_EL_BODY_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_break.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_break.h
new file mode 100644
index 000000000..81f38fec0
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_break.h
@@ -0,0 +1,17 @@
+#ifndef LH_EL_BREAK_H
+#define LH_EL_BREAK_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_break : public html_tag
+ {
+ public:
+ explicit el_break(const std::shared_ptr& doc);
+
+ bool is_break() const override;
+ };
+}
+
+#endif // LH_EL_BREAK_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_cdata.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_cdata.h
new file mode 100644
index 000000000..a948c6201
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_cdata.h
@@ -0,0 +1,19 @@
+#ifndef LH_EL_CDATA_H
+#define LH_EL_CDATA_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_cdata : public element
+ {
+ tstring m_text;
+ public:
+ explicit el_cdata(const std::shared_ptr& doc);
+
+ void get_text(tstring& text) override;
+ void set_data(const tchar_t* data) override;
+ };
+}
+
+#endif // LH_EL_CDATA_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_comment.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_comment.h
new file mode 100644
index 000000000..543b3b80b
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_comment.h
@@ -0,0 +1,20 @@
+#ifndef LH_EL_COMMENT_H
+#define LH_EL_COMMENT_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_comment : public element
+ {
+ tstring m_text;
+ public:
+ explicit el_comment(const std::shared_ptr& doc);
+
+ bool is_comment() const override;
+ void get_text(tstring& text) override;
+ void set_data(const tchar_t* data) override;
+ };
+}
+
+#endif // LH_EL_COMMENT_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_div.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_div.h
new file mode 100644
index 000000000..a2d031a32
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_div.h
@@ -0,0 +1,17 @@
+#ifndef LH_EL_DIV_H
+#define LH_EL_DIV_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_div : public html_tag
+ {
+ public:
+ explicit el_div(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+ };
+}
+
+#endif // LH_EL_DIV_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_font.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_font.h
new file mode 100644
index 000000000..ccb894512
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_font.h
@@ -0,0 +1,17 @@
+#ifndef LH_EL_FONT_H
+#define LH_EL_FONT_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_font : public html_tag
+ {
+ public:
+ explicit el_font(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+ };
+}
+
+#endif // LH_EL_FONT_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_image.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_image.h
new file mode 100644
index 000000000..fa13d3c1d
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_image.h
@@ -0,0 +1,28 @@
+#ifndef LH_EL_IMAGE_H
+#define LH_EL_IMAGE_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+
+ class el_image : public html_tag
+ {
+ tstring m_src;
+ public:
+ el_image(const std::shared_ptr& doc);
+ virtual ~el_image(void);
+
+ virtual int line_height() const override;
+ virtual bool is_replaced() const override;
+ virtual int render(int x, int y, int max_width, bool second_pass = false) override;
+ virtual void parse_attributes() override;
+ virtual void parse_styles(bool is_reparse = false) override;
+ virtual void draw(uint_ptr hdc, int x, int y, const position* clip) override;
+ virtual void get_content_size(size& sz, int max_width) override;
+ private:
+ int calc_max_height(int image_height);
+ };
+}
+
+#endif // LH_EL_IMAGE_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_li.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_li.h
new file mode 100644
index 000000000..4500465bc
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_li.h
@@ -0,0 +1,20 @@
+#ifndef LH_EL_LI_H
+#define LH_EL_LI_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_li : public html_tag
+ {
+ public:
+ explicit el_li(const std::shared_ptr& doc);
+
+ int render(int x, int y, int max_width, bool second_pass = false) override;
+
+ private:
+ bool m_index_initialized = false;
+ };
+}
+
+#endif // LH_EL_LI_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_link.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_link.h
new file mode 100644
index 000000000..0da3513dc
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_link.h
@@ -0,0 +1,18 @@
+#ifndef LH_EL_LINK_H
+#define LH_EL_LINK_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_link : public html_tag
+ {
+ public:
+ explicit el_link(const std::shared_ptr& doc);
+
+ protected:
+ void parse_attributes() override;
+ };
+}
+
+#endif // LH_EL_LINK_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_para.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_para.h
new file mode 100644
index 000000000..32ad53758
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_para.h
@@ -0,0 +1,18 @@
+#ifndef LH_EL_PARA_H
+#define LH_EL_PARA_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_para : public html_tag
+ {
+ public:
+ explicit el_para(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+
+ };
+}
+
+#endif // LH_EL_PARA_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_script.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_script.h
new file mode 100644
index 000000000..66767957c
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_script.h
@@ -0,0 +1,20 @@
+#ifndef LH_EL_SCRIPT_H
+#define LH_EL_SCRIPT_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_script : public element
+ {
+ tstring m_text;
+ public:
+ explicit el_script(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+ bool appendChild(const ptr &el) override;
+ const tchar_t* get_tagName() const override;
+ };
+}
+
+#endif // LH_EL_SCRIPT_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_space.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_space.h
new file mode 100644
index 000000000..e1c81b4f1
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_space.h
@@ -0,0 +1,20 @@
+#ifndef LH_EL_SPACE_H
+#define LH_EL_SPACE_H
+
+#include "html_tag.h"
+#include "el_text.h"
+
+namespace litehtml
+{
+ class el_space : public el_text
+ {
+ public:
+ el_space(const tchar_t* text, const std::shared_ptr& doc);
+
+ bool is_white_space() const override;
+ bool is_break() const override;
+ bool is_space() const override;
+ };
+}
+
+#endif // LH_EL_SPACE_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_style.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_style.h
new file mode 100644
index 000000000..630268808
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_style.h
@@ -0,0 +1,20 @@
+#ifndef LH_EL_STYLE_H
+#define LH_EL_STYLE_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_style : public element
+ {
+ elements_vector m_children;
+ public:
+ explicit el_style(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+ bool appendChild(const ptr &el) override;
+ const tchar_t* get_tagName() const override;
+ };
+}
+
+#endif // LH_EL_STYLE_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_table.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_table.h
new file mode 100644
index 000000000..ea9752142
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_table.h
@@ -0,0 +1,26 @@
+#ifndef LH_EL_TABLE_H
+#define LH_EL_TABLE_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ struct col_info
+ {
+ int width;
+ bool is_auto;
+ };
+
+
+ class el_table : public html_tag
+ {
+ public:
+ explicit el_table(const std::shared_ptr& doc);
+
+ bool appendChild(const litehtml::element::ptr& el) override;
+ void parse_styles(bool is_reparse = false) override;
+ void parse_attributes() override;
+ };
+}
+
+#endif // LH_EL_TABLE_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_td.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_td.h
new file mode 100644
index 000000000..03d21c1c7
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_td.h
@@ -0,0 +1,17 @@
+#ifndef LH_EL_TD_H
+#define LH_EL_TD_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_td : public html_tag
+ {
+ public:
+ explicit el_td(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+ };
+}
+
+#endif // LH_EL_TD_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_text.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_text.h
new file mode 100644
index 000000000..c53db7f7a
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_text.h
@@ -0,0 +1,37 @@
+#ifndef LH_EL_TEXT_H
+#define LH_EL_TEXT_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_text : public element
+ {
+ protected:
+ tstring m_text;
+ tstring m_transformed_text;
+ size m_size;
+ text_transform m_text_transform;
+ bool m_use_transformed;
+ bool m_draw_spaces;
+ public:
+ el_text(const tchar_t* text, const std::shared_ptr& doc);
+
+ void get_text(tstring& text) override;
+ const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) const override;
+ void parse_styles(bool is_reparse) override;
+ int get_base_line() override;
+ void draw(uint_ptr hdc, int x, int y, const position* clip) override;
+ int line_height() const override;
+ uint_ptr get_font(font_metrics* fm = nullptr) override;
+ style_display get_display() const override;
+ white_space get_white_space() const override;
+ element_position get_element_position(css_offsets* offsets = nullptr) const override;
+ css_offsets get_css_offsets() const override;
+
+ protected:
+ void get_content_size(size& sz, int max_width) override;
+ };
+}
+
+#endif // LH_EL_TEXT_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_title.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_title.h
new file mode 100644
index 000000000..201186a4a
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_title.h
@@ -0,0 +1,18 @@
+#ifndef LH_EL_TITLE_H
+#define LH_EL_TITLE_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_title : public html_tag
+ {
+ public:
+ explicit el_title(const std::shared_ptr& doc);
+
+ protected:
+ void parse_attributes() override;
+ };
+}
+
+#endif // LH_EL_TITLE_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_tr.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_tr.h
new file mode 100644
index 000000000..40a2f7038
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/el_tr.h
@@ -0,0 +1,18 @@
+#ifndef LH_EL_TR_H
+#define LH_EL_TR_H
+
+#include "html_tag.h"
+
+namespace litehtml
+{
+ class el_tr : public html_tag
+ {
+ public:
+ explicit el_tr(const std::shared_ptr& doc);
+
+ void parse_attributes() override;
+ void get_inline_boxes(position::vector& boxes) override;
+ };
+}
+
+#endif // LH_EL_TR_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/element.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/element.h
new file mode 100644
index 000000000..829424395
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/element.h
@@ -0,0 +1,408 @@
+#ifndef LH_ELEMENT_H
+#define LH_ELEMENT_H
+
+#include
+#include "stylesheet.h"
+#include "css_offsets.h"
+
+namespace litehtml
+{
+ class box;
+
+ class element : public std::enable_shared_from_this
+ {
+ friend class block_box;
+ friend class line_box;
+ friend class html_tag;
+ friend class el_table;
+ friend class document;
+ public:
+ typedef std::shared_ptr ptr;
+ typedef std::shared_ptr const_ptr;
+ typedef std::weak_ptr weak_ptr;
+ protected:
+ std::weak_ptr m_parent;
+ std::weak_ptr m_doc;
+ litehtml::box* m_box;
+ elements_vector m_children;
+ position m_pos;
+ margins m_margins;
+ margins m_padding;
+ margins m_borders;
+ bool m_skip;
+
+ virtual void select_all(const css_selector& selector, elements_vector& res);
+ public:
+ explicit element(const std::shared_ptr& doc);
+ virtual ~element() = default;
+
+ // returns refer to m_pos member;
+ position& get_position();
+
+ int left() const;
+ int right() const;
+ int top() const;
+ int bottom() const;
+ int height() const;
+ int width() const;
+
+ int content_margins_top() const;
+ int content_margins_bottom() const;
+ int content_margins_left() const;
+ int content_margins_right() const;
+ int content_margins_width() const;
+ int content_margins_height() const;
+
+ int margin_top() const;
+ int margin_bottom() const;
+ int margin_left() const;
+ int margin_right() const;
+ margins get_margins() const;
+
+ int padding_top() const;
+ int padding_bottom() const;
+ int padding_left() const;
+ int padding_right() const;
+ margins get_paddings() const;
+
+ int border_top() const;
+ int border_bottom() const;
+ int border_left() const;
+ int border_right() const;
+ margins get_borders() const;
+
+ bool in_normal_flow() const;
+ litehtml::web_color get_color(const tchar_t* prop_name, bool inherited, const litehtml::web_color& def_color = litehtml::web_color());
+ bool is_inline_box() const;
+ position get_placement() const;
+ bool collapse_top_margin() const;
+ bool collapse_bottom_margin() const;
+ bool is_positioned() const;
+
+ bool skip() const;
+ void skip(bool val);
+ bool have_parent() const;
+ element::ptr parent() const;
+ void parent(const element::ptr& par);
+ bool is_visible() const;
+ int calc_width(int defVal) const;
+ int get_inline_shift_left();
+ int get_inline_shift_right();
+ void apply_relative_shift(int parent_width);
+ // returns true for elements inside a table (but outside cells) that don't participate in table rendering
+ bool is_table_skip() const;
+
+ std::shared_ptr get_document() const;
+
+ virtual elements_vector select_all(const tstring& selector);
+ virtual elements_vector select_all(const css_selector& selector);
+
+ virtual element::ptr select_one(const tstring& selector);
+ virtual element::ptr select_one(const css_selector& selector);
+
+ virtual int render(int x, int y, int max_width, bool second_pass = false);
+ virtual int render_inline(const ptr &container, int max_width);
+ virtual int place_element(const ptr &el, int max_width);
+ virtual void calc_outlines( int parent_width );
+ virtual void calc_auto_margins(int parent_width);
+ virtual void apply_vertical_align();
+ virtual bool fetch_positioned();
+ virtual void render_positioned(render_type rt = render_all);
+
+ virtual bool appendChild(const ptr &el);
+ virtual bool removeChild(const ptr &el);
+ virtual void clearRecursive();
+
+ virtual const tchar_t* get_tagName() const;
+ virtual void set_tagName(const tchar_t* tag);
+ virtual void set_data(const tchar_t* data);
+ virtual element_float get_float() const;
+ virtual vertical_align get_vertical_align() const;
+ virtual element_clear get_clear() const;
+ virtual size_t get_children_count() const;
+ virtual element::ptr get_child(int idx) const;
+ virtual overflow get_overflow() const;
+
+ virtual css_length get_css_left() const;
+ virtual css_length get_css_right() const;
+ virtual css_length get_css_top() const;
+ virtual css_length get_css_bottom() const;
+ virtual css_offsets get_css_offsets() const;
+ virtual css_length get_css_width() const;
+ virtual void set_css_width(css_length& w);
+ virtual css_length get_css_height() const;
+
+ virtual void set_attr(const tchar_t* name, const tchar_t* val);
+ virtual const tchar_t* get_attr(const tchar_t* name, const tchar_t* def = nullptr) const;
+ virtual void apply_stylesheet(const litehtml::css& stylesheet);
+ virtual void refresh_styles();
+ virtual bool is_white_space() const;
+ virtual bool is_space() const;
+ virtual bool is_comment() const;
+ virtual bool is_body() const;
+ virtual bool is_break() const;
+ virtual int get_base_line();
+ virtual bool on_mouse_over();
+ virtual bool on_mouse_leave();
+ virtual bool on_lbutton_down();
+ virtual bool on_lbutton_up();
+ virtual void on_click();
+ virtual bool find_styles_changes(position::vector& redraw_boxes, int x, int y);
+ virtual const tchar_t* get_cursor();
+ virtual void init_font();
+ virtual bool is_point_inside(int x, int y);
+ virtual bool set_pseudo_class(const tchar_t* pclass, bool add);
+ virtual bool set_class(const tchar_t* pclass, bool add);
+ virtual bool is_replaced() const;
+ virtual int line_height() const;
+ virtual white_space get_white_space() const;
+ virtual style_display get_display() const;
+ virtual visibility get_visibility() const;
+ virtual element_position get_element_position(css_offsets* offsets = nullptr) const;
+ virtual void get_inline_boxes(position::vector& boxes);
+ virtual void parse_styles(bool is_reparse = false);
+ virtual void draw(uint_ptr hdc, int x, int y, const position* clip);
+ virtual void draw_background( uint_ptr hdc, int x, int y, const position* clip );
+ virtual const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) const;
+ virtual uint_ptr get_font(font_metrics* fm = nullptr);
+ virtual int get_font_size() const;
+ virtual void get_text(tstring& text);
+ virtual void parse_attributes();
+ virtual int select(const css_selector& selector, bool apply_pseudo = true);
+ virtual int select(const css_element_selector& selector, bool apply_pseudo = true);
+ virtual element::ptr find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr);
+ virtual bool is_ancestor(const ptr &el) const;
+ virtual element::ptr find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr);
+ virtual element::ptr find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr);
+ virtual bool is_first_child_inline(const element::ptr& el) const;
+ virtual bool is_last_child_inline(const element::ptr& el);
+ virtual bool have_inline_child() const;
+ virtual void get_content_size(size& sz, int max_width);
+ virtual void init();
+ virtual bool is_floats_holder() const;
+ virtual int get_floats_height(element_float el_float = float_none) const;
+ virtual int get_left_floats_height() const;
+ virtual int get_right_floats_height() const;
+ virtual int get_line_left(int y);
+ virtual int get_line_right(int y, int def_right);
+ virtual void get_line_left_right(int y, int def_right, int& ln_left, int& ln_right);
+ virtual void add_float(const ptr &el, int x, int y);
+ virtual void update_floats(int dy, const ptr &parent);
+ virtual void add_positioned(const ptr &el);
+ virtual int find_next_line_top(int top, int width, int def_right);
+ virtual int get_zindex() const;
+ virtual void draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned);
+ virtual void draw_children( uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex );
+ virtual bool is_nth_child(const element::ptr& el, int num, int off, bool of_type) const;
+ virtual bool is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const;
+ virtual bool is_only_child(const element::ptr& el, bool of_type) const;
+ virtual bool get_predefined_height(int& p_height) const;
+ virtual void calc_document_size(litehtml::size& sz, int x = 0, int y = 0);
+ virtual void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0);
+ virtual void add_style(const tstring& style, const tstring& baseurl);
+ virtual element::ptr get_element_by_point(int x, int y, int client_x, int client_y);
+ virtual element::ptr get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex);
+ virtual const background* get_background(bool own_only = false);
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // INLINE FUNCTIONS //
+ //////////////////////////////////////////////////////////////////////////
+
+ inline int litehtml::element::right() const
+ {
+ return left() + width();
+ }
+
+ inline int litehtml::element::left() const
+ {
+ return m_pos.left() - margin_left() - m_padding.left - m_borders.left;
+ }
+
+ inline int litehtml::element::top() const
+ {
+ return m_pos.top() - margin_top() - m_padding.top - m_borders.top;
+ }
+
+ inline int litehtml::element::bottom() const
+ {
+ return top() + height();
+ }
+
+ inline int litehtml::element::height() const
+ {
+ return m_pos.height + margin_top() + margin_bottom() + m_padding.height() + m_borders.height();
+ }
+
+ inline int litehtml::element::width() const
+ {
+ return m_pos.width + margin_left() + margin_right() + m_padding.width() + m_borders.width();
+ }
+
+ inline int litehtml::element::content_margins_top() const
+ {
+ return margin_top() + m_padding.top + m_borders.top;
+ }
+
+ inline int litehtml::element::content_margins_bottom() const
+ {
+ return margin_bottom() + m_padding.bottom + m_borders.bottom;
+ }
+
+ inline int litehtml::element::content_margins_left() const
+ {
+ return margin_left() + m_padding.left + m_borders.left;
+ }
+
+ inline int litehtml::element::content_margins_right() const
+ {
+ return margin_right() + m_padding.right + m_borders.right;
+ }
+
+ inline int litehtml::element::content_margins_width() const
+ {
+ return content_margins_left() + content_margins_right();
+ }
+
+ inline int litehtml::element::content_margins_height() const
+ {
+ return content_margins_top() + content_margins_bottom();
+ }
+
+ inline litehtml::margins litehtml::element::get_paddings() const
+ {
+ return m_padding;
+ }
+
+ inline litehtml::margins litehtml::element::get_borders() const
+ {
+ return m_borders;
+ }
+
+ inline int litehtml::element::padding_top() const
+ {
+ return m_padding.top;
+ }
+
+ inline int litehtml::element::padding_bottom() const
+ {
+ return m_padding.bottom;
+ }
+
+ inline int litehtml::element::padding_left() const
+ {
+ return m_padding.left;
+ }
+
+ inline int litehtml::element::padding_right() const
+ {
+ return m_padding.right;
+ }
+
+ inline bool litehtml::element::in_normal_flow() const
+ {
+ if(get_element_position() != element_position_absolute && get_display() != display_none)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ inline int litehtml::element::border_top() const
+ {
+ return m_borders.top;
+ }
+
+ inline int litehtml::element::border_bottom() const
+ {
+ return m_borders.bottom;
+ }
+
+ inline int litehtml::element::border_left() const
+ {
+ return m_borders.left;
+ }
+
+ inline int litehtml::element::border_right() const
+ {
+ return m_borders.right;
+ }
+
+ inline bool litehtml::element::skip() const
+ {
+ return m_skip;
+ }
+
+ inline void litehtml::element::skip(bool val)
+ {
+ m_skip = val;
+ }
+
+ inline bool litehtml::element::have_parent() const
+ {
+ return !m_parent.expired();
+ }
+
+ inline element::ptr litehtml::element::parent() const
+ {
+ return m_parent.lock();
+ }
+
+ inline void litehtml::element::parent(const element::ptr& par)
+ {
+ m_parent = par;
+ }
+
+ inline int litehtml::element::margin_top() const
+ {
+ return m_margins.top;
+ }
+
+ inline int litehtml::element::margin_bottom() const
+ {
+ return m_margins.bottom;
+ }
+
+ inline int litehtml::element::margin_left() const
+ {
+ return m_margins.left;
+ }
+
+ inline int litehtml::element::margin_right() const
+ {
+ return m_margins.right;
+ }
+
+ inline litehtml::margins litehtml::element::get_margins() const
+ {
+ margins ret;
+ ret.left = margin_left();
+ ret.right = margin_right();
+ ret.top = margin_top();
+ ret.bottom = margin_bottom();
+
+ return ret;
+ }
+
+ inline bool litehtml::element::is_positioned() const
+ {
+ return (get_element_position() > element_position_static);
+ }
+
+ inline bool litehtml::element::is_visible() const
+ {
+ return !(m_skip || get_display() == display_none || get_visibility() != visibility_visible);
+ }
+
+ inline position& litehtml::element::get_position()
+ {
+ return m_pos;
+ }
+
+ inline std::shared_ptr element::get_document() const
+ {
+ return m_doc.lock();
+ }
+}
+
+#endif // LH_ELEMENT_H
diff --git a/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/html.h b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/html.h
new file mode 100644
index 000000000..8bf9bedb3
--- /dev/null
+++ b/src/librssguard/3rd-party/qlitehtml/3rdparty/litehtml/include/litehtml/html.h
@@ -0,0 +1,117 @@
+#ifndef LH_HTML_H
+#define LH_HTML_H
+
+#include
+#include
+#include
+#include
+#include