// 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); }