ElementDefinition.h

00001 /*
00002  * This source file is part of libRocket, the HTML/CSS Interface Middleware
00003  *
00004  * For the latest information, see http://www.librocket.com
00005  *
00006  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a copy
00009  * of this software and associated documentation files (the "Software"), to deal
00010  * in the Software without restriction, including without limitation the rights
00011  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00012  * copies of the Software, and to permit persons to whom the Software is
00013  * furnished to do so, subject to the following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included in
00016  * all copies or substantial portions of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00021  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00024  * THE SOFTWARE.
00025  *
00026  */
00027 
00028 #ifndef ROCKETCOREELEMENTDEFINITION_H
00029 #define ROCKETCOREELEMENTDEFINITION_H
00030 
00031 #include <Rocket/Core/Dictionary.h>
00032 #include <Rocket/Core/ReferenceCountable.h>
00033 #include <map>
00034 #include <set>
00035 #include <Rocket/Core/FontEffect.h>
00036 #include "StyleSheetNode.h"
00037 
00038 namespace Rocket {
00039 namespace Core {
00040 
00041 class Decorator;
00042 class FontEffect;
00043 
00044 // Defines for the optimised version of the pseudo-class properties (note the difference from the
00045 // PseudoClassPropertyMap defined in StyleSheetNode.h ... bit clumsy). Here the properties are stored as a list
00046 // of definitions against each property name in specificity-order, along with the pseudo-class requirements for each
00047 // one. This makes it much more straight-forward to query at run-time.
00048 typedef std::pair< StringList, Property > PseudoClassProperty;
00049 typedef std::vector< PseudoClassProperty > PseudoClassPropertyList;
00050 typedef std::map< String, PseudoClassPropertyList > PseudoClassPropertyDictionary;
00051 
00052 typedef std::map< String, Decorator* > DecoratorMap;
00053 typedef std::map< StringList, DecoratorMap > PseudoClassDecoratorMap;
00054 
00059 class ElementDefinition : public ReferenceCountable
00060 {
00061 public:
00062         enum PseudoClassVolatility
00063         {
00064                 STABLE,                                 // pseudo-class has no volatility
00065                 FONT_VOLATILE,                  // pseudo-class may impact on font effects
00066                 STRUCTURE_VOLATILE              // pseudo-class may impact on definitions of child elements
00067         };
00068 
00069         ElementDefinition();
00070         virtual ~ElementDefinition();
00071 
00073         void Initialise(const std::vector< const StyleSheetNode* >& style_sheet_nodes, const PseudoClassList& volatile_pseudo_classes, bool structurally_volatile);
00074 
00079         const Property* GetProperty(const String& name, const PseudoClassList& pseudo_classes) const;
00080 
00085         void GetDefinedProperties(PropertyNameList& property_names, const PseudoClassList& pseudo_classes) const;
00091         void GetDefinedProperties(PropertyNameList& property_names, const PseudoClassList& pseudo_classes, const String& pseudo_class) const;
00092 
00100         bool IterateProperties(int& index, const PseudoClassList& pseudo_classes, PseudoClassList& property_pseudo_classes, String& property_name, const Property*& property) const;
00101 
00104         const DecoratorMap& GetDecorators() const;
00107         const PseudoClassDecoratorMap& GetPseudoClassDecorators() const;
00108 
00113         void GetFontEffects(FontEffectMap& font_effects, const PseudoClassList& pseudo_classes) const;
00114 
00118         PseudoClassVolatility GetPseudoClassVolatility(const String& pseudo_class) const;
00119 
00123         bool IsStructurallyVolatile() const;
00124 
00125 protected:
00127         void OnReferenceDeactivate();
00128 
00129 private:
00130         typedef std::pair< String, PropertyDictionary > PropertyGroup;
00131         typedef std::map< String, PropertyGroup > PropertyGroupMap;
00132 
00133         typedef std::vector< std::pair< StringList, int > > PseudoClassFontEffectIndex;
00134         typedef std::map< String, PseudoClassFontEffectIndex > FontEffectIndex;
00135 
00136         typedef std::map< String, PseudoClassVolatility > PseudoClassVolatilityMap;
00137 
00138         // Finds all propery declarations for a group.
00139         void BuildPropertyGroup(PropertyGroupMap& groups, const String& group_type, const PropertyDictionary& element_properties, const PropertyGroupMap* default_properties = NULL);
00140         // Updates a property dictionary of all properties for a single group.
00141         int BuildPropertyGroupDictionary(PropertyDictionary& group_properties, const String& group_type, const String& group_name, const PropertyDictionary& element_properties);
00142 
00143         // Builds decorator definitions from the parsed properties and instances decorators as
00144         // appropriate.
00145         void InstanceDecorators(const PseudoClassPropertyMap& merged_pseudo_class_properties);
00146         // Attempts to instance a decorator.
00147         bool InstanceDecorator(const String& name, const String& type, const PropertyDictionary& properties, const StringList& pseudo_class = StringList());
00148 
00149         // Builds font effect definitions from the parsed properties and instances font effects as
00150         // appropriate.
00151         void InstanceFontEffects(const PseudoClassPropertyMap& merged_pseudo_class_properties);
00152         // Attempts to instance a font effect.
00153         bool InstanceFontEffect(const String& name, const String& type, const PropertyDictionary& properties, const StringList& pseudo_class = StringList());
00154 
00155         // Returns true if the pseudo-class requirement of a rule is met by a list of an element's pseudo-classes.
00156         bool IsPseudoClassRuleApplicable(const StringList& rule_pseudo_classes, const PseudoClassList& element_pseudo_classes) const;
00157 
00158         // The attributes for the default state of the element, with no pseudo-classes.
00159         PropertyDictionary properties;
00160         // The overridden attributes for the element's pseudo-classes.
00161         PseudoClassPropertyDictionary pseudo_class_properties;
00162 
00163         // The instanced decorators for this element definition.
00164         DecoratorMap decorators;
00165         // The overridden decorators for the element's pseudo-classes.
00166         PseudoClassDecoratorMap pseudo_class_decorators;
00167 
00168         // The list of every decorator used by this element in every class.
00169         FontEffectList font_effects;
00170         // For each unique decorator name, this stores (in order of specificity) the name of the
00171         // pseudo-class that has a definition for it, and the index into the list of decorators.
00172         FontEffectIndex font_effect_index;
00173 
00174         // The list of volatile pseudo-classes in this definition, and how volatile they are.
00175         PseudoClassVolatilityMap pseudo_class_volatility;
00176 
00177         // True if this definition has the potential to change as sibling elements are added or removed.
00178         bool structurally_volatile;
00179 };
00180 
00181 }
00182 }
00183 
00184 #endif