コード例 #1
0
        /// <summary>
        /// Grabs HTML copied in the clipboard and pastes it into the document (pulls in a copy of embedded content too)
        /// </summary>
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            using (new WaitCursor())
            {
                try
                {
                    // get the list of files from the data meister
                    FileItem[] files = DataMeister.FileData.Files;

                    string[] filePaths = new string[files.Length];
                    // create an array of file entities to insert
                    for (int i = 0; i < files.Length; i++)
                    {
                        filePaths[i] = files[i].ContentsPath;
                    }

                    string html = EditorContext.HtmlGenerationService.GenerateHtmlFromFiles(filePaths);
                    EditorContext.InsertHtml(begin, end, html, null);

                    //place the caret at the end of the inserted content
                    //EditorContext.MoveCaretToMarkupPointer(end, true);
                    return true;
                }
                catch (Exception e)
                {
                    //bugfix 1696, put exceptions into the trace log.
                    Trace.Fail("Exception while inserting HTML: " + e.Message, e.StackTrace);
                    return false;
                }
            }
        }
コード例 #2
0
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            // get the table and its cells
            IHTMLTable sourceTable = GetSourceTable(DataMeister);
            IHTMLElementCollection cells = (sourceTable as IHTMLElement2).getElementsByTagName("td");

            // single-cell tables just get the innerHTML of the cell pasted at the selection
            if (cells.length == 1)
            {
                IHTMLElement cell = cells.item(0, 0) as IHTMLElement;
                EditorContext.InsertHtml(begin, end, cell.innerHTML, UrlHelper.GetBaseUrl(DataMeister.HTMLData.SourceURL));
            }
            else
            {
                // if we are inside a table
                TableSelection tableSelection = new TableSelection(EditorContext.MarkupServices.CreateMarkupRange(begin, end));
                if (tableSelection.Table != null)
                {
                    // paste the source cells into the table
                    PasteCellsIntoTable(sourceTable, tableSelection);
                }
                else
                {
                    // get table html (make sure width matches # of rows selected)
                    TableHelper.SynchronizeTableWidthForEditing(sourceTable);
                    string html = (sourceTable as IHTMLElement).outerHTML;

                    // insert the html (nests within an undo unit)
                    EditorContext.InsertHtml(begin, end, html, UrlHelper.GetBaseUrl(DataMeister.HTMLData.SourceURL));
                }
            }

            return true;
        }
コード例 #3
0
        /// <summary>
        /// Insert html at the given pointer.
        /// </summary>
        /// <param name="html"></param>
        /// <param name="insertionPoint"></param>
        public void InsertHtml(string html, MarkupPointer insertionPoint)
        {
            MarkupRange content = CreateMarkupRange();

            ParseString(html, content.Start, content.End);

            Move(content.Start, content.End, insertionPoint);
        }
コード例 #4
0
        /// <summary>
        /// Create an unpositioned MarkupRange.
        /// </summary>
        /// <returns></returns>
        public MarkupRange CreateMarkupRange()
        {
            MarkupPointer start = CreateMarkupPointer();
            MarkupPointer end   = CreateMarkupPointer();

            end.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right;
            return(CreateMarkupRange(start, end));
        }
コード例 #5
0
 public void EnsureStartIsBeforeEnd()
 {
     if (Start.IsRightOf(End))
     {
         MarkupPointer temp = End.Clone();
         End   = Start.Clone();
         Start = temp;
     }
 }
コード例 #6
0
 public void Normalize()
 {
     if (Start.IsRightOf(End))
     {
         MarkupPointer tmp = Start;
         Start = End;
         End   = tmp;
     }
 }
コード例 #7
0
        /// <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);
            }
        }
コード例 #8
0
 /// <summary>
 /// Create a text range spanning the specified markup positions.
 /// </summary>
 /// <param name="start">the start point of the text range</param>
 /// <param name="end">the end point of the text range</param>
 /// <returns></returns>
 public IHTMLTxtRange CreateTextRange(MarkupPointer start, MarkupPointer end)
 {
     // when switching between wywiwyg and source view sometimes .body is null
     // and this throws a null ref exception that we catch (can be detected by enabling
     // exception breaking in the debugger)
     IHTMLTxtRange range = (Document.body as IHTMLBodyElement).createTextRange();
     MarkupServices.MoveRangeToPointers(start, end, range);
     return range;
 }
