mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 23:34:06 +00:00
Stardict: Isolate resources stylesheets
This commit is contained in:
parent
9f1e2c1d63
commit
f4734c076c
117
dictionary.cc
117
dictionary.cc
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
namespace Dictionary {
|
namespace Dictionary {
|
||||||
|
|
||||||
|
@ -248,6 +249,122 @@ bool Class::loadIconFromFile( QString const & _filename, bool isFullName )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Class::isolateCSS( QString & css )
|
||||||
|
{
|
||||||
|
if( css.isEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int currentPos = 0;
|
||||||
|
QString newCSS;
|
||||||
|
QString prefix( "span#gdfrom-" );
|
||||||
|
prefix += QString::fromLatin1( getId().c_str() );
|
||||||
|
|
||||||
|
// Strip comments
|
||||||
|
css.replace( QRegExp( "\\/\\*[^*]*\\*+([^/][^*]*\\*+)*\\/" ), QString() );
|
||||||
|
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
if( currentPos >= css.length() )
|
||||||
|
break;
|
||||||
|
QChar ch = css[ currentPos ];
|
||||||
|
|
||||||
|
if( ch == '@' )
|
||||||
|
{
|
||||||
|
// @ rules
|
||||||
|
|
||||||
|
int n = currentPos;
|
||||||
|
if( css.mid( currentPos, 7 ).compare( "@import", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
// Copy rule as is.
|
||||||
|
n = css.indexOf( ';', currentPos );
|
||||||
|
int n2 = css.indexOf( '{', currentPos );
|
||||||
|
if( n2 > 0 && n > n2 )
|
||||||
|
n = n2 - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( css.mid( currentPos, 6 ).compare( "@media", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
// We must to parse it content to isolate it.
|
||||||
|
// Copy all up to '{' and continue parse inside.
|
||||||
|
n = css.indexOf( '{', currentPos );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( css.mid( currentPos, 5 ).compare( "@page", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
// Don't copy rule. GD use own page layout.
|
||||||
|
n = css.indexOf( '}', currentPos );
|
||||||
|
if( n < 0 )
|
||||||
|
break;
|
||||||
|
currentPos = n + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy rule as is.
|
||||||
|
n = css.indexOf( '}', currentPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
newCSS.append( css.mid( currentPos, n < 0 ? n : n - currentPos + 1 ) );
|
||||||
|
|
||||||
|
if( n < 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
currentPos = n + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ch == '{' )
|
||||||
|
{
|
||||||
|
// Selector declaration block.
|
||||||
|
// We copy it up to '}' as is.
|
||||||
|
|
||||||
|
int n = css.indexOf( '}', currentPos );
|
||||||
|
newCSS.append( css.mid( currentPos, n == -1 ? n : n - currentPos + 1 ) );
|
||||||
|
if( n < 0 )
|
||||||
|
break;
|
||||||
|
currentPos = n + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ch.isLetter() || ch == '.' || ch == '#' || ch == '*' || ch == '\\' )
|
||||||
|
{
|
||||||
|
// This is some selector.
|
||||||
|
// We must to add the isolate prefix to it.
|
||||||
|
|
||||||
|
int n = css.indexOf( QRegExp( "[ \\*\\>\\+,;:\\[\\{\\]]" ), currentPos + 1 );
|
||||||
|
QString s = css.mid( currentPos, n < 0 ? n : n - currentPos );
|
||||||
|
if( n < 0 )
|
||||||
|
{
|
||||||
|
newCSS.append( s );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QString trimmed = s.trimmed();
|
||||||
|
if( trimmed.compare( "body", Qt::CaseInsensitive ) == 0
|
||||||
|
|| trimmed.compare( "html", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
newCSS.append( s + " " + prefix + " " );
|
||||||
|
currentPos += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newCSS.append( prefix + " " );
|
||||||
|
}
|
||||||
|
|
||||||
|
n = css.indexOf( QRegExp( "[,;\\{]" ), currentPos );
|
||||||
|
s = css.mid( currentPos, n < 0 ? n : n - currentPos );
|
||||||
|
newCSS.append( s );
|
||||||
|
if( n < 0 )
|
||||||
|
break;
|
||||||
|
currentPos = n;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
newCSS.append( ch );
|
||||||
|
++currentPos;
|
||||||
|
}
|
||||||
|
css = newCSS;
|
||||||
|
}
|
||||||
|
|
||||||
string makeDictionaryId( vector< string > const & dictionaryFiles ) throw()
|
string makeDictionaryId( vector< string > const & dictionaryFiles ) throw()
|
||||||
{
|
{
|
||||||
std::vector< string > sortedList;
|
std::vector< string > sortedList;
|
||||||
|
|
|
@ -267,6 +267,9 @@ protected:
|
||||||
// else treat filename as name without extension
|
// else treat filename as name without extension
|
||||||
bool loadIconFromFile( QString const & filename, bool isFullName = false );
|
bool loadIconFromFile( QString const & filename, bool isFullName = false );
|
||||||
|
|
||||||
|
/// Make css content usable only for articles from this dictionary
|
||||||
|
void isolateCSS( QString & css );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Creates a dictionary. The id should be made using
|
/// Creates a dictionary. The id should be made using
|
||||||
|
|
|
@ -94,4 +94,12 @@ bool isNameOfTiff( string const & name )
|
||||||
endsWith( s, ".tiff" );
|
endsWith( s, ".tiff" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isNameOfCSS( string const & name )
|
||||||
|
{
|
||||||
|
string s = simplifyString( name );
|
||||||
|
|
||||||
|
return
|
||||||
|
endsWith( s, ".css" );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ bool isNameOfPicture( string const & );
|
||||||
/// with .tif or tiff). We have this one separately since we need to reconvert
|
/// with .tif or tiff). We have this one separately since we need to reconvert
|
||||||
/// TIFF files as WebKit doesn't seem to support them.
|
/// TIFF files as WebKit doesn't seem to support them.
|
||||||
bool isNameOfTiff( string const & );
|
bool isNameOfTiff( string const & );
|
||||||
|
/// Returns true if the name resembles the one of a .css file
|
||||||
|
bool isNameOfCSS( string const & );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
139
mdx.cc
139
mdx.cc
|
@ -15,6 +15,7 @@
|
||||||
#include "audiolink.hh"
|
#include "audiolink.hh"
|
||||||
#include "ex.hh"
|
#include "ex.hh"
|
||||||
#include "mdictparser.hh"
|
#include "mdictparser.hh"
|
||||||
|
#include "filetype.hh"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -263,9 +264,6 @@ private:
|
||||||
/// Process resource links (images, audios, etc)
|
/// Process resource links (images, audios, etc)
|
||||||
QString & filterResource( QString const & articleId, QString & article );
|
QString & filterResource( QString const & articleId, QString & article );
|
||||||
|
|
||||||
/// Make css content usable only for articles from this dictionary
|
|
||||||
void isolateCSS( QString & css );
|
|
||||||
|
|
||||||
friend class MdxHeadwordsRequest;
|
friend class MdxHeadwordsRequest;
|
||||||
friend class MdxArticleRequest;
|
friend class MdxArticleRequest;
|
||||||
friend class MddResourceRequest;
|
friend class MddResourceRequest;
|
||||||
|
@ -737,17 +735,16 @@ void MddResourceRequest::run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasAnyData = true;
|
if( Filetype::isNameOfCSS( u8ResourceName ) )
|
||||||
}
|
{
|
||||||
|
QString css = QString::fromUtf8( data.data(), data.size() );
|
||||||
|
dict.isolateCSS( css );
|
||||||
|
QByteArray bytes = css.toUtf8();
|
||||||
|
data.resize( bytes.size() );
|
||||||
|
memcpy( &data.front(), bytes.constData(), bytes.size() );
|
||||||
|
}
|
||||||
|
|
||||||
QString name = gd::toQString( resourceName );
|
hasAnyData = true;
|
||||||
if( name.endsWith( ".css" ) )
|
|
||||||
{
|
|
||||||
QString css = QString::fromUtf8( data.data(), data.size() );
|
|
||||||
dict.isolateCSS( css );
|
|
||||||
QByteArray bytes = css.toUtf8();
|
|
||||||
data.resize( bytes.size() );
|
|
||||||
memcpy( &data.front(), bytes.constData(), bytes.size() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -756,122 +753,6 @@ void MddResourceRequest::run()
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MdxDictionary::isolateCSS( QString & css )
|
|
||||||
{
|
|
||||||
if( css.isEmpty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
int currentPos = 0;
|
|
||||||
QString newCSS;
|
|
||||||
QString prefix( "span#gdfrom-" );
|
|
||||||
prefix += QString::fromLatin1( getId().c_str() );
|
|
||||||
|
|
||||||
// Strip comments
|
|
||||||
css.replace( QRegExp( "\\/\\*[^*]*\\*+([^/][^*]*\\*+)*\\/" ), QString() );
|
|
||||||
|
|
||||||
for( ; ; )
|
|
||||||
{
|
|
||||||
if( currentPos >= css.length() )
|
|
||||||
break;
|
|
||||||
QChar ch = css[ currentPos ];
|
|
||||||
|
|
||||||
if( ch == '@' )
|
|
||||||
{
|
|
||||||
// @ rules
|
|
||||||
|
|
||||||
int n = currentPos;
|
|
||||||
if( css.mid( currentPos, 7 ).compare( "@import", Qt::CaseInsensitive ) == 0 )
|
|
||||||
{
|
|
||||||
// Copy rule as is.
|
|
||||||
n = css.indexOf( ';', currentPos );
|
|
||||||
int n2 = css.indexOf( '{', currentPos );
|
|
||||||
if( n2 > 0 && n > n2 )
|
|
||||||
n = n2 - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( css.mid( currentPos, 6 ).compare( "@media", Qt::CaseInsensitive ) == 0 )
|
|
||||||
{
|
|
||||||
// We must to parse it content to isolate it.
|
|
||||||
// Copy all up to '{' and continue parse inside.
|
|
||||||
n = css.indexOf( '{', currentPos );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( css.mid( currentPos, 5 ).compare( "@page", Qt::CaseInsensitive ) == 0 )
|
|
||||||
{
|
|
||||||
// Don't copy rule. GD use own page layout.
|
|
||||||
n = css.indexOf( '}', currentPos );
|
|
||||||
if( n < 0 )
|
|
||||||
break;
|
|
||||||
currentPos = n + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Copy rule as is.
|
|
||||||
n = css.indexOf( '}', currentPos );
|
|
||||||
}
|
|
||||||
|
|
||||||
newCSS.append( css.mid( currentPos, n < 0 ? n : n - currentPos + 1 ) );
|
|
||||||
|
|
||||||
if( n < 0 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
currentPos = n + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ch == '{' )
|
|
||||||
{
|
|
||||||
// Selector declaration block.
|
|
||||||
// We copy it up to '}' as is.
|
|
||||||
|
|
||||||
int n = css.indexOf( '}', currentPos );
|
|
||||||
newCSS.append( css.mid( currentPos, n == -1 ? n : n - currentPos + 1 ) );
|
|
||||||
if( n < 0 )
|
|
||||||
break;
|
|
||||||
currentPos = n + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ch.isLetter() || ch == '.' || ch == '#' || ch == '*' || ch == '\\' )
|
|
||||||
{
|
|
||||||
// This is some selector.
|
|
||||||
// We must to add the isolate prefix to it.
|
|
||||||
|
|
||||||
int n = css.indexOf( QRegExp( "[ \\*\\>\\+,;:\\[\\{\\]]" ), currentPos + 1 );
|
|
||||||
QString s = css.mid( currentPos, n < 0 ? n : n - currentPos );
|
|
||||||
if( n < 0 )
|
|
||||||
{
|
|
||||||
newCSS.append( s );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
QString trimmed = s.trimmed();
|
|
||||||
if( trimmed.compare( "body", Qt::CaseInsensitive ) == 0
|
|
||||||
|| trimmed.compare( "html", Qt::CaseInsensitive ) == 0 )
|
|
||||||
{
|
|
||||||
newCSS.append( s + " " + prefix + " " );
|
|
||||||
currentPos += 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newCSS.append( prefix + " " );
|
|
||||||
}
|
|
||||||
|
|
||||||
n = css.indexOf( QRegExp( "[,;\\{]" ), currentPos );
|
|
||||||
s = css.mid( currentPos, n < 0 ? n : n - currentPos );
|
|
||||||
newCSS.append( s );
|
|
||||||
if( n < 0 )
|
|
||||||
break;
|
|
||||||
currentPos = n;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCSS.append( ch );
|
|
||||||
++currentPos;
|
|
||||||
}
|
|
||||||
css = newCSS;
|
|
||||||
}
|
|
||||||
|
|
||||||
sptr<Dictionary::DataRequest> MdxDictionary::getResource( const string & name ) throw( std::exception )
|
sptr<Dictionary::DataRequest> MdxDictionary::getResource( const string & name ) throw( std::exception )
|
||||||
{
|
{
|
||||||
return new MddResourceRequest( *this, name );
|
return new MddResourceRequest( *this, name );
|
||||||
|
|
11
stardict.cc
11
stardict.cc
|
@ -1084,7 +1084,16 @@ void StardictResourceRequest::run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Lock _( dataMutex );
|
if( Filetype::isNameOfCSS( resourceName ) )
|
||||||
|
{
|
||||||
|
Mutex::Lock _( dataMutex );
|
||||||
|
|
||||||
|
QString css = QString::fromUtf8( data.data(), data.size() );
|
||||||
|
dict.isolateCSS( css );
|
||||||
|
QByteArray bytes = css.toUtf8();
|
||||||
|
data.resize( bytes.size() );
|
||||||
|
memcpy( &data.front(), bytes.constData(), bytes.size() );
|
||||||
|
}
|
||||||
|
|
||||||
hasAnyData = true;
|
hasAnyData = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue