mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-07-23 03:02:50 +03:00
Moved StyleSheet classes into classes files.
--HG-- branch : dev-stateful-drawable
This commit is contained in:
21
include/eepp/ui/css/stylesheet.hpp
Normal file
21
include/eepp/ui/css/stylesheet.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEET_HPP
|
||||
#define EE_UI_CSS_STYLESHEET_HPP
|
||||
|
||||
#include <eepp/ui/css/stylesheetnode.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class StyleSheet {
|
||||
public:
|
||||
StyleSheet();
|
||||
|
||||
void addNode( StyleSheetNode node );
|
||||
|
||||
StyleSheetProperties find( const std::string& tagName = "", const std::string& id = "", const std::vector<std::string>& classes = {}, const std::string& pseudoClass = "" );
|
||||
|
||||
std::vector<StyleSheetNode> nodes;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
21
include/eepp/ui/css/stylesheetelement.hpp
Normal file
21
include/eepp/ui/css/stylesheetelement.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEETELEMENT_HPP
|
||||
#define EE_UI_CSS_STYLESHEETELEMENT_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class StyleSheetElement {
|
||||
public:
|
||||
virtual std::string getStyleSheetTag() const = 0;
|
||||
|
||||
virtual const std::string& getStyleSheetId() const;
|
||||
|
||||
virtual const std::vector<std::string>& getStyleSheetClasses() = 0;
|
||||
|
||||
virtual StyleSheetElement * getStyleSheetParentElement() = 0;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
21
include/eepp/ui/css/stylesheetnode.hpp
Normal file
21
include/eepp/ui/css/stylesheetnode.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEETNODE_HPP
|
||||
#define EE_UI_CSS_STYLESHEETNODE_HPP
|
||||
|
||||
#include <eepp/ui/css/stylesheetselector.hpp>
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class StyleSheetNode {
|
||||
public:
|
||||
explicit StyleSheetNode( const std::string& selector, const StyleSheetProperties& properties );
|
||||
|
||||
void print();
|
||||
|
||||
StyleSheetSelector selector;
|
||||
StyleSheetProperties properties;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -1,271 +1,20 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEETPARSER
|
||||
#define EE_UI_CSS_STYLESHEETPARSER
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <eepp/core/string.hpp>
|
||||
#include <eepp/system/iostream.hpp>
|
||||
#include <eepp/ui/css/stylesheetselector.hpp>
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
#include <eepp/ui/css/stylesheetnode.hpp>
|
||||
#include <eepp/ui/css/stylesheet.hpp>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
using namespace EE;
|
||||
using namespace EE::System;
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
// This is not how it should be.
|
||||
class StyleSheetSelector {
|
||||
public:
|
||||
enum SelectorType {
|
||||
TagName = 1 << 0,
|
||||
Id = 1 << 1,
|
||||
Class = 1 << 2,
|
||||
PseudoClass = 1 << 3
|
||||
};
|
||||
|
||||
enum SpecificityVal {
|
||||
SpecificityId = 1000000,
|
||||
SpecificityClass = 100000,
|
||||
SpecificityTag = 10000,
|
||||
SpecificityPseudoClass = 0
|
||||
};
|
||||
|
||||
explicit StyleSheetSelector( const std::string& selectorName ) :
|
||||
name( selectorName ),
|
||||
specificity(0)
|
||||
{
|
||||
auto parts = String::split( name, ' ' );
|
||||
|
||||
for ( auto it = parts.begin(); it != parts.end(); ++it ) {
|
||||
parseSelector( *it );
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 getRequiredFlags() {
|
||||
Uint32 flags = 0;
|
||||
|
||||
if ( hasTagName() )
|
||||
flags |= TagName;
|
||||
|
||||
if ( hasId() )
|
||||
flags |= Id;
|
||||
|
||||
if ( hasClasses() )
|
||||
flags |= Class;
|
||||
|
||||
if ( hasPseudoClass() )
|
||||
flags |= PseudoClass;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
const std::string& getName() const { return name; };
|
||||
|
||||
const std::string& getTagName() const { return tagName; }
|
||||
|
||||
const std::string getId() const { return id; }
|
||||
|
||||
const std::vector<std::string> getClasses() const { return classes; }
|
||||
|
||||
const std::string& getPseudoClass() const;
|
||||
|
||||
bool hasTagName() { return !tagName.empty(); }
|
||||
|
||||
bool hasId() { return !id.empty(); }
|
||||
|
||||
bool hasClasses() { return !classes.empty(); }
|
||||
|
||||
bool hasClass( std::string cls ) { return std::find(classes.begin(), classes.end(), cls) != classes.end(); }
|
||||
|
||||
bool hasPseudoClass() { return !pseudoClass.empty(); }
|
||||
|
||||
Uint32 getSpecificity() { return specificity; }
|
||||
protected:
|
||||
std::string name;
|
||||
std::string tagName;
|
||||
std::string id;
|
||||
std::vector<std::string> classes;
|
||||
std::string pseudoClass;
|
||||
Uint32 specificity;
|
||||
|
||||
void parseSelector( const std::string& selector ) {
|
||||
auto selPseudo = String::split( selector, ':' );
|
||||
|
||||
if ( !selPseudo.empty() ) {
|
||||
std::string rselector( selPseudo[0] );
|
||||
|
||||
if ( !rselector.empty() ) {
|
||||
if ( rselector[0] == '.' ) {
|
||||
classes.push_back( rselector.substr(1) );
|
||||
specificity += SpecificityClass;
|
||||
} else if ( selector[0] == '#' ) {
|
||||
id = rselector.substr(1);
|
||||
specificity += SpecificityId;
|
||||
} else {
|
||||
tagName = rselector;
|
||||
specificity += SpecificityTag;
|
||||
}
|
||||
}
|
||||
|
||||
if ( selPseudo.size() > 1 ) {
|
||||
pseudoClass = selPseudo[1];
|
||||
specificity += SpecificityPseudoClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class StyleSheetProperty {
|
||||
public:
|
||||
StyleSheetProperty()
|
||||
{}
|
||||
|
||||
explicit StyleSheetProperty( const std::string& name, const std::string& value ) :
|
||||
name( String::trim( name ) ),
|
||||
value( String::trim( value ) )
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, StyleSheetProperty> StyleSheetProperties;
|
||||
|
||||
class StyleSheetSelectorParser {
|
||||
public:
|
||||
StyleSheetSelectorParser(){}
|
||||
|
||||
explicit StyleSheetSelectorParser( std::string name )
|
||||
{
|
||||
std::vector<std::string> sels = String::split( name, ',' );
|
||||
|
||||
for ( std::vector<std::string>::iterator it = sels.begin(); it != sels.end(); ++it )
|
||||
{
|
||||
std::string cur = String::trim( *it );
|
||||
|
||||
selectors.push_back( StyleSheetSelector( cur ) );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<StyleSheetSelector> selectors;
|
||||
};
|
||||
|
||||
class StyleSheetPropertiesParser {
|
||||
public:
|
||||
typedef std::map<std::string, StyleSheetProperty> PropertiesDictionary;
|
||||
|
||||
StyleSheetPropertiesParser(){}
|
||||
|
||||
explicit StyleSheetPropertiesParser( const std::string& propsstr ) {
|
||||
std::vector<std::string> props = String::split( propsstr, ';' );
|
||||
|
||||
if ( !props.empty() ) {
|
||||
parse( propsstr );
|
||||
}
|
||||
};
|
||||
|
||||
void print();
|
||||
|
||||
PropertiesDictionary properties;
|
||||
protected:
|
||||
enum ReadState {
|
||||
ReadingPropertyName,
|
||||
ReadingPropertyValue,
|
||||
ReadingValueUrl,
|
||||
ReadingComment
|
||||
};
|
||||
|
||||
ReadState prevRs;
|
||||
|
||||
void parse( std::string propsstr );
|
||||
|
||||
int readPropertyName( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
|
||||
int readPropertyValue( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
|
||||
int readComment( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
|
||||
int readValueUrl( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
};
|
||||
|
||||
class StyleSheetNode {
|
||||
public:
|
||||
explicit StyleSheetNode( const std::string& selector, const StyleSheetProperties& properties ) :
|
||||
selector( selector ),
|
||||
properties( properties )
|
||||
{}
|
||||
|
||||
void print() {
|
||||
std::cout << selector.getName() << " {" << std::endl;
|
||||
|
||||
for ( StyleSheetProperties::iterator it = properties.begin(); it != properties.end(); ++it ) {
|
||||
StyleSheetProperty& prop = it->second;
|
||||
|
||||
std::cout << "\t" << prop.name << ": " << prop.value << ";" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "}" << std::endl;
|
||||
}
|
||||
|
||||
StyleSheetSelector selector;
|
||||
StyleSheetProperties properties;
|
||||
};
|
||||
|
||||
class StyleSheet {
|
||||
public:
|
||||
StyleSheet() {}
|
||||
|
||||
void addNode( StyleSheetNode node ) {
|
||||
nodes.push_back( node );
|
||||
}
|
||||
|
||||
StyleSheetProperties find( const std::string& tagName = "", const std::string& id = "", const std::vector<std::string>& classes = {}, const std::string& pseudoClass = "" ) {
|
||||
StyleSheetProperties propertiesSelected;
|
||||
Uint32 lastSpecificity = -1;
|
||||
|
||||
for ( auto it = nodes.begin(); it != nodes.end(); ++it ) {
|
||||
StyleSheetNode& node = *it;
|
||||
StyleSheetSelector& selector = node.selector;
|
||||
|
||||
Uint32 flags = 0;
|
||||
|
||||
if ( selector.hasTagName() && !tagName.empty() && selector.getTagName() == tagName ) {
|
||||
flags |= StyleSheetSelector::TagName;
|
||||
}
|
||||
|
||||
if ( selector.hasId() && !id.empty() && selector.getId() == id ) {
|
||||
flags |= StyleSheetSelector::Id;
|
||||
}
|
||||
|
||||
if ( selector.hasClasses() && !classes.empty() ) {
|
||||
bool hasClasses = true;
|
||||
for ( auto cit = classes.begin(); cit != classes.end(); ++cit ) {
|
||||
if ( !selector.hasClass( *cit ) ) {
|
||||
hasClasses = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasClasses ) {
|
||||
flags |= StyleSheetSelector::Class;
|
||||
}
|
||||
}
|
||||
|
||||
if ( selector.hasPseudoClass() && !pseudoClass.empty() && selector.getPseudoClass() == pseudoClass ) {
|
||||
flags |= StyleSheetSelector::PseudoClass;
|
||||
}
|
||||
|
||||
if ( flags == selector.getRequiredFlags() && selector.getSpecificity() > lastSpecificity ) {
|
||||
propertiesSelected = node.properties;
|
||||
lastSpecificity = selector.getSpecificity();
|
||||
}
|
||||
}
|
||||
|
||||
return propertiesSelected;
|
||||
}
|
||||
|
||||
std::vector<StyleSheetNode> nodes;
|
||||
};
|
||||
|
||||
class StyleSheetParser {
|
||||
public:
|
||||
StyleSheetParser();
|
||||
@@ -275,6 +24,8 @@ class StyleSheetParser {
|
||||
bool loadFromFile( const std::string& file );
|
||||
|
||||
void print();
|
||||
|
||||
StyleSheet& getStyleSheet();
|
||||
protected:
|
||||
enum ReadState {
|
||||
ReadingStyle,
|
||||
|
||||
43
include/eepp/ui/css/stylesheetpropertiesparser.hpp
Normal file
43
include/eepp/ui/css/stylesheetpropertiesparser.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEETPROPERTIESPARSER_HPP
|
||||
#define EE_UI_CSS_STYLESHEETPROPERTIESPARSER_HPP
|
||||
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
#include <eepp/core/string.hpp>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class StyleSheetPropertiesParser {
|
||||
public:
|
||||
StyleSheetPropertiesParser();
|
||||
|
||||
explicit StyleSheetPropertiesParser( const std::string& propsstr );
|
||||
|
||||
void print();
|
||||
|
||||
StyleSheetProperties properties;
|
||||
protected:
|
||||
enum ReadState {
|
||||
ReadingPropertyName,
|
||||
ReadingPropertyValue,
|
||||
ReadingValueUrl,
|
||||
ReadingComment
|
||||
};
|
||||
|
||||
ReadState prevRs;
|
||||
|
||||
void parse( std::string propsstr );
|
||||
|
||||
int readPropertyName( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
|
||||
int readPropertyValue( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
|
||||
int readComment( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
|
||||
int readValueUrl( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
24
include/eepp/ui/css/stylesheetproperty.hpp
Normal file
24
include/eepp/ui/css/stylesheetproperty.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEETPROPERTY_HPP
|
||||
#define EE_UI_CSS_STYLESHEETPROPERTY_HPP
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class StyleSheetProperty {
|
||||
public:
|
||||
StyleSheetProperty();
|
||||
|
||||
explicit StyleSheetProperty( const std::string& name, const std::string& value );
|
||||
|
||||
std::string name;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, StyleSheetProperty> StyleSheetProperties;
|
||||
typedef std::map<std::string, StyleSheetProperty> PropertiesDictionary;
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
62
include/eepp/ui/css/stylesheetselector.hpp
Normal file
62
include/eepp/ui/css/stylesheetselector.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEETSELECTOR_HPP
|
||||
#define EE_UI_CSS_STYLESHEETSELECTOR_HPP
|
||||
|
||||
#include <eepp/core.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class StyleSheetSelector {
|
||||
public:
|
||||
enum SelectorType {
|
||||
TagName = 1 << 0,
|
||||
Id = 1 << 1,
|
||||
Class = 1 << 2,
|
||||
PseudoClass = 1 << 3
|
||||
};
|
||||
|
||||
enum SpecificityVal {
|
||||
SpecificityId = 1000000,
|
||||
SpecificityClass = 100000,
|
||||
SpecificityTag = 10000,
|
||||
SpecificityPseudoClass = 0
|
||||
};
|
||||
|
||||
explicit StyleSheetSelector( const std::string& selectorName );
|
||||
|
||||
Uint32 getRequiredFlags();
|
||||
|
||||
const std::string& getName() const;
|
||||
|
||||
const std::string& getTagName() const;
|
||||
|
||||
const std::string getId() const;
|
||||
|
||||
const std::vector<std::string> getClasses() const;
|
||||
|
||||
const std::string& getPseudoClass() const;
|
||||
|
||||
bool hasTagName();
|
||||
|
||||
bool hasId();
|
||||
|
||||
bool hasClasses();
|
||||
|
||||
bool hasClass( std::string cls );
|
||||
|
||||
bool hasPseudoClass();
|
||||
|
||||
Uint32 getSpecificity();
|
||||
protected:
|
||||
std::string name;
|
||||
std::string tagName;
|
||||
std::string id;
|
||||
std::vector<std::string> classes;
|
||||
std::string pseudoClass;
|
||||
Uint32 specificity;
|
||||
|
||||
void parseSelector( const std::string& selector );
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
18
include/eepp/ui/css/stylesheetselectorparser.hpp
Normal file
18
include/eepp/ui/css/stylesheetselectorparser.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef EE_UI_CSS_STYLESHEETSELECTORPARSER_HPP
|
||||
#define EE_UI_CSS_STYLESHEETSELECTORPARSER_HPP
|
||||
|
||||
#include <eepp/ui/css/stylesheetselector.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class StyleSheetSelectorParser {
|
||||
public:
|
||||
StyleSheetSelectorParser();
|
||||
|
||||
explicit StyleSheetSelectorParser( std::string name );
|
||||
|
||||
std::vector<StyleSheetSelector> selectors;
|
||||
};
|
||||
|
||||
}}}
|
||||
#endif
|
||||
@@ -293,7 +293,14 @@
|
||||
../../include/eepp/thirdparty/PlusCallback/callback.hpp
|
||||
../../include/eepp/ui/base.hpp
|
||||
../../include/eepp/ui.hpp
|
||||
../../include/eepp/ui/css/stylesheet.hpp
|
||||
../../include/eepp/ui/css/stylesheetelement.hpp
|
||||
../../include/eepp/ui/css/stylesheetnode.hpp
|
||||
../../include/eepp/ui/css/stylesheetparser.hpp
|
||||
../../include/eepp/ui/css/stylesheetpropertiesparser.hpp
|
||||
../../include/eepp/ui/css/stylesheetproperty.hpp
|
||||
../../include/eepp/ui/css/stylesheetselector.hpp
|
||||
../../include/eepp/ui/css/stylesheetselectorparser.hpp
|
||||
../../include/eepp/ui/marginmove/scale.hpp
|
||||
../../include/eepp/ui/tools/textureatlaseditor.hpp
|
||||
../../include/eepp/ui/uicheckbox.hpp
|
||||
@@ -693,7 +700,13 @@
|
||||
../../src/eepp/system/translator.cpp
|
||||
../../src/eepp/system/virtualfilesystem.cpp
|
||||
../../src/eepp/system/zip.cpp
|
||||
../../src/eepp/ui/css/stylesheet.cpp
|
||||
../../src/eepp/ui/css/stylesheetnode.cpp
|
||||
../../src/eepp/ui/css/stylesheetparser.cpp
|
||||
../../src/eepp/ui/css/stylesheetpropertiesparser.cpp
|
||||
../../src/eepp/ui/css/stylesheetproperty.cpp
|
||||
../../src/eepp/ui/css/stylesheetselector.cpp
|
||||
../../src/eepp/ui/css/stylesheetselectorparser.cpp
|
||||
../../src/eepp/ui/tools/textureatlaseditor.cpp
|
||||
../../src/eepp/ui/tools/textureatlasnew.cpp
|
||||
../../src/eepp/ui/tools/textureatlasnew.hpp
|
||||
|
||||
58
src/eepp/ui/css/stylesheet.cpp
Normal file
58
src/eepp/ui/css/stylesheet.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <eepp/ui/css/stylesheet.hpp>
|
||||
#include <eepp/ui/css/stylesheetselector.hpp>
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
StyleSheet::StyleSheet() {}
|
||||
|
||||
void StyleSheet::addNode( StyleSheetNode node ) {
|
||||
nodes.push_back( node );
|
||||
}
|
||||
|
||||
StyleSheetProperties StyleSheet::find( const std::string& tagName, const std::string& id, const std::vector<std::string>& classes, const std::string& pseudoClass ) {
|
||||
StyleSheetProperties propertiesSelected;
|
||||
Uint32 lastSpecificity = -1;
|
||||
|
||||
for ( auto it = nodes.begin(); it != nodes.end(); ++it ) {
|
||||
StyleSheetNode& node = *it;
|
||||
StyleSheetSelector& selector = node.selector;
|
||||
|
||||
Uint32 flags = 0;
|
||||
|
||||
if ( selector.hasTagName() && !tagName.empty() && selector.getTagName() == tagName ) {
|
||||
flags |= StyleSheetSelector::TagName;
|
||||
}
|
||||
|
||||
if ( selector.hasId() && !id.empty() && selector.getId() == id ) {
|
||||
flags |= StyleSheetSelector::Id;
|
||||
}
|
||||
|
||||
if ( selector.hasClasses() && !classes.empty() ) {
|
||||
bool hasClasses = true;
|
||||
for ( auto cit = classes.begin(); cit != classes.end(); ++cit ) {
|
||||
if ( !selector.hasClass( *cit ) ) {
|
||||
hasClasses = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasClasses ) {
|
||||
flags |= StyleSheetSelector::Class;
|
||||
}
|
||||
}
|
||||
|
||||
if ( selector.hasPseudoClass() && !pseudoClass.empty() && selector.getPseudoClass() == pseudoClass ) {
|
||||
flags |= StyleSheetSelector::PseudoClass;
|
||||
}
|
||||
|
||||
if ( flags == selector.getRequiredFlags() && selector.getSpecificity() > lastSpecificity ) {
|
||||
propertiesSelected = node.properties;
|
||||
lastSpecificity = selector.getSpecificity();
|
||||
}
|
||||
}
|
||||
|
||||
return propertiesSelected;
|
||||
}
|
||||
|
||||
}}}
|
||||
23
src/eepp/ui/css/stylesheetnode.cpp
Normal file
23
src/eepp/ui/css/stylesheetnode.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <eepp/ui/css/stylesheetnode.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
StyleSheetNode::StyleSheetNode( const std::string& selector, const StyleSheetProperties& properties ) :
|
||||
selector( selector ),
|
||||
properties( properties )
|
||||
{}
|
||||
|
||||
void StyleSheetNode::print() {
|
||||
std::cout << selector.getName() << " {" << std::endl;
|
||||
|
||||
for ( StyleSheetProperties::iterator it = properties.begin(); it != properties.end(); ++it ) {
|
||||
StyleSheetProperty& prop = it->second;
|
||||
|
||||
std::cout << "\t" << prop.name << ": " << prop.value << ";" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "}" << std::endl;
|
||||
}
|
||||
|
||||
}}}
|
||||
@@ -1,151 +1,10 @@
|
||||
#include <eepp/ui/css/stylesheetparser.hpp>
|
||||
#include <eepp/ui/css/stylesheetselectorparser.hpp>
|
||||
#include <eepp/ui/css/stylesheetpropertiesparser.hpp>
|
||||
#include <eepp/system/iostreamfile.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
void StyleSheetPropertiesParser::parse( std::string propsstr ) {
|
||||
ReadState rs = ReadingPropertyName;
|
||||
prevRs = rs;
|
||||
std::size_t pos = 0;
|
||||
std::string buffer;
|
||||
|
||||
while ( pos < propsstr.size() ) {
|
||||
switch (rs) {
|
||||
case ReadingPropertyName:
|
||||
{
|
||||
pos = readPropertyName(rs, pos, buffer, propsstr);
|
||||
break;
|
||||
}
|
||||
case ReadingPropertyValue:
|
||||
{
|
||||
pos = readPropertyValue(rs, pos, buffer, propsstr);
|
||||
break;
|
||||
}
|
||||
case ReadingComment:
|
||||
{
|
||||
pos = readComment(rs, pos, buffer, propsstr);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readPropertyName(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string& str) {
|
||||
prevRs = rs;
|
||||
buffer.clear();
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '/' && str.size() > pos + 1 && str[pos+1] == '*' ) {
|
||||
rs = ReadingComment;
|
||||
return pos;
|
||||
}
|
||||
|
||||
if ( str[pos] == ':' ) {
|
||||
rs = ReadingPropertyValue;
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
if ( str[pos] != '\n' && str[pos] != '\t' )
|
||||
buffer += str[pos];
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readPropertyValue(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string& str) {
|
||||
std::string propName( buffer );
|
||||
|
||||
buffer.clear();
|
||||
|
||||
prevRs = rs;
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '/' && str.size() > pos + 1 && str[pos+1] == '*' ) {
|
||||
rs = ReadingComment;
|
||||
return pos;
|
||||
}
|
||||
|
||||
if ( buffer.size() == 4 && buffer.substr(0,4) == "url(" ) {
|
||||
rs = ReadingValueUrl;
|
||||
pos = readValueUrl( rs, pos, buffer, str );
|
||||
}
|
||||
|
||||
if ( str[pos] == ';' ) {
|
||||
rs = ReadingPropertyName;
|
||||
|
||||
properties[ propName ] = StyleSheetProperty( propName, buffer );
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
if ( str[pos] != '\n' && str[pos] != '\t' )
|
||||
buffer += str[pos];
|
||||
|
||||
pos++;
|
||||
|
||||
if ( pos == str.size() ) {
|
||||
rs = ReadingPropertyName;
|
||||
|
||||
properties[ propName ] = StyleSheetProperty( propName, buffer );
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readComment(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string & str) {
|
||||
buffer.clear();
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '*' && str.size() > pos + 1 && str[pos+1] == '/' ) {
|
||||
rs = prevRs;
|
||||
return pos + 2;
|
||||
}
|
||||
|
||||
buffer += str[pos];
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readValueUrl(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string& str) {
|
||||
bool quoted = false;
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( !quoted && str[pos] == '"' ) {
|
||||
buffer += str[pos];
|
||||
|
||||
quoted = true;
|
||||
} else if ( !quoted ) {
|
||||
if ( str[pos] != '\n' && str[pos] != '\t' )
|
||||
buffer += str[pos];
|
||||
|
||||
if ( str[pos] == ')' ) {
|
||||
rs = ReadingPropertyValue;
|
||||
return pos + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
buffer += str[pos];
|
||||
|
||||
if ( quoted && str[pos] == '"' ) {
|
||||
quoted = false;
|
||||
}
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
StyleSheetParser::StyleSheetParser() {
|
||||
}
|
||||
|
||||
@@ -168,6 +27,10 @@ void StyleSheetParser::print() {
|
||||
}
|
||||
}
|
||||
|
||||
StyleSheet &StyleSheetParser::getStyleSheet() {
|
||||
return mStyleSheet;
|
||||
}
|
||||
|
||||
bool StyleSheetParser::parse() {
|
||||
ReadState rs = ReadingStyle;
|
||||
std::size_t pos = 0;
|
||||
|
||||
158
src/eepp/ui/css/stylesheetpropertiesparser.cpp
Normal file
158
src/eepp/ui/css/stylesheetpropertiesparser.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#include <eepp/ui/css/stylesheetpropertiesparser.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
StyleSheetPropertiesParser::StyleSheetPropertiesParser(){}
|
||||
|
||||
StyleSheetPropertiesParser::StyleSheetPropertiesParser( const std::string& propsstr ) {
|
||||
std::vector<std::string> props = String::split( propsstr, ';' );
|
||||
|
||||
if ( !props.empty() ) {
|
||||
parse( propsstr );
|
||||
}
|
||||
};
|
||||
|
||||
void StyleSheetPropertiesParser::parse( std::string propsstr ) {
|
||||
ReadState rs = ReadingPropertyName;
|
||||
prevRs = rs;
|
||||
std::size_t pos = 0;
|
||||
std::string buffer;
|
||||
|
||||
while ( pos < propsstr.size() ) {
|
||||
switch (rs) {
|
||||
case ReadingPropertyName:
|
||||
{
|
||||
pos = readPropertyName(rs, pos, buffer, propsstr);
|
||||
break;
|
||||
}
|
||||
case ReadingPropertyValue:
|
||||
{
|
||||
pos = readPropertyValue(rs, pos, buffer, propsstr);
|
||||
break;
|
||||
}
|
||||
case ReadingComment:
|
||||
{
|
||||
pos = readComment(rs, pos, buffer, propsstr);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readPropertyName(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string& str) {
|
||||
prevRs = rs;
|
||||
buffer.clear();
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '/' && str.size() > pos + 1 && str[pos+1] == '*' ) {
|
||||
rs = ReadingComment;
|
||||
return pos;
|
||||
}
|
||||
|
||||
if ( str[pos] == ':' ) {
|
||||
rs = ReadingPropertyValue;
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
if ( str[pos] != '\n' && str[pos] != '\t' )
|
||||
buffer += str[pos];
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readPropertyValue(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string& str) {
|
||||
std::string propName( buffer );
|
||||
|
||||
buffer.clear();
|
||||
|
||||
prevRs = rs;
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '/' && str.size() > pos + 1 && str[pos+1] == '*' ) {
|
||||
rs = ReadingComment;
|
||||
return pos;
|
||||
}
|
||||
|
||||
if ( buffer.size() == 4 && buffer.substr(0,4) == "url(" ) {
|
||||
rs = ReadingValueUrl;
|
||||
pos = readValueUrl( rs, pos, buffer, str );
|
||||
}
|
||||
|
||||
if ( str[pos] == ';' ) {
|
||||
rs = ReadingPropertyName;
|
||||
|
||||
properties[ propName ] = StyleSheetProperty( propName, buffer );
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
if ( str[pos] != '\n' && str[pos] != '\t' )
|
||||
buffer += str[pos];
|
||||
|
||||
pos++;
|
||||
|
||||
if ( pos == str.size() ) {
|
||||
rs = ReadingPropertyName;
|
||||
|
||||
properties[ propName ] = StyleSheetProperty( propName, buffer );
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readComment(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string & str) {
|
||||
buffer.clear();
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '*' && str.size() > pos + 1 && str[pos+1] == '/' ) {
|
||||
rs = prevRs;
|
||||
return pos + 2;
|
||||
}
|
||||
|
||||
buffer += str[pos];
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readValueUrl(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string& str) {
|
||||
bool quoted = false;
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( !quoted && str[pos] == '"' ) {
|
||||
buffer += str[pos];
|
||||
|
||||
quoted = true;
|
||||
} else if ( !quoted ) {
|
||||
if ( str[pos] != '\n' && str[pos] != '\t' )
|
||||
buffer += str[pos];
|
||||
|
||||
if ( str[pos] == ')' ) {
|
||||
rs = ReadingPropertyValue;
|
||||
return pos + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
buffer += str[pos];
|
||||
|
||||
if ( quoted && str[pos] == '"' ) {
|
||||
quoted = false;
|
||||
}
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
}}}
|
||||
14
src/eepp/ui/css/stylesheetproperty.cpp
Normal file
14
src/eepp/ui/css/stylesheetproperty.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
#include <eepp/core/string.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
StyleSheetProperty::StyleSheetProperty()
|
||||
{}
|
||||
|
||||
StyleSheetProperty::StyleSheetProperty( const std::string& name, const std::string& value ) :
|
||||
name( String::trim( name ) ),
|
||||
value( String::trim( value ) )
|
||||
{}
|
||||
|
||||
}}}
|
||||
84
src/eepp/ui/css/stylesheetselector.cpp
Normal file
84
src/eepp/ui/css/stylesheetselector.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include <eepp/ui/css/stylesheetselector.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
|
||||
StyleSheetSelector::StyleSheetSelector( const std::string& selectorName ) :
|
||||
name( selectorName ),
|
||||
specificity(0)
|
||||
{
|
||||
auto parts = String::split( name, ' ' );
|
||||
|
||||
for ( auto it = parts.begin(); it != parts.end(); ++it ) {
|
||||
parseSelector( *it );
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 StyleSheetSelector::getRequiredFlags() {
|
||||
Uint32 flags = 0;
|
||||
|
||||
if ( hasTagName() )
|
||||
flags |= TagName;
|
||||
|
||||
if ( hasId() )
|
||||
flags |= Id;
|
||||
|
||||
if ( hasClasses() )
|
||||
flags |= Class;
|
||||
|
||||
if ( hasPseudoClass() )
|
||||
flags |= PseudoClass;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
const std::string& StyleSheetSelector::getName() const { return name; };
|
||||
|
||||
const std::string& StyleSheetSelector::getTagName() const { return tagName; }
|
||||
|
||||
const std::string StyleSheetSelector::getId() const { return id; }
|
||||
|
||||
const std::vector<std::string> StyleSheetSelector::getClasses() const { return classes; }
|
||||
|
||||
const std::string& StyleSheetSelector::getPseudoClass() const { return pseudoClass; };
|
||||
|
||||
bool StyleSheetSelector::hasTagName() { return !tagName.empty(); }
|
||||
|
||||
bool StyleSheetSelector::hasId() { return !id.empty(); }
|
||||
|
||||
bool StyleSheetSelector::hasClasses() { return !classes.empty(); }
|
||||
|
||||
bool StyleSheetSelector::hasClass( std::string cls ) { return std::find(classes.begin(), classes.end(), cls) != classes.end(); }
|
||||
|
||||
bool StyleSheetSelector::hasPseudoClass() { return !pseudoClass.empty(); }
|
||||
|
||||
Uint32 StyleSheetSelector::getSpecificity() { return specificity; }
|
||||
|
||||
void StyleSheetSelector::parseSelector( const std::string& selector ) {
|
||||
auto selPseudo = String::split( selector, ':' );
|
||||
|
||||
if ( !selPseudo.empty() ) {
|
||||
std::string rselector( selPseudo[0] );
|
||||
|
||||
if ( !rselector.empty() ) {
|
||||
if ( rselector[0] == '.' ) {
|
||||
classes.push_back( rselector.substr(1) );
|
||||
specificity += SpecificityClass;
|
||||
} else if ( selector[0] == '#' ) {
|
||||
id = rselector.substr(1);
|
||||
specificity += SpecificityId;
|
||||
} else {
|
||||
tagName = rselector;
|
||||
specificity += SpecificityTag;
|
||||
}
|
||||
}
|
||||
|
||||
if ( selPseudo.size() > 1 ) {
|
||||
pseudoClass = selPseudo[1];
|
||||
specificity += SpecificityPseudoClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}}
|
||||
19
src/eepp/ui/css/stylesheetselectorparser.cpp
Normal file
19
src/eepp/ui/css/stylesheetselectorparser.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <eepp/ui/css/stylesheetselectorparser.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
StyleSheetSelectorParser::StyleSheetSelectorParser(){}
|
||||
|
||||
StyleSheetSelectorParser::StyleSheetSelectorParser( std::string name )
|
||||
{
|
||||
std::vector<std::string> sels = String::split( name, ',' );
|
||||
|
||||
for ( std::vector<std::string>::iterator it = sels.begin(); it != sels.end(); ++it )
|
||||
{
|
||||
std::string cur = String::trim( *it );
|
||||
|
||||
selectors.push_back( StyleSheetSelector( cur ) );
|
||||
}
|
||||
}
|
||||
|
||||
}}}
|
||||
Reference in New Issue
Block a user