mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-06 03:50:19 +02:00
CSS @import support
This commit is contained in:
parent
8824ec019e
commit
f22f0a041f
3 changed files with 58 additions and 10 deletions
|
@ -2,6 +2,7 @@
|
||||||
* Experimental video support
|
* Experimental video support
|
||||||
* CSS parsing optimization for ePubs (do not parse css files multiple times)
|
* CSS parsing optimization for ePubs (do not parse css files multiple times)
|
||||||
* CSS support improvement: added support for space-separated classes list
|
* CSS support improvement: added support for space-separated classes list
|
||||||
|
* Added CSS @import support
|
||||||
|
|
||||||
===== 1.9.6.1 (Feb 24, 2014) =====
|
===== 1.9.6.1 (Feb 24, 2014) =====
|
||||||
* Fixed some config vaues reading (e.g. background)
|
* Fixed some config vaues reading (e.g. background)
|
||||||
|
|
|
@ -42,6 +42,8 @@ void StyleSheetParser::reset() {
|
||||||
myInsideComment = false;
|
myInsideComment = false;
|
||||||
mySelectorString.erase();
|
mySelectorString.erase();
|
||||||
myMap.clear();
|
myMap.clear();
|
||||||
|
myImportVector.clear();
|
||||||
|
myFirstRuleProcessed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetParser::parse(const char *text, int len, bool final) {
|
void StyleSheetParser::parse(const char *text, int len, bool final) {
|
||||||
|
@ -81,6 +83,8 @@ bool StyleSheetParser::isControlSymbol(const char symbol) {
|
||||||
return false;
|
return false;
|
||||||
case SELECTOR:
|
case SELECTOR:
|
||||||
return symbol == '{' || symbol == ';';
|
return symbol == '{' || symbol == ';';
|
||||||
|
case IMPORT:
|
||||||
|
return symbol == ';';
|
||||||
case WAITING_FOR_ATTRIBUTE:
|
case WAITING_FOR_ATTRIBUTE:
|
||||||
return symbol == '}' || symbol == ':';
|
return symbol == '}' || symbol == ':';
|
||||||
case ATTRIBUTE_NAME:
|
case ATTRIBUTE_NAME:
|
||||||
|
@ -93,6 +97,23 @@ bool StyleSheetParser::isControlSymbol(const char symbol) {
|
||||||
void StyleSheetParser::storeData(const std::string&, const StyleSheetTable::AttributeMap&) {
|
void StyleSheetParser::storeData(const std::string&, const StyleSheetTable::AttributeMap&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string StyleSheetParser::url2FullPath(const std::string &url) const {
|
||||||
|
std::string path = url;
|
||||||
|
if (ZLStringUtil::stringStartsWith(path, "url(") &&
|
||||||
|
ZLStringUtil::stringEndsWith(path, ")")) {
|
||||||
|
path = path.substr(4, path.size() - 5);
|
||||||
|
}
|
||||||
|
if (path.size() > 2 && path[0] == path[path.size() - 1]) {
|
||||||
|
if (path[0] == '\'' || path[0] == '"') {
|
||||||
|
path = path.substr(1, path.size() - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return myPathPrefix + MiscUtil::decodeHtmlURL(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheetParser::importCSS(const std::string &path) {
|
||||||
|
}
|
||||||
|
|
||||||
void StyleSheetParser::processControl(const char control) {
|
void StyleSheetParser::processControl(const char control) {
|
||||||
switch (myReadState) {
|
switch (myReadState) {
|
||||||
case WAITING_FOR_SELECTOR:
|
case WAITING_FOR_SELECTOR:
|
||||||
|
@ -108,6 +129,15 @@ void StyleSheetParser::processControl(const char control) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IMPORT:
|
||||||
|
if (control == ';') {
|
||||||
|
if (!myImportVector.empty()) {
|
||||||
|
importCSS(url2FullPath(myImportVector[0]));
|
||||||
|
myImportVector.clear();
|
||||||
|
}
|
||||||
|
myReadState = WAITING_FOR_SELECTOR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case WAITING_FOR_ATTRIBUTE:
|
case WAITING_FOR_ATTRIBUTE:
|
||||||
if (control == '}') {
|
if (control == '}') {
|
||||||
myReadState = WAITING_FOR_SELECTOR;
|
myReadState = WAITING_FOR_SELECTOR;
|
||||||
|
@ -155,12 +185,19 @@ void StyleSheetParser::processWord(std::string &word) {
|
||||||
void StyleSheetParser::processWordWithoutComments(const std::string &word) {
|
void StyleSheetParser::processWordWithoutComments(const std::string &word) {
|
||||||
switch (myReadState) {
|
switch (myReadState) {
|
||||||
case WAITING_FOR_SELECTOR:
|
case WAITING_FOR_SELECTOR:
|
||||||
myReadState = SELECTOR;
|
|
||||||
mySelectorString = word;
|
mySelectorString = word;
|
||||||
|
if (word == "@import") {
|
||||||
|
myReadState = IMPORT;
|
||||||
|
} else {
|
||||||
|
myReadState = SELECTOR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SELECTOR:
|
case SELECTOR:
|
||||||
mySelectorString += ' ' + word;
|
mySelectorString += ' ' + word;
|
||||||
break;
|
break;
|
||||||
|
case IMPORT:
|
||||||
|
myImportVector.push_back(word);
|
||||||
|
break;
|
||||||
case WAITING_FOR_ATTRIBUTE:
|
case WAITING_FOR_ATTRIBUTE:
|
||||||
myReadState = ATTRIBUTE_NAME;
|
myReadState = ATTRIBUTE_NAME;
|
||||||
// go through
|
// go through
|
||||||
|
@ -240,26 +277,21 @@ void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const St
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
|
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
|
||||||
std::string url;
|
std::string path;
|
||||||
if (it != attributes.end()) {
|
if (it != attributes.end()) {
|
||||||
for (std::vector<std::string>::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
|
for (std::vector<std::string>::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
|
||||||
if (ZLStringUtil::stringStartsWith(*jt, "url(") &&
|
if (ZLStringUtil::stringStartsWith(*jt, "url(") &&
|
||||||
ZLStringUtil::stringEndsWith(*jt, ")")) {
|
ZLStringUtil::stringEndsWith(*jt, ")")) {
|
||||||
url = jt->substr(4, jt->size() - 5);
|
path = url2FullPath(*jt);
|
||||||
if (url.size() > 2 && url[0] == url[url.size() - 1]) {
|
|
||||||
if (url[0] == '\'' || url[0] == '"') {
|
|
||||||
url = url.substr(1, url.size() - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (url.empty()) {
|
if (path.empty()) {
|
||||||
ZLLogger::Instance().println("FONT", "Source not specified for " + family);
|
ZLLogger::Instance().println("FONT", "Source not specified for " + family);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ZLFile fontFile(myPathPrefix + MiscUtil::decodeHtmlURL(url));
|
const ZLFile fontFile(path);
|
||||||
const bool bold = firstValue(attributes, "font-weight") == "bold";
|
const bool bold = firstValue(attributes, "font-weight") == "bold";
|
||||||
const bool italic = firstValue(attributes, "font-style") == "italic";
|
const bool italic = firstValue(attributes, "font-style") == "italic";
|
||||||
ZLLogger::Instance().println("FONT", family + " => " + fontFile.path());
|
ZLLogger::Instance().println("FONT", family + " => " + fontFile.path());
|
||||||
|
@ -295,6 +327,15 @@ void StyleSheetParserWithCache::store(const std::string &tag, const std::string
|
||||||
myEntries.push_back(new Entry(tag, aClass, map));
|
myEntries.push_back(new Entry(tag, aClass, map));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StyleSheetParserWithCache::importCSS(const std::string &path) {
|
||||||
|
shared_ptr<ZLInputStream> stream = ZLFile(path).inputStream();
|
||||||
|
if (!stream.isNull()) {
|
||||||
|
StyleSheetParserWithCache importParser(myPathPrefix);
|
||||||
|
importParser.parseStream(*stream);
|
||||||
|
myEntries.(myEntries.end(), importParser.myEntries.begin(), importParser.myEntries.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void StyleSheetParserWithCache::applyToTable(StyleSheetTable &table) const {
|
void StyleSheetParserWithCache::applyToTable(StyleSheetTable &table) const {
|
||||||
for (std::list<shared_ptr<Entry> >::const_iterator it = myEntries.begin(); it != myEntries.end(); ++it) {
|
for (std::list<shared_ptr<Entry> >::const_iterator it = myEntries.begin(); it != myEntries.end(); ++it) {
|
||||||
const Entry &entry = **it;
|
const Entry &entry = **it;
|
||||||
|
|
|
@ -38,6 +38,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
|
virtual void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
|
||||||
|
std::string url2FullPath(const std::string &url) const;
|
||||||
|
virtual void importCSS(const std::string &path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isControlSymbol(const char symbol);
|
bool isControlSymbol(const char symbol);
|
||||||
|
@ -54,6 +56,7 @@ private:
|
||||||
enum {
|
enum {
|
||||||
WAITING_FOR_SELECTOR,
|
WAITING_FOR_SELECTOR,
|
||||||
SELECTOR,
|
SELECTOR,
|
||||||
|
IMPORT,
|
||||||
WAITING_FOR_ATTRIBUTE,
|
WAITING_FOR_ATTRIBUTE,
|
||||||
ATTRIBUTE_NAME,
|
ATTRIBUTE_NAME,
|
||||||
ATTRIBUTE_VALUE,
|
ATTRIBUTE_VALUE,
|
||||||
|
@ -61,6 +64,8 @@ private:
|
||||||
bool myInsideComment;
|
bool myInsideComment;
|
||||||
std::string mySelectorString;
|
std::string mySelectorString;
|
||||||
StyleSheetTable::AttributeMap myMap;
|
StyleSheetTable::AttributeMap myMap;
|
||||||
|
std::vector<std::string> myImportVector;
|
||||||
|
bool myFirstRuleProcessed;
|
||||||
|
|
||||||
friend class StyleSheetSingleStyleParser;
|
friend class StyleSheetSingleStyleParser;
|
||||||
};
|
};
|
||||||
|
@ -117,6 +122,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
|
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
|
||||||
|
void importCSS(const std::string &path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<shared_ptr<Entry> > myEntries;
|
std::list<shared_ptr<Entry> > myEntries;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue