mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 23:34:06 +00:00
Websites: Isolate styles for every site when possible
This commit is contained in:
parent
b72d377d78
commit
ecc4203247
145
website.cc
145
website.cc
|
@ -61,6 +61,10 @@ public:
|
||||||
wstring const & context )
|
wstring const & context )
|
||||||
throw( std::exception );
|
throw( std::exception );
|
||||||
|
|
||||||
|
virtual sptr< Dictionary::DataRequest > getResource( string const & name ) throw( std::exception );
|
||||||
|
|
||||||
|
void isolateWebCSS( QString & css );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void loadIcon() throw();
|
virtual void loadIcon() throw();
|
||||||
|
@ -76,9 +80,13 @@ sptr< WordSearchRequest > WebSiteDictionary::prefixMatch( wstring const & /*word
|
||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebSiteDictionary::isolateWebCSS( QString & css )
|
||||||
|
{
|
||||||
|
isolateCSS( css, ".website" );
|
||||||
|
}
|
||||||
|
|
||||||
class WebSiteArticleRequest: public WebSiteDataRequestSlots
|
class WebSiteArticleRequest: public WebSiteDataRequestSlots
|
||||||
{
|
{
|
||||||
typedef std::list< std::pair< QNetworkReply *, bool > > NetReplies;
|
|
||||||
QNetworkReply * netReply;
|
QNetworkReply * netReply;
|
||||||
QString url;
|
QString url;
|
||||||
Class * dictPtr;
|
Class * dictPtr;
|
||||||
|
@ -161,8 +169,6 @@ void WebSiteArticleRequest::requestFinished( QNetworkReply * r )
|
||||||
else
|
else
|
||||||
articleString = QString::fromUtf8( replyData );
|
articleString = QString::fromUtf8( replyData );
|
||||||
|
|
||||||
QString divName = QString( "website_" ) + dictPtr->getId().c_str();
|
|
||||||
|
|
||||||
// Change links from relative to absolute
|
// Change links from relative to absolute
|
||||||
|
|
||||||
QString root = netReply->url().scheme() + "://" + netReply->url().host();
|
QString root = netReply->url().scheme() + "://" + netReply->url().host();
|
||||||
|
@ -216,6 +222,24 @@ void WebSiteArticleRequest::requestFinished( QNetworkReply * r )
|
||||||
pos += tag.size();
|
pos += tag.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redirect CSS links to own handler
|
||||||
|
|
||||||
|
QString prefix = QString( "bres://" ) + dictPtr->getId().c_str() + "/";
|
||||||
|
QRegExp linkTags( "(<\\s*link\\s[^>]*rel\\s*=\\s*['\"]stylesheet['\"]\\s+[^>]*href\\s*=\\s*['\"])([^'\"]+)://([^'\"]+['\"][^>]+>)",
|
||||||
|
Qt::CaseInsensitive, QRegExp::RegExp2 );
|
||||||
|
pos = 0;
|
||||||
|
while( pos >= 0 )
|
||||||
|
{
|
||||||
|
pos = articleString.indexOf( linkTags, pos );
|
||||||
|
if( pos < 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
QString newTag = linkTags.cap( 1 ) + prefix + linkTags.cap( 2 )
|
||||||
|
+ "/" + linkTags.cap( 3 );
|
||||||
|
articleString.replace( pos, linkTags.cap().size(), newTag );
|
||||||
|
pos += newTag.size();
|
||||||
|
}
|
||||||
|
|
||||||
// Check for unclosed <span> and <div>
|
// Check for unclosed <span> and <div>
|
||||||
|
|
||||||
int openTags = articleString.count( QRegExp( "<\\s*span\\b", Qt::CaseInsensitive ) );
|
int openTags = articleString.count( QRegExp( "<\\s*span\\b", Qt::CaseInsensitive ) );
|
||||||
|
@ -243,7 +267,7 @@ void WebSiteArticleRequest::requestFinished( QNetworkReply * r )
|
||||||
|
|
||||||
QByteArray articleBody = articleString.toUtf8();
|
QByteArray articleBody = articleString.toUtf8();
|
||||||
|
|
||||||
QString divStr = QString( "<div class=\"" ) + divName + "\"";
|
QString divStr = QString( "<div class=\"website\"" );
|
||||||
divStr += dictPtr->isToLanguageRTL() ? " dir=\"rtl\">" : ">";
|
divStr += dictPtr->isToLanguageRTL() ? " dir=\"rtl\">" : ">";
|
||||||
|
|
||||||
articleBody.prepend( divStr.toUtf8() );
|
articleBody.prepend( divStr.toUtf8() );
|
||||||
|
@ -275,8 +299,6 @@ sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str,
|
||||||
wstring const & context )
|
wstring const & context )
|
||||||
throw( std::exception )
|
throw( std::exception )
|
||||||
{
|
{
|
||||||
sptr< DataRequestInstant > dr = new DataRequestInstant( true );
|
|
||||||
|
|
||||||
QByteArray urlString;
|
QByteArray urlString;
|
||||||
|
|
||||||
// Context contains the right url to go to
|
// Context contains the right url to go to
|
||||||
|
@ -327,6 +349,8 @@ sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str,
|
||||||
{
|
{
|
||||||
// Just insert link in <iframe> tag
|
// Just insert link in <iframe> tag
|
||||||
|
|
||||||
|
sptr< DataRequestInstant > dr = new DataRequestInstant( true );
|
||||||
|
|
||||||
string result = "<div class=\"website_padding\"></div>";
|
string result = "<div class=\"website_padding\"></div>";
|
||||||
|
|
||||||
result += string( "<iframe id=\"gdexpandframe-" ) + getId() +
|
result += string( "<iframe id=\"gdexpandframe-" ) + getId() +
|
||||||
|
@ -350,6 +374,115 @@ sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str,
|
||||||
return new WebSiteArticleRequest( urlString, netMgr, this );
|
return new WebSiteArticleRequest( urlString, netMgr, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WebSiteResourceRequest: public WebSiteDataRequestSlots
|
||||||
|
{
|
||||||
|
QNetworkReply * netReply;
|
||||||
|
QString url;
|
||||||
|
WebSiteDictionary * dictPtr;
|
||||||
|
QNetworkAccessManager & mgr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WebSiteResourceRequest( QString const & url_, QNetworkAccessManager & _mgr,
|
||||||
|
WebSiteDictionary * dictPtr_ );
|
||||||
|
~WebSiteResourceRequest()
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void cancel();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual void requestFinished( QNetworkReply * );
|
||||||
|
};
|
||||||
|
|
||||||
|
WebSiteResourceRequest::WebSiteResourceRequest( QString const & url_,
|
||||||
|
QNetworkAccessManager & _mgr,
|
||||||
|
WebSiteDictionary * dictPtr_ ):
|
||||||
|
url( url_ ), dictPtr( dictPtr_ ), mgr( _mgr )
|
||||||
|
{
|
||||||
|
connect( &mgr, SIGNAL( finished( QNetworkReply * ) ),
|
||||||
|
this, SLOT( requestFinished( QNetworkReply * ) ),
|
||||||
|
Qt::QueuedConnection );
|
||||||
|
|
||||||
|
QUrl reqUrl( url );
|
||||||
|
|
||||||
|
netReply = mgr.get( QNetworkRequest( reqUrl ) );
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENSSL
|
||||||
|
connect( netReply, SIGNAL( sslErrors( QList< QSslError > ) ),
|
||||||
|
netReply, SLOT( ignoreSslErrors() ) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSiteResourceRequest::cancel()
|
||||||
|
{
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSiteResourceRequest::requestFinished( QNetworkReply * r )
|
||||||
|
{
|
||||||
|
if ( isFinished() ) // Was cancelled
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( r != netReply )
|
||||||
|
{
|
||||||
|
// Well, that's not our reply, don't do anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( netReply->error() == QNetworkReply::NoError )
|
||||||
|
{
|
||||||
|
// Check for redirect reply
|
||||||
|
|
||||||
|
QVariant possibleRedirectUrl = netReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
|
||||||
|
QUrl redirectUrl = possibleRedirectUrl.toUrl();
|
||||||
|
if( !redirectUrl.isEmpty() )
|
||||||
|
{
|
||||||
|
netReply->deleteLater();
|
||||||
|
netReply = mgr.get( QNetworkRequest( redirectUrl ) );
|
||||||
|
#ifndef QT_NO_OPENSSL
|
||||||
|
connect( netReply, SIGNAL( sslErrors( QList< QSslError > ) ),
|
||||||
|
netReply, SLOT( ignoreSslErrors() ) );
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle reply data
|
||||||
|
|
||||||
|
QByteArray replyData = netReply->readAll();
|
||||||
|
QString cssString = QString::fromUtf8( replyData );
|
||||||
|
|
||||||
|
dictPtr->isolateWebCSS( cssString );
|
||||||
|
|
||||||
|
QByteArray cssData = cssString.toUtf8();
|
||||||
|
|
||||||
|
Mutex::Lock _( dataMutex );
|
||||||
|
|
||||||
|
size_t prevSize = data.size();
|
||||||
|
|
||||||
|
data.resize( prevSize + cssData.size() );
|
||||||
|
|
||||||
|
memcpy( &data.front() + prevSize, cssData.data(), cssData.size() );
|
||||||
|
|
||||||
|
hasAnyData = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setErrorString( netReply->errorString() );
|
||||||
|
|
||||||
|
netReply->deleteLater();
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr< Dictionary::DataRequest > WebSiteDictionary::getResource( string const & name ) throw( std::exception )
|
||||||
|
{
|
||||||
|
QString link = QString::fromUtf8( name.c_str() );
|
||||||
|
int pos = link.indexOf( '/' );
|
||||||
|
if( pos > 0 )
|
||||||
|
link.replace( pos, 1, "://" );
|
||||||
|
return new WebSiteResourceRequest( link, netMgr, this );
|
||||||
|
}
|
||||||
|
|
||||||
void WebSiteDictionary::loadIcon() throw()
|
void WebSiteDictionary::loadIcon() throw()
|
||||||
{
|
{
|
||||||
if ( dictionaryIconLoaded )
|
if ( dictionaryIconLoaded )
|
||||||
|
|
Loading…
Reference in a new issue