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