コード例 #9
0
        /// <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);
            }
        }
コード例 #10
0
        /// <summary>
        /// Returns a copy of this markup pointer that is positioned at the same location.
        /// </summary>
        /// <returns></returns>
        public MarkupPointer Clone()
        {
            MarkupPointer p = MarkupServices.CreateMarkupPointer(this);

            p.Cling        = Cling;
            p.Gravity      = Gravity;
            p.clingStack   = (Stack)clingStack.Clone();
            p.gravityStack = (Stack)gravityStack.Clone();
            return(p);
        }
コード例 #11
0
        /// <summary>
        /// Create a text range spanning the specified markup positions.
        /// </summary>
        /// <param name="start">the start point of the text range</param>
        /// <param name="end">the end point of the text range</param>
        /// <returns></returns>
        public IHTMLTxtRange CreateTextRange(MarkupPointer start, MarkupPointer end)
        {
            // when switching between wywiwyg and source view sometimes .body is null
            // and this throws a null ref exception that we catch (can be detected by enabling
            // exception breaking in the debugger)
            IHTMLTxtRange range = (Document.body as IHTMLBodyElement).createTextRange();

            MarkupServices.MoveRangeToPointers(start, end, range);
            return(range);
        }
コード例 #12
0
        /// <summary>
        /// Create a MarkupRange from a TextRange.
        /// </summary>
        /// <param name="textRange"></param>
        /// <returns></returns>
        public MarkupRange CreateMarkupRange(IHTMLTxtRange textRange)
        {
            MarkupPointer Begin = CreateMarkupPointer();
            MarkupPointer End   = CreateMarkupPointer();

            End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right;
            MovePointersToRange(textRange, Begin, End);
            MarkupRange markupRange = new MarkupRange(Begin, End, this);

            return(markupRange);
        }
コード例 #13
0
 private static void MovePointer(MarkupPointer p, MoveDirection d, MarkupContext context)
 {
     if (d == MoveDirection.LEFT)
     {
         p.Left(true, context);
     }
     else
     {
         p.Right(true, context);
     }
 }
コード例 #14
0
 /// <summary>
 /// Returns true if the specified pointer is in a position between, or equal to this range's Start/End points.
 /// </summary>
 /// <param name="p"></param>
 /// <returns></returns>
 public bool InRange(MarkupPointer p, bool allowEquals)
 {
     if (allowEquals)
     {
         return(Start.IsLeftOfOrEqualTo(p) && End.IsRightOfOrEqualTo(p));
     }
     else
     {
         return(Start.IsLeftOf(p) && End.IsRightOf(p));
     }
 }
コード例 #15
0
 private static bool CheckMoveBoundary(MarkupPointer p, MarkupPointer boundary, MoveDirection d)
 {
     if (d == MoveDirection.LEFT)
     {
         return(p.IsRightOf(boundary));
     }
     else
     {
         return(p.IsLeftOf(boundary));
     }
 }
コード例 #16
0
 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;
 }
コード例 #17
0
        /// <summary>
        /// Create a MarkupRange from that surrounds an Element.
        /// </summary>
        /// <returns></returns>
        public MarkupRange CreateMarkupRange(IHTMLElement element, bool outside)
        {
            _ELEMENT_ADJACENCY beginAdj = outside ? _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin : _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin;
            _ELEMENT_ADJACENCY endAdj   = outside ? _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd : _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeEnd;
            MarkupPointer      Begin    = CreateMarkupPointer(element, beginAdj);
            MarkupPointer      End      = CreateMarkupPointer(element, endAdj);

            End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right;
            MarkupRange markupRange = new MarkupRange(Begin, End, this);

            return(markupRange);
        }
コード例 #18
0
        public TypographicCharacterHandler(MarkupRange currentSelection, InsertHtml insertHtml, IBlogPostImageEditingContext imageEditingContext, IHTMLElement postBodyElement, char c, string htmlText, MarkupPointer blockBoundary)
        {
            _currentSelection = currentSelection.Clone();
            _currentSelection.Start.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right;
            _currentSelection.End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Left;
            _insertHtml = insertHtml;
            _imageEditingContext = imageEditingContext;
            _postBodyElement = postBodyElement;

            this.c = c;
            this.htmlText = htmlText;
            this.blockBoundary = blockBoundary;
        }
