mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-03 09:49:19 +02:00
CSS parser cache
This commit is contained in:
parent
e85d8481bb
commit
f1043daea9
6 changed files with 141 additions and 85 deletions
|
@ -1,5 +1,6 @@
|
||||||
===== 1.9.7 (Mar ??, 2014) =====
|
===== 1.9.7 (Mar ??, 2014) =====
|
||||||
* Experimental video support
|
* Experimental video support
|
||||||
|
* CSS parsing optimization for ePubs (do not parse css files multiple times)
|
||||||
|
|
||||||
===== 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)
|
||||||
|
|
|
@ -26,51 +26,6 @@
|
||||||
|
|
||||||
#include "StyleSheetParser.h"
|
#include "StyleSheetParser.h"
|
||||||
|
|
||||||
StyleSheetTableParser::StyleSheetTableParser(StyleSheetTable &table) : myTable(table) {
|
|
||||||
//ZLLogger::Instance().registerClass("CSS");
|
|
||||||
}
|
|
||||||
|
|
||||||
void StyleSheetTableParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
|
|
||||||
std::string s = selector;
|
|
||||||
ZLStringUtil::stripWhiteSpaces(s);
|
|
||||||
|
|
||||||
if (s.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s[0] == '@') {
|
|
||||||
processAtRule(s, map);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string> ids = ZLStringUtil::split(s, ",");
|
|
||||||
for (std::vector<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it) {
|
|
||||||
std::string id = *it;
|
|
||||||
ZLStringUtil::stripWhiteSpaces(id);
|
|
||||||
if (!id.empty()) {
|
|
||||||
const std::size_t index = id.find('.');
|
|
||||||
if (index == std::string::npos) {
|
|
||||||
myTable.addMap(id, std::string(), map);
|
|
||||||
} else {
|
|
||||||
myTable.addMap(id.substr(0, index), id.substr(index + 1), map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StyleSheetTableParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map) {
|
|
||||||
if (name == "@font-face") {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
|
|
||||||
myReadState = WAITING_FOR_ATTRIBUTE;
|
|
||||||
parse(text, std::strlen(text), true);
|
|
||||||
shared_ptr<ZLTextStyleEntry> control = StyleSheetTable::createControl(myMap);
|
|
||||||
reset();
|
|
||||||
return control;
|
|
||||||
}
|
|
||||||
|
|
||||||
StyleSheetParser::StyleSheetParser() {
|
StyleSheetParser::StyleSheetParser() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
@ -87,21 +42,6 @@ void StyleSheetParser::reset() {
|
||||||
myMap.clear();
|
myMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetParser::parse(ZLInputStream &stream) {
|
|
||||||
if (stream.open()) {
|
|
||||||
char *buffer = new char[1024];
|
|
||||||
while (true) {
|
|
||||||
int len = stream.read(buffer, 1024);
|
|
||||||
if (len == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
parse(buffer, len);
|
|
||||||
}
|
|
||||||
delete[] buffer;
|
|
||||||
stream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StyleSheetParser::parse(const char *text, int len, bool final) {
|
void StyleSheetParser::parse(const char *text, int len, bool final) {
|
||||||
const char *start = text;
|
const char *start = text;
|
||||||
const char *end = text + len;
|
const char *end = text + len;
|
||||||
|
@ -151,9 +91,6 @@ bool StyleSheetParser::isControlSymbol(const char symbol) {
|
||||||
void StyleSheetParser::storeData(const std::string&, const StyleSheetTable::AttributeMap&) {
|
void StyleSheetParser::storeData(const std::string&, const StyleSheetTable::AttributeMap&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetParser::processAtRule(const std::string&, const StyleSheetTable::AttributeMap&) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void StyleSheetParser::processControl(const char control) {
|
void StyleSheetParser::processControl(const char control) {
|
||||||
switch (myReadState) {
|
switch (myReadState) {
|
||||||
case WAITING_FOR_SELECTOR:
|
case WAITING_FOR_SELECTOR:
|
||||||
|
@ -241,3 +178,77 @@ void StyleSheetParser::processWordWithoutComments(const std::string &word) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
|
||||||
|
myReadState = WAITING_FOR_ATTRIBUTE;
|
||||||
|
parse(text, std::strlen(text), true);
|
||||||
|
shared_ptr<ZLTextStyleEntry> control = StyleSheetTable::createControl(myMap);
|
||||||
|
reset();
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
|
||||||
|
std::string s = selector;
|
||||||
|
ZLStringUtil::stripWhiteSpaces(s);
|
||||||
|
|
||||||
|
if (s.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s[0] == '@') {
|
||||||
|
processAtRule(s, map);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> ids = ZLStringUtil::split(s, ",");
|
||||||
|
for (std::vector<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it) {
|
||||||
|
std::string id = *it;
|
||||||
|
ZLStringUtil::stripWhiteSpaces(id);
|
||||||
|
if (!id.empty()) {
|
||||||
|
const std::size_t index = id.find('.');
|
||||||
|
if (index == std::string::npos) {
|
||||||
|
store(id, std::string(), map);
|
||||||
|
} else {
|
||||||
|
store(id.substr(0, index), id.substr(index + 1), map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap&) {
|
||||||
|
if (name == "@font-face") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheetMultiStyleParser::parseStream(ZLInputStream &stream) {
|
||||||
|
if (stream.open()) {
|
||||||
|
char *buffer = new char[1024];
|
||||||
|
while (true) {
|
||||||
|
int len = stream.read(buffer, 1024);
|
||||||
|
if (len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parse(buffer, len);
|
||||||
|
}
|
||||||
|
delete[] buffer;
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleSheetTableParser::StyleSheetTableParser(StyleSheetTable &table) : myTable(table) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheetTableParser::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
|
||||||
|
myTable.addMap(tag, aClass, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheetParserWithCache::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
|
||||||
|
myEntries.push_back(new Entry(tag, aClass, map));
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
table.addMap(entry.Tag, entry.Class, entry.Map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#ifndef __STYLESHEETPARSER_H__
|
#ifndef __STYLESHEETPARSER_H__
|
||||||
#define __STYLESHEETPARSER_H__
|
#define __STYLESHEETPARSER_H__
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "StyleSheetTable.h"
|
#include "StyleSheetTable.h"
|
||||||
|
|
||||||
class ZLInputStream;
|
class ZLInputStream;
|
||||||
|
@ -32,12 +34,10 @@ protected:
|
||||||
public:
|
public:
|
||||||
virtual ~StyleSheetParser();
|
virtual ~StyleSheetParser();
|
||||||
void reset();
|
void reset();
|
||||||
void parse(ZLInputStream &stream);
|
|
||||||
void parse(const char *text, int len, bool final = false);
|
void parse(const char *text, int len, bool final = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
|
virtual void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
|
||||||
virtual void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isControlSymbol(const char symbol);
|
bool isControlSymbol(const char symbol);
|
||||||
|
@ -62,23 +62,59 @@ private:
|
||||||
friend class StyleSheetSingleStyleParser;
|
friend class StyleSheetSingleStyleParser;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StyleSheetTableParser : public StyleSheetParser {
|
|
||||||
|
|
||||||
public:
|
|
||||||
StyleSheetTableParser(StyleSheetTable &table);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
|
|
||||||
void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
|
|
||||||
|
|
||||||
private:
|
|
||||||
StyleSheetTable &myTable;
|
|
||||||
};
|
|
||||||
|
|
||||||
class StyleSheetSingleStyleParser : public StyleSheetParser {
|
class StyleSheetSingleStyleParser : public StyleSheetParser {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
shared_ptr<ZLTextStyleEntry> parseString(const char *text);
|
shared_ptr<ZLTextStyleEntry> parseString(const char *text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StyleSheetMultiStyleParser : public StyleSheetParser {
|
||||||
|
|
||||||
|
public:
|
||||||
|
void parseStream(ZLInputStream &stream);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
|
||||||
|
void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
|
||||||
|
};
|
||||||
|
|
||||||
|
class StyleSheetTableParser : public StyleSheetMultiStyleParser {
|
||||||
|
|
||||||
|
public:
|
||||||
|
StyleSheetTableParser(StyleSheetTable &table);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
|
||||||
|
|
||||||
|
private:
|
||||||
|
StyleSheetTable &myTable;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StyleSheetParserWithCache : public StyleSheetMultiStyleParser {
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Entry {
|
||||||
|
const std::string Tag;
|
||||||
|
const std::string Class;
|
||||||
|
const StyleSheetTable::AttributeMap Map;
|
||||||
|
|
||||||
|
Entry(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
void applyToTable(StyleSheetTable &table) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::list<shared_ptr<Entry> > myEntries;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline StyleSheetParserWithCache::Entry::Entry(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) : Tag(tag), Class(aClass), Map(map) {
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __STYLESHEETPARSER_H__ */
|
#endif /* __STYLESHEETPARSER_H__ */
|
||||||
|
|
|
@ -64,6 +64,7 @@ private:
|
||||||
std::map<Key,bool> myPageBreakAfterMap;
|
std::map<Key,bool> myPageBreakAfterMap;
|
||||||
|
|
||||||
friend class StyleSheetTableParser;
|
friend class StyleSheetTableParser;
|
||||||
|
friend class StyleSheetParserWithCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StyleSheetTable::Key::Key(const std::string &tag, const std::string &aClass) : TagName(tag), ClassName(aClass) {
|
inline StyleSheetTable::Key::Key(const std::string &tag, const std::string &aClass) : TagName(tag), ClassName(aClass) {
|
||||||
|
|
|
@ -260,15 +260,21 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href);
|
const std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href);
|
||||||
|
//ZLLogger::Instance().registerClass("CSS");
|
||||||
ZLLogger::Instance().println("CSS", "style file: " + cssFilePath);
|
ZLLogger::Instance().println("CSS", "style file: " + cssFilePath);
|
||||||
shared_ptr<ZLInputStream> cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap);
|
const ZLFile cssFile(cssFilePath);
|
||||||
if (cssStream.isNull()) {
|
shared_ptr<StyleSheetParserWithCache> parser = reader.myFileParsers[cssFile.path()];
|
||||||
return;
|
if (parser.isNull()) {
|
||||||
|
parser = new StyleSheetParserWithCache();
|
||||||
|
reader.myFileParsers[cssFile.path()] = parser;
|
||||||
|
ZLLogger::Instance().println("CSS", "creating stream");
|
||||||
|
shared_ptr<ZLInputStream> cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap);
|
||||||
|
if (!cssStream.isNull()) {
|
||||||
|
ZLLogger::Instance().println("CSS", "parsing file");
|
||||||
|
parser->parseStream(*cssStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ZLLogger::Instance().println("CSS", "parsing file");
|
parser->applyToTable(reader.myStyleSheetTable);
|
||||||
StyleSheetTableParser parser(reader.myStyleSheetTable);
|
|
||||||
parser.parse(*cssStream);
|
|
||||||
//reader.myStyleSheetTable.dump();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {
|
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {
|
||||||
|
|
|
@ -112,6 +112,7 @@ private:
|
||||||
bool myCurrentParagraphIsEmpty;
|
bool myCurrentParagraphIsEmpty;
|
||||||
shared_ptr<StyleSheetSingleStyleParser> myStyleParser;
|
shared_ptr<StyleSheetSingleStyleParser> myStyleParser;
|
||||||
shared_ptr<StyleSheetTableParser> myTableParser;
|
shared_ptr<StyleSheetTableParser> myTableParser;
|
||||||
|
std::map<std::string,shared_ptr<StyleSheetParserWithCache> > myFileParsers;
|
||||||
XHTMLReadingState myReadState;
|
XHTMLReadingState myReadState;
|
||||||
int myBodyCounter;
|
int myBodyCounter;
|
||||||
bool myMarkNextImageAsCover;
|
bool myMarkNextImageAsCover;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue