Example #1
0
 /// <summary>
 /// Assigns the given css style block properties to the given css box.
 /// </summary>
 /// <param name="box">the css box to assign css to</param>
 /// <param name="block">the css block to assign</param>
 private static void AssignCssBlock(CssBox box, CssBlock block)
 {
     foreach (var prop in block.Properties)
     {
         var value = prop.Value;
         if (prop.Value == CssConstants.Inherit && box.ParentBox != null)
         {
             value = CssUtils.GetPropertyValue(box.ParentBox, prop.Key);
         }
         if (IsStyleOnElementAllowed(box, prop.Key, value))
         {
             CssUtils.SetPropertyValue(box, prop.Key, value);
         }
     }
 }
Example #2
0
        /// <summary>
        /// Check if the given css block is assignable to the given css box.<br/>
        /// the block is assignable if it has no hierarchical selectors or if the hierarchy matches.<br/>
        /// Special handling for ":hover" pseudo-class.<br/>
        /// </summary>
        /// <param name="box">the box to check assign to</param>
        /// <param name="block">the block to check assign of</param>
        /// <returns>true - the block is assignable to the box, false - otherwise</returns>
        private static bool IsBlockAssignableToBox(CssBox box, CssBlock block)
        {
            bool assignable = true;
            if (block.Selectors != null)
            {
                assignable = IsBlockAssignableToBoxWithSelector(box, block);
            }
            else if (box.HtmlTag.Name.Equals("a", StringComparison.OrdinalIgnoreCase) && block.Class.Equals("a", StringComparison.OrdinalIgnoreCase) && !box.HtmlTag.HasAttribute("href"))
            {
                assignable = false;
            }

            if (assignable && block.Hover)
            {
                box.HtmlContainer.AddHoverBox(box, block);
                assignable = false;
            }

            return assignable;
        }
Example #3
0
        /// <summary>
        /// Check if the given css block is assignable to the given css box by validating the selector.<br/>
        /// </summary>
        /// <param name="box">the box to check assign to</param>
        /// <param name="block">the block to check assign of</param>
        /// <returns>true - the block is assignable to the box, false - otherwise</returns>
        private static bool IsBlockAssignableToBoxWithSelector(CssBox box, CssBlock block)
        {
            foreach (var selector in block.Selectors)
            {
                bool matched = false;
                while (!matched)
                {
                    box = box.ParentBox;
                    while (box != null && box.HtmlTag == null)
                        box = box.ParentBox;

                    if (box == null)
                        return false;

                    if (box.HtmlTag.Name.Equals(selector.Class, StringComparison.InvariantCultureIgnoreCase))
                        matched = true;

                    if (!matched && box.HtmlTag.HasAttribute("class"))
                    {
                        var className = box.HtmlTag.TryGetAttribute("class");
                        if (selector.Class.Equals("." + className, StringComparison.InvariantCultureIgnoreCase) || selector.Class.Equals(box.HtmlTag.Name + "." + className, StringComparison.InvariantCultureIgnoreCase))
                            matched = true;
                    }

                    if (!matched && box.HtmlTag.HasAttribute("id"))
                    {
                        var id = box.HtmlTag.TryGetAttribute("id");
                        if (selector.Class.Equals("#" + id, StringComparison.InvariantCultureIgnoreCase))
                            matched = true;
                    }

                    if (!matched && selector.DirectParent)
                        return false;
                }
            }
            return true;
        }
Example #4
0
        /// <summary>
        /// Add the given css block to the css data, merging to existing block if required.
        /// </summary>
        /// <remarks>
        /// If there is no css blocks for the same class it will be added to data collection.<br/>
        /// If there is already css blocks for the same class it will check for each existing block
        /// if the hierarchical selectors match (or not exists). if do the two css blocks will be merged into
        /// one where the new block properties overwrite existing if needed. if the new block doesn't mach any
        /// existing it will be added either to the beginning of the list if it has no  hierarchical selectors or at the end.<br/>
        /// Css block without hierarchical selectors must be added to the beginning of the list so more specific block
        /// can overwrite it when the style is applied.
        /// </remarks>
        /// <param name="media">the media type to add the CSS to</param>
        /// <param name="cssBlock">the css block to add</param>
        public void AddCssBlock(string media, CssBlock cssBlock)
        {
            Dictionary<string, List<CssBlock>> mid;
            if (!_mediaBlocks.TryGetValue(media, out mid))
            {
                mid = new Dictionary<string, List<CssBlock>>(StringComparer.InvariantCultureIgnoreCase);
                _mediaBlocks.Add(media, mid);
            }

            if (!mid.ContainsKey(cssBlock.Class))
            {
                var list = new List<CssBlock>();
                list.Add(cssBlock);
                mid[cssBlock.Class] = list;
            }
            else
            {
                bool merged = false;
                var list = mid[cssBlock.Class];
                foreach (var block in list)
                {
                    if (block.EqualsSelector(cssBlock))
                    {
                        merged = true;
                        block.Merge(cssBlock);
                        break;
                    }
                }

                if (!merged)
                {
                    // general block must be first
                    if (cssBlock.Selectors == null)
                        list.Insert(0, cssBlock);
                    else
                        list.Add(cssBlock);
                }
            }
        }
 /// <summary>
 /// Init.
 /// </summary>
 public HoverBoxBlock(CssBox cssBox, CssBlock cssBlock)
 {
     _cssBox = cssBox;
     _cssBlock = cssBlock;
 }
Example #6
0
        /// <summary>
        /// Check if the selectors of the css blocks is the same.
        /// </summary>
        /// <param name="other">the other block to compare to</param>
        /// <returns>true - the selectors on blocks are the same, false - otherwise</returns>
        public bool EqualsSelector(CssBlock other)
        {
            if (ReferenceEquals(null, other))
                return false;
            if (ReferenceEquals(this, other))
                return true;

            if (other.Hover != Hover)
                return false;
            if (other._selectors == null && _selectors != null)
                return false;
            if (other._selectors != null && _selectors == null)
                return false;

            if (other._selectors != null && _selectors != null)
            {
                if (!Equals(other._selectors.Count, _selectors.Count))
                    return false;

                for (int i = 0; i < _selectors.Count; i++)
                {
                    if (!Equals(other._selectors[i].Class, _selectors[i].Class))
                        return false;
                    if (!Equals(other._selectors[i].DirectParent, _selectors[i].DirectParent))
                        return false;
                }
            }

            return true;
        }
Example #7
0
        /// <summary>
        /// Check if the two css blocks are the same (same class, selectors and properties).
        /// </summary>
        /// <param name="other">the other block to compare to</param>
        /// <returns>true - the two blocks are the same, false - otherwise</returns>
        public bool Equals(CssBlock other)
        {
            if (ReferenceEquals(null, other))
                return false;
            if (ReferenceEquals(this, other))
                return true;
            if (!Equals(other._class, _class))
                return false;

            if (!Equals(other._properties.Count, _properties.Count))
                return false;

            foreach (var property in _properties)
            {
                if (!other._properties.ContainsKey(property.Key))
                    return false;
                if (!Equals(other._properties[property.Key], property.Value))
                    return false;
            }

            if (!EqualsSelector(other))
                return false;

            return true;
        }
Example #8
0
        /// <summary>
        /// Merge the other block properties into this css block.<br/>
        /// Other block properties can overwrite this block properties.
        /// </summary>
        /// <param name="other">the css block to merge with</param>
        public void Merge(CssBlock other)
        {
            ArgChecker.AssertArgNotNull(other, "other");

            foreach (var prop in other._properties.Keys)
            {
                _properties[prop] = other._properties[prop];
            }
        }