コード例 #19
0
        private static void AdjustMarkupRangeCore(MarkupRange range, int offset, int length, string currentText)
        {
            MarkupPointer start = range.Start;
            MarkupPointer end   = range.End;

            if (offset > 0)
            {
                start.MoveToMarkupPosition(start.Container, start.MarkupPosition + offset);
            }
            if (length < (offset + currentText.Length))
            {
                end.MoveToMarkupPosition(start.Container, start.MarkupPosition + length);
            }
        }
コード例 #20
0
        public static void PerformImageBreakout(MarkupPointer p)
        {
            Direction dir = ImageBreakout(p);

            if (dir == Direction.Right)
            {
                p.MoveAdjacentToElement(p.CurrentScope, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
            }

            if (dir == Direction.Left)
            {
                p.MoveAdjacentToElement(p.CurrentScope, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
            }
        }
コード例 #21
0
        /// <summary>
        /// Returns true if the specified element begins and ends within the range.
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private bool isInScope(IHTMLElement e)
        {
            MarkupPointer p = MarkupServices.CreateMarkupPointer(e, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);

            if (p.IsRightOfOrEqualTo(Start))
            {
                p = MarkupServices.CreateMarkupPointer(e, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                if (p.IsLeftOfOrEqualTo(End))
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #22
0
        /// <summary>
        /// Creates a MarkupContainer that contains the results of parsing the contents of a string.
        /// </summary>
        /// <param name="html">html content to parse</param>
        /// <param name="start">pointer to position at the beginning of the parsed content (null is allowed)</param>
        /// <param name="end">pointer to position at the end of the parsed content (null is allowed)</param>
        /// <returns></returns>
        public MarkupContainer ParseString(string html, MarkupPointer start, MarkupPointer end)
        {
            if (start == null)
            {
                start = CreateMarkupPointer();
            }
            if (end == null)
            {
                end = CreateMarkupPointer();
            }
            IMarkupContainerRaw container;

            MarkupServices.ParseString(html, 0, out container, start.PointerRaw, end.PointerRaw);
            return(new MarkupContainer(this, container));
        }
コード例 #23
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);
        }
コード例 #24
0
        /// <summary>
        /// Returns null if ranges do not intersect
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public MarkupRange Intersect(MarkupRange range)
        {
            MarkupPointer maxStart = Start.IsRightOf(range.Start) ? Start : range.Start;
            MarkupPointer minEnd   = End.IsLeftOf(range.End) ? End : range.End;

            if (minEnd.IsLeftOf(maxStart))
            {
                return(null);
            }

            MarkupRange intersection = MarkupServices.CreateMarkupRange();

            intersection.Start.MoveToPointer(maxStart);
            intersection.End.MoveToPointer(minEnd);

            return(intersection);
        }
コード例 #25
0
        /// <summary>
        /// Shrinks the range until further shrinking would exclude text that is currently in the range.
        /// </summary>
        public void SelectInner()
        {
            // Without this check, the start pointer can move outside
            // of the current container tag (e.g. ...text...|</p> => </p>|)
            if (IsEmpty())
            {
                return;
            }

            EnsureStartIsBeforeEnd();

            // Move the start until you hit text
            MarkupPointer innerStart = GetFirstTextPoint(Start, true);
            MarkupPointer innerEnd   = GetFirstTextPoint(End, false);

            Start = innerStart;
            End   = innerEnd;
        }
コード例 #26
0
        //this is similar to the GetTopLevelElements except will also return table cells if correct filter
        // is set and recurse is equal to true
        public IHTMLElement[] GetTopLevelBlocksAndCells(IHTMLElementFilter filter, bool recurse)
        {
            ArrayList list         = new ArrayList();
            Hashtable usedElements = new Hashtable();

            MarkupPointer p       = MarkupServices.CreateMarkupPointer(Start);
            MarkupContext context = p.Right(false);

            //move p through the range to locate each of the top level elements
            while (p.IsLeftOf(End))
            {
                if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope || context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_NoScope)
                {
                    p.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                    if (usedElements[context.Element] == null)
                    {
                        if (p.IsLeftOfOrEqualTo(End) && (filter == null || filter(context.Element)))
                        {
                            list.Add(context.Element);
                        }
                        //special case--inside of a table element, want to get out the cells inside
                        else if (recurse && ElementFilters.TABLE_ELEMENTS(context.Element))
                        {
                            MarkupRange newRange = MarkupServices.CreateMarkupRange(context.Element);
                            newRange.Start.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
                            if (newRange.Start.IsLeftOf(Start))
                            {
                                newRange.Start.MoveToPointer(Start);
                            }
                            if (newRange.End.IsRightOf(End))
                            {
                                newRange.End.MoveToPointer(End);
                            }
                            //recursively check inside table element for table cells
                            list.AddRange(newRange.GetTopLevelBlocksAndCells(filter, true));
                        }
                        //cache the fact that we've already tested this element.
                        usedElements[context.Element] = context.Element;
                    }
                }
                p.Right(true, context);
            }
            return(HTMLElementHelper.ToElementArray(list));
        }
コード例 #27
0
        /// <summary>
        /// Checks if the MarkupPointer is inside of an anchor that only contains
        /// an image, and if so, moves the pointer to be outside the anchor.
        /// This prevents cases where hyperlinked images were getting nested inside
        /// of each other as a result of drag and drop.
        /// </summary>
        public static Direction ImageBreakout(MarkupPointer p)
        {
            //   If inside <a><img></a>, then move to outside
            IHTMLElement currentScope = p.CurrentScope;

            if (currentScope is IHTMLAnchorElement)
            {
                IHTMLDOMNode anchor = (IHTMLDOMNode)currentScope;
                if (anchor.hasChildNodes() && anchor.firstChild is IHTMLImgElement && anchor.firstChild.nextSibling == null)
                {
                    // Figure out if we are positioned before or after the image; this will determine
                    // whether we want to move before or after the anchor
                    return((p.Right(false).Element is IHTMLImgElement)
                                                              ? Direction.Left
                                                              : Direction.Right);
                }
            }
            return(Direction.None);
        }
コード例 #28
0
        /// <summary>
        /// Grabs text copied in the clipboard and pastes it into the document
        /// </summary>
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            try
            {
                // get the text data as a string
                string textData = DataMeister.TextData.Text;
                string html = EditorContext.HtmlGenerationService.GenerateHtmlFromPlainText(textData);

                //insert captured content into the document
                EditorContext.InsertHtml(begin, end, html, null);
                return true;
            }
            catch (Exception e)
            {
                //bugfix 1696, put exceptions into the trace log.
                Trace.Fail("Exception while inserting URL: " + e.Message, e.StackTrace);
                return false;
            }
        }
コード例 #29
0
        public static void TraceMoveToMarkupPointer(IDisplayPointerRaw displayPointer, MarkupPointer markupPointer)
        {
            try
            {
                if (displayPointer == null)
                    throw new ArgumentException("Unexpected null display pointer.");

                if (markupPointer == null)
                    throw new ArgumentException("Unexpected null markup pointer.");

                //position a display pointer on the same line as the markup pointer
                displayPointer.MoveToMarkupPointer(markupPointer.PointerRaw, null);
            }
            catch (Exception e)
            {
                Trace.Fail("Unexpected exception in TraceMoveToMarkupPointer: " + e.ToString());
                throw;
            }
        }
コード例 #30
0
        /// <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);
        }
