Merge branch 'master' of github.com:martinrotter/rssguard
This commit is contained in:
commit
0d046d6b20
3
.gitignore
vendored
3
.gitignore
vendored
@ -24,4 +24,5 @@
|
||||
*.autosave
|
||||
*.user*
|
||||
localization/*qm
|
||||
*.TMP
|
||||
*.TMP
|
||||
resources/skins/*/*.map
|
@ -229,11 +229,11 @@ version by clicking this popup notification.</source>
|
||||
<name>ColorToolButton</name>
|
||||
<message>
|
||||
<source>Click me to change color!</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Click me to change colour!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select new color</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Select new colour</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -3607,7 +3607,7 @@ List of supported readers:</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>OK-ish color</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>OK-ish colour</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -4446,7 +4446,7 @@ Authors of this application are NOT responsible for lost data.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Fetch color from activated skin</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Fetch colour from activated skin</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -82,6 +82,10 @@ win32 {
|
||||
|
||||
# Additionally link against Shell32.
|
||||
LIBS *= Shell32.lib
|
||||
|
||||
static {
|
||||
LIBS *= -lodbc32
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
|
@ -11,7 +11,7 @@ APP_URL = "https://github.com/martinrotter/rssguard"
|
||||
APP_URL_ISSUES = "https://github.com/martinrotter/rssguard/issues"
|
||||
APP_URL_ISSUES_NEW = "https://github.com/martinrotter/rssguard/issues/new"
|
||||
APP_URL_DOCUMENTATION = "https://github.com/martinrotter/rssguard/blob/master/resources/docs/Documentation.md"
|
||||
APP_USERAGENT = "RSS Guard/$$APP_VERSION (github.com/martinrotter/rssguard)"
|
||||
APP_USERAGENT = "RSS Guard/$$APP_VERSION"
|
||||
APP_DONATE_URL = "https://martinrotter.github.io/donate"
|
||||
|
||||
message($$MSG_PREFIX: Welcome RSS Guard qmake script.)
|
||||
|
@ -26,7 +26,7 @@
|
||||
<url type="donation">https://github.com/sponsors/martinrotter</url>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="4.0.4" date="2021-11-26"/>
|
||||
<release version="4.0.4" date="2021-12-22"/>
|
||||
</releases>
|
||||
<content_rating type="oars-1.0">
|
||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||
|
@ -167,6 +167,7 @@ Note that `MessageObject` attributes which can be synchronized with service are
|
||||
| Method | `hostname()` | `String` | `utils.hostname()` | Returns name of your PC.
|
||||
| Method | `fromXmlToJson(String)` | `String` | `utils.fromXmlToJson('<h1>hello</h1>')` | Converts `XML` string into `JSON`.
|
||||
| Method | `parseDateTime(String)` | `Date` | `utils.parseDateTime('2020-02-24T08:00:00')` | Converts textual date/time representation into proper `Date` object.
|
||||
| Method | `runExecutableGetOutput(String, String[])` | `String` | `utils.runExecutableGetOutput('cmd.exe', ['/c', 'dir'])` | Launches external executable with optional parameters, reads its standard output and returns the output when executable finishes.
|
||||
|
||||
#### Examples
|
||||
Accept only messages/articles from "Bob", while also mark them "important":
|
||||
@ -399,12 +400,15 @@ RSS Guard is distributed in two variants:
|
||||
|
||||
If you're not sure which version to use, **use the WebEngine-based RSS Guard**.
|
||||
|
||||
#### AdBlock
|
||||
#### AdBlock <a id="adbl"></a>
|
||||
[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).
|
||||
|
||||
You need to have have [Node.js](https://nodejs.org) with [NPM](https://www.npmjs.com) (which is usually included in Node.js installer) installed to have ad-blocking in RSS Guard working. Also, the implementation requires additional [npm](https://www.npmjs.com) modules to be installed. You see the list of needed modules near the top of [this](https://github.com/martinrotter/rssguard/blob/master/resources/scripts/adblock/adblock-server.js) file.
|
||||
If you want to enable AdBlock in RSS Guard you need to do this:
|
||||
|
||||
I understand that the above installation of needed dependencies is not trivial, but it is necessary evil to have up-to-date and modern implementation of AdBlock in RSS Guard. Previous, "C++"-based, implementation was buggy, quite slow, and hard to maintain.
|
||||
1. Have [Node.js](https://nodejs.org) with [NPM](https://www.npmjs.com) (which is usually included in Node.js installer) installed. Also you need to have paths `node.exe` and `npm` added to your system `PATH` environment available.
|
||||
2. The implementation requires additional [npm](https://www.npmjs.com) modules to be installed. You see the list of needed modules near the top of [this](https://github.com/martinrotter/rssguard/blob/master/resources/scripts/adblock/adblock-server.js) file.
|
||||
|
||||
I understand that the above installation is not trivial, but it is necessary evil to have up-to-date and modern implementation of AdBlock in RSS Guard. Previous, `C++`-based, implementation was buggy, slow, and hard to maintain.
|
||||
|
||||
You can find elaborate lists of AdBlock rules [here](https://easylist.to). You can just copy direct hyperlinks to those lists and paste them into the "Filter lists" text-box as shown below. Remember to always separate individual links with newlines. Same applies to "Custom filters", where you can insert individual filters, for example [filter](https://adblockplus.org/filter-cheatsheet) "idnes" to block all URLs with "idnes" in them.
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
<file>./graphics/Breeze/actions/22/edit-clear.svg</file>
|
||||
<file>./graphics/Breeze/actions/22/edit-copy.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/edit-reset.svg</file>
|
||||
<file>./graphics/Breeze/actions/22/edit-select-all.svg</file>
|
||||
<file>./graphics/Breeze/actions/22/edit-select-none.svg</file>
|
||||
<file>./graphics/Breeze/places/96/folder.svg</file>
|
||||
<file>./graphics/Breeze/actions/22/format-indent-more.svg</file>
|
||||
<file>./graphics/Breeze/actions/22/format-justify-fill.svg</file>
|
||||
@ -89,6 +91,8 @@
|
||||
<file>./graphics/Breeze Dark/actions/22/edit-clear.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/22/edit-copy.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/edit-reset.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/22/edit-select-all.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/22/edit-select-none.svg</file>
|
||||
<file>./graphics/Breeze Dark/places/96/folder.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/22/format-indent-more.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/22/format-justify-fill.svg</file>
|
||||
@ -153,6 +157,7 @@
|
||||
<file>./graphics/Faenza/actions/64/down.png</file>
|
||||
<file>./graphics/Faenza/actions/64/edit-clear.png</file>
|
||||
<file>./graphics/Faenza/actions/64/edit-copy.png</file>
|
||||
<file>./graphics/Faenza/actions/64/edit-select-all.png</file>
|
||||
<file>./graphics/Faenza/emblems/64/emblem-downloads.png</file>
|
||||
<file>./graphics/Faenza/emblems/64/emblem-system.png</file>
|
||||
<file>./graphics/Faenza/places/64/folder.png</file>
|
||||
@ -223,6 +228,7 @@
|
||||
<file>./graphics/Numix/22/actions/download.svg</file>
|
||||
<file>./graphics/Numix/22/actions/edit-clear.svg</file>
|
||||
<file>./graphics/Numix/22/actions/edit-copy.svg</file>
|
||||
<file>./graphics/Numix/22/actions/edit-select-all.svg</file>
|
||||
<file>./graphics/Numix/22/emblems/emblem-downloads.svg</file>
|
||||
<file>./graphics/Numix/22/emblems/emblem-system.svg</file>
|
||||
<file>./graphics/Numix/22/places/folder.svg</file>
|
||||
|
@ -81,13 +81,20 @@
|
||||
<file>skins/vergilius/metadata.xml</file>
|
||||
<file>skins/vergilius/qt_style.qss</file>
|
||||
|
||||
<file>skins/nudus/html_adblocked.html</file>
|
||||
<file>skins/nudus/html_enclosure_every.html</file>
|
||||
<file>skins/nudus/html_enclosure_image.html</file>
|
||||
<file>skins/nudus/html_single_message.html</file>
|
||||
<file>skins/nudus/html_wrapper.html</file>
|
||||
<file>skins/nudus/metadata.xml</file>
|
||||
<file>skins/nudus/qt_style.qss</file>
|
||||
<file>skins/nudus-base/html_adblocked.html</file>
|
||||
<file>skins/nudus-base/html_enclosure_every.html</file>
|
||||
<file>skins/nudus-base/html_enclosure_image.html</file>
|
||||
<file>skins/nudus-base/html_single_message.html</file>
|
||||
<file>skins/nudus-base/html_wrapper.html</file>
|
||||
|
||||
<file>skins/nudus-dark/html_wrapper.html</file>
|
||||
<file>skins/nudus-dark/html_style.css</file>
|
||||
<file>skins/nudus-dark/metadata.xml</file>
|
||||
<file>skins/nudus-dark/qt_style.qss</file>
|
||||
|
||||
<file>skins/nudus-light/html_style.css</file>
|
||||
<file>skins/nudus-light/metadata.xml</file>
|
||||
<file>skins/nudus-light/qt_style.qss</file>
|
||||
|
||||
<file>initial_feeds/feeds-en.opml</file>
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const tldts = require('tldts-experimental');
|
||||
const adblock = require('@cliqz/adblocker')
|
||||
const adblock = require('@cliqz/adblocker');
|
||||
const http = require('http');
|
||||
const cluster = require('cluster');
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
# Downloads full articles for RSS 2.0 feed and replaces original articles.
|
||||
#
|
||||
# Make sure to have all dependencies installed:
|
||||
# pip3 install asyncio (if using parallel version of the script)
|
||||
#
|
||||
# You must provide raw RSS 2.0 UTF-8 feed XML data as input, for example with curl:
|
||||
# curl 'http://rss.cnn.com/rss/edition.rss' | python ./scrape-rss2.py "4"
|
||||
#
|
||||
# You must provide three command line arguments:
|
||||
# scrape-rss2.py [NUMBER-OF-PARALLEL-THREADS]
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import html
|
||||
import urllib.request
|
||||
import distutils.util
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
no_threads = int(sys.argv[1])
|
||||
|
||||
if no_threads > 1:
|
||||
import asyncio
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
sys.stdin.reconfigure(encoding='utf-8')
|
||||
rss_data = sys.stdin.read()
|
||||
rss_document = ET.fromstring(rss_data)
|
||||
|
||||
def process_article(article):
|
||||
try:
|
||||
link = "https://us-central1-technews-251304.cloudfunctions.net/article-parser?url=" + article.find("link").text
|
||||
response = urllib.request.urlopen(link)
|
||||
text = response.read().decode("utf-8")
|
||||
js = json.loads(text)
|
||||
|
||||
if int(js["error"]) == 0:
|
||||
article.find("description").text = js["data"]["content"]
|
||||
except:
|
||||
pass
|
||||
|
||||
# Scrape articles.
|
||||
if no_threads > 1:
|
||||
with ThreadPoolExecutor(max_workers = no_threads) as executor:
|
||||
futures = []
|
||||
for article in rss_document.findall(".//item"):
|
||||
futures.append(executor.submit(process_article, article))
|
||||
for future in futures:
|
||||
future.result()
|
||||
else:
|
||||
for article in rss_document.findall(".//item"):
|
||||
process_article(article)
|
||||
|
||||
print(ET.tostring(rss_document, encoding = "unicode"))
|
96
resources/scripts/scrapers/scrape-full-articles.py
Normal file
96
resources/scripts/scrapers/scrape-full-articles.py
Normal file
@ -0,0 +1,96 @@
|
||||
# Downloads full (HTML) articles for ATOM or RSS 2.0 feed and replaces original articles.
|
||||
#
|
||||
# Make sure to have all dependencies installed:
|
||||
# pip3 install asyncio (if using parallel version of the script)
|
||||
#
|
||||
# You must provide raw ATOM or RSS 2.0 UTF-8 feed XML data as input, for example with curl:
|
||||
# curl 'http://rss.cnn.com/rss/edition.rss' | python ./scrape-full-articles.py "4"
|
||||
#
|
||||
# You must provide three command line arguments:
|
||||
# scrape-full-articles.py [NUMBER-OF-PARALLEL-THREADS]
|
||||
|
||||
import json
|
||||
import sys
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
# Globals.
|
||||
atom_ns = {"atom": "http://www.w3.org/2005/Atom"}
|
||||
article_parser_url = "https://us-central1-technews-251304.cloudfunctions.net/article-parser?url="
|
||||
|
||||
|
||||
# Methods.
|
||||
def process_article(article, is_rss, is_atom):
|
||||
try:
|
||||
# Extract link.
|
||||
scraped_article = ""
|
||||
|
||||
if is_rss:
|
||||
article_link = article.find("link").text
|
||||
elif is_atom:
|
||||
article_link = article.find("atom:link", atom_ns).attrib['href']
|
||||
|
||||
# Scrape with article-parser.
|
||||
link = article_parser_url + article_link
|
||||
|
||||
response = urllib.request.urlopen(link)
|
||||
text = response.read().decode("utf-8")
|
||||
js = json.loads(text)
|
||||
|
||||
if int(js["error"]) == 0:
|
||||
scraped_article = js["data"]["content"]
|
||||
|
||||
# Save scraped data.
|
||||
if scraped_article:
|
||||
if is_rss:
|
||||
article.find("description").text = scraped_article
|
||||
elif is_atom:
|
||||
article.find("atom:content", atom_ns).text = scraped_article
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
no_threads = int(sys.argv[1]) if len(sys.argv) >= 2 else 1
|
||||
|
||||
if no_threads > 1:
|
||||
import asyncio
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
sys.stdin.reconfigure(encoding="utf-8")
|
||||
|
||||
#feed_data = urllib.request.urlopen("https://dilbert.com/feed").read()
|
||||
feed_data = sys.stdin.read()
|
||||
feed_document = ET.fromstring(feed_data)
|
||||
|
||||
# Determine feed type.
|
||||
is_rss = feed_document.tag == "rss"
|
||||
is_atom = feed_document.tag == "{http://www.w3.org/2005/Atom}feed"
|
||||
|
||||
if not is_rss and not is_atom:
|
||||
sys.exit("Passed file is neither ATOM nor RSS 2.0 feed.")
|
||||
|
||||
# Extract articles.
|
||||
if is_rss:
|
||||
feed_articles = feed_document.findall(".//item")
|
||||
elif is_atom:
|
||||
feed_articles = feed_document.findall(".//atom:entry", atom_ns)
|
||||
|
||||
# Scrape articles.
|
||||
if no_threads > 1:
|
||||
with ThreadPoolExecutor(max_workers=no_threads) as executor:
|
||||
futures = []
|
||||
for article in feed_articles:
|
||||
futures.append(
|
||||
executor.submit(process_article, article, is_rss, is_atom))
|
||||
for future in futures:
|
||||
future.result()
|
||||
else:
|
||||
for article in feed_articles:
|
||||
process_article(article, is_rss, is_atom)
|
||||
|
||||
print(ET.tostring(feed_document, encoding="unicode"))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,56 +0,0 @@
|
||||
# Downloads full articles for RSS 2.0 feed and replaces original articles.
|
||||
#
|
||||
# Make sure to have all dependencies installed:
|
||||
# pip3 install newspaper3k
|
||||
# pip3 install asyncio (if using parallel version of the script)
|
||||
#
|
||||
# You must provide raw RSS 2.0 UTF-8 feed XML data as input, for example with curl:
|
||||
# curl 'http://rss.cnn.com/rss/edition.rss' | python ./scrape-rss2.py "4"
|
||||
#
|
||||
# You must provide three command line arguments:
|
||||
# scrape-rss2.py [NUMBER-OF-PARALLEL-THREADS]
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import html
|
||||
import requests
|
||||
import distutils.util
|
||||
import xml.etree.ElementTree as ET
|
||||
from newspaper import Article
|
||||
|
||||
no_threads = int(sys.argv[1])
|
||||
|
||||
if no_threads > 1:
|
||||
import asyncio
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
sys.stdin.reconfigure(encoding='utf-8')
|
||||
rss_data = sys.stdin.read()
|
||||
rss_document = ET.fromstring(rss_data)
|
||||
|
||||
def process_article(article):
|
||||
try:
|
||||
link = article.find("link").text
|
||||
|
||||
f = Article(link, keep_article_html = True)
|
||||
f.download()
|
||||
f.parse()
|
||||
article.find("description").text = f.article_html
|
||||
except:
|
||||
pass
|
||||
|
||||
# Scrape articles.
|
||||
if no_threads > 1:
|
||||
with ThreadPoolExecutor(max_workers = no_threads) as executor:
|
||||
futures = []
|
||||
for article in rss_document.findall(".//item"):
|
||||
futures.append(executor.submit(process_article, article))
|
||||
for future in futures:
|
||||
future.result()
|
||||
else:
|
||||
for article in rss_document.findall(".//item"):
|
||||
process_article(article)
|
||||
|
||||
print(ET.tostring(rss_document, encoding = "unicode"))
|
@ -1,16 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Transka executable.
|
||||
TRANSKA=./transka
|
||||
TRANSKA="$(dirname "$0")/transka/transka"
|
||||
|
||||
# Get credentials.
|
||||
read -p "Username: " USERNAME
|
||||
read -e -p "Username: " -i "martinrotter" USERNAME
|
||||
read -p "Password: " PASSWORD
|
||||
|
||||
# Setup parameters.
|
||||
RESOURCE=../../../localization/rssguard_en.ts
|
||||
RESOURCE="./localization/rssguard_en.ts"
|
||||
CODES="cs da de en_GB es fi fr gl he id it ja lt nl pl pt_BR pt_PT ru sv uk zh_CN zh_TW"
|
||||
TRANSLATION='../../../localization/rssguard_$CODE.ts'
|
||||
TRANSLATION='./localization/rssguard_$CODE.ts'
|
||||
|
||||
declare PARAMS
|
||||
|
||||
@ -20,6 +20,4 @@ for CODE in $CODES; do
|
||||
PARAMS+="-dt "$CODE" "$(eval echo $TRANSLATION)" "
|
||||
done
|
||||
|
||||
cd ./transka
|
||||
|
||||
$TRANSKA $PARAMS
|
||||
$TRANSKA $PARAMS
|
1
resources/skins/nudus-base/html_enclosure_every.html
Normal file
1
resources/skins/nudus-base/html_enclosure_every.html
Normal file
@ -0,0 +1 @@
|
||||
 / <a class="menc" href="%1"><span style="display:none"><!-- Cannot be removed -->%2</span><span style="text-transform: uppercase;">%3</span></a>
|
16
resources/skins/nudus-base/html_single_message.html
Normal file
16
resources/skins/nudus-base/html_single_message.html
Normal file
@ -0,0 +1,16 @@
|
||||
<div class="rssguard-mwrapper" dir="auto" id="%8">
|
||||
|
||||
<section class="rssguard-mhead">
|
||||
<div style="float: right; margin: 10px;"><!-- Should it remain here??? -->%7</div>
|
||||
<span class="msmall">%2</span>
|
||||
<h1>%1<span class="mlinks">%6<span class="mwrapurl"><a href="%3">URL</a><span> / </span></span></h1>
|
||||
<span class="msmall">%5</span>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="rssguard-mbody">
|
||||
%4
|
||||
</div>
|
||||
|
||||
</div>
|
432
resources/skins/nudus-base/html_style_base.scss
Normal file
432
resources/skins/nudus-base/html_style_base.scss
Normal file
@ -0,0 +1,432 @@
|
||||
// ___________________________
|
||||
// < I'm an expert in my field. >
|
||||
// ---------------------------
|
||||
// \ ^__^
|
||||
// \ (oo)\_______
|
||||
// (__)\ )\/\
|
||||
// ||----w |
|
||||
// || ||
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
|
||||
$base-unit: 10px !default;
|
||||
|
||||
//
|
||||
// Styling
|
||||
//
|
||||
|
||||
// Let the font be customised via RSS Guard settings
|
||||
// Note: Font size there related **only** to that font alone, it is
|
||||
// not absolute, and nothing else can be done from my side
|
||||
// E.g. "Roboto 10" <-- something like this is send from RSS Guard side
|
||||
* {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
//
|
||||
// Reset some basic elements
|
||||
//
|
||||
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Add some basic styling
|
||||
//
|
||||
|
||||
body {
|
||||
background-color: $cbg00;
|
||||
|
||||
box-sizing: border-box;
|
||||
color: $cfg00;
|
||||
//cursor: default;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-font-feature-settings: "kern" 1;
|
||||
font-feature-settings: "kern" 1;
|
||||
font-kerning: normal;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: $clink;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure,
|
||||
details {
|
||||
margin-bottom: $base-unit;
|
||||
}
|
||||
|
||||
hr {
|
||||
background-color: $cbor2;
|
||||
border: none;
|
||||
display: block;
|
||||
height: 2px;
|
||||
margin: $base-unit 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
h1 { font-size: 1.25rem !important; }
|
||||
h2 { font-size: 1.20rem !important; }
|
||||
h3 { font-size: 1.15rem !important; }
|
||||
h4 { font-size: 1.1rem !important; }
|
||||
h5 { font-size: 1rem !important; }
|
||||
h6 { font-size: .95rem !important; }
|
||||
|
||||
b {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 800 !important;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: oblique !important;
|
||||
}
|
||||
|
||||
mark {
|
||||
background-color: $cmark;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: .8rem !important;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: .9rem !important;
|
||||
}
|
||||
|
||||
abbr {
|
||||
cursor: help;
|
||||
font-style: italic !important;
|
||||
font-weight: 100 !important;
|
||||
}
|
||||
|
||||
q {
|
||||
font-style: italic !important;
|
||||
|
||||
&::before {
|
||||
content: '“';
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '”';
|
||||
}
|
||||
}
|
||||
|
||||
time {
|
||||
font-weight: 450 !important;
|
||||
}
|
||||
|
||||
var {
|
||||
font-style: oblique !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $clink;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
cite {
|
||||
font-style: italic !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: .8rem !important;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: .3em solid $cbor2;
|
||||
margin-left: 0;
|
||||
padding: 0 $base-unit;
|
||||
|
||||
&,
|
||||
p {
|
||||
color: $cfg11;
|
||||
}
|
||||
}
|
||||
|
||||
pre,
|
||||
code {
|
||||
border: 1px solid $cbor3;
|
||||
border-radius: $radius-unit;
|
||||
color: $cfg10;
|
||||
// cursor: text;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: $ccode;
|
||||
padding: 0 .25em;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: $ccodeblock;
|
||||
overflow-x: auto;
|
||||
padding: 7px 13px;
|
||||
tab-size: 2;
|
||||
// For <pre style='white-space:pre-wrap;'>
|
||||
white-space: pre !important;
|
||||
|
||||
// For <pre style='white-space:pre-wrap;width:81ex'>
|
||||
width: unset !important;
|
||||
|
||||
> code {
|
||||
background-color: unset;
|
||||
border: none;
|
||||
color: unset;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
tab-size: 2;
|
||||
}
|
||||
}
|
||||
|
||||
kbd {
|
||||
background: $ccode;
|
||||
border: 1px solid $cbor3;
|
||||
border-bottom: 3px solid darken($cbor3, 3%);
|
||||
border-radius: $radius-unit;
|
||||
box-shadow:
|
||||
0 2px 4px darken($cbg00, 6%),
|
||||
inset 0 1px $cbg00
|
||||
;
|
||||
font-size: .9rem !important;
|
||||
padding: .1em .4em .2em .4em;
|
||||
}
|
||||
|
||||
select {
|
||||
background-color: $ccodeblock;
|
||||
border: 1px solid $cbor3;
|
||||
border-radius: $radius-unit;
|
||||
color: $cfg00;
|
||||
padding: .04em .25em;
|
||||
// Do not use max-width here
|
||||
width: 100%;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
|
||||
background-color: $cbg00;
|
||||
}
|
||||
|
||||
> option {
|
||||
background-color: $cbg00;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
// `!important` is set to override something like <table width="900px">
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
// Return this if something goes wrong, and return the JS override for dark theme
|
||||
//table,
|
||||
//th,
|
||||
//td {
|
||||
// color: $cfg00;
|
||||
//}
|
||||
|
||||
li {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
|
||||
li ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-type: decimal;
|
||||
|
||||
li ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
// Let the width be defined (see .rssguard-mbody img), but keep aspect ratio
|
||||
height: auto;
|
||||
// `width auto` creates many problems even if set as a fallback
|
||||
//width: auto;
|
||||
}
|
||||
|
||||
details {
|
||||
border: 1px solid $ccodeblock;
|
||||
border-radius: $radius-unit;
|
||||
padding: .5em .5em 0;
|
||||
|
||||
> summary {
|
||||
background-color: $ccodeblock;
|
||||
border-radius: $radius-unit * 0.9;
|
||||
cursor: pointer;
|
||||
margin: -.5em -.5em 0;
|
||||
padding-left: .5em;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
& *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
details[open] {
|
||||
border-color: $cbor3;
|
||||
padding: .5em;
|
||||
|
||||
> summary {
|
||||
border-bottom: 1px solid $cbor3;
|
||||
border-radius: ($radius-unit * 0.9) ($radius-unit * 0.9) 0 0;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
}
|
||||
|
||||
iframe {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
a,
|
||||
select,
|
||||
summary {
|
||||
|
||||
&:focus {
|
||||
background-color: $cbor3;
|
||||
text-shadow: 0 -1px $cbg00;
|
||||
}
|
||||
}
|
||||
|
||||
:target {
|
||||
outline: 1px solid $clink;
|
||||
}
|
||||
|
||||
// m* == message*
|
||||
body:hover .rssguard-mwrapper .rssguard-mhead .mwrapurl {
|
||||
|
||||
a,
|
||||
span {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.rssguard-mwrapper .rssguard-mhead .mwrapurl a:focus {
|
||||
|
||||
&,
|
||||
& + span {
|
||||
visibility: visible !important;
|
||||
}
|
||||
}
|
||||
|
||||
.rssguard-mwrapper {
|
||||
padding: $base-unit !important;
|
||||
|
||||
.rssguard-mhead {
|
||||
|
||||
.msmall,
|
||||
.mlinks {
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
> h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.msmall {
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.mlinks {
|
||||
|
||||
.menc {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.mwrapurl {
|
||||
display: inline-flex;
|
||||
|
||||
a {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
a,
|
||||
span {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rssguard-mbody img {
|
||||
// Needs to be `!important` when max-width is defined by image style
|
||||
// <img src="https://....png" alt="alt" style="max-width: 100%;">
|
||||
max-width: 450px !important;
|
||||
// For cases when they both are set
|
||||
max-height: unset !important;
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
// `!important` to override `!important` that is set above
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Other
|
||||
//
|
||||
|
||||
// For articles without any html elements;
|
||||
// If not applied to _all_, *must* be applied to links in mbody
|
||||
// mbody == article body
|
||||
.rssguard-mbody {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
// Fix at least some mess produced by above
|
||||
table {
|
||||
word-break: normal;
|
||||
}
|
16
resources/skins/nudus-base/html_wrapper.html
Normal file
16
resources/skins/nudus-base/html_wrapper.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>%1</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
%style%
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
%2
|
||||
|
||||
</body>
|
||||
</html>
|
505
resources/skins/nudus-dark/html_style.css
Normal file
505
resources/skins/nudus-dark/html_style.css
Normal file
@ -0,0 +1,505 @@
|
||||
@charset "UTF-8";
|
||||
* {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #373A3D;
|
||||
box-sizing: border-box;
|
||||
color: #f5f5f5;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-font-feature-settings: "kern" 1;
|
||||
font-feature-settings: "kern" 1;
|
||||
font-kerning: normal;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: #8291AD;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure,
|
||||
details {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
hr {
|
||||
background-color: #545556;
|
||||
border: none;
|
||||
display: block;
|
||||
height: 2px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.25rem !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.20rem !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.15rem !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.1rem !important;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1rem !important;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: .95rem !important;
|
||||
}
|
||||
|
||||
b {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 800 !important;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: oblique !important;
|
||||
}
|
||||
|
||||
mark {
|
||||
background-color: #f8d08c66;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: .8rem !important;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: .9rem !important;
|
||||
}
|
||||
|
||||
abbr {
|
||||
cursor: help;
|
||||
font-style: italic !important;
|
||||
font-weight: 100 !important;
|
||||
}
|
||||
|
||||
q {
|
||||
font-style: italic !important;
|
||||
}
|
||||
q::before {
|
||||
content: '“';
|
||||
}
|
||||
q::after {
|
||||
content: '”';
|
||||
}
|
||||
|
||||
time {
|
||||
font-weight: 450 !important;
|
||||
}
|
||||
|
||||
var {
|
||||
font-style: oblique !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #8291AD;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
cite {
|
||||
font-style: italic !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: .8rem !important;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 0.3em solid #545556;
|
||||
margin-left: 0;
|
||||
padding: 0 10px;
|
||||
}
|
||||
blockquote,
|
||||
blockquote p {
|
||||
color: #D8D8D8;
|
||||
}
|
||||
|
||||
pre,
|
||||
code {
|
||||
border: 1px solid #282a2c;
|
||||
border-radius: 0.3em;
|
||||
color: #D8D8D8;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: rgba(33, 35, 39, 0.4);
|
||||
padding: 0 .25em;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: rgba(33, 35, 39, 0.4);
|
||||
overflow-x: auto;
|
||||
padding: 7px 13px;
|
||||
tab-size: 2;
|
||||
white-space: pre !important;
|
||||
width: unset !important;
|
||||
}
|
||||
pre > code {
|
||||
background-color: unset;
|
||||
border: none;
|
||||
color: unset;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
kbd {
|
||||
background: rgba(33, 35, 39, 0.4);
|
||||
border: 1px solid #282a2c;
|
||||
border-bottom: 3px solid #212224;
|
||||
border-radius: 0.3em;
|
||||
box-shadow: 0 2px 4px #282b2d, inset 0 1px #373A3D;
|
||||
font-size: .9rem !important;
|
||||
padding: .1em .4em .2em .4em;
|
||||
}
|
||||
|
||||
select {
|
||||
background-color: rgba(33, 35, 39, 0.4);
|
||||
border: 1px solid #282a2c;
|
||||
border-radius: 0.3em;
|
||||
color: #f5f5f5;
|
||||
padding: .04em .25em;
|
||||
width: 100%;
|
||||
}
|
||||
select:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
background-color: #373A3D;
|
||||
}
|
||||
select > option {
|
||||
background-color: #373A3D;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
li {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
ul li ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
ol li ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
img {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
details {
|
||||
border: 1px solid rgba(33, 35, 39, 0.4);
|
||||
border-radius: 0.3em;
|
||||
padding: .5em .5em 0;
|
||||
}
|
||||
details > summary {
|
||||
background-color: rgba(33, 35, 39, 0.4);
|
||||
border-radius: 0.27em;
|
||||
cursor: pointer;
|
||||
margin: -.5em -.5em 0;
|
||||
padding-left: .5em;
|
||||
}
|
||||
details > summary:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
details *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
details[open] {
|
||||
border-color: #282a2c;
|
||||
padding: .5em;
|
||||
}
|
||||
details[open] > summary {
|
||||
border-bottom: 1px solid #282a2c;
|
||||
border-radius: 0.27em 0.27em 0 0;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
iframe {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
a:focus,
|
||||
select:focus,
|
||||
summary:focus {
|
||||
background-color: #282a2c;
|
||||
text-shadow: 0 -1px #373A3D;
|
||||
}
|
||||
|
||||
:target {
|
||||
outline: 1px solid #8291AD;
|
||||
}
|
||||
|
||||
body:hover .rssguard-mwrapper .rssguard-mhead .mwrapurl a,
|
||||
body:hover .rssguard-mwrapper .rssguard-mhead .mwrapurl span {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.rssguard-mwrapper .rssguard-mhead .mwrapurl a:focus, .rssguard-mwrapper .rssguard-mhead .mwrapurl a:focus + span {
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
.rssguard-mwrapper {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .msmall,
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks {
|
||||
opacity: .8;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead > h1 {
|
||||
margin: 0;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .msmall {
|
||||
font-size: .9em;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .menc {
|
||||
word-break: break-word;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl {
|
||||
display: inline-flex;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a {
|
||||
order: 1;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a,
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl span {
|
||||
visibility: hidden;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mbody img {
|
||||
max-width: 450px !important;
|
||||
max-height: unset !important;
|
||||
}
|
||||
@media only screen and (max-width: 800px) {
|
||||
.rssguard-mwrapper .rssguard-mbody img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.rssguard-mbody {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
table {
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
html::before,
|
||||
html::after,
|
||||
body::before,
|
||||
body::after {
|
||||
content: "";
|
||||
background-color: #282a2c;
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
html::before {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
html::after {
|
||||
width: 1px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
body::before {
|
||||
height: 1px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
body::after {
|
||||
width: 1px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
height: 13px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: #37393c;
|
||||
box-shadow: inset 1px 1px #323437;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
border-radius: 0 0 0.3em 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
box-shadow: inset 1px 1px #565a5f, inset -1px -1px #565a5f, inset 0px 1px #565a5f, inset 0px -1px #565a5f, inset 1px 0px #565a5f, inset 1px -1px #565a5f, inset -1px 0px #565a5f, inset -1px 1px #565a5f;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:horizontal {
|
||||
background-image: linear-gradient(#414347 5%, #3c3e42);
|
||||
min-width: 25px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:horizontal:hover {
|
||||
background-image: linear-gradient(#43464a 25%, #3c3e42);
|
||||
}
|
||||
::-webkit-scrollbar-thumb:vertical {
|
||||
background-image: linear-gradient(to right, #414347 5%, #3c3e42);
|
||||
min-height: 25px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:vertical:hover {
|
||||
background-image: linear-gradient(to right, #43464a 25%, #3c3e42);
|
||||
}
|
||||
::-webkit-scrollbar-thumb:active {
|
||||
background-image: linear-gradient(#3c3e42, #3c3e42) !important;
|
||||
}
|
||||
|
||||
:not(body)::-webkit-scrollbar-thumb:horizontal {
|
||||
box-shadow: inset 1px 1px #565a5f, inset -1px -1px #565a5f, inset 0px 1px #565a5f, inset 0px -1px #565a5f, inset 1px 0px #565a5f, inset 1px -1px #565a5f, inset -1px 0px #565a5f, inset -1px 1px #565a5f, 1px 0px #282a2c, 1px 1px #282a2c, -1px 1px #282a2c, -1px 0px #282a2c;
|
||||
}
|
||||
:not(body)::-webkit-scrollbar-thumb:vertical {
|
||||
box-shadow: inset 1px 1px #565a5f, inset -1px -1px #565a5f, inset 0px 1px #565a5f, inset 0px -1px #565a5f, inset 1px 0px #565a5f, inset 1px -1px #565a5f, inset -1px 0px #565a5f, inset -1px 1px #565a5f, 0px -1px #282a2c, 1px -1px #282a2c, 1px 1px #282a2c, 0px 1px #282a2c;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:horizontal,
|
||||
::-webkit-scrollbar-track:horizontal {
|
||||
border-top: 1px solid #282a2c;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:vertical,
|
||||
::-webkit-scrollbar-track:vertical {
|
||||
border-left: 1px solid #282a2c;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-thumb:horizontal, body::-webkit-scrollbar-thumb:vertical,
|
||||
body::-webkit-scrollbar-track:horizontal,
|
||||
body::-webkit-scrollbar-track:vertical {
|
||||
border: 1px solid #282a2c;
|
||||
}
|
||||
body::-webkit-scrollbar-thumb:horizontal,
|
||||
body::-webkit-scrollbar-track:horizontal {
|
||||
border-top: none;
|
||||
}
|
||||
body::-webkit-scrollbar-thumb:vertical,
|
||||
body::-webkit-scrollbar-track:vertical {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-corner {
|
||||
border: 1px solid #282a2c;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track:corner-present:horizontal,
|
||||
::-webkit-scrollbar-thumb:corner-present:horizontal {
|
||||
border-radius: 0 0 0 0.3em;
|
||||
}
|
||||
::-webkit-scrollbar-track:corner-present:vertical,
|
||||
::-webkit-scrollbar-thumb:corner-present:vertical {
|
||||
border-radius: 0 0.3em 0 0;
|
||||
}
|
||||
::-webkit-scrollbar-track:horizontal,
|
||||
::-webkit-scrollbar-thumb:horizontal {
|
||||
border-radius: 0 0 0.3em 0.3em;
|
||||
}
|
||||
::-webkit-scrollbar-track:vertical,
|
||||
::-webkit-scrollbar-thumb:vertical {
|
||||
border-radius: 0 0.3em 0.3em 0;
|
||||
}
|
||||
|
||||
/* Please enable JS for additional font-colouring features */
|
||||
:root {
|
||||
--rssguard-red: 0;
|
||||
--rssguard-green: 0;
|
||||
--rssguard-blue: 0;
|
||||
--rssguard-threshold: 0.5;
|
||||
}
|
||||
|
||||
:root {
|
||||
--rssguard-r: calc(var(--rssguard-red) * 0.2126);
|
||||
--rssguard-g: calc(var(--rssguard-green) * 0.7152);
|
||||
--rssguard-b: calc(var(--rssguard-blue) * 0.0722);
|
||||
--rssguard-sum:
|
||||
calc(
|
||||
var(--rssguard-r) +
|
||||
var(--rssguard-g) +
|
||||
var(--rssguard-b)
|
||||
);
|
||||
--rssguard-perceived-lightness: calc(var(--rssguard-sum) / 255);
|
||||
}
|
||||
|
||||
body,
|
||||
::selection,
|
||||
mark, code, pre, pre > code,
|
||||
blockquote {
|
||||
color: hsla(0, 0%, calc( ( var(--rssguard-perceived-lightness) - var(--rssguard-threshold) ) * -10000000% ), 0.9);
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=html_style.css.map */
|
313
resources/skins/nudus-dark/html_style.scss
Normal file
313
resources/skins/nudus-dark/html_style.scss
Normal file
@ -0,0 +1,313 @@
|
||||
@charset "utf-8";
|
||||
|
||||
$qtbg-base: #373A3D !default; // clr_basbg
|
||||
$qtbg-button: #323437 !default; // clr_altbg // button bg (scrollbar, alt bg)
|
||||
$qcselbg: #8291AD !default; // clr_selbg
|
||||
|
||||
//
|
||||
// Emulate fusion colour processing (dark only)
|
||||
//
|
||||
|
||||
//
|
||||
// Scrollbar colours
|
||||
//
|
||||
|
||||
//$qcbgbg: lighten($qtbg-button, 6%); // See toolbar bg
|
||||
$bgscroll: lighten($qtbg-button, 2%) !default; // track and corner bg
|
||||
$tr-border: darken($qtbg-button, 4%) !default; // track brdr
|
||||
|
||||
//
|
||||
// Scrollbar thumb
|
||||
//
|
||||
|
||||
// bg gradient
|
||||
|
||||
// Normal
|
||||
$thscrlin: lighten($qtbg-button, 6%) !default;
|
||||
$thscrlout: lighten($qtbg-button, 4%) !default;
|
||||
|
||||
// Hover
|
||||
$thscrlhvin: lighten($qtbg-button, 7%) !default;
|
||||
$thscrlhvout: $thscrlout;
|
||||
|
||||
// Light outline
|
||||
$th-border: lighten($qtbg-button, 15%) !default;
|
||||
|
||||
//
|
||||
// HTML palette (Colours)
|
||||
//
|
||||
|
||||
$cbg00: $qtbg-base;
|
||||
|
||||
// Irrelevant, because fg is overridden by the switcher ~~~
|
||||
$cfg00: #f5f5f5 !default;
|
||||
$cfg10: #D8D8D8 !default;
|
||||
$cfg11: $cfg10;
|
||||
// ~~~
|
||||
|
||||
$cbor2: #545556 !default;
|
||||
|
||||
$ccodeblock: rgba(33, 35, 39, 0.4) !default;
|
||||
$ccode: $ccodeblock;
|
||||
$cbor3: $tr-border;
|
||||
$cmark: #f8d08c66 !default; // 40% transparency
|
||||
|
||||
$clink: $qcselbg;
|
||||
|
||||
//
|
||||
// Other
|
||||
//
|
||||
|
||||
$radius-unit: .3em !default;
|
||||
|
||||
@import
|
||||
"../nudus-base/html_style_base"
|
||||
;
|
||||
|
||||
//
|
||||
// Dark HTML-style has following additions:
|
||||
//
|
||||
|
||||
//
|
||||
// Border around viewport
|
||||
|
||||
// https://csswizardry.com/2010/12/simplified-page-borders-in-pure-css/
|
||||
//
|
||||
|
||||
html::before,
|
||||
html::after,
|
||||
body::before,
|
||||
body::after {
|
||||
content: "";
|
||||
background-color: $tr-border;
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
html::before {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
html::after {
|
||||
width: 1px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
body::before {
|
||||
height: 1px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
body::after {
|
||||
width: 1px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Enhanced scrollbar
|
||||
//
|
||||
|
||||
::-webkit-scrollbar {
|
||||
height: 13px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: $bgscroll;
|
||||
box-shadow: inset 1px 1px lighten($tr-border, 4%);
|
||||
}
|
||||
|
||||
// Part where vertical and horizontal scrollbars meet
|
||||
::-webkit-scrollbar-corner {
|
||||
border-radius: 0 0 $radius-unit 0;
|
||||
}
|
||||
|
||||
// TODO: Can be simplified to @include and function
|
||||
$th-outline:
|
||||
inset 1px 1px $th-border,
|
||||
inset -1px -1px $th-border,
|
||||
|
||||
inset 0px 1px $th-border,
|
||||
inset 0px -1px $th-border,
|
||||
|
||||
inset 1px 0px $th-border,
|
||||
inset 1px -1px $th-border,
|
||||
|
||||
inset -1px 0px $th-border,
|
||||
inset -1px 1px $th-border
|
||||
;
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
$th-min-unit: 25px;
|
||||
box-shadow: $th-outline;
|
||||
|
||||
&:horizontal {
|
||||
background-image: linear-gradient($thscrlin 5%, $thscrlout);
|
||||
min-width: $th-min-unit;
|
||||
|
||||
&:hover {
|
||||
background-image: linear-gradient($thscrlhvin 25%, $thscrlhvout);
|
||||
}
|
||||
}
|
||||
|
||||
&:vertical {
|
||||
background-image: linear-gradient(to right, $thscrlin 5%, $thscrlout);
|
||||
min-height: $th-min-unit;
|
||||
|
||||
&:hover {
|
||||
background-image: linear-gradient(to right, $thscrlhvin 25%, $thscrlhvout);
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-image: linear-gradient($thscrlout, $thscrlout) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Light and dark borders to outline the thumb
|
||||
// Clockwise (x y)
|
||||
:not(body)::-webkit-scrollbar-thumb {
|
||||
|
||||
&:horizontal {
|
||||
box-shadow:
|
||||
$th-outline,
|
||||
1px 0px $tr-border,
|
||||
1px 1px $tr-border,
|
||||
-1px 1px $tr-border,
|
||||
-1px 0px $tr-border
|
||||
;
|
||||
}
|
||||
|
||||
&:vertical {
|
||||
box-shadow:
|
||||
$th-outline,
|
||||
0px -1px $tr-border,
|
||||
1px -1px $tr-border,
|
||||
1px 1px $tr-border,
|
||||
0px 1px $tr-border
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb,
|
||||
::-webkit-scrollbar-track {
|
||||
|
||||
&:horizontal {
|
||||
border-top: 1px solid $tr-border;
|
||||
}
|
||||
|
||||
&:vertical {
|
||||
border-left: 1px solid $tr-border;
|
||||
}
|
||||
}
|
||||
|
||||
// More complete borders for `body` scrollbar
|
||||
body::-webkit-scrollbar-thumb,
|
||||
body::-webkit-scrollbar-track {
|
||||
|
||||
&:horizontal,
|
||||
&:vertical {
|
||||
border: 1px solid $tr-border;
|
||||
}
|
||||
|
||||
&:horizontal {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
&:vertical {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-corner {
|
||||
border: 1px solid $tr-border;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-thumb {
|
||||
|
||||
&:corner-present {
|
||||
|
||||
&:horizontal {
|
||||
border-radius: 0 0 0 $radius-unit;
|
||||
}
|
||||
|
||||
&:vertical {
|
||||
border-radius: 0 $radius-unit 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:horizontal {
|
||||
border-radius: 0 0 $radius-unit $radius-unit;
|
||||
}
|
||||
|
||||
&:vertical {
|
||||
border-radius: 0 $radius-unit $radius-unit 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Font colour switcher
|
||||
|
||||
// Thank you so much!!
|
||||
// https://css-tricks.com/switch-font-color-for-different-backgrounds-with-css/
|
||||
//
|
||||
|
||||
/* Please enable JS for additional font-colouring features */
|
||||
:root {
|
||||
// Default RGB values for background colour
|
||||
--rssguard-red: 0;
|
||||
--rssguard-green: 0;
|
||||
--rssguard-blue: 0;
|
||||
// The threshold at which colours are considered "light
|
||||
// Range: decimals from 0 to 1, recommended 0.5 - 0.6
|
||||
--rssguard-threshold: 0.5;
|
||||
}
|
||||
|
||||
:root {
|
||||
// Calculates perceived lightness using the sRGB Luma method
|
||||
// Luma = (red * 0.2126 + green * 0.7152 + blue * 0.0722) / 255
|
||||
--rssguard-r: calc(var(--rssguard-red) * 0.2126);
|
||||
--rssguard-g: calc(var(--rssguard-green) * 0.7152);
|
||||
--rssguard-b: calc(var(--rssguard-blue) * 0.0722);
|
||||
--rssguard-sum:
|
||||
calc(
|
||||
var(--rssguard-r) +
|
||||
var(--rssguard-g) +
|
||||
var(--rssguard-b)
|
||||
);
|
||||
--rssguard-perceived-lightness: calc(var(--rssguard-sum) / 255);
|
||||
}
|
||||
|
||||
// Shows either white or black colour depending on perceived lightness
|
||||
body,
|
||||
::selection,
|
||||
mark, code, pre, pre > code,
|
||||
blockquote {
|
||||
color:
|
||||
hsla(
|
||||
0,
|
||||
0%,
|
||||
calc(
|
||||
(
|
||||
var(--rssguard-perceived-lightness) -
|
||||
var(--rssguard-threshold)
|
||||
) *
|
||||
-10000000%
|
||||
),
|
||||
.9
|
||||
);
|
||||
}
|
29
resources/skins/nudus-dark/html_wrapper.html
Normal file
29
resources/skins/nudus-dark/html_wrapper.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>%1</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
%style%
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
%2
|
||||
|
||||
<script>
|
||||
const rssGuardroot = document.documentElement;
|
||||
rssGuardBody = document.body;
|
||||
let rssGuardColor = window.getComputedStyle(rssGuardBody).backgroundColor;
|
||||
rssGuardMatch = rssGuardColor.match(/(\w+)\((\d+), (\d+), (\d+)\)/);
|
||||
|
||||
if (rssGuardMatch != null) {
|
||||
rssGuardroot.style.setProperty('--rssguard-red', rssGuardMatch[2]);
|
||||
rssGuardroot.style.setProperty('--rssguard-green', rssGuardMatch[3]);
|
||||
rssGuardroot.style.setProperty('--rssguard-blue', rssGuardMatch[4]);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
13
resources/skins/nudus-dark/metadata.xml
Normal file
13
resources/skins/nudus-dark/metadata.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<skin version="0.1" base="nudus-base">
|
||||
<author>
|
||||
<name>akinokonomi</name>
|
||||
</author>
|
||||
<palette>
|
||||
<color key="FgInteresting" >#85ACF6</color>
|
||||
<color key="FgSelectedInteresting" >#D9E3F7</color>
|
||||
<color key="FgError" >#DF5656</color>
|
||||
<color key="FgSelectedError" >#910303</color>
|
||||
<color key="Allright" >#44AA44</color>
|
||||
</palette>
|
||||
</skin>
|
32
resources/skins/nudus-dark/qt_style.qss
Normal file
32
resources/skins/nudus-dark/qt_style.qss
Normal file
@ -0,0 +1,32 @@
|
||||
QListWidget,
|
||||
QScrollArea {
|
||||
border: 1px solid palette(dark);
|
||||
}
|
||||
|
||||
|
||||
QPlainTextEdit:focus {
|
||||
border: 1px solid palette(highlight);
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
background-color: palette(window);
|
||||
border: 1px solid palette(dark);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* TODO: Fine for now, may be improved in future */
|
||||
QProgressBar {
|
||||
background-color: palette(highlight);
|
||||
color: palette(window);
|
||||
}
|
||||
|
||||
QSplitter::handle {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
/*
|
||||
* For `qt5-styleplugins`: motif, cde, gtk2, etc.
|
||||
*/
|
||||
QStatusBar::item {
|
||||
border: none;
|
||||
}
|
353
resources/skins/nudus-light/html_style.css
Normal file
353
resources/skins/nudus-light/html_style.css
Normal file
@ -0,0 +1,353 @@
|
||||
@charset "UTF-8";
|
||||
* {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #FBFBFB;
|
||||
box-sizing: border-box;
|
||||
color: #000000;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-font-feature-settings: "kern" 1;
|
||||
font-feature-settings: "kern" 1;
|
||||
font-kerning: normal;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: #5D88D2;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure,
|
||||
details {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
hr {
|
||||
background-color: #CFCFCF;
|
||||
border: none;
|
||||
display: block;
|
||||
height: 2px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.25rem !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.20rem !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.15rem !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.1rem !important;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1rem !important;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: .95rem !important;
|
||||
}
|
||||
|
||||
b {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 800 !important;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: oblique !important;
|
||||
}
|
||||
|
||||
mark {
|
||||
background-color: #FFECCC;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: .8rem !important;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: .9rem !important;
|
||||
}
|
||||
|
||||
abbr {
|
||||
cursor: help;
|
||||
font-style: italic !important;
|
||||
font-weight: 100 !important;
|
||||
}
|
||||
|
||||
q {
|
||||
font-style: italic !important;
|
||||
}
|
||||
q::before {
|
||||
content: '“';
|
||||
}
|
||||
q::after {
|
||||
content: '”';
|
||||
}
|
||||
|
||||
time {
|
||||
font-weight: 450 !important;
|
||||
}
|
||||
|
||||
var {
|
||||
font-style: oblique !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #5D88D2;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
cite {
|
||||
font-style: italic !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: .8rem !important;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 0.3em solid #CFCFCF;
|
||||
margin-left: 0;
|
||||
padding: 0 10px;
|
||||
}
|
||||
blockquote,
|
||||
blockquote p {
|
||||
color: #343434;
|
||||
}
|
||||
|
||||
pre,
|
||||
code {
|
||||
border: 1px solid #DEDEDE;
|
||||
border-radius: 0.1em;
|
||||
color: #343434;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #F1F1F1;
|
||||
padding: 0 .25em;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #F1F1F1;
|
||||
overflow-x: auto;
|
||||
padding: 7px 13px;
|
||||
tab-size: 2;
|
||||
white-space: pre !important;
|
||||
width: unset !important;
|
||||
}
|
||||
pre > code {
|
||||
background-color: unset;
|
||||
border: none;
|
||||
color: unset;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
kbd {
|
||||
background: #F1F1F1;
|
||||
border: 1px solid #DEDEDE;
|
||||
border-bottom: 3px solid #d6d6d6;
|
||||
border-radius: 0.1em;
|
||||
box-shadow: 0 2px 4px #ececec, inset 0 1px #FBFBFB;
|
||||
font-size: .9rem !important;
|
||||
padding: .1em .4em .2em .4em;
|
||||
}
|
||||
|
||||
select {
|
||||
background-color: #F1F1F1;
|
||||
border: 1px solid #DEDEDE;
|
||||
border-radius: 0.1em;
|
||||
color: #000000;
|
||||
padding: .04em .25em;
|
||||
width: 100%;
|
||||
}
|
||||
select:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
background-color: #FBFBFB;
|
||||
}
|
||||
select > option {
|
||||
background-color: #FBFBFB;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
li {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
ul li ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
ol li ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
img {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
details {
|
||||
border: 1px solid #F1F1F1;
|
||||
border-radius: 0.1em;
|
||||
padding: .5em .5em 0;
|
||||
}
|
||||
details > summary {
|
||||
background-color: #F1F1F1;
|
||||
border-radius: 0.09em;
|
||||
cursor: pointer;
|
||||
margin: -.5em -.5em 0;
|
||||
padding-left: .5em;
|
||||
}
|
||||
details > summary:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
details *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
details[open] {
|
||||
border-color: #DEDEDE;
|
||||
padding: .5em;
|
||||
}
|
||||
details[open] > summary {
|
||||
border-bottom: 1px solid #DEDEDE;
|
||||
border-radius: 0.09em 0.09em 0 0;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
iframe {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
a:focus,
|
||||
select:focus,
|
||||
summary:focus {
|
||||
background-color: #DEDEDE;
|
||||
text-shadow: 0 -1px #FBFBFB;
|
||||
}
|
||||
|
||||
:target {
|
||||
outline: 1px solid #5D88D2;
|
||||
}
|
||||
|
||||
body:hover .rssguard-mwrapper .rssguard-mhead .mwrapurl a,
|
||||
body:hover .rssguard-mwrapper .rssguard-mhead .mwrapurl span {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.rssguard-mwrapper .rssguard-mhead .mwrapurl a:focus, .rssguard-mwrapper .rssguard-mhead .mwrapurl a:focus + span {
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
.rssguard-mwrapper {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .msmall,
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks {
|
||||
opacity: .8;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead > h1 {
|
||||
margin: 0;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .msmall {
|
||||
font-size: .9em;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .menc {
|
||||
word-break: break-word;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl {
|
||||
display: inline-flex;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a {
|
||||
order: 1;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a,
|
||||
.rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl span {
|
||||
visibility: hidden;
|
||||
}
|
||||
.rssguard-mwrapper .rssguard-mbody img {
|
||||
max-width: 450px !important;
|
||||
max-height: unset !important;
|
||||
}
|
||||
@media only screen and (max-width: 800px) {
|
||||
.rssguard-mwrapper .rssguard-mbody img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.rssguard-mbody {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
table {
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: #F1F1F1;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=html_style.css.map */
|
39
resources/skins/nudus-light/html_style.scss
Normal file
39
resources/skins/nudus-light/html_style.scss
Normal file
@ -0,0 +1,39 @@
|
||||
@charset "utf-8";
|
||||
|
||||
//
|
||||
// Colours
|
||||
//
|
||||
|
||||
$cbg00: #FBFBFB !default; // Background // Qt5 fusion bg light toolbar-grey
|
||||
|
||||
$cfg00: #000000 !default;
|
||||
//$cfg10: #A23542 !default; // TODO: fg for code
|
||||
$cfg11: #343434 !default; // Lighter fg for blockquote
|
||||
$cfg10: $cfg11;
|
||||
|
||||
$cbor2: #CFCFCF !default; // hr and blockquote border
|
||||
|
||||
$ccodeblock: #F1F1F1 !default; // bg for `pre > code` and `details > summ`
|
||||
$ccode: $ccodeblock !default; // bg for `code`
|
||||
$cbor3: #DEDEDE !default; // code/pre border
|
||||
$cmark: #FFECCC !default;
|
||||
|
||||
$clink: #5D88D2 !default; // Else use steelblue
|
||||
|
||||
//
|
||||
// Other
|
||||
//
|
||||
|
||||
$radius-unit: .1em !default;
|
||||
|
||||
@import
|
||||
"../nudus-base/html_style_base"
|
||||
;
|
||||
|
||||
//
|
||||
// Light style has following additions:
|
||||
//
|
||||
|
||||
::selection {
|
||||
color: #F1F1F1;
|
||||
}
|
13
resources/skins/nudus-light/metadata.xml
Normal file
13
resources/skins/nudus-light/metadata.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<skin version="0.1" base="nudus-base">
|
||||
<author>
|
||||
<name>akinokonomi</name>
|
||||
</author>
|
||||
<palette>
|
||||
<color key="FgInteresting" >#3A6FE4</color>
|
||||
<color key="FgSelectedInteresting" >#F0F2FC</color>
|
||||
<color key="FgError" >#E74343</color>
|
||||
<color key="FgSelectedError" >#FFD7D7</color>
|
||||
<color key="Allright" >#77dd77</color>
|
||||
</palette>
|
||||
</skin>
|
14
resources/skins/nudus-light/qt_style.qss
Normal file
14
resources/skins/nudus-light/qt_style.qss
Normal file
@ -0,0 +1,14 @@
|
||||
QPlainTextEdit:focus {
|
||||
border: 1px solid palette(highlight);
|
||||
}
|
||||
|
||||
QSplitter::handle {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
/*
|
||||
* For `qt5-styleplugins`: motif, cde, gtk2, etc.
|
||||
*/
|
||||
QStatusBar::item {
|
||||
border: none;
|
||||
}
|
@ -1 +0,0 @@
|
||||
 / <a class="rssguard-menc" href="%1"><span style="display:none"><!-- Cannot be removed -->%2</span><span style="text-transform: uppercase;">%3</span></a>
|
@ -1,12 +0,0 @@
|
||||
<div class="rssguard-mwrapper" dir="auto">
|
||||
<section class="rssguard-mhead">
|
||||
<div style="float: right; margin: 10px;"><!-- Should it remain here??? -->%7</div>
|
||||
<span class="rssguard-msmall">%2</span>
|
||||
<h1>%1<span class="rssguard-mlinks">%6<span class="rssguard-murl"> / <a href="%3">URL</a></span></span></h1>
|
||||
<span class="rssguard-msmall">%5</span>
|
||||
</section>
|
||||
<hr>
|
||||
<div class="rssguard-mbody">
|
||||
%4
|
||||
</div>
|
||||
</div>
|
@ -1,287 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
___________________________
|
||||
< I'm an expert in my field. >
|
||||
---------------------------
|
||||
\ ^__^
|
||||
\ (oo)\_______
|
||||
(__)\ )\/\
|
||||
||----w |
|
||||
|| ||
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
:root {
|
||||
--rssguard-base-unit: 10px;
|
||||
--rssguard-em-unit: .3em;
|
||||
|
||||
/* Qt5 fusion border grey */
|
||||
--rssguard-grey01: #B8B8B8;
|
||||
|
||||
/* Some other grey */
|
||||
--rssguard-grey02: #CFCFCF;
|
||||
--rssguard-grey10: #343434;
|
||||
--rssguard-grey20: #F1F1F1;
|
||||
}
|
||||
article, aside, details, div, dt,
|
||||
figcaption, footer, form, header,
|
||||
hgroup, html, main, nav, section, summary {
|
||||
display: block;
|
||||
}
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure {
|
||||
margin-bottom: var(--rssguard-base-unit);
|
||||
}
|
||||
body {
|
||||
/*
|
||||
* Another Qt grey;
|
||||
* bg required for "newspaper mode"
|
||||
*/
|
||||
background-color: #FBFBFB;
|
||||
|
||||
box-sizing: border-box;
|
||||
cursor: default;
|
||||
font-kerning: normal;
|
||||
|
||||
/* redundant? */
|
||||
-webkit-font-feature-settings: "kern" 1;
|
||||
font-feature-settings: "kern" 1;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
h1 { font-size: 1.25em !important; }
|
||||
h2 { font-size: 1.20em !important; }
|
||||
h3 { font-size: 1.15em !important; }
|
||||
h4 { font-size: 1.1em !important; }
|
||||
h5 { font-size: 1em !important; }
|
||||
h6 { font-size: .95em !important; }
|
||||
b {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
i {
|
||||
font-style: italic !important;
|
||||
}
|
||||
strong {
|
||||
font-weight: 800 !important;
|
||||
}
|
||||
em {
|
||||
font-style: oblique !important;
|
||||
}
|
||||
mark {
|
||||
background-color: #FFECCC;
|
||||
}
|
||||
sub,
|
||||
sup {
|
||||
font-size: .8em !important;
|
||||
}
|
||||
small {
|
||||
font-size: .9em !important;
|
||||
}
|
||||
q {
|
||||
font-style: italic !important;
|
||||
}
|
||||
q::before {
|
||||
content: '“';
|
||||
}
|
||||
q::after {
|
||||
content: '”';
|
||||
}
|
||||
a {
|
||||
color: steelblue;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
cite {
|
||||
font-style: italic !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
figcaption {
|
||||
font-size: .8em !important;
|
||||
}
|
||||
blockquote {
|
||||
color: var(--rssguard-grey10);
|
||||
border-left: var(--rssguard-em-unit) solid var(--rssguard-grey02);
|
||||
margin-left: 0;
|
||||
padding: 0 var(--rssguard-base-unit);
|
||||
}
|
||||
pre,
|
||||
code {
|
||||
background-color: var(--rssguard-grey20);
|
||||
cursor: text;
|
||||
}
|
||||
pre {
|
||||
--rssguard-horiz: 13px;
|
||||
|
||||
border-radius: var(--rssguard-em-unit);
|
||||
overflow-x: auto;
|
||||
padding: 7px var(--rssguard-horiz);
|
||||
white-space: pre !important;
|
||||
width: calc(100wv - calc(var(--rssguard-horiz) * 2)) !important;
|
||||
}
|
||||
code {
|
||||
border-radius: var(--rssguard-em-unit);
|
||||
color: var(--rssguard-grey10);
|
||||
padding: 0 .25em;
|
||||
word-break: break-word;
|
||||
}
|
||||
pre code {
|
||||
display: block;
|
||||
padding: 0;
|
||||
tab-size: 4;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
table,
|
||||
th,
|
||||
td {
|
||||
border: 1px solid var(--rssguard-grey01);
|
||||
}
|
||||
li {
|
||||
display: list-item;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
ul {
|
||||
display: block;
|
||||
list-style-type: circle;
|
||||
}
|
||||
ul li ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
ol {
|
||||
display: block;
|
||||
list-style-type: decimal;
|
||||
}
|
||||
ol li ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
img {
|
||||
/* redundant? */
|
||||
display: inline-block;
|
||||
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
details > summary {
|
||||
border-radius: var(--rssguard-em-unit);
|
||||
cursor: pointer;
|
||||
}
|
||||
details > summary:hover,
|
||||
details[open] > summary {
|
||||
background-color: var(--rssguard-grey20);
|
||||
}
|
||||
details > summary:focus {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
hr {
|
||||
background-color: var(--rssguard-grey02);
|
||||
border: none;
|
||||
display: block;
|
||||
height: 2px;
|
||||
margin: var(--rssguard-base-unit) 0;
|
||||
}
|
||||
iframe {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
select {
|
||||
max-width: 100%;
|
||||
}
|
||||
.rssguard-mwrapper {
|
||||
padding: var(--rssguard-base-unit) !important;
|
||||
}
|
||||
.rssguard-mhead .rssguard-msmall,
|
||||
.rssguard-mhead .rssguard-mlinks {
|
||||
opacity: .8;
|
||||
}
|
||||
.rssguard-mhead h1 {
|
||||
margin: 0;
|
||||
}
|
||||
.rssguard-msmall {
|
||||
font-size: .9em;
|
||||
}
|
||||
.rssguard-mlinks a.rssguard-menc {
|
||||
word-break: break-word;
|
||||
}
|
||||
.rssguard-murl {
|
||||
visibility: hidden;
|
||||
}
|
||||
body:hover .rssguard-mwrapper .rssguard-murl {
|
||||
visibility: visible;
|
||||
}
|
||||
@media only screen and (max-width: 800px) {
|
||||
|
||||
.rssguard-mbody img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
.rssguard-mbody img {
|
||||
max-width: 450px;
|
||||
}
|
||||
.rssguard-mbody {
|
||||
/*
|
||||
* For articles without html elements;
|
||||
* Not sure if I want to apply this to *all*;
|
||||
* otherwise *must* be applied to links in mbody
|
||||
*/
|
||||
word-break: break-word;
|
||||
}
|
||||
/* Fix at least some mess produced by above */
|
||||
table {
|
||||
word-break: normal;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
font: inherit;
|
||||
font-size: 100%;
|
||||
}
|
||||
html {
|
||||
height: 100vh;
|
||||
}
|
||||
body {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
<title>%1</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
%2
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<skin version="0.01">
|
||||
<author>
|
||||
<name>Maki Blackwell</name>
|
||||
</author>
|
||||
<palette>
|
||||
<color key="FgInteresting">#3A4EE4</color>
|
||||
<color key="FgSelectedInteresting">#ff66cc</color>
|
||||
<color key="FgError">#4EE43A</color>
|
||||
<color key="FgSelectedError">#ff99ff</color>
|
||||
<color key="Allright">#00ff99</color>
|
||||
</palette>
|
||||
</skin>
|
@ -1,11 +0,0 @@
|
||||
QTextEdit {
|
||||
selection-background-color: #4861f0;
|
||||
}
|
||||
|
||||
QStatusBar::item {
|
||||
border: none;
|
||||
}
|
||||
|
||||
QSplitter::handle {
|
||||
background: rgba(117, 117, 117, 0.5);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<div class="card filled fluid" dir="auto">
|
||||
<div class="card filled fluid" dir="auto" id="%8">
|
||||
<h5 class="doc section">%1 <a class="button small primary" href="%3">🔗URL</a> %6</h5>
|
||||
<div class="doc section">
|
||||
<div style="text-align: center;">
|
||||
|
@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<skin version="0.24">
|
||||
<skin version="0.25">
|
||||
<author>
|
||||
<name>Martin Rotter</name>
|
||||
</author>
|
||||
<palette>
|
||||
<color key="FgInteresting">#3A4EE4</color>
|
||||
<color key="FgSelectedInteresting">#ff66cc</color>
|
||||
<color key="FgError">#4EE43A</color>
|
||||
<color key="FgSelectedError">#ff99ff</color>
|
||||
<color key="Allright">#00ff99</color>
|
||||
<color key="FgInteresting" >#3A4EE4</color>
|
||||
<color key="FgSelectedInteresting" >#F0F2FC</color>
|
||||
<color key="FgError" >#DF5656</color>
|
||||
<color key="FgSelectedError" >#FFD7D7</color>
|
||||
<color key="Allright" >#77dd77</color>
|
||||
</palette>
|
||||
</skin>
|
@ -198,7 +198,15 @@ bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right
|
||||
bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const {
|
||||
bool should_show = filterAcceptsRowInternal(source_row, source_parent);
|
||||
|
||||
qDebugNN << LOGSEC_CORE
|
||||
<< "Filter accepts row"
|
||||
<< QUOTE_W_SPACE(m_sourceModel->itemForIndex(m_sourceModel->index(source_row, 0, source_parent))->title())
|
||||
<< "and filter result is:"
|
||||
<< QUOTE_W_SPACE_DOT(should_show);
|
||||
|
||||
if (should_show && m_hiddenIndices.contains(QPair<int, QModelIndex>(source_row, source_parent))) {
|
||||
qDebugNN << LOGSEC_CORE << "Item was previously hidden and now shows up, expand.";
|
||||
|
||||
const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.removeAll(QPair<int, QModelIndex>(source_row, source_parent));
|
||||
|
||||
// Load status.
|
||||
@ -213,10 +221,6 @@ bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source
|
||||
}
|
||||
|
||||
bool FeedsProxyModel::filterAcceptsRowInternal(int source_row, const QModelIndex& source_parent) const {
|
||||
if (!m_showUnreadOnly) {
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
|
||||
const QModelIndex idx = m_sourceModel->index(source_row, 0, source_parent);
|
||||
|
||||
if (!idx.isValid()) {
|
||||
@ -225,18 +229,23 @@ bool FeedsProxyModel::filterAcceptsRowInternal(int source_row, const QModelIndex
|
||||
|
||||
const RootItem* item = m_sourceModel->itemForIndex(idx);
|
||||
|
||||
if (item->kind() != RootItem::Kind::Category && item->kind() != RootItem::Kind::Feed) {
|
||||
if (item->kind() != RootItem::Kind::Category &&
|
||||
item->kind() != RootItem::Kind::Feed &&
|
||||
item->kind() != RootItem::Kind::Label) {
|
||||
// Some items are always visible.
|
||||
return true;
|
||||
}
|
||||
else if (item->isParentOf(m_selectedItem) /* || item->isChildOf(m_selectedItem)*/ || m_selectedItem == item) {
|
||||
// Currently selected item and all its parents and children must be displayed.
|
||||
return true;
|
||||
|
||||
if (!m_showUnreadOnly) {
|
||||
// Take only regexp filtering into account.
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
else {
|
||||
// NOTE: If item has < 0 of unread message it may mean, that the count
|
||||
// of unread messages is not (yet) known, display that item too.
|
||||
return item->countOfUnreadMessages() != 0;
|
||||
return
|
||||
item->countOfUnreadMessages() != 0 &&
|
||||
QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,14 @@
|
||||
#include "core/filterutils.h"
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
#include "miscellaneous/iofactory.h"
|
||||
#include "miscellaneous/textfactory.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QHostInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QProcess>
|
||||
|
||||
FilterUtils::FilterUtils(QObject* parent) : QObject(parent) {}
|
||||
|
||||
@ -84,3 +86,7 @@ QString FilterUtils::fromXmlToJson(const QString& xml) const {
|
||||
QDateTime FilterUtils::parseDateTime(const QString& dat) const {
|
||||
return TextFactory::parseDateTime(dat);
|
||||
}
|
||||
|
||||
QString FilterUtils::runExecutableGetOutput(const QString& executable, const QStringList& arguments) const {
|
||||
return IOFactory::startProcessGetOutput(executable, arguments);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ class FilterUtils : public QObject {
|
||||
|
||||
// Parses string into date/time object.
|
||||
Q_INVOKABLE QDateTime parseDateTime(const QString& dat) const;
|
||||
Q_INVOKABLE QString runExecutableGetOutput(const QString& executable, const QStringList& arguments = {}) const;
|
||||
};
|
||||
|
||||
#endif // FILTERUTILS_H
|
||||
|
@ -431,7 +431,9 @@ bool DatabaseQueries::purgeReadMessages(const QSqlDatabase& db) {
|
||||
|
||||
bool DatabaseQueries::purgeOldMessages(const QSqlDatabase& db, int older_than_days) {
|
||||
QSqlQuery q(db);
|
||||
const qint64 since_epoch = QDateTime::currentDateTimeUtc().addDays(-older_than_days).toMSecsSinceEpoch();
|
||||
const qint64 since_epoch = older_than_days == 0
|
||||
? QDateTime::currentDateTimeUtc().addYears(10).toMSecsSinceEpoch()
|
||||
: QDateTime::currentDateTimeUtc().addDays(-older_than_days).toMSecsSinceEpoch();
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(QSL("DELETE FROM Messages WHERE is_important = :is_important AND date_created < :date_created;"));
|
||||
|
@ -143,6 +143,12 @@
|
||||
#define DEFAULT_ZOOM_FACTOR 1.0f
|
||||
#define ZOOM_FACTOR_STEP 0.1f
|
||||
|
||||
#if defined(USE_WEBENGINE)
|
||||
#define HTTP_COMPLETE_USERAGENT (QWebEngineProfile::defaultProfile()->httpUserAgent().toLocal8Bit() + QByteArrayLiteral(" ") + QByteArrayLiteral(APP_USERAGENT))
|
||||
#else
|
||||
#define HTTP_COMPLETE_USERAGENT (QByteArrayLiteral(APP_USERAGENT))
|
||||
#endif
|
||||
|
||||
#define INTERNAL_URL_MESSAGE "http://rssguard.message"
|
||||
#define INTERNAL_URL_BLANK "http://rssguard.blank"
|
||||
#define INTERNAL_URL_ADBLOCKED "http://rssguard.adblocked"
|
||||
|
@ -36,8 +36,8 @@ FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const Q
|
||||
|
||||
m_ui.m_treeFeeds->setIndentation(FEEDS_VIEW_INDENTATION);
|
||||
m_ui.m_treeFeeds->setModel(m_feedsModel);
|
||||
m_ui.m_btnCheckAll->setIcon(qApp->icons()->fromTheme(QSL("dialog-yes")));
|
||||
m_ui.m_btnUncheckAll->setIcon(qApp->icons()->fromTheme(QSL("dialog-no")));
|
||||
m_ui.m_btnCheckAll->setIcon(qApp->icons()->fromTheme(QSL("dialog-yes"), QSL("edit-select-all")));
|
||||
m_ui.m_btnUncheckAll->setIcon(qApp->icons()->fromTheme(QSL("dialog-no"), QSL("edit-select-none")));
|
||||
m_ui.m_btnAddNew->setIcon(qApp->icons()->fromTheme(QSL("list-add")));
|
||||
m_ui.m_btnRemoveSelected->setIcon(qApp->icons()->fromTheme(QSL("list-remove")));
|
||||
m_ui.m_btnBeautify->setIcon(qApp->icons()->fromTheme(QSL("format-justify-fill")));
|
||||
@ -152,8 +152,14 @@ void FormMessageFiltersManager::removeSelectedFilter() {
|
||||
return;
|
||||
}
|
||||
|
||||
m_reader->removeMessageFilter(fltr);
|
||||
delete m_ui.m_listFilters->currentItem();
|
||||
if (MessageBox::show(this, QMessageBox::Icon::Question, tr("Are you sure?"),
|
||||
tr("Do you really want to remove selected filter?"),
|
||||
{}, fltr->name(),
|
||||
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No,
|
||||
QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
|
||||
m_reader->removeMessageFilter(fltr);
|
||||
delete m_ui.m_listFilters->currentItem();
|
||||
}
|
||||
}
|
||||
|
||||
void FormMessageFiltersManager::loadFilters() {
|
||||
|
@ -106,6 +106,14 @@ void FeedsView::saveExpandStates(RootItem* item) {
|
||||
QModelIndex source_index = sourceModel()->indexForItem(it);
|
||||
QModelIndex visible_index = model()->mapFromSource(source_index);
|
||||
|
||||
// TODO: Think.
|
||||
|
||||
/*
|
||||
if (isRowHidden(visible_index.row(), visible_index.parent())) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
settings->setValue(GROUP(CategoriesExpandStates),
|
||||
setting_name,
|
||||
isExpanded(visible_index));
|
||||
@ -550,7 +558,9 @@ void FeedsView::focusInEvent(QFocusEvent* event) {
|
||||
|
||||
void FeedsView::expandItemDelayed(const QModelIndex& idx) {
|
||||
QTimer::singleShot(100, this, [=] {
|
||||
setExpanded(m_proxyModel->mapFromSource(idx), true);
|
||||
QModelIndex pidx = m_proxyModel->mapFromSource(idx);
|
||||
|
||||
setExpanded(pidx, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,6 @@ SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(se
|
||||
|
||||
// Setup skins.
|
||||
m_ui->m_treeSkins->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
|
||||
|
||||
m_ui->m_treeSkins->header()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents);
|
||||
m_ui->m_treeSkins->header()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents);
|
||||
|
||||
@ -238,7 +237,7 @@ void SettingsGui::loadSettings() {
|
||||
clr_btn->setObjectName(QString::number(enumer.value(i)));
|
||||
clr_btn->setColor(clr);
|
||||
|
||||
auto* lay = new QHBoxLayout(this);
|
||||
auto* lay = new QHBoxLayout();
|
||||
|
||||
lay->addWidget(clr_btn);
|
||||
lay->addWidget(rst_btn);
|
||||
@ -251,7 +250,6 @@ void SettingsGui::loadSettings() {
|
||||
m_ui->m_layoutCustomColors->setLayout(row,
|
||||
QFormLayout::ItemRole::FieldRole,
|
||||
lay);
|
||||
|
||||
}
|
||||
|
||||
onEndLoadSettings();
|
||||
|
@ -101,6 +101,8 @@ Application::Application(const QString& id, int& argc, char** argv)
|
||||
#if defined(USE_WEBENGINE)
|
||||
m_webFactory->urlIinterceptor()->load();
|
||||
|
||||
QWebEngineProfile::defaultProfile()->setHttpUserAgent(QString(HTTP_COMPLETE_USERAGENT));
|
||||
|
||||
connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, this, &Application::downloadRequested);
|
||||
connect(m_webFactory->adBlock(), &AdBlockManager::processTerminated, this, &Application::onAdBlockFailure);
|
||||
|
||||
|
@ -93,6 +93,32 @@ bool IOFactory::startProcessDetached(const QString& program, const QStringList&
|
||||
return process.startDetached(nullptr);
|
||||
}
|
||||
|
||||
QString IOFactory::startProcessGetOutput(const QString& executable,
|
||||
const QStringList& arguments,
|
||||
const QProcessEnvironment& pe) {
|
||||
QProcess proc;
|
||||
|
||||
proc.setProgram(executable);
|
||||
proc.setArguments(arguments);
|
||||
|
||||
QProcessEnvironment system_pe = QProcessEnvironment::systemEnvironment();
|
||||
|
||||
system_pe.insert(pe);
|
||||
proc.setProcessEnvironment(system_pe);
|
||||
proc.start();
|
||||
|
||||
if (proc.waitForFinished() &&
|
||||
proc.exitStatus() == QProcess::ExitStatus::NormalExit &&
|
||||
proc.exitCode() == EXIT_SUCCESS) {
|
||||
return proc.readAllStandardOutput();
|
||||
}
|
||||
else {
|
||||
QString err = proc.readAllStandardError().simplified();
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray IOFactory::readFile(const QString& file_path) {
|
||||
QFile input_file(file_path);
|
||||
QByteArray input_data;
|
||||
@ -121,6 +147,14 @@ void IOFactory::writeFile(const QString& file_path, const QByteArray& data) {
|
||||
|
||||
bool IOFactory::copyFile(const QString& source, const QString& destination) {
|
||||
if (QFile::exists(destination)) {
|
||||
QFile file(destination);
|
||||
|
||||
file.setPermissions(file.permissions() |
|
||||
QFileDevice::WriteOwner |
|
||||
QFileDevice::WriteUser |
|
||||
QFileDevice::WriteGroup |
|
||||
QFileDevice::WriteOther);
|
||||
|
||||
if (!QFile::remove(destination)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
|
||||
#include <QProcessEnvironment>
|
||||
#include <QStandardPaths>
|
||||
|
||||
class IOFactory {
|
||||
@ -31,6 +32,9 @@ class IOFactory {
|
||||
const QStringList& arguments,
|
||||
const QString& native_arguments = {},
|
||||
const QString& working_directory = {});
|
||||
static QString startProcessGetOutput(const QString& executable,
|
||||
const QStringList& arguments = {},
|
||||
const QProcessEnvironment& pe = {});
|
||||
|
||||
// Returns contents of a file.
|
||||
// Throws exception when no such file exists.
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#if !defined(Q_OS_OS2)
|
||||
#include <QMediaPlayer>
|
||||
#include <QSoundEffect>
|
||||
|
||||
#if QT_VERSION_MAJOR == 6
|
||||
#include <QAudioOutput>
|
||||
@ -36,50 +37,77 @@ void Notification::setSoundPath(const QString& sound_path) {
|
||||
void Notification::playSound(Application* app) const {
|
||||
if (!m_soundPath.isEmpty()) {
|
||||
#if !defined(Q_OS_OS2)
|
||||
QMediaPlayer* play = new QMediaPlayer(app);
|
||||
if (m_soundPath.endsWith(QSL(".wav"), Qt::CaseSensitivity::CaseInsensitive)) {
|
||||
qDebugNN << LOGSEC_CORE << "Using QSoundEffect to play notification sound.";
|
||||
|
||||
QSoundEffect* play = new QSoundEffect(app);
|
||||
|
||||
QObject::connect(play, &QSoundEffect::playingChanged, play, [play]() {
|
||||
if (!play->isPlaying()) {
|
||||
play->deleteLater();
|
||||
}
|
||||
});
|
||||
|
||||
if (m_soundPath.startsWith(QSL(":"))) {
|
||||
play->setSource(QUrl(QSL("qrc") + m_soundPath));
|
||||
|
||||
}
|
||||
else {
|
||||
play->setSource(QUrl::fromLocalFile(
|
||||
QDir::toNativeSeparators(app->replaceDataUserDataFolderPlaceholder(m_soundPath))));
|
||||
}
|
||||
|
||||
play->setVolume(m_volume);
|
||||
play->play();
|
||||
}
|
||||
else {
|
||||
qDebugNN << LOGSEC_CORE << "Using QMediaPlayer to play notification sound.";
|
||||
|
||||
QMediaPlayer* play = new QMediaPlayer(app);
|
||||
|
||||
#if QT_VERSION_MAJOR == 6
|
||||
QAudioOutput* out = new QAudioOutput(app);
|
||||
QAudioOutput* out = new QAudioOutput(app);
|
||||
|
||||
play->setAudioOutput(out);
|
||||
play->setAudioOutput(out);
|
||||
|
||||
QObject::connect(play, &QMediaPlayer::playbackStateChanged, play, [play, out](QMediaPlayer::PlaybackState state) {
|
||||
if (state == QMediaPlayer::PlaybackState::StoppedState) {
|
||||
out->deleteLater();
|
||||
play->deleteLater();
|
||||
}
|
||||
});
|
||||
|
||||
if (m_soundPath.startsWith(QSL(":"))) {
|
||||
play->setSource(QUrl(QSL("qrc") + m_soundPath));
|
||||
|
||||
QObject::connect(play, &QMediaPlayer::playbackStateChanged, play, [play, out](QMediaPlayer::PlaybackState state) {
|
||||
if (state == QMediaPlayer::PlaybackState::StoppedState) {
|
||||
out->deleteLater();
|
||||
play->deleteLater();
|
||||
}
|
||||
});
|
||||
else {
|
||||
play->setSource(QUrl::fromLocalFile(QDir::toNativeSeparators(app->replaceDataUserDataFolderPlaceholder(m_soundPath))));
|
||||
}
|
||||
|
||||
if (m_soundPath.startsWith(QSL(":"))) {
|
||||
play->setSource(QUrl(QSL("qrc") + m_soundPath));
|
||||
|
||||
}
|
||||
else {
|
||||
play->setSource(QUrl::fromLocalFile(QDir::toNativeSeparators(app->replaceDataUserDataFolderPlaceholder(m_soundPath))));
|
||||
}
|
||||
|
||||
play->audioOutput()->setVolume((m_volume * 1.0f) / 100.0f);
|
||||
play->play();
|
||||
play->audioOutput()->setVolume((m_volume * 1.0f) / 100.0f);
|
||||
play->play();
|
||||
#else
|
||||
QObject::connect(play, &QMediaPlayer::stateChanged, play, [play](QMediaPlayer::State state) {
|
||||
if (state == QMediaPlayer::State::StoppedState) {
|
||||
play->deleteLater();
|
||||
QObject::connect(play, &QMediaPlayer::stateChanged, play, [play](QMediaPlayer::State state) {
|
||||
if (state == QMediaPlayer::State::StoppedState) {
|
||||
play->deleteLater();
|
||||
}
|
||||
});
|
||||
|
||||
if (m_soundPath.startsWith(QSL(":"))) {
|
||||
play->setMedia(QMediaContent(QUrl(QSL("qrc") + m_soundPath)));
|
||||
|
||||
}
|
||||
else {
|
||||
play->setMedia(QMediaContent(
|
||||
QUrl::fromLocalFile(
|
||||
QDir::toNativeSeparators(app->replaceDataUserDataFolderPlaceholder(m_soundPath)))));
|
||||
}
|
||||
});
|
||||
|
||||
if (m_soundPath.startsWith(QSL(":"))) {
|
||||
play->setMedia(QMediaContent(QUrl(QSL("qrc") + m_soundPath)));
|
||||
|
||||
}
|
||||
else {
|
||||
play->setMedia(QMediaContent(
|
||||
QUrl::fromLocalFile(
|
||||
QDir::toNativeSeparators(app->replaceDataUserDataFolderPlaceholder(m_soundPath)))));
|
||||
}
|
||||
|
||||
play->setVolume(m_volume);
|
||||
play->play();
|
||||
play->setVolume(m_volume);
|
||||
play->play();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -68,36 +68,40 @@ void SkinFactory::loadSkinFromData(const Skin& skin) {
|
||||
qDebugNN << LOGSEC_GUI << "Activating dark palette for Fusion style.";
|
||||
|
||||
QPalette fusion_palette = qApp->palette();
|
||||
QColor clr_bg(QSL("#2D2F32"));
|
||||
QColor clr_maibg(QSL("#2D2F32"));
|
||||
QColor clr_basbg(QSL("#373A3D"));
|
||||
QColor clr_altbg(QSL("#323437"));
|
||||
QColor clr_selbg(QSL("#8291AD"));
|
||||
QColor clr_fg(QSL("#D8D8D8"));
|
||||
QColor clr_brdr(QSL("#585C65"));
|
||||
QColor clr_tooltip_brdr(QSL("#707580"));
|
||||
QColor clr_link(QSL("#a1acc1"));
|
||||
QColor clr_dis_fg(QSL("#727272"));
|
||||
QColor clr_selfg(QSL("#FFFFFF"));
|
||||
QColor clr_btnfg(QSL("#E7E7E7"));
|
||||
QColor clr_dibfg(QSL("#A7A7A7"));
|
||||
QColor clr_winfg(QSL("#D8D8D8"));
|
||||
QColor clr_diwfg(QSL("#999999"));
|
||||
QColor clr_brdbg(QSL("#202224")); // Use colour picker on dark brdr under list header for this one
|
||||
QColor clr_wlink(QSL("#a1acc1"));
|
||||
|
||||
//
|
||||
// Normal state.
|
||||
//
|
||||
|
||||
// Backgrounds & bases.
|
||||
fusion_palette.setColor(QPalette::ColorRole::Window, clr_bg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Base, clr_bg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Dark, clr_bg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Window, clr_maibg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Base, clr_basbg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Dark, clr_brdbg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::AlternateBase, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Button, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Highlight, clr_selbg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Button, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Light, clr_altbg); // Bright
|
||||
fusion_palette.setColor(QPalette::ColorRole::Highlight, clr_selbg);
|
||||
|
||||
// Texts.
|
||||
fusion_palette.setColor(QPalette::ColorRole::WindowText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::ButtonText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::BrightText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Text, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::PlaceholderText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Link, clr_link);
|
||||
fusion_palette.setColor(QPalette::ColorRole::LinkVisited, clr_link);
|
||||
fusion_palette.setColor(QPalette::ColorRole::HighlightedText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::ButtonText, clr_btnfg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::WindowText, clr_winfg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::BrightText, clr_basbg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Text, clr_winfg); // Normal text
|
||||
fusion_palette.setColor(QPalette::ColorRole::PlaceholderText, clr_dibfg);
|
||||
fusion_palette.setColor(QPalette::ColorRole::Link, clr_wlink);
|
||||
fusion_palette.setColor(QPalette::ColorRole::LinkVisited, clr_wlink);
|
||||
fusion_palette.setColor(QPalette::ColorRole::HighlightedText, clr_selfg);
|
||||
|
||||
//
|
||||
// Inactive state.
|
||||
@ -112,29 +116,30 @@ void SkinFactory::loadSkinFromData(const Skin& skin) {
|
||||
//
|
||||
|
||||
// Backgrounds & bases.
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Window, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Base, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Dark, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Window, clr_maibg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Base, clr_basbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Dark, clr_brdbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::AlternateBase, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Button, Qt::GlobalColor::red);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Highlight, clr_selbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Button, clr_altbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Light, clr_altbg); // Bright
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Highlight, clr_selbg);
|
||||
|
||||
// Texts.
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::WindowText, clr_dis_fg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::ButtonText, clr_dis_fg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::BrightText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Text, clr_dis_fg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::PlaceholderText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Link, clr_link);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::LinkVisited, clr_link);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::HighlightedText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::ButtonText, clr_dibfg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::WindowText, clr_diwfg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::BrightText, clr_basbg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Text, clr_diwfg); // Normal text
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::PlaceholderText, clr_dibfg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Link, clr_wlink);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::LinkVisited, clr_wlink);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::HighlightedText, clr_selfg);
|
||||
|
||||
//
|
||||
// Tooltips.
|
||||
//
|
||||
|
||||
fusion_palette.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipBase, clr_bg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipText, clr_fg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipBase, clr_maibg);
|
||||
fusion_palette.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipText, clr_winfg);
|
||||
|
||||
QToolTip::setPalette(fusion_palette);
|
||||
qApp->setPalette(fusion_palette);
|
||||
|
@ -296,19 +296,20 @@ QProcess* AdBlockManager::startServer(int port) {
|
||||
proc->setProcessEnvironment(QProcessEnvironment::systemEnvironment());
|
||||
|
||||
auto pe = proc->processEnvironment();
|
||||
QString default_node_path =
|
||||
#if defined(Q_OS_WIN)
|
||||
pe.value(QSL("APPDATA")) + QDir::separator() + QSL("npm") + QDir::separator() + QSL("node_modules");
|
||||
#elif defined(Q_OS_LINUX)
|
||||
QSL("/usr/lib/node_modules");
|
||||
#elif defined(Q_OS_MACOS)
|
||||
QSL("/usr/local/lib/node_modules");
|
||||
#else
|
||||
QSL("");
|
||||
#endif
|
||||
|
||||
if (!pe.contains(QSL("NODE_PATH")) && !default_node_path.isEmpty()) {
|
||||
pe.insert(QSL("NODE_PATH"), default_node_path);
|
||||
if (!pe.contains(QSL("NODE_PATH"))) {
|
||||
const QString system_node_prefix = IOFactory::startProcessGetOutput(
|
||||
#if defined(Q_OS_WIN)
|
||||
QSL("npm.cmd")
|
||||
#else
|
||||
QSL("npm")
|
||||
#endif
|
||||
, { QSL("root"), QSL("--quiet"), QSL("-g") }
|
||||
);
|
||||
|
||||
if (!system_node_prefix.isEmpty()) {
|
||||
pe.insert(QSL("NODE_PATH"), system_node_prefix.simplified());
|
||||
}
|
||||
}
|
||||
|
||||
proc->setProcessEnvironment(pe);
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#if defined(USE_WEBENGINE)
|
||||
#include <QWebEngineProfile>
|
||||
#endif
|
||||
|
||||
BaseNetworkAccessManager::BaseNetworkAccessManager(QObject* parent)
|
||||
: QNetworkAccessManager(parent) {
|
||||
connect(this, &BaseNetworkAccessManager::sslErrors, this, &BaseNetworkAccessManager::onSslErrors);
|
||||
@ -61,7 +65,7 @@ QNetworkReply* BaseNetworkAccessManager::createRequest(QNetworkAccessManager::Op
|
||||
#endif
|
||||
|
||||
new_request.setRawHeader(HTTP_HEADERS_COOKIE, QSL("JSESSIONID= ").toLocal8Bit());
|
||||
new_request.setRawHeader(HTTP_HEADERS_USER_AGENT, QSL(APP_USERAGENT).toLocal8Bit());
|
||||
new_request.setRawHeader(HTTP_HEADERS_USER_AGENT, HTTP_COMPLETE_USERAGENT);
|
||||
|
||||
auto reply = QNetworkAccessManager::createRequest(op, new_request, outgoingData);
|
||||
return reply;
|
||||
|
@ -14,6 +14,8 @@ class CookieJar : public QNetworkCookieJar {
|
||||
virtual bool insertCookie(const QNetworkCookie& cookie);
|
||||
virtual bool updateCookie(const QNetworkCookie& cookie);
|
||||
virtual bool deleteCookie(const QNetworkCookie& cookie);
|
||||
|
||||
public:
|
||||
static QList<QNetworkCookie> extractCookiesFromUrl(const QString& url);
|
||||
|
||||
private:
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "miscellaneous/settings.h"
|
||||
#include "network-web/urlinterceptor.h"
|
||||
|
||||
#include <QWebEngineProfile>
|
||||
|
||||
NetworkUrlInterceptor::NetworkUrlInterceptor(QObject* parent)
|
||||
: QWebEngineUrlRequestInterceptor(parent), m_sendDnt(false) {}
|
||||
|
||||
|
@ -315,6 +315,25 @@ void WebFactory::createMenu(QMenu* menu) {
|
||||
actions << createEngineSettingsAction(tr("Allow geolocation on insecure origins"), QWebEngineSettings::WebAttribute::AllowGeolocationOnInsecureOrigins);
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= 0x050A00 // Qt >= 5.10.0
|
||||
actions << createEngineSettingsAction(tr("JS can activate windows"), QWebEngineSettings::WebAttribute::AllowWindowActivationFromJavaScript);
|
||||
actions << createEngineSettingsAction(tr("Show scrollbars"), QWebEngineSettings::WebAttribute::ShowScrollBars);
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= 0x050B00 // Qt >= 5.11.0
|
||||
actions << createEngineSettingsAction(tr("Media playback with gestures"), QWebEngineSettings::WebAttribute::PlaybackRequiresUserGesture);
|
||||
actions << createEngineSettingsAction(tr("WebRTC uses only public interfaces"), QWebEngineSettings::WebAttribute::WebRTCPublicInterfacesOnly);
|
||||
actions << createEngineSettingsAction(tr("JS can paste from clipboard"), QWebEngineSettings::WebAttribute::JavascriptCanPaste);
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= 0x050C00 // Qt >= 5.12.0
|
||||
actions << createEngineSettingsAction(tr("DNS prefetch enabled"), QWebEngineSettings::WebAttribute::DnsPrefetchEnabled);
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= 0x050D00 // Qt >= 5.13.0
|
||||
actions << createEngineSettingsAction(tr("PDF viewer enabled"), QWebEngineSettings::WebAttribute::PdfViewerEnabled);
|
||||
#endif
|
||||
|
||||
menu->addActions(actions);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,13 @@ int main(int argc, char* argv[]) {
|
||||
QApplication::setDesktopFileName(APP_DESKTOP_ENTRY_FILE);
|
||||
#endif
|
||||
|
||||
#if defined(QT_STATIC)
|
||||
// NOTE: Add all used resources here.
|
||||
Q_INIT_RESOURCE(icons);
|
||||
Q_INIT_RESOURCE(sql);
|
||||
Q_INIT_RESOURCE(rssguard);
|
||||
#endif
|
||||
|
||||
// Ensure that ini format is used as application settings storage on macOS.
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user