// 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