Exemple #1
0
        /// <summary>
        /// Build a new layout tree, deferring layout calculations.
        /// </summary>
        /// <param name="rootNode">A <see cref="xavierHTML.DOM.Document"/>'s root <see cref="StyledNode"/>.</param>
        /// <returns>Fully built layout tree.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when given a <see cref="StyledNode"/> with display property set to none.
        /// </exception>
        public static Box FromStyledNode(StyledNode rootNode)
        {
            if (rootNode.Display == Display.None)
            {
                throw new InvalidOperationException("Root node has display: none.");
            }

            var nodes = rootNode.Children
                        // Skip nodes with `display: none;`
                        .Where(node => node.Display != Display.None)
                        .Select(FromStyledNode).ToList();

            // If a block-level node has only inline children, return just this block-level box with
            // the inline children.
            if (rootNode.Display == Display.Block &&
                nodes.TrueForAll(box => box.Display == Display.Inline))
            {
                return(new NodeBox(nodes.AsReadOnly(), rootNode));
            }

            // TODO: Handle case where an inline node contains a block-level child
            // CSS2 box generation algorithm
            // http://www.w3.org/TR/CSS2/visuren.html#box-gen

            // If a block node contains an inline child, create an anonymous block box to contain it.
            // If there are several inline children in a row, put them all in the same anonymous container.
            var children = new List <Box>();

            nodes.ForEach(box =>
            {
                if (box.Display != Display.Inline)
                {
                    children.Add(box);
                }

                var anonymousBox = children.LastOrDefault(b => !(b is NodeBox));
                if (anonymousBox != null)
                {
                    children.Add(new Box(anonymousBox.Children.Append(box).ToList().AsReadOnly()));
                }

                children.Add(new Box(new List <Box> {
                    box
                }.AsReadOnly()));
            });

            return(new NodeBox(children.AsReadOnly(), rootNode));
        }
Exemple #2
0
 public NodeBox(ReadOnlyCollection <Box> children, StyledNode style) : base(children)
 {
     Style = style;
 }