30#include <QWebEngineScript>
31#include <QCryptographicHash>
32#include <QNetworkReply>
33#include <QNetworkRequest>
39 , m_namespace(
QSL(
"GreaseMonkeyNS"))
40 , m_startAt(DocumentEnd)
42 , m_fileName(filePath)
69 return QSL(
"%1/%2").arg(m_namespace, m_name);
114 return m_valid && m_enabled;
144 QWebEngineScript script;
148 script.setRunsOnSubFrames(!m_noframes);
159 if (!m_downloadUrl.isValid() || m_updating)
165 auto *downloader =
new GM_Downloader(m_downloadUrl, m_manager);
166 downloader->updateScript(m_fileName);
178void GM_Script::watchedFileChanged(
const QString &file)
180 if (m_fileName == file) {
185void GM_Script::parseScript()
188 m_namespace =
QSL(
"GreaseMonkeyNS");
189 m_description.clear();
196 m_downloadUrl.clear();
204 QFile file(m_fileName);
205 if (!file.open(QFile::ReadOnly)) {
206 qWarning() <<
"GreaseMonkey: Cannot open file for reading" << m_fileName;
210 if (!m_fileWatcher->files().contains(m_fileName)) {
211 m_fileWatcher->addPath(m_fileName);
214 const QByteArray fileData = file.readAll();
216 bool inMetadata =
false;
218 QTextStream stream(fileData);
220 while (stream.readLineInto(&line)) {
221 if (line.startsWith(
QL1S(
"// ==UserScript=="))) {
224 if (line.startsWith(
QL1S(
"// ==/UserScript=="))) {
231 if (!line.startsWith(QLatin1String(
"// @"))) {
235 line = line.mid(3).replace(QLatin1Char(
'\t'), QLatin1Char(
' '));
236 int index = line.indexOf(QLatin1Char(
' '));
238 const QString key = line.left(index).trimmed();
239 const QString
value = index > 0 ? line.mid(index + 1).trimmed() : QString();
245 if (key == QLatin1String(
"@name")) {
248 else if (key == QLatin1String(
"@namespace")) {
251 else if (key == QLatin1String(
"@description")) {
252 m_description =
value;
254 else if (key == QLatin1String(
"@version")) {
257 else if (key == QLatin1String(
"@updateURL")) {
258 m_updateUrl = QUrl(
value);
260 else if (key == QLatin1String(
"@downloadURL")) {
261 m_downloadUrl = QUrl(
value);
263 else if (key == QLatin1String(
"@include") || key == QLatin1String(
"@match")) {
264 m_include.append(
value);
266 else if (key == QLatin1String(
"@exclude") || key == QLatin1String(
"@exclude_match")) {
267 m_exclude.append(
value);
269 else if (key == QLatin1String(
"@require")) {
270 m_require.append(
value);
272 else if (key == QLatin1String(
"@run-at")) {
273 if (
value == QLatin1String(
"document-end")) {
276 else if (
value == QLatin1String(
"document-start")) {
279 else if (
value == QLatin1String(
"document-idle")) {
283 else if (key ==
QL1S(
"@icon")) {
284 m_iconUrl = QUrl(
value);
286 else if (key ==
QL1S(
"@noframes")) {
292 qWarning() <<
"GreaseMonkey: File does not contain metadata block" << m_fileName;
296 m_iconUrl = m_downloadUrl.resolved(m_iconUrl);
298 if (m_include.isEmpty()) {
299 m_include.append(
QSL(
"*"));
302 const QString nspace = QString::fromLatin1(QCryptographicHash::hash(
fullName().toUtf8(), QCryptographicHash::Md4).toHex());
303 const QString gmValues = m_manager->
valuesScript().arg(nspace);
304 m_script =
QSL(
"(function(){%1\n%2\n%3\n})();").arg(gmValues, m_manager->
requireScripts(m_require), QString::fromUtf8(fileData));
311void GM_Script::reloadScript()
321void GM_Script::downloadIcon()
323 if (m_iconUrl.isValid()) {
324 QNetworkReply *reply =
mApp->networkManager()->get(QNetworkRequest(m_iconUrl));
325 connect(reply, &QNetworkReply::finished,
this, [=]() {
326 reply->deleteLater();
327 if (reply->error() == QNetworkReply::NoError) {
328 m_icon = QPixmap::fromImage(QImage::fromData(reply->readAll()));
334void GM_Script::downloadRequires()
336 for (
const QString &url : std::as_const(m_require)) {
void delayedFileChanged(const QString &path)
void finished(const QString &fileName)
QString requireScripts(const QStringList &urlList) const
bool removeScript(GM_Script *script, bool removeFile=true)
bool addScript(GM_Script *script)
QString bootstrapScript() const
QString valuesScript() const
QString nameSpace() const
QStringList exclude() const
QStringList include() const
QStringList require() const
GM_Script(GM_Manager *manager, const QString &filePath)
QWebEngineScript webScript() const
void setEnabled(bool enable)
void updatingChanged(bool updating)
QString description() const
int value(const QColor &c)