From 88b265765f3dec5365a82e15f3f0b4257576b564 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Tue, 7 Jun 2022 21:22:37 +0800 Subject: [PATCH 1/5] add entry:// link support --- article_netmgr.cc | 22 ++++++++++++++++++---- globalbroadcaster.cpp | 8 ++++++++ globalbroadcaster.h | 6 ++++++ resources/gd-custom.js | 5 +++++ utils.hh | 4 +++- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/article_netmgr.cc b/article_netmgr.cc index 5a172289..32c65ea9 100644 --- a/article_netmgr.cc +++ b/article_netmgr.cc @@ -8,6 +8,7 @@ #include "gddebug.hh" #include "utils.hh" #include +#include "globalbroadcaster.h" using std::string; @@ -249,11 +250,22 @@ QNetworkReply * ArticleNetworkAccessManager::getArticleReply( QNetworkRequest co } sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource( - QUrl const & url, QString & contentType ) + QUrl const & resUrl, QString & contentType ) { - GD_DPRINTF( "getResource: %ls", url.toString().toStdWString().c_str() ); - GD_DPRINTF( "scheme: %ls", url.scheme().toStdWString().c_str() ); - GD_DPRINTF( "host: %ls", url.host().toStdWString().c_str() ); + GD_DPRINTF( "getResource: %ls", resUrl.toString().toStdWString().c_str() ); + GD_DPRINTF( "scheme: %ls", resUrl.scheme().toStdWString().c_str() ); + GD_DPRINTF( "host: %ls", resUrl.host().toStdWString().c_str() ); + + QUrl url = resUrl; + if( url.scheme() == "bword" || url.scheme() == "entry" ) + { + url.setScheme( "gdlookup" ); + url.setHost( "localhost" ); + url.setPath( "" ); + auto [ valid, word ] = Utils::Url::getQueryWord( resUrl ); + Utils::Url::addQueryItem( url, "word", word ); + Utils::Url::addQueryItem( url, "group", QString( "%1" ).arg( GlobalBroadcaster::instance()->getGroupId() ) ); + } if ( url.scheme() == "gdlookup" ) { @@ -273,6 +285,8 @@ sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource( bool groupIsValid = false; unsigned group = Utils::Url::queryItemValue( url, "group" ).toUInt( &groupIsValid ); + + GlobalBroadcaster::instance()->setGroupId(group); QString dictIDs = Utils::Url::queryItemValue( url, "dictionaries" ); if( !dictIDs.isEmpty() ) diff --git a/globalbroadcaster.cpp b/globalbroadcaster.cpp index 885bf89a..7d2468d7 100644 --- a/globalbroadcaster.cpp +++ b/globalbroadcaster.cpp @@ -29,4 +29,12 @@ void GlobalBroadcaster::addWhitelist(QString url){ bool GlobalBroadcaster::existedInWhitelist(QString url){ return std::find(whitelist.begin(), whitelist.end(), url) != whitelist.end(); } + +void GlobalBroadcaster::setGroupId(int groupId){ + this->groupId = groupId; +} + +int GlobalBroadcaster::getGroupId(){ + return groupId; +} // namespace global diff --git a/globalbroadcaster.h b/globalbroadcaster.h index 3014a46e..c53bc50f 100644 --- a/globalbroadcaster.h +++ b/globalbroadcaster.h @@ -17,6 +17,8 @@ class GlobalBroadcaster : public QObject private: Config::Preferences * preference; std::vector whitelist; + int groupId; + public: void setPreference( Config::Preferences * _pre ); Config::Preferences * getPreference(); @@ -24,6 +26,10 @@ public: void addWhitelist(QString host); bool existedInWhitelist(QString host); static GlobalBroadcaster * instance(); + + //store the latest groupId; + void setGroupId(int groupId); + int getGroupId(); signals: void dictionaryChanges( ActiveDictIds ad ); }; diff --git a/resources/gd-custom.js b/resources/gd-custom.js index ae07cf31..d7557151 100644 --- a/resources/gd-custom.js +++ b/resources/gd-custom.js @@ -6,6 +6,11 @@ $(function() { if ('string' != typeof(link)) { return; } + + if(link.indexOf("javascript:")>=0){ + return; + } + if(link.indexOf(":")>=0){ emitClickedEvent(link); return false; diff --git a/utils.hh b/utils.hh index eb4fee08..6f4b0b1b 100644 --- a/utils.hh +++ b/utils.hh @@ -231,7 +231,9 @@ inline std::pair< bool, QString > getQueryWord( QUrl const & url ) { //url,bword://localhost/word if( path.startsWith( "/" ) ) - word = url.path().mid( 1 ); + word = path.mid( 1 ); + else + word = path; } else { From 547f2a4cd286c4711a69b62e3c6bdc89b1fd7da2 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Wed, 8 Jun 2022 08:19:23 +0800 Subject: [PATCH 2/5] remember last link's groupId and muted dictionary --- article_netmgr.cc | 21 ++++----------------- articlewebpage.cpp | 25 ++++++++++++++++++++++++- articlewebpage.h | 7 +++++++ globalbroadcaster.cpp | 22 ++++++++-------------- globalbroadcaster.h | 4 ---- mainwindow.cc | 1 + 6 files changed, 44 insertions(+), 36 deletions(-) diff --git a/article_netmgr.cc b/article_netmgr.cc index 32c65ea9..e0e23650 100644 --- a/article_netmgr.cc +++ b/article_netmgr.cc @@ -250,22 +250,11 @@ QNetworkReply * ArticleNetworkAccessManager::getArticleReply( QNetworkRequest co } sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource( - QUrl const & resUrl, QString & contentType ) + QUrl const & url, QString & contentType ) { - GD_DPRINTF( "getResource: %ls", resUrl.toString().toStdWString().c_str() ); - GD_DPRINTF( "scheme: %ls", resUrl.scheme().toStdWString().c_str() ); - GD_DPRINTF( "host: %ls", resUrl.host().toStdWString().c_str() ); - - QUrl url = resUrl; - if( url.scheme() == "bword" || url.scheme() == "entry" ) - { - url.setScheme( "gdlookup" ); - url.setHost( "localhost" ); - url.setPath( "" ); - auto [ valid, word ] = Utils::Url::getQueryWord( resUrl ); - Utils::Url::addQueryItem( url, "word", word ); - Utils::Url::addQueryItem( url, "group", QString( "%1" ).arg( GlobalBroadcaster::instance()->getGroupId() ) ); - } + GD_DPRINTF( "getResource: %ls", url.toString().toStdWString().c_str() ); + GD_DPRINTF( "scheme: %ls", url.scheme().toStdWString().c_str() ); + GD_DPRINTF( "host: %ls", url.host().toStdWString().c_str() ); if ( url.scheme() == "gdlookup" ) { @@ -285,8 +274,6 @@ sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource( bool groupIsValid = false; unsigned group = Utils::Url::queryItemValue( url, "group" ).toUInt( &groupIsValid ); - - GlobalBroadcaster::instance()->setGroupId(group); QString dictIDs = Utils::Url::queryItemValue( url, "dictionaries" ); if( !dictIDs.isEmpty() ) diff --git a/articlewebpage.cpp b/articlewebpage.cpp index 9b782f8d..bf686114 100644 --- a/articlewebpage.cpp +++ b/articlewebpage.cpp @@ -1,15 +1,38 @@ #include "articlewebpage.h" +#include "utils.hh" ArticleWebPage::ArticleWebPage(QObject *parent) : QWebEnginePage{parent} { } -bool ArticleWebPage::acceptNavigationRequest( const QUrl & url, NavigationType type, bool isMainFrame ) +bool ArticleWebPage::acceptNavigationRequest( const QUrl & resUrl, NavigationType type, bool isMainFrame ) { + QUrl url = resUrl; + if( url.scheme() == "bword" || url.scheme() == "entry" ) + { + url.setScheme( "gdlookup" ); + url.setHost( "localhost" ); + url.setPath( "" ); + auto [ valid, word ] = Utils::Url::getQueryWord( resUrl ); + Utils::Url::addQueryItem( url, "word", word ); + Utils::Url::addQueryItem( url, "group", lastReq.group ); + Utils::Url::addQueryItem( url, "muted", lastReq.mutedDicts ); + setUrl( url ); + return false; + } + + //save current gdlookup's values. + if( url.scheme() == "gdlookup" ) + { + lastReq.group = Utils::Url::queryItemValue( url, "group" ); + lastReq.mutedDicts = Utils::Url::queryItemValue( url, "muted" ); + } + if( type == QWebEnginePage::NavigationTypeLinkClicked ) { emit linkClicked( url ); return true; } + return QWebEnginePage::acceptNavigationRequest( url, type, isMainFrame ); } diff --git a/articlewebpage.h b/articlewebpage.h index 3e1d32d6..19027148 100644 --- a/articlewebpage.h +++ b/articlewebpage.h @@ -3,6 +3,11 @@ #include +struct LastReqInfo{ + QString group; + QString mutedDicts; +}; + class ArticleWebPage : public QWebEnginePage { Q_OBJECT @@ -12,6 +17,8 @@ signals: void linkClicked( const QUrl & url ); protected: virtual bool acceptNavigationRequest( const QUrl & url, NavigationType type, bool isMainFrame ); +private: + LastReqInfo lastReq; }; #endif // ARTICLEWEBPAGE_H diff --git a/globalbroadcaster.cpp b/globalbroadcaster.cpp index 7d2468d7..bcac205f 100644 --- a/globalbroadcaster.cpp +++ b/globalbroadcaster.cpp @@ -20,21 +20,15 @@ Config::Preferences * GlobalBroadcaster::getPreference() return preference; } -void GlobalBroadcaster::addWhitelist(QString url){ - whitelist.push_back(url); - auto baseUrl=::getHostBase(url); - whitelist.push_back(baseUrl); +void GlobalBroadcaster::addWhitelist( QString url ) +{ + whitelist.push_back( url ); + auto baseUrl = ::getHostBase( url ); + whitelist.push_back( baseUrl ); } -bool GlobalBroadcaster::existedInWhitelist(QString url){ - return std::find(whitelist.begin(), whitelist.end(), url) != whitelist.end(); -} - -void GlobalBroadcaster::setGroupId(int groupId){ - this->groupId = groupId; -} - -int GlobalBroadcaster::getGroupId(){ - return groupId; +bool GlobalBroadcaster::existedInWhitelist( QString url ) +{ + return std::find( whitelist.begin(), whitelist.end(), url ) != whitelist.end(); } // namespace global diff --git a/globalbroadcaster.h b/globalbroadcaster.h index c53bc50f..6e6992c2 100644 --- a/globalbroadcaster.h +++ b/globalbroadcaster.h @@ -17,7 +17,6 @@ class GlobalBroadcaster : public QObject private: Config::Preferences * preference; std::vector whitelist; - int groupId; public: void setPreference( Config::Preferences * _pre ); @@ -27,9 +26,6 @@ public: bool existedInWhitelist(QString host); static GlobalBroadcaster * instance(); - //store the latest groupId; - void setGroupId(int groupId); - int getGroupId(); signals: void dictionaryChanges( ActiveDictIds ad ); }; diff --git a/mainwindow.cc b/mainwindow.cc index 29f2bee3..fb4ae931 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -1417,6 +1417,7 @@ void MainWindow::updateGroupList() groupList->fill( groupInstances ); groupList->setCurrentGroup( cfg.lastMainGroupId ); + updateCurrentGroupProperty(); updateDictionaryBar(); From 3e6c85b404fdea58c3fdbb4f2fc279ed2f012ee1 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Wed, 8 Jun 2022 20:55:01 +0800 Subject: [PATCH 3/5] add dict's margin back to lingos style --- article-style-st-lingoes.css | 1 + article-style.css | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/article-style-st-lingoes.css b/article-style-st-lingoes.css index 9f31b39e..455aa75b 100644 --- a/article-style-st-lingoes.css +++ b/article-style-st-lingoes.css @@ -97,4 +97,5 @@ body { clear: both; border-top: 1px solid #92b0dd; + margin-bottom: 1em; } diff --git a/article-style.css b/article-style.css index a7ea4d2a..959edbaa 100644 --- a/article-style.css +++ b/article-style.css @@ -531,7 +531,7 @@ div.xdxf /************* MDict dictionaries **************/ .mdict { - /* margin-top: 1em; */ + } .mdict a[name] From 4ce03e9415bee694c2b0d8ab745077c6a29bb65e Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Wed, 8 Jun 2022 21:13:07 +0800 Subject: [PATCH 4/5] html unescape --- htmlescape.cc | 29 +++++++++++++++++++++++++++++ htmlescape.hh | 3 +++ mdictparser.cc | 2 +- utils.hh | 7 ------- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/htmlescape.cc b/htmlescape.cc index 59086e8c..bb2c65e6 100644 --- a/htmlescape.cc +++ b/htmlescape.cc @@ -157,6 +157,35 @@ QString unescape( QString const & str, bool saveFormat ) return str; } +QString fromHtmlEscaped( QString const & str){ + QString retVal = str; + QRegularExpression regExp("(?\\<\\;)|(?\\>\\;)|(?\\&\\;)|(?\\"\\;)", QRegularExpression::PatternOption::CaseInsensitiveOption); + auto match = regExp.match(str, 0); + + while (match.hasMatch()) + { + if (!match.captured("lt").isEmpty()) + { + retVal.replace(match.capturedStart("lt"), match.capturedLength("lt"), "<"); + } + else if (!match.captured("gt").isEmpty()) + { + retVal.replace(match.capturedStart("gt"), match.capturedLength("gt"), ">"); + } + else if (!match.captured("amp").isEmpty()) + { + retVal.replace(match.capturedStart("amp"), match.capturedLength("amp"), "&"); + } + else if (!match.captured("quot").isEmpty()) + { + retVal.replace(match.capturedStart("quot"), match.capturedLength("quot"), "\""); + } + match = regExp.match(retVal, match.capturedStart() + 1); + } + + return retVal; +} + string unescapeUtf8( const string &str, bool saveFormat ) { return string( unescape( QString::fromUtf8( str.c_str(), str.size() ) ).toUtf8().data(), saveFormat ); diff --git a/htmlescape.hh b/htmlescape.hh index f86e4136..39f3d161 100644 --- a/htmlescape.hh +++ b/htmlescape.hh @@ -4,6 +4,7 @@ #ifndef __HTMLESCAPE_HH_INCLUDED__ #define __HTMLESCAPE_HH_INCLUDED__ +#include #include namespace Html { @@ -24,6 +25,8 @@ string escapeForJavaScript( string const & ); // Replace html entities QString unescape( QString const & str, bool saveFormat = false ); + +QString fromHtmlEscaped( QString const & str); string unescapeUtf8( string const & str, bool saveFormat = false ); } diff --git a/mdictparser.cc b/mdictparser.cc index f3124a46..a4ec7142 100644 --- a/mdictparser.cc +++ b/mdictparser.cc @@ -374,7 +374,7 @@ bool MdictParser::readHeader( QDataStream & in ) { #if( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) ) styleSheets_[ lines[ i ].toInt() ] = - pair< QString, QString >( Html::unescape( lines[ i + 1 ] ), Html::unescape( lines[ i + 2 ] ) ); + pair< QString, QString >( Html::fromHtmlEscaped( lines[ i + 1 ] ), Html::fromHtmlEscaped( lines[ i + 2 ] ) ); #else styleSheets_[ lines[ i ].toInt() ] = pair< QString, QString >( lines[ i + 1 ], lines[ i + 2 ] ); #endif diff --git a/utils.hh b/utils.hh index 6f4b0b1b..a12175af 100644 --- a/utils.hh +++ b/utils.hh @@ -78,13 +78,6 @@ inline QString rstripnull(const QString &str) { return ""; } -inline QString unescapeHtml(const QString &str) { - QTextDocument text; - text.setHtml(str); - return text.toPlainText(); -} - - inline bool isExternalLink(QUrl const &url) { return url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "ftp" || url.scheme() == "mailto" || url.scheme() == "file" || url.toString().startsWith( "//" ); From 01da9c93ab31a883210a8417112cb8c44093f1f8 Mon Sep 17 00:00:00 2001 From: Xiao YiFang Date: Wed, 8 Jun 2022 21:16:04 +0800 Subject: [PATCH 5/5] github: changelog modify --- .github/workflows/macos.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7624d090..6601aefd 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -75,8 +75,11 @@ jobs: mv ${targetName}.app ./tmp # --background "installer_background.png" create-dmg --volname "${targetName} Installer" --volicon "icons/macicon.icns" --window-pos 200 120 --window-size 800 400 --icon-size 100 --icon "${targetName}.app" 200 190 --hide-extension "${targetName}.app" --app-drop-link 600 185 --skip-jenkins "${targetName}.dmg" tmp/ - - + - name: Generate changelog + id: changelog + uses: metcalfc/changelog-generator@v3.0.0 + with: + myToken: ${{ secrets.GITHUB_TOKEN }} - name: Set outputs id: vars run: | @@ -122,4 +125,6 @@ jobs: auto built by github action. use on your on risk:-) CHANGES: - ${{ steps.vars.outputs.COMMIT_SUMMARY }} + ${{ steps.vars.outputs.COMMIT_SUMMARY }} + CHANGE LOGS: + ${{ steps.changelog.outputs.changelog }}