コード例 #31
0
        public IHTMLElement SeekElementRight(IHTMLElementFilter filter, MarkupPointer boundaryPointer)
        {
            // initialize markup context used to track seeking
            MarkupContext markupContext = new MarkupContext();

            markupContext.Context = _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_NoScope;

            while ((boundaryPointer == null || IsLeftOf(boundaryPointer)) &&                          // apply boundary if one exists
                   (markupContext.Context != _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_None))                 // otherwise use end of document
            {
                Right(true, markupContext);

                IHTMLElement element = markupContext.Element;

                if (element != null && filter(element))
                {
                    return(element);
                }
            }

            // none found
            return(null);
        }
コード例 #32
0
        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);
        }
コード例 #33
0
        /// <summary>
        /// Gets the elements in the range that match the filter.
        /// </summary>
        /// <param name="filter">the delegate testing each element to determine if it should be added to the list of elements to return</param>
        /// <param name="inScopeElementsOnly">if true, the only</param>
        /// <returns></returns>
        public IHTMLElement[] GetElements(IHTMLElementFilter filter, bool inScopeElementsOnly)
        {
            ArrayList list = new ArrayList();

            if (!IsEmpty())
            {
                Hashtable     usedElements = new Hashtable();
                MarkupPointer p            = MarkupServices.CreateMarkupPointer(Start);
                MarkupPointer end          = MarkupServices.CreateMarkupPointer(End);
                MarkupContext context      = p.Right(false);

                //move p through the range to locate each the elements adding elements that pass the filter
                while (p.IsLeftOfOrEqualTo(end))
                {
                    if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope ||
                        context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_ExitScope ||
                        context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_NoScope)
                    {
                        if (usedElements[context.Element] == null)
                        {
                            if ((inScopeElementsOnly && isInScope(context.Element)) || !inScopeElementsOnly)
                            {
                                if (filter(context.Element))
                                {
                                    list.Add(context.Element);
                                }
                            }

                            //cache the fact that we've already tested this element.
                            usedElements[context.Element] = context.Element;
                        }
                    }
                    p.Right(true, context);
                }
            }
            return(HTMLElementHelper.ToElementArray(list));
        }
