Exemple #1
0
 /// <summary>
 /// Asigns 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);
         }
         CssUtils.SetPropertyValue(box, prop.Key, value);
     }
 }
Exemple #2
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);
        }
Exemple #3
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);
        }
Exemple #4
0
        /// <summary>
        /// Check if the given css block is assignable to the given css box.<br/>
        /// the block is assignable if it has no hierarchial selectors or if the hierarchy matches.<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)
        {
            if (block.Selectors != null)
            {
                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 == selector.Class)
                            matched = true;

                        if (!matched && box.HtmlTag.HasAttribute("class"))
                        {
                            var className = box.HtmlTag.Attributes["class"];
                            if (selector.Class == "." + className || selector.Class == box.HtmlTag.Name + "." + className)
                                matched = true;
                        }

                        if (!matched && box.HtmlTag.HasAttribute("id"))
                        {
                            var id = box.HtmlTag.Attributes["id"];
                            if (selector.Class == "#" + id)
                                matched = true;
                        }

                        if (!matched && selector.DirectParent)
                            return false;
                    }
                }
            }

            return true;
        }
Exemple #5
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 beggining 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>>();
                _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);
                }
            }
        }
Exemple #6
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];
            }
        }
Exemple #7
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;
        }
Exemple #8
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;
        }
        /// <summary>
        /// Add css box that has ":hover" selector to be handled on mouse hover.
        /// </summary>
        /// <param name="box">the box that has the hover selector</param>
        /// <param name="block">the css block with the css data with the selector</param>
        internal void AddHoverBox(CssBox box, CssBlock block)
        {
            ArgChecker.AssertArgNotNull(box, "box");
            ArgChecker.AssertArgNotNull(block, "block");

            if(_hoverBoxes == null)
                _hoverBoxes = new List<Tupler<CssBox, CssBlock>>();

            _hoverBoxes.Add(new Tupler<CssBox, CssBlock>(box, block));
        }
Exemple #10
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;
        }
Exemple #11
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;
        }