/// <summary>
        /// Condenses this range into the smallest well-formed state that still contains the same
        /// text markup.
        /// </summary>
        /// <returns></returns>
        public bool Trim()
        {
            MarkupPointer newStart = MarkupServices.CreateMarkupPointer(Start);
            MarkupPointer newEnd   = MarkupServices.CreateMarkupPointer(End);
            MarkupContext context  = new MarkupContext();

            //set newStart adjacent to the first text element to its right
            newStart.Right(true, context);
            while (!HasContentBetween(Start, newStart) && newStart.IsLeftOf(End))
            {
                newStart.Right(true, context);
            }
            if (HasContentBetween(Start, newStart))
            {
                newStart.Left(true); //we overstepped the text, so back up one step
            }
            //set newEnd adjacent to the first text element to its left
            newEnd.Left(true, context);
            while (!HasContentBetween(newEnd, End) && newEnd.IsRightOf(Start))
            {
                newEnd.Left(true, context);
            }
            if (HasContentBetween(newEnd, End))
            {
                newEnd.Right(true); //we overstepped the text, so back up one step
            }
            IHTMLElement sharedParent = GetSharedParent(newStart, newEnd);

            //span the start and end pointers as siblings by finding the parents of start and end
            //pointers that are direct children of the sharedParent
            IHTMLElement child = GetOuterMostChildOfParent(newStart, true, sharedParent);

            if (child != null)
            {
                newStart.MoveAdjacentToElement(child, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
            }

            child = GetOuterMostChildOfParent(newEnd, false, sharedParent);
            if (child != null)
            {
                newEnd.MoveAdjacentToElement(child, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
            }

            if (!HasContentBetween(newStart, Start) && !HasContentBetween(End, newEnd) &&
                !(Start.IsEqualTo(newStart) && End.IsEqualTo(newEnd)))
            {
                Start.MoveToPointer(newStart);
                End.MoveToPointer(newEnd);
                return(true);
            }
            else
            {
                //the range didn't change, so return false.
                return(false);
            }
        }
        /// <summary>
        /// Walk through the markup range in reverse, letting the walker visit each position.
        /// </summary>
        /// <param name="walker">the delegate walking navigating the the markup range</param>
        /// <param name="inScopeElementsOnly">if true, enter/exit notifications about out-of-scope elements will be suppressed.</param>
        /// <returns></returns>
        public void WalkRangeReverse(MarkupRangeWalker walker, bool inScopeContextsOnly)
        {
            MarkupPointer p1 = MarkupServices.CreateMarkupPointer(End);
            MarkupPointer p2 = MarkupServices.CreateMarkupPointer(End);

            p1.Cling = false;
            p2.Cling = false;
            MarkupContext context         = new MarkupContext();
            bool          continueWalking = true;
            MarkupRange   currentRange    = null;

            while (continueWalking && p2.IsRightOf(Start))
            {
                string text      = null;
                bool   isInScope = true;

                p2.Left(true, context);
                currentRange = new MarkupRange(p2.Clone(), p1.Clone(), MarkupServices);

                if (inScopeContextsOnly)
                {
                    if (context.Element != null)
                    {
                        if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope)
                        {
                            p1.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                            isInScope = InRange(p1);
                        }
                        else if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_ExitScope)
                        {
                            p1.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
                            isInScope = InRange(p1);
                        }
                    }
                    else if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_Text)
                    {
                        // It's possible part of the text is out of scope, so only return the in-scope text.
                        if (currentRange.Start.IsLeftOf(Start))
                        {
                            currentRange.Start.MoveToPointer(Start);
                        }
                    }
                }

                if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_Text)
                {
                    text = currentRange.Text;
                }

                if (!inScopeContextsOnly || isInScope)
                {
                    continueWalking = walker(currentRange, context, text);
                }

                p1.MoveToPointer(p2);
            }
        }