コード例 #34
0
        private static void MoveUnitBounded(MarkupPointer p, MoveDirection direction, MoveContextFilter continueFilter, MarkupPointer boundary)
        {
            MarkupPointer p1 = p.Clone();
            MarkupPointer lastGoodPosition = p.Clone();
            MarkupContext context = new MarkupContext();
            MoveFilterResult result = MoveFilterResult.CONTINUE;
            while (CheckMoveBoundary(p1, boundary, direction) && result == MoveFilterResult.CONTINUE)
            {
                lastGoodPosition.MoveToPointer(p1);
                MovePointer(p1, direction, context);
                result = continueFilter(context);
            }
            if (result == MoveFilterResult.CONTINUE)
            {
                //we hit the boundary, so position pointer at the boundary
                p1.MoveToPointer(boundary);
            }
            else if (result == MoveFilterResult.STOP_BACK)
            {
                p1.MoveToPointer(lastGoodPosition);
            }

            p.MoveToPointer(p1);
        }
コード例 #35
0
 public bool IsAdjacentToWordEnd(MarkupPointer p)
 {
     lock (_p)
     {
         _p.MoveToPointer(p);
         _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTCHAR);
         _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVWORDEND);
         return _p.IsEqualTo(p);
     }
 }
コード例 #36
0
 private float GetFontSizeAt(MarkupPointer location)
 {
     IDisplayServicesRaw displayServices = (IDisplayServicesRaw)HTMLDocument;
     IHTMLComputedStyle computedStyle;
     displayServices.GetComputedStyle(location.PointerRaw, out computedStyle);
     float pixels = DisplayHelper.TwipsToPixelsY(computedStyle.fontSize);
     float points = HTMLElementHelper.PixelsToPointSize(pixels, true);
     return points;
 }
コード例 #37
0
 public void MoveToWordEnd(MarkupPointer p)
 {
     lock (_p)
     {
         _p.MoveToPointer(p);
         _p2.MoveToPointer(p);
         _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDBEGIN);
         _p2.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDEND);
         // If CurrentScope is null, this means we have walked off the end of the
         // document, in that case we don't want to move the pointer, at is already
         // at the end of word.
         if (_p2.IsLeftOfOrEqualTo(_p) && _p.CurrentScope != null)
             p.MoveToPointer(_p2);
         //else, the pointer is already at the end of the current word
     }
 }
コード例 #38
0
 private IDisposable CreateDamageTracking(MarkupPointer end, bool p)
 {
     return _damageServices.CreateDamageTracker(end, end, true);
 }
コード例 #39
0
 /// <summary>
 /// Moves the pointer one unit, but not past a given markup pointer's position.
 /// </summary>
 /// <param name="muAction"></param>
 public void MoveUnitBounded(_MOVEUNIT_ACTION muAction, MarkupPointer boundary)
 {
     (PointerRaw as IMarkupPointer2Raw).MoveUnitBounded(muAction, boundary.PointerRaw);
 }
