Beispiel #1
0
        private void ConvertChildrenToControlBlocks(LoveBlock block)
        {
            if (block.Children.Count == 0)
            {
                return;
            }

            // Find inner most control block

            var regexControlStart = @"\s*((?:if)|(?:foreach))\s*\((.*)\)\s*({)?\s*";
            var regexControlEnd   = @"\s*}\s*";

            var childrenWithIndex = block.Children
                                    .Select((Child, Index) => new { Child, Index }).ToList();

            var controlBlockStarts = childrenWithIndex
                                     .Where(c => c.Child is LoveBinding && Regex.IsMatch((c.Child as LoveBinding).Content, regexControlStart)).ToList();
            var controlBlockEnds = childrenWithIndex
                                   .Where(c => c.Child is LoveBinding && Regex.IsMatch((c.Child as LoveBinding).Content, regexControlEnd)).ToList();

            if (controlBlockStarts.Any())
            {
                var lastStart = controlBlockStarts.Last();
                var nextEnd   = controlBlockEnds.Where(c => c.Index > lastStart.Index).FirstOrDefault();

                var blockSet = childrenWithIndex.Where(c => c.Index >= lastStart.Index && c.Index <= nextEnd.Index).ToList();

                var m = Regex.Match((lastStart.Child as LoveBinding).Content, regexControlStart);

                var controlType = m.Groups[1].Value;
                var statement   = m.Groups[2].Value;
                var openBraces  = m.Groups.Count > 2 ? m.Groups[3].Value : "";

                LoveBlock controlBlock = CreateControlBlock(blockSet.Select(c => c.Child).ToList(), controlType, statement, openBraces);

                if (controlBlock == null)
                {
                    // If failed, stick it in a regular block (to avoid a loop)
                    controlBlock = new LoveBlock(lastStart.Child.Start, blockSet.Sum(b => b.Child.Length));
                    controlBlock.Children.AddRange(blockSet.Select(c => c.Child));
                }

                // Switch the old blocks for the new
                for (int i = 0; i < blockSet.Count; i++)
                {
                    block.Children.RemoveAt(blockSet.First().Index);
                }

                block.Children.Add(controlBlock);
            }

            if (controlBlockStarts.Count() > 1)
            {
                // Repeat if needed
                ConvertChildrenToControlBlocks(block);
            }
        }
Beispiel #2
0
        private LoveControlBlock CreateControlBlock(List <LoveNode> blockSet, string controlType, string statement, string openBraces)
        {
            var controlStart = blockSet.First() as LoveBinding;
            var controlEnd   = blockSet.Last();

            var hasClosingBraces = openBraces == "{" &&
                                   controlEnd is LoveBinding &&
                                   (controlEnd as LoveBinding).Content.Trim() == "}";

            var bodyLength = blockSet.Count - 1;

            bodyLength -= hasClosingBraces ? 1 : 0;

            var bodyChildren = blockSet.Skip(1).Take(bodyLength);
            var bodyBlock    = new LoveBlock(bodyChildren.First().Start, bodyChildren.Sum(c => c.Length));

            bodyBlock.Children.AddRange(bodyChildren);

            if (controlType == "if")
            {
                LoveBindingBase statementBinding = CreateStatement(controlStart, statement);

                return(new LoveIfBlock(controlStart.Start, controlEnd.Start - controlStart.Start + controlEnd.Length,
                                       statementBinding,
                                       bodyBlock));
            }
            else if (controlType == "foreach")
            {
                var regexForeach = @"\s*(\S+)\s+in\s+(\S+)\s*";

                var m = Regex.Match(statement, regexForeach);
                if (m.Success)
                {
                    var itemName = m.Groups[1].Value;
                    statement = m.Groups[2].Value;

                    var itemNameSpan = new LoveName(controlStart.Start + controlStart.Content.IndexOf(itemName), itemName.Length, itemName);

                    LoveBindingBase statementBinding = CreateStatement(controlStart, statement);
                    return(new LoveForeachBlock(controlStart.Start, controlEnd.Start - controlStart.Start + controlEnd.Length,
                                                itemNameSpan,
                                                statementBinding,
                                                bodyBlock));
                }
                else
                {
                    return(null);
                }
            }

            return(null);
        }
