// Ryzom - MMORPG Framework // Copyright (C) 2010-2021 Winch Gate Property Limited // // This source file has been modified by the following contributors: // Copyright (C) 2020 Jan BOON (Kaetemi) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpch.h" #include #include "nel/misc/types_nl.h" #include "nel/gui/html_element.h" #include "nel/gui/css_style.h" #include "nel/gui/css_parser.h" #include "nel/gui/libwww.h" using namespace NLMISC; #ifdef DEBUG_NEW #define new DEBUG_NEW #endif namespace NLGUI { uint CCssStyle::SStyleRule::specificity() const { uint count = 0; for(uint i = 0; i < Selector.size(); ++i) { count += Selector[i].specificity(); } // counted as element tag like DIV if (!PseudoElement.empty()) { count += 0x000001; } return count; } // *************************************************************************** void CCssStyle::reset() { _StyleRules.clear(); _StyleStack.clear(); Root = CStyleParams(); Current = CStyleParams(); } // *************************************************************************** // Sorting helper struct CCssSpecificityPred { bool operator()(CCssStyle::SStyleRule lhs, CCssStyle::SStyleRule rhs) const { return lhs.specificity() < rhs.specificity(); } }; // *************************************************************************** void CCssStyle::parseStylesheet(const std::string &styleString) { CCssParser parser; parser.parseStylesheet(styleString, _StyleRules); // keep the list sorted std::stable_sort(_StyleRules.begin(), _StyleRules.end(), CCssSpecificityPred()); } void CCssStyle::getStyleFor(CHtmlElement &elm) const { std::vector mRules; for (std::vector::const_iterator it = _StyleRules.begin(); it != _StyleRules.end(); ++it) { if (match(it->Selector, elm)) { mRules.push_back(*it); } } elm.Style.clear(); elm.clearPseudo(); if (!mRules.empty()) { // style is sorted by specificity (lowest first), eg. html, .class, html.class, #id, html#id.class for(std::vector::const_iterator i = mRules.begin(); i != mRules.end(); ++i) { if (i->PseudoElement.empty()) { merge(elm.Style, i->Properties); } else { TStyle props; merge(props, i->Properties); elm.setPseudo(i->PseudoElement, props); } } } // style from "style" attribute overrides