示例#1
0
// Returns true if the pseudo-class requirement of a rule is met by a list of an element's pseudo-classes.
bool ElementDefinition::IsPseudoClassRuleApplicable(const StringList& rule_pseudo_classes, const PseudoClassList& element_pseudo_classes) const
{
	for (StringList::size_type i = 0; i < rule_pseudo_classes.size(); ++i)
	{
		if (element_pseudo_classes.find(rule_pseudo_classes[i]) == element_pseudo_classes.end())
			return false;
	}

	return true;
}
示例#2
0
// Returns the list of properties this element definition has explicit definitions for involving the given
// pseudo-class.
void ElementDefinition::GetDefinedProperties(PropertyNameList& property_names, const PseudoClassList& pseudo_classes, const String& pseudo_class) const
{
	for (PseudoClassPropertyDictionary::const_iterator i = pseudo_class_properties.begin(); i != pseudo_class_properties.end(); ++i)
	{
		// If this property has already been found, don't bother checking for it again.
		if (property_names.find((*i).first) != property_names.end())
			continue;

		const PseudoClassPropertyList& property_list = (*i).second;

		bool property_defined = false;
		for (size_t j = 0; j < property_list.size(); ++j)
		{
			bool rule_valid = true;
			bool found_toggled_pseudo_class = false;

			const StringList& rule_pseudo_classes = property_list[j].first;
			for (size_t j = 0; j < rule_pseudo_classes.size(); ++j)
			{
				if (rule_pseudo_classes[j] == pseudo_class)
				{
					found_toggled_pseudo_class = true;
					continue;
				}

				if (pseudo_classes.find(rule_pseudo_classes[j]) == pseudo_classes.end())
				{			
					rule_valid = false;
					break;
				}
			}

			if (rule_valid &&
				found_toggled_pseudo_class)
			{
				property_defined = true;
				break;
			}
		}

		if (property_defined)
			property_names.insert((*i).first);
	}
}
示例#3
0
// Initialises the element definition from a list of style sheet nodes.
void ElementDefinition::Initialise(const std::vector< const StyleSheetNode* >& style_sheet_nodes, const PseudoClassList& volatile_pseudo_classes, bool _structurally_volatile)
{
	// Set the volatile structure flag.
	structurally_volatile = _structurally_volatile;

	// Mark all the volatile pseudo-classes as structurally volatile.
	for (PseudoClassList::const_iterator i = volatile_pseudo_classes.begin(); i != volatile_pseudo_classes.end(); ++i)
		pseudo_class_volatility[*i] = STRUCTURE_VOLATILE;


	// Merge the default (non-pseudo-class) properties.
	for (size_t i = 0; i < style_sheet_nodes.size(); ++i)
		properties.Merge(style_sheet_nodes[i]->GetProperties());


	// Merge the pseudo-class properties.
	PseudoClassPropertyMap merged_pseudo_class_properties;
	for (size_t i = 0; i < style_sheet_nodes.size(); ++i)
	{
		// Merge all the pseudo-classes.
		PseudoClassPropertyMap node_properties;
		style_sheet_nodes[i]->GetPseudoClassProperties(node_properties);
		for (PseudoClassPropertyMap::iterator j = node_properties.begin(); j != node_properties.end(); ++j)
		{
			// Merge the property maps into one uber-map; for the decorators.
			PseudoClassPropertyMap::iterator k = merged_pseudo_class_properties.find((*j).first);
			if (k == merged_pseudo_class_properties.end())
				merged_pseudo_class_properties[(*j).first] = (*j).second;
			else
				(*k).second.Merge((*j).second);

			// Search through all entries in this dictionary; we'll insert each one into our optimised list of
			// pseudo-class properties.
			for (PropertyMap::const_iterator k = (*j).second.GetProperties().begin(); k != (*j).second.GetProperties().end(); ++k)
			{
				const String& property_name = (*k).first;
				const Property& property = (*k).second;

				// Skip this property if its specificity is lower than the base property's, as in
				// this case it will never be used.
				const Property* default_property = properties.GetProperty(property_name);
				if (default_property != NULL &&
					default_property->specificity >= property.specificity)
					continue;

				PseudoClassPropertyDictionary::iterator l = pseudo_class_properties.find(property_name);
				if (l == pseudo_class_properties.end())
					pseudo_class_properties[property_name] = PseudoClassPropertyList(1, PseudoClassProperty((*j).first, property));
				else
				{
					// Find the location to insert this entry in the map, based on property priorities.
					int index = 0;
					while (index < (int) (*l).second.size() &&
						   (*l).second[index].second.specificity > property.specificity)
						index++;

					(*l).second.insert((*l).second.begin() + index, PseudoClassProperty((*j).first, property));
				}
			}
		}
	}

	InstanceDecorators(merged_pseudo_class_properties);
	InstanceFontEffects(merged_pseudo_class_properties);
}