コード例 #40
0
        /// <summary>
        /// Inserts the extended entry break into the editor at the specified location.
        /// </summary>
        internal IHTMLElement InsertExtendedEntryBreak(MarkupPointer insertionPoint)
        {
            IHTMLElement entryBreakDiv = EditorContext.MarkupServices.CreateElement(_ELEMENT_TAG_ID.TAGID_DIV, null);
            IHTMLElement postBodyElement = HTMLElement;
            insertionPoint.PushCling(false);
            insertionPoint.PushGravity(_POINTER_GRAVITY.POINTER_GRAVITY_Right);
            try
            {
                //insert the entryBreak DIV into the beginning of the post body
                entryBreakDiv.id = EXTENDED_ENTRY_ID;
                entryBreakDiv.setAttribute("name", EXTENDED_ENTRY_ID, 0);

                MarkupRange markupRange = EditorContext.MarkupServices.CreateMarkupRange();
                markupRange.MoveToElement(postBodyElement, false);
                markupRange.End.MoveToPointer(markupRange.Start);
                EditorContext.MarkupServices.InsertElement(entryBreakDiv, markupRange.Start, markupRange.End);

                //move all content that should stay above the extended entry line, above the entryBreakDiv
                //this effectively forces all open tags to be closed, and leaves the insertion point below
                //the extended entry line (with the pre-insert parent tree still intact.
                markupRange.Start.MoveAdjacentToElement(entryBreakDiv, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                markupRange.End.MoveToPointer(insertionPoint);
                MarkupPointer target = EditorContext.MarkupServices.CreateMarkupPointer(entryBreakDiv, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
                EditorContext.MarkupServices.Move(markupRange.Start, markupRange.End, target);
            }
            finally
            {
                insertionPoint.PopCling();
                insertionPoint.PopGravity();
            }

            return entryBreakDiv;
        }
コード例 #41
0
        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;
        }
コード例 #42
0
        private bool OverwriteDestinationBlockIfEmpty(MarkupPointer destinationStart, MarkupRange bounds)
        {
            bool blockOverwritten = false;
            IHTMLElement parentBlockElement = destinationStart.GetParentElement(ElementFilters.BLOCK_ELEMENTS);
            if (parentBlockElement != null)
            {
                MarkupRange parentBlockRange = MarkupServices.CreateMarkupRange(parentBlockElement, false);
                if (bounds.InRange(parentBlockRange, false))
                {
                    if (PrimaryEditableBounds == null || PrimaryEditableBounds.InRange(parentBlockRange))
                    {
                        if (parentBlockRange.IsEmptyOfContent())
                        {
                            parentBlockRange.MoveToElement(parentBlockElement, true);
                            DeleteContentNoCling(parentBlockRange.Start, parentBlockRange.End);
                            // Check to see if the delete we just did caused the insertion point to be
                            // to become a no longer positioned, and if it did we move it to the start
                            // of what we deleted
                            if (!destinationStart.Positioned)
                            {
                                //Debug.WriteLine("Invalid pointer after delete, moving the target pointer to the start of the deleted markup.");
                                destinationStart.MoveToPointer(parentBlockRange.Start);
                            }

                            blockOverwritten = true;
                        }
                    }
                }
            }
            return blockOverwritten;
        }
コード例 #43
0
 public IDisposable CreateDamageTracker(MarkupPointer start, MarkupPointer end, bool includeAdjacentWords)
 {
     if (DamageTrackingEnabled)
         return new DamageTracker(this, start, end, includeAdjacentWords);
     else
         return null;
 }
コード例 #44
0
        public static void MoveUnitBounded(MarkupPointer p, MoveDirection direction, MarkupPointerAdjacency stopRule, MarkupPointer boundary)
        {
            MoveContextFilter filter = CreateMoveContextFilter(stopRule);

            MoveUnitBounded(p, direction, filter, boundary);
        }
コード例 #45
0
        private static void MoveUnitBounded(MarkupPointer p, MoveDirection direction, MoveContextFilter continueFilter, MarkupPointer boundary)
        {
            MarkupPointer    p1 = p.Clone();
            MarkupPointer    lastGoodPosition = p.Clone();
            MarkupContext    context          = new MarkupContext();
            MoveFilterResult result           = MoveFilterResult.CONTINUE;

            while (CheckMoveBoundary(p1, boundary, direction) && result == MoveFilterResult.CONTINUE)
            {
                lastGoodPosition.MoveToPointer(p1);
                MovePointer(p1, direction, context);
                result = continueFilter(context);
            }
            if (result == MoveFilterResult.CONTINUE)
            {
                //we hit the boundary, so position pointer at the boundary
                p1.MoveToPointer(boundary);
            }
            else if (result == MoveFilterResult.STOP_BACK)
            {
                p1.MoveToPointer(lastGoodPosition);
            }

            p.MoveToPointer(p1);
        }
コード例 #46
0
 void IHtmlMarshallingTarget.InsertHtml(MarkupPointer start, MarkupPointer end, string html, string sourceUrl)
 {
     InsertHtml(start, end, html, sourceUrl, true);
 }
コード例 #47
0
        /// <summary>
        /// Utility for deleting a range of content while suppressing pointer cling.
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        private void DeleteContentNoCling(MarkupPointer start, MarkupPointer end)
        {
            start.PushCling(false);
            end.PushCling(false);

            try
            {
                DeleteContent(start, end);
            }
            finally
            {
                start.PopCling();
                end.PopCling();
            }
        }
コード例 #48
0
 /// <summary>
 /// Delete the content between 2 pointers from the document.
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end"></param>
 private void DeleteContent(MarkupPointer start, MarkupPointer end)
 {
     MarkupRange range = MarkupServices.CreateMarkupRange(start, end);
     DeleteContent(range);
 }
コード例 #49
0
        /// <summary>
        /// Grabs HTML copied in the clipboard and pastes it into the document (pulls in a copy of embedded content too)
        /// </summary>
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            using (new WaitCursor())
            {
                try
                {
                    //StringBuilder html = new StringBuilder();
                    //html.AppendFormat("<a href=\"{0}\">{1}</a>", DataMeister.URLData.URL, DataMeister.URLData.Title);
                    string html = EditorContext.HtmlGenerationService.GenerateHtmlFromLink(Url, Title, Title, String.Empty, false);
                    EditorContext.InsertHtml(begin, end, html, null);

                    //place the caret at the end of the inserted content
                    //EditorContext.MoveCaretToMarkupPointer(end, true);
                    return true;
                }
                catch (Exception e)
                {
                    //bugfix 1696, put exceptions into the trace log.
                    Trace.Fail("Exception while inserting URL: " + e.Message, e.StackTrace);
                    return false;
                }
            }
        }
