From f4734c076cb0089024a6087260cac4d4e3d2f2e9 Mon Sep 17 00:00:00 2001 From: Abs62 Date: Thu, 23 May 2013 18:01:50 +0400 Subject: [PATCH] Stardict: Isolate resources stylesheets --- dictionary.cc | 117 ++++++++++++++++++++++++++++++++++++++++++ dictionary.hh | 3 ++ filetype.cc | 8 +++ filetype.hh | 2 + mdx.cc | 139 ++++---------------------------------------------- stardict.cc | 11 +++- 6 files changed, 150 insertions(+), 130 deletions(-) diff --git a/dictionary.cc b/dictionary.cc index c0d14c0f..fe395f11 100644 --- a/dictionary.cc +++ b/dictionary.cc @@ -21,6 +21,7 @@ #include #include +#include namespace Dictionary { @@ -248,6 +249,122 @@ bool Class::loadIconFromFile( QString const & _filename, bool isFullName ) 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() { std::vector< string > sortedList; diff --git a/dictionary.hh b/dictionary.hh index 456500a9..2b32bc8e 100644 --- a/dictionary.hh +++ b/dictionary.hh @@ -267,6 +267,9 @@ protected: // else treat filename as name without extension bool loadIconFromFile( QString const & filename, bool isFullName = false ); + /// Make css content usable only for articles from this dictionary + void isolateCSS( QString & css ); + public: /// Creates a dictionary. The id should be made using diff --git a/filetype.cc b/filetype.cc index 8d055f56..aca3dbfc 100644 --- a/filetype.cc +++ b/filetype.cc @@ -94,4 +94,12 @@ bool isNameOfTiff( string const & name ) endsWith( s, ".tiff" ); } +bool isNameOfCSS( string const & name ) +{ + string s = simplifyString( name ); + + return + endsWith( s, ".css" ); +} + } diff --git a/filetype.hh b/filetype.hh index 5e980220..30379f96 100644 --- a/filetype.hh +++ b/filetype.hh @@ -21,6 +21,8 @@ bool isNameOfPicture( string const & ); /// with .tif or tiff). We have this one separately since we need to reconvert /// TIFF files as WebKit doesn't seem to support them. bool isNameOfTiff( string const & ); +/// Returns true if the name resembles the one of a .css file +bool isNameOfCSS( string const & ); } diff --git a/mdx.cc b/mdx.cc index b4f051b8..5e4c71de 100644 --- a/mdx.cc +++ b/mdx.cc @@ -15,6 +15,7 @@ #include "audiolink.hh" #include "ex.hh" #include "mdictparser.hh" +#include "filetype.hh" #include #include @@ -263,9 +264,6 @@ private: /// Process resource links (images, audios, etc) 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 MdxArticleRequest; 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 ); - 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() ); + hasAnyData = true; } break; @@ -756,122 +753,6 @@ void MddResourceRequest::run() 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 MdxDictionary::getResource( const string & name ) throw( std::exception ) { return new MddResourceRequest( *this, name ); diff --git a/stardict.cc b/stardict.cc index 9f26123c..eead0451 100644 --- a/stardict.cc +++ b/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; }