diff --git a/code/nel/include/nel/gui/css_selector.h b/code/nel/include/nel/gui/css_selector.h index b2b5372e9..ed04ba86d 100644 --- a/code/nel/include/nel/gui/css_selector.h +++ b/code/nel/include/nel/gui/css_selector.h @@ -43,8 +43,9 @@ namespace NLGUI std::string key; std::string value; char op; // =, ~, |, ^, $, * - SAttribute(const std::string &k, const std::string &v, char o) - :key(k),value(v),op(o) + bool caseSensitive; + SAttribute(const std::string &k, const std::string &v, char o, bool cs) + :key(k),value(v),op(o), caseSensitive(cs) {} }; @@ -69,7 +70,8 @@ namespace NLGUI // add attribute to selector // ' ' op means 'key exists, ignore value' - void addAttribute(const std::string &key, const std::string &val = "", char op = ' '); + // cs case-sensitive true|false + void addAttribute(const std::string &key, const std::string &val = "", char op = ' ', bool cs = true); // add pseudo class to selector, eg 'first-child' void addPseudoClass(const std::string &key); diff --git a/code/nel/src/gui/css_parser.cpp b/code/nel/src/gui/css_parser.cpp index d34dc8f7a..39a4496bc 100644 --- a/code/nel/src/gui/css_parser.cpp +++ b/code/nel/src/gui/css_parser.cpp @@ -463,7 +463,7 @@ namespace NLGUI { if (sel[pos] == '\'' || sel[pos] == '"') { - // value is quoted + // skip over quoted value start = pos; pos++; while(pos < sel.size() && sel[pos] != sel[start]) @@ -476,9 +476,6 @@ namespace NLGUI } if (pos == sel.size()) break; - - value = sel.substr(start + 1, pos - start - 1); - break; } else if (sel[pos] == '\\') { @@ -486,7 +483,6 @@ namespace NLGUI } else if (!quote && sel[pos] == ']') { - // unquoted value value = sel.substr(start, pos - start); break; } @@ -494,17 +490,20 @@ namespace NLGUI pos++; } // while 'value' - // TODO: scan for sel[pos] == ']' - if (pos == sel.size()) break; - // whitespace between quote and ], ie '[ attr $= "val" ]' - if (sel[pos] != ']') - { - while(pos < sel.size() && sel[pos] != ']') - pos++; - } if (pos == sel.size()) break; - current.addAttribute(key.toUtf8(), value.toUtf8(), (char)op); + bool cs = true; + // [value="attr" i] + if (value.size() > 2 && value[value.size()-2] == ' ') + { + ucchar lastChar = value[value.size()-1]; + if (lastChar == 'i' || lastChar == 'I' || lastChar == 's' || lastChar == 'S') + { + value = value.substr(0, value.size()-2); + cs = !((lastChar == 'i' || lastChar == 'I')); + } + } + current.addAttribute(key.toUtf8(), trimQuotes(value).toUtf8(), (char)op, cs); } // op error } // no value diff --git a/code/nel/src/gui/css_selector.cpp b/code/nel/src/gui/css_selector.cpp index 46806a2db..2c9d94559 100644 --- a/code/nel/src/gui/css_selector.cpp +++ b/code/nel/src/gui/css_selector.cpp @@ -71,9 +71,17 @@ namespace NLGUI } } - void CCssSelector::addAttribute(const std::string &key, const std::string &val, char op) + void CCssSelector::addAttribute(const std::string &key, const std::string &val, char op, bool cs) { - Attr.push_back(SAttribute(key, val, op)); + if (cs) + { + // case sensitive match + Attr.push_back(SAttribute(key, val, op, cs)); + } + else + { + Attr.push_back(SAttribute(key, toLower(val), op, cs)); + } } void CCssSelector::addPseudoClass(const std::string &key) @@ -135,6 +143,12 @@ namespace NLGUI if (!elm.hasAttribute(Attr[i].key)) return false; std::string value = elm.getAttribute(Attr[i].key); + // case-insensitive compare, Attr.value is already lowercased + if (!Attr[i].caseSensitive) + { + value = toLower(value); + } + switch(Attr[i].op) { case '=':