コード例 #50
0
 public DamageTracker(HtmlEditorControlDamageServices damageServices, MarkupPointer start, MarkupPointer end, bool includeAdjacentWords)
 {
     _damageServices = damageServices;
     _damageRange = damageServices.wordRangeDamager.CreateDamageTrackingRange(start, end, includeAdjacentWords);
 }
コード例 #51
0
 protected virtual bool ContentIsDeletableForInsert(MarkupPointer start, MarkupPointer end)
 {
     return true;
 }
コード例 #52
0
 internal MarkupRange CreateDamageTrackingRange(MarkupPointer start, MarkupPointer end, bool includeAdjecentWords)
 {
     MarkupRange range = _mshtmlEditor.MshtmlControl.MarkupServices.CreateMarkupRange();
     range.Start.MoveToPointer(start);
     range.Start.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Left;
     range.End.MoveToPointer(end);
     range.End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right;
     _wordHelper.MoveToWordStart(range.Start);
     _wordHelper.MoveToWordEnd(range.End);
     if (includeAdjecentWords)
     {
         ExpandDamageToAdjacentWords(range);
     }
     return range;
 }
コード例 #53
0
 private void DeleteInsertionTargetBlockIfEmpty(MarkupPointer insertionPoint)
 {
     //locate the parent block element (stop at post body element)
     IHTMLElement parent = insertionPoint.GetParentElement(
         ElementFilters.CreateCompoundElementFilter(ElementFilters.CreateElementEqualsFilter(HTMLElement),
         ElementFilters.BLOCK_ELEMENTS));
     if (parent != null &&
         parent.sourceIndex != HTMLElement.sourceIndex &&  //never remove the post body block
         EditorContext.MarkupServices.CreateMarkupRange(parent, false).IsEmptyOfContent())
     {
         //delete the empty parent block element
         (parent as IHTMLDOMNode).removeNode(true);
     }
 }