Beispiel #3
0
        private void SimplifyChildren(LoveBlock block)
        {
            for (int i = 0; i < block.Children.Count; i++)
            {
                var child = block.Children[i];

                // Go deeper
                if (child is LoveBlock)
                {
                    SimplifyChildren(child as LoveBlock);
                }

                // Remove Bindings with only whitespace
                if (child is LoveBindingBase)
                {
                    var cBinding = child as LoveBindingBase;

                    if (string.IsNullOrEmpty(cBinding.Content.Trim()))
                    {
                        block.Children.RemoveAt(i);
                        i--;
                        continue;
                    }
                }

                // Simplify child blocks
                if (child.GetType() == typeof(LoveBlock))
                {
                    var cBlock = child as LoveBlock;

                    // Remove if no children
                    if (cBlock.Children.Count == 0)
                    {
                        block.Children.RemoveAt(i);
                        i--;
                        continue;
                    }

                    // Flatten if only one child
                    if (cBlock.Children.Count == 1)
                    {
                        block.Children[i] = cBlock.Children[0];
                    }
                }
            }
        }
        public static LoveBlock MapBinding(LoveMarkupExpression htmlHelperExpression, string normalHtml, string simpleHtml, string simpleExpression)
        {
            var indices = normalHtml.Find(simpleHtml).ToList();

            if (indices.Count == 0)
            {
                // Apparently Static
                var b = new LoveBlock(0, 0);
                b.Children.Add(new LoveMarkup(0, 0, normalHtml));
                return(b);
            }
            else
            {
                // Create a block with bindings
                var b = new LoveBlock(0, 0);

                // Add before binding
                b.Children.Add(new LoveMarkup(0, 0, normalHtml.Substring(0, indices[0])));

                for (int i = 0; i < indices.Count; i++)
                {
                    var index     = indices[i];
                    var nextIndex = i < indices.Count - 1 ? indices[i + 1] : (int?)null;

                    // Add binding
                    var bindingContent = simpleExpression;
                    b.Children.Add(new LoveBinding(0, 0, bindingContent));

                    // Add after binding
                    var afterIndex = index + simpleHtml.Length;

                    if (nextIndex.HasValue)
                    {
                        b.Children.Add(new LoveMarkup(0, 0, normalHtml.Substring(afterIndex, nextIndex.Value - afterIndex)));
                    }
                    else
                    {
                        b.Children.Add(new LoveMarkup(0, 0, normalHtml.Substring(afterIndex)));
                    }
                }

                return(b);
            }
        }
Beispiel #5
0
        private void HandleModelStatement(LoveBlock document)
        {
            if (document.Children.Count <= 1)
            {
                return;
            }

            var first  = document.Children[0] as LoveSpan;
            var second = document.Children[1] as LoveSpan;

            // Go into 2nd child if block
            if (document.Children[1].GetType() == typeof(LoveBlock))
            {
                var secondBlock = (document.Children[1] as LoveBlock);
                second = secondBlock.Children.FirstOrDefault() as LoveSpan;
            }

            if (first == null || second == null)
            {
                return;
            }

            var modelMatch = Regex.Match(second.Content, @"^(\s*[A-Za-z0-9\.]+(?:\r\n)?)([\s\S]*)?$");

            if (first.Content == "model" && modelMatch.Success)
            {
                var modelLine = modelMatch.Groups[1].Value;
                var remaining = modelMatch.Groups.Count > 1 ? modelMatch.Groups[2].Value : "";

                document.Children[0] = new LoveModelStatement(first.Start, first.Length + modelLine.Length, modelLine.Trim());

                if (!string.IsNullOrWhiteSpace(remaining))
                {
                    second.Modify(second.Start + modelLine.Length, remaining.Length, remaining);
                }
                else
                {
                    second.Modify(0, 0, "");
                    SimplifyChildren(document);
                }
            }
        }
Beispiel #6
0
        private LoveBlock VisitBlock(Block block)
        {
            // Handle regular block
            var lBlock = new LoveBlock(block.Start.AbsoluteIndex, block.Length);

            foreach (var c in block.Children)
            {
                var node = VisitNode(c);

                if (node != null)
                {
                    lBlock.Children.Add(node);
                }
            }

            // Merge blocks of same type
            var      newChildren = new List <LoveNode>();
            LoveNode newChild    = null;

            foreach (var c in lBlock.Children)
            {
                if (newChild != null && newChild.GetType() == c.GetType() && c is LoveSpan)
                {
                    var cSpan   = c as LoveSpan;
                    var newSpan = newChild as LoveSpan;

                    if (cSpan is LoveBinding)
                    {
                        newChild = new LoveBinding(newSpan.Start, newSpan.Length + cSpan.Length, newSpan.Content + cSpan.Content);
                    }
                    else if (cSpan is LoveMarkup)
                    {
                        newChild = new LoveMarkup(newSpan.Start, newSpan.Length + cSpan.Length, newSpan.Content + cSpan.Content);
                    }
                    else if (cSpan is LoveMarkupExpression)
                    {
                        newChild = new LoveMarkupExpression(newSpan.Start, newSpan.Length + cSpan.Length, newSpan.Content + cSpan.Content);
                    }
                }
                else
                {
                    if (newChild != null)
                    {
                        newChildren.Add(newChild);
                        newChild = null;
                    }

                    newChild = c;
                }
            }

            if (newChild != null)
            {
                newChildren.Add(newChild);
                newChild = null;
            }

            lBlock.Children.Clear();
            lBlock.Children.AddRange(newChildren);

            if (lBlock.Children.Count == 0)
            {
                return(null);
            }

            // Simplify children
            for (int i = 0; i < lBlock.Children.Count; i++)
            {
                var child = lBlock.Children[i];

                // Convert bindings to specific bindings if possible
                if (child is LoveBinding)
                {
                    lBlock.Children[i] = ConvertBinding(child as LoveBinding);
                }
            }

            ConvertChildrenToControlBlocks(lBlock);

            //// Convert to control blocks if Possible
            //var cBlock = ConvertToControlBlock(lBlock);
            //if (cBlock != null) { return cBlock; }

            return(lBlock);
        }
Beispiel #7
0
 private void VisitBlock(LoveTranslation translation, LoveBlock loveBlock, object model)
 {
     throw new NotImplementedException();
 }