示例#1
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);
}