Beispiel #1
0
        public static void SplitBlockForInsertionOrBreakout(MshtmlMarkupServices markupServices, MarkupRange bounds, MarkupPointer insertAt)
        {
            IHTMLElement currentBlock = insertAt.GetParentElement(ElementFilters.BLOCK_OR_TABLE_CELL_ELEMENTS);

            if (currentBlock == null)
            {
                return;
            }

            if (ElementFilters.IsBlockQuoteElement(currentBlock) || ElementFilters.IsTableCellElement(currentBlock))
            {
                return;
            }


            MarkupPointer blockStart = markupServices.CreateMarkupPointer(currentBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
            MarkupPointer blockEnd   = markupServices.CreateMarkupPointer(currentBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);

            if (bounds != null && (blockStart.IsLeftOf(bounds.Start) || blockEnd.IsRightOf(bounds.End)))
            {
                return;
            }

            // Don't split if at the beginning or end of the visible content in the block.
            // Instead just move the insertion point outside the block.
            MarkupRange testRange = markupServices.CreateMarkupRange();

            testRange.Start.MoveToPointer(insertAt);
            testRange.End.MoveAdjacentToElement(currentBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeEnd);
            if (testRange.IsEmptyOfContent())
            {
                insertAt.MoveAdjacentToElement(currentBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                return;
            }
            testRange.Start.MoveAdjacentToElement(currentBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
            testRange.End.MoveToPointer(insertAt);
            if (testRange.IsEmptyOfContent())
            {
                insertAt.MoveAdjacentToElement(currentBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
                return;
            }

            MarkupPointer moveTarget = markupServices.CreateMarkupPointer(blockEnd);

            markupServices.Move(insertAt, blockEnd, moveTarget);
            insertAt.MoveAdjacentToElement(currentBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
        }
        private void ApplyBlockStyle(_ELEMENT_TAG_ID styleTagId, MarkupRange selection, MarkupRange maximumBounds, MarkupRange postOpSelection)
        {
            Debug.Assert(selection != maximumBounds, "selection and maximumBounds must be distinct objects");
            SelectionPositionPreservationCookie selectionPreservationCookie = null;

            //update the range cling and gravity so it will stick with the re-arranged block content
            selection.Start.PushCling(false);
            selection.Start.PushGravity(_POINTER_GRAVITY.POINTER_GRAVITY_Left);
            selection.End.PushCling(false);
            selection.End.PushGravity(_POINTER_GRAVITY.POINTER_GRAVITY_Right);

            try
            {
                if (selection.IsEmpty())
                {
                    //nothing is selected, so expand the selection to cover the entire parent block element
                    IHTMLElementFilter stopFilter =
                        ElementFilters.CreateCompoundElementFilter(ElementFilters.BLOCK_ELEMENTS,
                                                                   new IHTMLElementFilter(IsSplitStopElement));
                    MovePointerLeftUntilRegionBreak(selection.Start, stopFilter, maximumBounds.Start);
                    MovePointerRightUntilRegionBreak(selection.End, stopFilter, maximumBounds.End);
                }

                using (IUndoUnit undo = _editor.CreateSelectionUndoUnit(selection))
                {
                    selectionPreservationCookie = SelectionPositionPreservationHelper.Save(_markupServices, postOpSelection, selection);
                    if (selection.IsEmptyOfContent())
                    {
                        ApplyBlockFormatToEmptySelection(selection, styleTagId, maximumBounds);
                    }
                    else
                    {
                        ApplyBlockFormatToContentSelection(selection, styleTagId, maximumBounds);
                    }
                    undo.Commit();
                }
            }
            finally
            {
                selection.Start.PopCling();
                selection.Start.PopGravity();
                selection.End.PopCling();
                selection.End.PopGravity();
            }

            if (!SelectionPositionPreservationHelper.Restore(selectionPreservationCookie, selection, selection.Clone()))
                selection.ToTextRange().select();
        }
        /// <summary>
        /// Returns true if there is non-empty content between 2 pointers.
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns>true if there is visible content between the pointers</returns>
        private bool HasContentBetween(MarkupPointer start, MarkupPointer end)
        {
            MarkupRange range = MarkupServices.CreateMarkupRange(start, end);

            return(!range.IsEmptyOfContent(false));
        }
        /// <summary>
        /// Returns true if the parent element was removed and false otherwise.
        /// </summary>
        private bool RemoveEmptyParentBlock(MarkupRange range, IHTMLElement parentBlock, MarkupRange maximumBounds)
        {
            if (parentBlock != null)
            {
                range.MoveToElement(parentBlock, false);
                if (maximumBounds.InRange(range) && range.IsEmptyOfContent())
                {
                    if (!IsSplitStopElement(parentBlock))
                    {
                        //delete the parent node (only if it doesn't fall outside the maxrange (bug 465995))
                        range.MoveToElement(parentBlock, true); //expand the range around deletion area to test for maxBounds exceeded
                        if (maximumBounds.InRange(range))
                        {
                            (parentBlock as IHTMLDOMNode).removeNode(true);
                            return true;
                        }
                    }
                }
            }

            return false;
        }