/// <summary>
        /// <font><span>aaa[splitPoint]bbb</span></font> --> <font><span>aaa</span></font><font>[splitPoint]<span>bbb</span></font>
        /// </summary>
        private void SplitInlineTags(MarkupPointer splitPoint)
        {
            Debug.Assert(splitPoint.Positioned);

            IHTMLElement currentElement = splitPoint.GetParentElement(ElementFilters.CreateElementPassFilter());

            while (currentElement != null)
            {
                if (!ElementFilters.IsInlineElement(currentElement))
                {
                    return;
                }

                IHTMLElement parentElement = currentElement.parentElement;

                MarkupRange currentElementRange = _markupServices.CreateMarkupRange(currentElement, false);

                MarkupRange  leftRange   = _markupServices.CreateMarkupRange();
                IHTMLElement leftElement = _markupServices.CreateElement(_markupServices.GetElementTagId(currentElement), null);
                HTMLElementHelper.CopyAttributes(currentElement, leftElement);
                leftRange.MoveToPointers(currentElementRange.Start, splitPoint);
                _markupServices.InsertElement(leftElement, leftRange.Start, leftRange.End);

                splitPoint.MoveAdjacentToElement(leftElement, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);

                MarkupRange  rightRange   = _markupServices.CreateMarkupRange();
                IHTMLElement rightElement = _markupServices.CreateElement(_markupServices.GetElementTagId(currentElement), null);
                HTMLElementHelper.CopyAttributes(currentElement, rightElement);
                rightRange.MoveToPointers(splitPoint, currentElementRange.End);

#if DEBUG
                // Verify that the right range does not overlap the left *element*
                MarkupRange leftElementRange = _markupServices.CreateMarkupRange(leftElement, true);
                Debug.Assert(leftElementRange.End.IsLeftOfOrEqualTo(rightRange.Start), "Your right range overlaps the left element that you just created!");
#endif
                _markupServices.InsertElement(rightElement, rightRange.Start, rightRange.End);
                splitPoint.MoveAdjacentToElement(rightElement, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);

                _markupServices.RemoveElement(currentElement);

                currentElement = parentElement;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Fixes up a range that is contained in a single header element.
        /// </summary>
        /// <param name="range">A range that is contained in a single header element.</param>
        /// <param name="turnBold">Whether or not the text should be turning bold.</param>
        private void FixupHeaderRange(MarkupRange range, bool turnBold)
        {
            IHTMLElement parentHeaderElement = range.ParentBlockElement();

            if (parentHeaderElement == null || !ElementFilters.IsHeaderElement(parentHeaderElement))
            {
                Debug.Fail("Expected entire range to be inside a single header element.");
                return;
            }

            MarkupRange expandedRange = range.Clone();

            // Make sure we expand the selection to include any <font> tags that may be wrapping us.
            MarkupPointerMoveHelper.MoveUnitBounded(expandedRange.Start, MarkupPointerMoveHelper.MoveDirection.LEFT,
                                                    MarkupPointerAdjacency.BeforeVisible, parentHeaderElement);
            MarkupPointerMoveHelper.MoveUnitBounded(expandedRange.End, MarkupPointerMoveHelper.MoveDirection.RIGHT,
                                                    MarkupPointerAdjacency.BeforeVisible, parentHeaderElement);

            // Walks in-scope elements and clears out any elements or styles that might affect the bold formatting.
            var elementsToRemove = new List <IHTMLElement>();

            expandedRange.WalkRange(
                delegate(MarkupRange currentexpandedRange, MarkupContext context, string text)
            {
                IHTMLElement currentElement = context.Element;
                if (currentElement != null && context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope)
                {
                    if (IsStrongOrBold(currentElement))
                    {
                        elementsToRemove.Add(currentElement);
                    }
                    else if (IsFontableElement(currentElement) && HTMLElementHelper.IsBold((IHTMLElement2)currentElement) != turnBold)
                    {
                        currentElement.style.fontWeight = String.Empty;
                    }
                }

                return(true);
            }, true);

            elementsToRemove.ForEach(e => markupServices.RemoveElement(e));

            // Walks the range to find any segments of text that need to be fixed up.
            var rangesToWrap = new List <MarkupRange>();

            range.WalkRange(
                delegate(MarkupRange currentRange, MarkupContext context, string text)
            {
                if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_Text)
                {
                    TextStyles currentTextStyles = new TextStyles(currentRange.Start);
                    if (currentTextStyles.Bold != turnBold)
                    {
                        rangesToWrap.Add(currentRange.Clone());
                    }
                }

                return(true);
            }, true);

            rangesToWrap.ForEach(r => WrapRangeInFontIfNecessary(r, turnBold));
        }
        public static void ChangeElementTagIds(MshtmlMarkupServices markupServices, MarkupRange selection, _ELEMENT_TAG_ID[] tagBefore, _ELEMENT_TAG_ID tagAfter)
        {
            HtmlStyleHelper htmlStyleHelper = new HtmlStyleHelper(markupServices);

            int         parentStartDiff = 0;
            MarkupRange rangeToChange;
            bool        selectionStartedEmpty = selection.IsEmpty();

            if (selectionStartedEmpty)
            {
                // Operate on parent block element
                rangeToChange   = markupServices.CreateMarkupRange(selection.ParentBlockElement());
                parentStartDiff = selection.Start.MarkupPosition - rangeToChange.Start.MarkupPosition;
            }
            else
            {
                rangeToChange = selection;

                // If expanding the selection would not include any new text, then expand it.
                // <h1>|abc|</h1> --> |<h1>abc</h1>|
                rangeToChange.MoveOutwardIfNoText();
            }

            IHTMLElementFilter[] filters = new IHTMLElementFilter[tagBefore.Length];

            for (int i = 0; i < tagBefore.Length; i++)
            {
                filters[i] = ElementFilters.CreateTagIdFilter(markupServices.GetNameForTagId(tagBefore[i]));
            }


            IHTMLElement[] elements = rangeToChange.GetElements(ElementFilters.CreateCompoundElementFilter(filters), false);
            foreach (IHTMLElement element in elements)
            {
                MarkupRange elementRange = markupServices.CreateMarkupRange(element);

                int startPositionDiff = rangeToChange.Start.MarkupPosition - elementRange.Start.MarkupPosition;
                int endPositionDiff   = rangeToChange.End.MarkupPosition - elementRange.End.MarkupPosition;

                // @RIBBON TODO: Appropriately preserve element attributes when changing tag ids?
                MarkupRange newElementRange = markupServices.CreateMarkupRange(htmlStyleHelper.WrapRangeInSpanElement(tagAfter, null, elementRange));
                markupServices.RemoveElement(element);

                MarkupPointer startPointer = rangeToChange.Start.Clone();
                startPointer.MoveToMarkupPosition(startPointer.Container, newElementRange.Start.MarkupPosition + startPositionDiff);
                if (startPointer.IsLeftOf(rangeToChange.Start))
                {
                    rangeToChange.Start.MoveToPointer(startPointer);
                }

                MarkupPointer endPointer = rangeToChange.End.Clone();
                endPointer.MoveToMarkupPosition(endPointer.Container, newElementRange.End.MarkupPosition + endPositionDiff);
                if (endPointer.IsLeftOf(elementRange.End))
                {
                    rangeToChange.End.MoveToPointer(endPointer);
                }
            }

            if (selectionStartedEmpty)
            {
                selection.Start.MoveToMarkupPosition(selection.Start.Container, rangeToChange.Start.MarkupPosition + parentStartDiff);
                selection.Collapse(true);
            }
        }