コード例 #54
0
 public MarkupServicesWordHelper(MshtmlMarkupServices markupServices)
 {
     MarkupServices = markupServices;
     _p = MarkupServices.CreateMarkupPointer();
     _p2 = MarkupServices.CreateMarkupPointer();
 }
コード例 #55
0
        private void EnsureNewLineAtDocEnd(MarkupPointer mpStart, MarkupPointer mpEnd)
        {
            // Add a <p></p> at the end of the document if there isn't one.
            MarkupPointer endBody = MarkupServices.CreateMarkupPointer();
            endBody.MoveAdjacentToElement(PostBodyElement, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeEnd);

            // If we have to insert the <p> this is where we will do it, so save it for later
            MarkupPointer insertLocation = endBody.Clone();

            // Move left one more time to find out if it is p with a space in it.
            endBody.Left(true);

            // Check to see if it a p with a space.  We use innerHtml because if the html looked like
            // <p><img ...>&nbsp;</p> innerText only reports " " though this isnt really just a blank line.
            // We dont use HtmlUtils.HtmlToText because it will replace img tags as a space.
            if (endBody.CurrentScope.tagName != "P" || endBody.CurrentScope.innerHTML != "&nbsp;")
            {
                // Move it into the real document
                IHTMLDocument2 docInsert = mpStart.GetDocument();
                MarkupRange stagingRangeInsert = MarkupServices.CreateMarkupRange(mpStart, mpEnd);
                stagingRangeInsert.MoveToElement(docInsert.body, false);
                MarkupServices.Move(stagingRangeInsert.Start, stagingRangeInsert.End, insertLocation);
            }
        }
コード例 #56
0
 public void MoveToWordStart(MarkupPointer p)
 {
     lock (_p)
     {
         _p.MoveToPointer(p);
         _p2.MoveToPointer(p);
         _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVWORDEND);
         _p2.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVWORDBEGIN);
         if (_p2.IsRightOfOrEqualTo(_p))
             p.MoveToPointer(_p2);
         //else, the pointer is already at the start of the current word
     }
 }
コード例 #57
0
 /// <summary>
 /// Moves this pointer to another pointer's location.
 /// </summary>
 /// <param name="p"></param>
 public void MoveToPointer(MarkupPointer p)
 {
     PointerRaw.MoveToPointer(p.PointerRaw);
 }
コード例 #58
0
 public bool IsAdjacentToWordStart(MarkupPointer p)
 {
     lock (_p)
     {
         _p.MoveToPointer(p);
         _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVCHAR);
         _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDBEGIN);
         return _p.IsEqualTo(p);
     }
 }
コード例 #59
0
        public void InsertPlainText(MarkupPointer start, MarkupPointer end, string text)
        {
            IUndoUnit undo = CreateUndoUnit();
            using (undo)
            {
                if (!start.IsEqualTo(end))
                {
                    DeleteContentNoCling(start, end);
                }

                if (start.CurrentScope.tagName == "PRE")
                {
                    //if pasting into a preblock, then we want to preserve the whitespace in
                    //the text, and we don't want to convert line breaks into <BR>.  MSHTML
                    //is really nasty about tossing out whitespace, but will keep its hands
                    //off the text as long as it has <pre> tags around it

                    //hack MSHTML's whitespace mangling by the text wrapping in a <pre> tag
                    //for insertion, and then yank it.
                    text = "<pre>" + HttpUtility.HtmlEncode(text) + "</pre>";
                    MarkupRange range = MarkupServices.CreateMarkupRange();
                    MarkupContainer c = MarkupServices.ParseString(text, range.Start, range.End);
                    range.MoveToElement((IHTMLElement)(c.Document.body as IHTMLDOMNode).firstChild, false);
                    MarkupServices.Move(range.Start, range.End, start);
                }
                else
                {
                    //if this insn't wrapped in a <pre> tag, then use a textRange to insert the
                    //text so that it will be padded with <BR> and &nbsp.
                    MarkupRange range = MarkupServices.CreateMarkupRange(start, end);
                    IHTMLTxtRange txtRange = range.ToTextRange();
                    txtRange.text = text;
                }

                undo.Commit();
            }
        }
コード例 #60
0
 public virtual bool ShouldMoveDropLocationRight(MarkupPointer dropLocation)
 {
     return false;
 }