Example #1
0
        public static IEnumerable <RangeNode> InRange(IEnumerable <INode> bodyNodes, MarkUpRange range)
        {
            int offset                  = 0;
            int iPosRangeStart          = range.PositionStart - 1;
            int iPosRangeEnd            = range.PositionEnd - 1;
            List <RangeNode> rangeNodes = new List <RangeNode>();

            if (bodyNodes.Count() == 1 && bodyNodes.First().NodeName == HTMLConstants.SpanDiv)
            {
                rangeNodes.Add(new RangeNode(bodyNodes.First(), 0));
            }
            else
            {
                foreach (var node in bodyNodes)
                {
                    if (offset > iPosRangeEnd + 1)
                    {
                        break;
                    }

                    if (node.NodeType == NodeType.Text)
                    {
                        string nodeText = node.TextContent;

                        int iNodeLength = nodeText.Length;
                        int iRange      = iPosRangeEnd - iPosRangeStart;

                        bool rangeStartInNode = iPosRangeStart < offset || (iPosRangeStart + 1) < offset + iNodeLength;
                        bool rangeEndInNode   = iPosRangeEnd >= offset || iPosRangeEnd == iPosRangeStart;

                        if (rangeStartInNode && rangeEndInNode)
                        {
                            rangeNodes.Add(new RangeNode(node, offset));
                        }
                        offset += iNodeLength;
                    }
                }
            }
            return(rangeNodes);
        }
Example #2
0
 private bool RangeOutreachesTexNodeLength(MarkUpRange range, int length)
 {
     return(range.PositionEnd > Offset + length);
 }
Example #3
0
        /// <summary>
        /// Applies/Unapplies style to the elements in the given range.
        /// </summary>
        /// <param name="range">Range</param>
        /// <param name="cmd">A style command</param>
        /// <param name="document"></param>
        /// <param name="attributeValue">The attribute value, that fits the style command</param>
        public void ApplyStyleCommand(MarkUpRange range, EStyleCommand cmd, IDocument document, Func <string> attributeValue)
        {
            IElement elem;

            void createStyleElement()
            {
                elem = CreateElem(cmd, StyleAttribute, document, attributeValue);
            }

            var isCmdForBlockElement = CommandIsBlockNodeCommand(cmd);

            if (cmd == EStyleCommand.FormatClear)
            {
                var elementWithStyle = FindParentElementWithAStyleAttribute(Node) as IElement;
                if (elementWithStyle != null)
                {
                    elementWithStyle.RemoveAttribute(HTMLConstants.Style);
                    if (elementWithStyle.NodeName == HTMLConstants.SpanTag)
                    {
                        RemoveFromParentKeepContent(Node, HTMLConstants.SpanTag, document);
                    }
                }
                return;
            }

            if (isCmdForBlockElement)
            {
                var blockElement = FindBlockParent(Node) as IElement;
                if (blockElement != null)
                {
                    var blockstyleAttr = blockElement.GetAttribute(HTMLConstants.Style);
                    StyleAttribute = ReDefineStyle(blockstyleAttr, HTMLConstants.TextAlign, attributeValue());
                    blockElement.SetAttribute(HTMLConstants.Style, StyleAttribute);
                }
                return;
            }

            var    rangeLength    = (range.PositionEnd - range.PositionStart);
            var    posEndWord     = range.PositionEnd - Offset;
            var    posStartWord   = range.PositionStart > Offset ? range.PositionStart - Offset : 0;
            string nodeText       = Node.TextContent;
            int    nodeTextLength = Node.TextContent.Length;

            if (nodeText.Trim().Length == 0)
            {
                return;
            }

            _styleattribute = GetParentElement(Node).GetAttribute(HTMLConstants.Style);
            if (RangeOutreachesTexNodeLength(range, nodeTextLength))
            {
                ApplyElementStyle(cmd, this.Node, attributeValue, document);
                return;
            }

            if (ContainsZeroCharachtersOrOnlyWhiteSpaces(posStartWord, posEndWord, nodeText))
            {
                return;
            }

            var poslength = posEndWord - posStartWord;

            if (poslength == 0)
            {
                poslength = 1;
            }

            string extractedTextRange = nodeText.Substring(posStartWord, poslength);

            //rangeLength == 0 -> no selection only cursor. Then apply style to the word under the cursor
            if (rangeLength == 0)
            {
                var startIndex = Math.Max(nodeText.LastIndexOf(" ", posStartWord), nodeText.LastIndexOf((char)160, posStartWord));
                startIndex = startIndex == -1 ? 0 : startIndex;

                var endIndex = Math.Max(nodeText.IndexOf(" ", posStartWord), nodeText.IndexOf((char)160, posStartWord));
                endIndex = endIndex == -1 ? nodeTextLength : endIndex;

                extractedTextRange = ExtractWord(startIndex, endIndex, nodeText);
                if (extractedTextRange == "")
                {
                    return;
                }
                posStartWord = startIndex == 0 ? startIndex : startIndex + 1;
            }
            posEndWord = extractedTextRange.Length;

            if (ExtractedRangeEqualsTextRange(extractedTextRange, nodeText) || isCmdForBlockElement)
            {
                ApplyElementStyle(cmd, Node, attributeValue, document);
                return;
            }

            if (ExtractedRangeIsAtStartOfTextRange(posStartWord))
            {
                createStyleElement();
                elem.TextContent = nodeText.Substring(0, posEndWord);

                ((ICharacterData)Node).Data = nodeText.Substring(posEndWord);
                Node.InsertBefore(new[] { elem });
                return;
            }


            if (ExtractedRangeIsAtEndOfTextRange(posStartWord, posEndWord, extractedTextRange))
            {
                createStyleElement();
                elem.TextContent = nodeText.Substring(posStartWord);
                Node.TextContent = nodeText.Substring(0, posStartWord);
                Node.InsertAfter(new[] { elem });
                return;
            }

            //range is in the middle of the textnode
            var newElementname = GetElementName(cmd);

            if (newElementname != HTMLConstants.SpanTag)
            {
                var alreadyPresent = ParentElementAlreadyExists(Node, newElementname.ToUpper());
                if (alreadyPresent != null && alreadyPresent.IndexOf(Node) != 0)
                {
                    //redefine all
                    ApplyElementStyle(cmd, Node, attributeValue, document);
                    return;
                }
            }
            createStyleElement();
            elem.TextContent = nodeText.Substring(posStartWord, posEndWord);

            Node.TextContent = nodeText.Substring(0, posStartWord);
            var restNode = Node.Clone();

            restNode.TextContent = nodeText.Substring(posStartWord + posEndWord);
            Node.ReplaceWith(new[] { Node.Clone(), elem, restNode });
        }