init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
126
Telegram/SourceFiles/ui/webview_helpers.cpp
Normal file
126
Telegram/SourceFiles/ui/webview_helpers.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/webview_helpers.h"
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] QByteArray Serialize(const QColor &qt) {
|
||||
if (qt.alpha() == 255) {
|
||||
return '#'
|
||||
+ QByteArray::number(qt.red(), 16).rightJustified(2, '0')
|
||||
+ QByteArray::number(qt.green(), 16).rightJustified(2, '0')
|
||||
+ QByteArray::number(qt.blue(), 16).rightJustified(2, '0');
|
||||
}
|
||||
return "rgba("
|
||||
+ QByteArray::number(qt.red()) + ","
|
||||
+ QByteArray::number(qt.green()) + ","
|
||||
+ QByteArray::number(qt.blue()) + ","
|
||||
+ QByteArray::number(qt.alpha() / 255.) + ")";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QByteArray ComputeStyles(
|
||||
const base::flat_map<QByteArray, const style::color*> &colors,
|
||||
const base::flat_map<QByteArray, tr::phrase<>> &phrases,
|
||||
int zoom,
|
||||
bool nightTheme) {
|
||||
static const auto serialize = [](const style::color *color) {
|
||||
return Serialize((*color)->c);
|
||||
};
|
||||
static const auto escape = [](tr::phrase<> phrase) {
|
||||
const auto text = phrase(tr::now);
|
||||
|
||||
auto result = QByteArray();
|
||||
for (auto i = 0; i != text.size(); ++i) {
|
||||
uint ucs4 = text[i].unicode();
|
||||
if (QChar::isHighSurrogate(ucs4) && i + 1 != text.size()) {
|
||||
ushort low = text[i + 1].unicode();
|
||||
if (QChar::isLowSurrogate(low)) {
|
||||
ucs4 = QChar::surrogateToUcs4(ucs4, low);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (ucs4 == '\'' || ucs4 == '\"' || ucs4 == '\\') {
|
||||
result.append('\\').append(char(ucs4));
|
||||
} else if (ucs4 < 32 || ucs4 > 127) {
|
||||
result.append('\\' + QByteArray::number(ucs4, 16) + ' ');
|
||||
} else {
|
||||
result.append(char(ucs4));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
auto result = QByteArray();
|
||||
for (const auto &[name, phrase] : phrases) {
|
||||
result += "--td-lng-"_q + name + ":'"_q + escape(phrase) + "'; "_q;
|
||||
}
|
||||
for (const auto &[name, color] : colors) {
|
||||
result += "--td-"_q + name + ':' + serialize(color) + ';';
|
||||
}
|
||||
result += "--td-night:"_q + (nightTheme ? "1" : "0") + ';';
|
||||
result += "--td-zoom-percentage:"_q
|
||||
+ (QString::number(zoom).toUtf8() + '%')
|
||||
+ ';';
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray ComputeSemiTransparentOverStyle(
|
||||
const QByteArray &name,
|
||||
const style::color &over,
|
||||
const style::color &bg) {
|
||||
const auto result = [&](const QColor &c) {
|
||||
return "--td-"_q + name + ':' + Serialize(c) + ';';
|
||||
};
|
||||
if (over->c.alpha() < 255) {
|
||||
return result(over->c);
|
||||
}
|
||||
// The most transparent color that will still give the same result.
|
||||
const auto r0 = bg->c.red();
|
||||
const auto g0 = bg->c.green();
|
||||
const auto b0 = bg->c.blue();
|
||||
const auto r1 = over->c.red();
|
||||
const auto g1 = over->c.green();
|
||||
const auto b1 = over->c.blue();
|
||||
const auto mina = [](int c0, int c1) {
|
||||
return (c0 == c1)
|
||||
? 0
|
||||
: (c0 > c1)
|
||||
? (((c0 - c1) * 255) / c0)
|
||||
: (((c1 - c0) * 255) / (255 - c0));
|
||||
};
|
||||
const auto rmina = mina(r0, r1);
|
||||
const auto gmina = mina(g0, g1);
|
||||
const auto bmina = mina(b0, b1);
|
||||
const auto a = std::max({ rmina, gmina, bmina });
|
||||
const auto r = (a > 0) ? ((r1 * 255 - r0 * (255 - a)) / a) : r0;
|
||||
const auto g = (a > 0) ? ((g1 * 255 - g0 * (255 - a)) / a) : g0;
|
||||
const auto b = (a > 0) ? ((b1 * 255 - b0 * (255 - a)) / a) : b0;
|
||||
return result(QColor(r, g, b, a));
|
||||
}
|
||||
|
||||
QByteArray EscapeForAttribute(QByteArray value) {
|
||||
return value
|
||||
.replace('&', "&")
|
||||
.replace('"', """)
|
||||
.replace('\'', "'")
|
||||
.replace('<', "<")
|
||||
.replace('>', ">");
|
||||
}
|
||||
|
||||
QByteArray EscapeForScriptString(QByteArray value) {
|
||||
return value
|
||||
.replace('\\', "\\\\")
|
||||
.replace('"', "\\\"")
|
||||
.replace('\'', "\\\'");
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
Reference in New Issue
Block a user