Beispiel #3
0
 private static void MovePointer(MarkupPointer p, MoveDirection d, MarkupContext context)
 {
     if (d == MoveDirection.LEFT)
     {
         p.Left(true, context);
     }
     else
     {
         p.Right(true, context);
     }
 }
 public override bool ShouldMoveDropLocationRight(MarkupPointer dropLocation)
 {
     MarkupContext mc = new MarkupContext();
     dropLocation.Right(false, mc);
     if (mc.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope && ElementFilters.IsBlockElement(mc.Element) && !ContentSourceManager.IsSmartContent(mc.Element))
     {
         dropLocation.Left(false, mc);
         if (mc.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope && ElementFilters.IsBlockElement(mc.Element))
             return true;
     }
     return false;
 }
        private MarkupPointer GetFirstTextPoint(MarkupPointer from, bool forward)
        {
            MarkupPointer firstTextPoint = from.Clone();

            MarkupContext context     = new MarkupContext();
            bool          keepLooking = true;

            do
            {
                if (forward)
                {
                    firstTextPoint.Right(false, context);
                }
                else
                {
                    firstTextPoint.Left(false, context);
                }

                if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_Text)
                {
                    break;
                }

                if (forward)
                {
                    firstTextPoint.Right(true, context);
                    keepLooking = context.Element != null && firstTextPoint.IsLeftOf(End);
                }
                else
                {
                    firstTextPoint.Left(true, context);
                    keepLooking = context.Element != null && firstTextPoint.IsRightOf(Start);
                }
            } while (keepLooking);

            return(firstTextPoint);
        }
        /// <summary>
        /// Retrieve the parent of a child element that is closest to an outer parent element.
        /// </summary>
        /// <param name="from">the position to move move out from</param>
        /// <param name="lookRight">if true, look right for the inner child to start from, otherwise look left</param>
        /// <param name="outerParent">parent element to move out to</param>
        /// <returns>the direct child of the outerparent that contains the innerChild</returns>
        IHTMLElement GetOuterMostChildOfParent(MarkupPointer from, bool lookRight, IHTMLElement outerParent)
        {
            MarkupContext lookContext = new MarkupContext();

            if (lookRight)
            {
                from.Right(false, lookContext);
            }
            else
            {
                from.Left(false, lookContext);
            }

            //if there is a new element coming into scope, start the search from there,
            //otherwise, start from the currentScope.
            IHTMLElement innerChild;

            if (lookContext.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope)
            {
                innerChild = lookContext.Element;
            }
            else
            {
                innerChild = from.CurrentScope;
            }

            IHTMLElement parent      = innerChild;
            IHTMLElement innerParent = innerChild;

            while (parent != outerParent && parent != null)
            {
                innerParent = parent;
                parent      = parent.parentElement;
            }
            Debug.Assert(innerParent != null, "Parent not found");

            if (innerParent == outerParent) //occurs when the from pointer is position directly in the parent.
            {
                return(null);
            }
            return(innerParent);
        }
        private IHTMLElement GetNextElement(MarkupPointer start, MarkupRange boundaries, IHTMLElementFilter filter, bool forward)
        {
            start = start.Clone();
            MarkupPointer boundary = forward ? boundaries.End : boundaries.Start;
            MarkupContext moveResult = new MarkupContext();
            _MARKUP_CONTEXT_TYPE skipContext = _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_ExitScope;

            //advance the pointer
            if (forward)
                start.Right(true, moveResult);
            else
                start.Left(true, moveResult);

            while (forward ? start.IsLeftOf(boundary) : start.IsRightOf(boundary))
            {
                if (moveResult.Element != null && moveResult.Context != skipContext && filter(moveResult.Element))
                {
                    return moveResult.Element;
                }
                //advance the pointer
                if (forward)
                    start.Right(true, moveResult);
                else
                    start.Left(true, moveResult);
            }
            return null;
        }
        /// <summary>
        /// Retrieve the parent of a child element that is closest to an outer parent element.
        /// </summary>
        /// <param name="from">the position to move move out from</param>
        /// <param name="lookRight">if true, look right for the inner child to start from, otherwise look left</param>
        /// <param name="outerParent">parent element to move out to</param>
        /// <returns>the direct child of the outerparent that contains the innerChild</returns>
        IHTMLElement GetOuterMostChildOfParent(MarkupPointer from, bool lookRight, IHTMLElement outerParent)
        {
            MarkupContext lookContext = new MarkupContext();
            if (lookRight)
                from.Right(false, lookContext);
            else
                from.Left(false, lookContext);

            //if there is a new element coming into scope, start the search from there,
            //otherwise, start from the currentScope.
            IHTMLElement innerChild;
            if (lookContext.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope)
                innerChild = lookContext.Element;
            else
                innerChild = from.CurrentScope;

            IHTMLElement parent = innerChild;
            IHTMLElement innerParent = innerChild;
            while (parent != outerParent && parent != null)
            {
                innerParent = parent;
                parent = parent.parentElement;
            }
            Debug.Assert(innerParent != null, "Parent not found");

            if (innerParent == outerParent) //occurs when the from pointer is position directly in the parent.
            {
                return null;
            }
            return innerParent;
        }
 private static void MovePointer(MarkupPointer p, MoveDirection d, MarkupContext context)
 {
     if (d == MoveDirection.LEFT)
         p.Left(true, context);
     else
         p.Right(true, context);
 }
 private void MovePointerRightUntilRegionBreak(MarkupPointer p, IHTMLElementFilter regionBreakFilter, MarkupPointer rightBoundary)
 {
     MarkupContext moveContext = new MarkupContext();
     while (p.IsLeftOf(rightBoundary))
     {
         p.Right(true, moveContext);
         if (moveContext.Element != null && regionBreakFilter(moveContext.Element))
         {
             p.Left(true);
             return;
         }
     }
 }