Ejemplo n.º 1
0
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            // get a reference to the underlying data object
            IDataObject dataObject = DataMeister.IDataObject;

            string dataObjectInstanceId = dataObject.GetData(SmartContentDataObject.INSTANCE_ID_DATAFORMAT) as string;

            if (EditorContext.EditorId.Equals(dataObjectInstanceId))
            {
                // get the internal items out of the data object
                string smartContentElementId = (string)dataObject.GetData(SmartContentDataObject.INTERNAL_SMART_CONTENT_DATAFORMAT);

                IHTMLElement element = (EditorContext.HtmlDocument as IHTMLDocument3).getElementById(smartContentElementId);
                Debug.Assert(element != null, "Invalid smart content item id detected: " + smartContentElementId);
                if (element != null)
                {
                    MarkupRange   elementRange   = EditorContext.MarkupServices.CreateMarkupRange(element, true);
                    MarkupPointer insertionPoint = begin;
                    MarkupPointerMoveHelper.PerformImageBreakout(insertionPoint);

                    insertionPoint.PushCling(false);
                    insertionPoint.PushGravity(_POINTER_GRAVITY.POINTER_GRAVITY_Left);

                    //verify the insertion point is inside of the same content editable parent (bug 290729)
                    if (!IsValidInsertionPoint(element, insertionPoint))
                    {
                        return(false);
                    }

                    try
                    {
                        if (InlineEditField.IsEditField(insertionPoint.CurrentScope))
                        {
                            // If we are in an edit field, since we strip the content wdown to plain text we have to use
                            // InsertHtml.  However, this means we need to move the content via a string.  This sucks because
                            // we break any markup ranges in that area.  This is why ignore once will not work in edit fields.
                            EditorContext.MarkupServices.Remove(begin, end);
                            string html = elementRange.HtmlText;
                            EditorContext.MarkupServices.Remove(elementRange.Start, elementRange.End);
                            EditorContext.InsertHtml(insertionPoint, insertionPoint, html, null);
                        }
                        else
                        {
                            EditorContext.MarkupServices.Remove(begin, end);
                            EditorContext.MarkupServices.Move(elementRange.Start, elementRange.End, insertionPoint);
                        }
                        return(true);
                    }
                    finally
                    {
                        insertionPoint.PopCling();
                        insertionPoint.PopGravity();
                    }
                }
            }
            return(false);
        }
 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));
     }
 }
 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));
     }
 }
 public IDisposable CreateDamageTracker(MarkupPointer start, MarkupPointer end, bool includeAdjacentWords)
 {
     if (DamageTrackingEnabled)
     {
         return(new DamageTracker(this, start, end, includeAdjacentWords));
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 5
0
        private string GetHtmlText(out MarkupPointer blockBoundary)
        {
            MarkupRange  blockRange = _blogPostHtmlEditorControl.SelectedMarkupRange.Clone();
            MarkupRange  textRange  = blockRange.Clone();
            IHTMLElement ele        = blockRange.ParentElement(ElementFilters.IsBlockOrTableCellOrBodyElement);

            if (ele == null)
            {
                blockBoundary = null;
                return(String.Empty);
            }

            blockRange.MoveToElement(ele, false);
            blockBoundary = blockRange.Start;

            //   Fix Bug 616152 - We want the start and end pointer to match so
            //  we can look back from the start of the insertion point (not the end,
            //  which would include the selection that is going to be overwritten)
            textRange.Collapse(true);

            // Fix bug WinLive 59172: Specific characters of mixed characters are broken in mail body after press the 'Enter' key
            // Caused by using MOVEUNIT_PREVCHAR to navigate into Unicode surrogate (32-bit) characters. We work around this by moving
            // only at word or block boundaries.
            string html = null;

            do
            {
                int startPos = textRange.Start.MarkupPosition;
                textRange.Start.MoveUnitBounded(_MOVEUNIT_ACTION.MOVEUNIT_PREVWORDBEGIN, blockBoundary);
                if (textRange.Start.MarkupPosition == startPos)
                {
                    // PREVWORDBEGIN didn't actually move us, due to no word being available.
                    // To avoid an infinite loop, just move the text range to include the whole
                    // block and move on.
                    textRange.Start.MoveToPointer(blockRange.Start);
                    break;
                }

                if (textRange.Positioned && textRange.Start.IsLeftOfOrEqualTo(textRange.End))
                {
                    html = MarkupHelpers.GetRangeTextFast(textRange);
                }

                html = html ?? string.Empty;
            } while (html.Length < MinLookBack && textRange.Start.IsRightOf(blockRange.Start));

            if (html == null && textRange.Positioned && textRange.Start.IsLeftOfOrEqualTo(textRange.End))
            {
                html = MarkupHelpers.GetRangeTextFast(textRange);
            }

            return(html ?? string.Empty);
        }
Ejemplo n.º 6
0
 //remove any covered segments from the tracker and clear their highlights
 public void ClearRange(MarkupPointer start, MarkupPointer end)
 {
     IHighlightSegmentRaw[] segments =
         _tracker.GetSegments(start.PointerRaw, end.PointerRaw);
     if (segments != null)
     {
         for (int i = 0; i < segments.Length; i++)
         {
             _highlightRenderingServices.RemoveSegment(segments[i]);
         }
     }
 }
Ejemplo n.º 7
0
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            // get the live clipboard data
            LiveClipboardData lcData = DataMeister.LiveClipboardData;

            if (lcData == null)
            {
                Trace.Fail("Unexpected failure to get LC data!");
                return(false);
            }

            // lookup the content-source
            ContentSourceInfo contentSource =
                LiveClipboardManager.FindContentSourceForLiveClipboard(lcData.Formats);

            if (contentSource == null)
            {
                Trace.Fail("Unexpected failure to find content soure!");
                return(false);
            }

            using (new WaitCursor())
            {
                try
                {
                    // HACK: drive the selection textRange to the caret so we can call generic
                    // content-source routines that work off the current selection
                    // Note that we do the same thing below for Images so we can use the common
                    // InsertImages method -- we may want to bake this into core marshalling
                    // or add MarkupRange parameters to the image and content-source routines
                    EditorContext.MarkupServices.CreateMarkupRange(begin, end).ToTextRange().select();

                    if (contentSource.Instance is SmartContentSource)
                    {
                        return(InsertSmartContentFromLiveClipboard(contentSource, lcData.Document));
                    }
                    else if (contentSource.Instance is ContentSource)
                    {
                        return(InsertSimpleContentFromLiveClipboard(contentSource, lcData.Document));
                    }
                    else
                    {
                        Debug.Fail("Unexpected content source type: " + contentSource.GetType());
                        return(false);
                    }
                }
                catch (Exception ex)
                {
                    ContentSourceManager.DisplayContentRetreivalError(EditorContext.FrameWindow, ex, contentSource);
                    return(false);
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Notify the data format handler that data was dropped and should be inserted into
        /// the document at whatever insert location the handler has internally tracked.
        /// </summary>
        /// <param name="action"></param>
        public override bool DataDropped(DataAction action)
        {
            if (currentCaretLocation == null)
            {
                return(false);
            }

            // create two markup pointers that map to the location of the caret
            MarkupPointer begin = EditorContext.MarkupServices.CreateMarkupPointer();
            MarkupPointer end   = EditorContext.MarkupServices.CreateMarkupPointer();

            EditorContext.MarkupServices.MoveMarkupPointerToCaret(currentCaretLocation, begin);
            MarkupPointerMoveHelper.PerformImageBreakout(begin);

            //optimize the drop location to keep it from being in an unexpected location (fixes bug 395224)
            if (EditorContext.ShouldMoveDropLocationRight(begin))
            {
                begin.Right(true);
            }

            //synchronize the end pointer with the being pointer
            end.MoveToPointer(begin);

            MarkupRange selectedRange = EditorContext.SelectedMarkupRange;

            // WinLive 91888 Photomail image drag drop loses images
            //if (!selectedRange.IsEmpty() && selectedRange.InRange(end))
            if (!selectedRange.IsEmpty() && selectedRange.InRange(end, false))
            {
                //the drop location is over the drag source location, so don't so anything.
                return(false);
            }

            // Forces a SelectionChanged event so that the correct behaviors around the drop location are activated.
            // For example, one side effect of this call is that the OnEditableRegionFocusChanged event is fired, which
            // sets whether the current drop location in the canvas supports images, html and/or text.
            MarkupRange dropRange = EditorContext.MarkupServices.CreateMarkupRange(begin, end);

            dropRange.ToTextRange().select();

            try
            {
                // insert the data at the current insertion point
                return(InsertData(action, begin, end));
            }
            catch (Exception e)
            {
                Trace.Fail(e.Message, e.StackTrace);
                return(false);
            }
        }
Ejemplo n.º 9
0
        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;
                }
            }
        }
 /// <summary>
 /// Prepare the HTML selection to deal with keyboard navigation events.
 /// </summary>
 /// <param name="direction"></param>
 /// <param name="selectBlock"></param>
 private void PrepareForKeyboardNavigation(MarkupDirection direction, bool selectBlock)
 {
     if (direction == MarkupDirection.Left && selectBlock)
     {
         //HACK: make shift+Left keep the div selected by putting the selection at the
         //right-side of the div before the key event is handled.
         MarkupPointer caretPointer = EditorContext.MarkupServices.CreateMarkupPointer(HTMLElement, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
         EditorContext.MarkupServices.CreateMarkupRange(caretPointer, caretPointer).ToTextRange().select();
     }
     else
     {
         ElementRange.ToTextRange().select();
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Instruct the handler to insert data into the presentation editor
        /// </summary>
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            string imagePath = SaveImageDataToTempFile(DataMeister.ImageData);

            if (imagePath != null)
            {
                //hack: drive the selection textRange to the caret (before calling InsertImages)
                EditorContext.MarkupServices.CreateMarkupRange(begin, end).ToTextRange().select();

                _blogEditor.InsertImages(new string[] { imagePath }, ImageInsertEntryPoint.DragDrop);
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Grabs an HTML img copied in the clipboard and pastes it into the document.
        /// </summary>
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            using (new WaitCursor())
            {
                try
                {
                    HTMLData htmlData = DataMeister.HTMLData;
                    string   baseUrl  = UrlHelper.GetBaseUrl(htmlData.SourceURL);
                    string   html     = htmlData.HTMLSelection;

                    if (HtmlHandler.IsPasteFromSharedCanvas(DataMeister))
                    {
                        if (action == DataAction.Move)
                        {
                            // if we are dragging and dropping the image, we need to grow to find the anchor for an image
                            html = GrowToAnchorParent(htmlData);
                        }
                        else
                        {
                            // if we are copying and pasting an image from writer, we need to change temp path references the orginal file path
                            if (htmlData.OnlyImageElement != null)
                            {
                                // WinLive 96840 - Copying and pasting images within shared canvas should persist source
                                // decorator settings. "wlCopySrcUrl" is inserted while copy/pasting within canvas.
                                // Insert wlCopySrcUrl attribute
                                html = ImageCopyFixupHelper.FixupSourceUrlForCopy(html);
                            }
                            html = EditorContext.FixImageReferences(html, htmlData.SourceURL);
                        }
                    }
                    else
                    {
                        html = EditorContext.FixImageReferences(html, htmlData.SourceURL);
                        html = EditorContext.HtmlGenerationService.CleanupHtml(html, baseUrl, HtmlCleanupRule.Normal);
                    }

                    html = EditorContext.HtmlGenerationService.GenerateHtmlFromHtmlFragment(html, baseUrl);
                    EditorContext.InsertHtml(begin, end, html, DataMeister.HTMLData.SourceURL);

                    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);
                }
            }
        }
 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
     }
 }
        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);
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Wraps the range from startPointer to endPointer with the given element (as long as the range is non-empty)
        /// and then moves the pointers past the inserted element.
        /// </summary>
        /// <param name="element">The element to wrap the range in.</param>
        /// <param name="markupServices">The MarkupServices for the start and end pointers.</param>
        /// <param name="startPointer">Pointer to place the beginning of the element.</param>
        /// <param name="endPointer">Pointer to place the end of the element.</param>
        private void InsertElement(IHTMLElement element, MshtmlMarkupServices markupServices,
                                   MarkupPointer startPointer, MarkupPointer endPointer)
        {
            Debug.Assert(startPointer.IsLeftOfOrEqualTo(endPointer), "Expected start to be left of or equal to end!");
            Debug.Assert(HTMLElementHelper.ElementsAreEqual(startPointer.CurrentScope, endPointer.CurrentScope),
                         "Expected start and end to be in the same scope, otherwise resulting HTML will be invalid!");

            if (startPointer.IsLeftOf(endPointer))
            {
                markupServices.InsertElement(element, startPointer, endPointer);
            }

            endPointer.Right(true);
            startPointer.MoveToPointer(endPointer);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Searches through the provided document for a start and end comment marker and then returns the fragment as
        /// a MarkupRange.
        /// </summary>
        /// <param name="document">The document to search.</param>
        /// <param name="startMarker">The comment text that marks the start of the fragment
        /// (e.g. &lt;!--StartFragment--&gt; ).</param>
        /// <param name="endMarker">The comment text that marks the end of the fragment
        /// (e.g. &lt;!--EndFragment--&gt; ).</param>
        /// <returns>The fragment as a MarkupRange or null if no valid fragment was found.</returns>
        private MarkupRange FindMarkedFragment(IHTMLDocument2 document, string startMarker, string endMarker)
        {
            MarkupPointer        startFragment  = null;
            MarkupPointer        endFragment    = null;
            MshtmlMarkupServices markupServices = new MshtmlMarkupServices((IMarkupServicesRaw)document);

            // Look for the markers in the document.
            foreach (IHTMLElement element in document.all)
            {
                if (element is IHTMLCommentElement && ((IHTMLCommentElement)element).text == startMarker)
                {
                    startFragment = markupServices.CreateMarkupPointer(element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                }
                else if (element is IHTMLCommentElement && ((IHTMLCommentElement)element).text == endMarker)
                {
                    endFragment = markupServices.CreateMarkupPointer(element, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
                }
            }

            if (startFragment == null || endFragment == null || !startFragment.Positioned || !endFragment.Positioned ||
                startFragment.IsRightOf(endFragment))
            {
                Trace.WriteLine("Unable to find fragment or invalid fragment!");
                return(null);
            }

            // WinLive 251786: IE (and most other browsers) allow HTML like the following:
            //  <p>This is a paragraph[cursor]
            //  <p>This is a paragraph
            // However, when we use MarkupPointers to walk through this HTML, IE pretends there is a </p> at the end
            // of each of the above lines. This can cause issues when we copy part of this HTML somewhere else (e.g
            // everything after the [cursor]) and attempt to walk through both copies (e.g. during paste with keep
            // source formatting) at the same time. This holds true for some other elements, such as <li>s and <td>s.
            MarkupContext startContext = startFragment.Right(false);

            if (startFragment.IsLeftOf(endFragment) &&
                startContext.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_ExitScope &&
                startContext.Element != null &&
                ElementFilters.IsEndTagOptional(startContext.Element) &&
                !Regex.IsMatch(startContext.Element.outerHTML,
                               String.Format(CultureInfo.InvariantCulture, @"</{0}(\s[^>]*)?>\s*$", startContext.Element.tagName),
                               RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
            {
                startFragment.Right(true);
            }

            return(markupServices.CreateMarkupRange(startFragment, endFragment));
        }
        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);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Returns the markup pointer that is most deeply placed within the DOM.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        private MarkupPointer GetDeeperPoint(MarkupPointer p1, MarkupPointer p2)
        {
            IHTMLElement startElement     = p1.CurrentScope;
            IHTMLElement endElement       = p2.CurrentScope;
            int          startSourceIndex = startElement != null ? startElement.sourceIndex : -1;
            int          endSourceIndex   = startElement != null ? endElement.sourceIndex : -1;

            if (startSourceIndex > endSourceIndex || (startSourceIndex == endSourceIndex && p1.IsRightOfOrEqualTo(p2)))
            {
                return(p1);
            }
            else
            {
                return(p2);
            }
        }
Ejemplo n.º 19
0
        protected bool DoInsertDataCore(List <string> files, DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            IHtmlEditorHost       blogEditor            = _blogEditor;
            ImageInsertEntryPoint imageInsertEntryPoint = ImageInsertEntryPoint;

            EditorContext.Invoke(delegate
            {
                //hack: drive the selection textRange to the caret (before calling InsertImages)
                EditorContext.MarkupServices.CreateMarkupRange(begin, end).ToTextRange().select();

                string[] fileArray = files.ToArray();
                blogEditor.InsertImages(fileArray, ImageInsertEntryPoint.DragDrop);
            });

            return(true);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Returns the markup pointer to the position of the first exit scope of type tagId or type terminatingTagId which follows this markup range.
        /// Returns null if text exists between the range and such an exit scope, or if there is no such exit scope.
        /// </summary>
        /// <param name="terminatingTagId"></param>
        /// <returns></returns>
        internal MarkupPointer NextExitScopeWithoutInterveningText(MarkupRange selection, _ELEMENT_TAG_ID tagId, _ELEMENT_TAG_ID terminatingTagId, out bool primaryTagIdMatch)
        {
            MarkupContext context = new MarkupContext();

            MarkupPointer pointer = selection.End.Clone();

            primaryTagIdMatch = false;

            while (true)
            {
                pointer.Right(true, context);
                if (context.Element == null)
                {
                    return(null);
                }

                switch (context.Context)
                {
                case _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_None:
                    return(null);

                case _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_ExitScope:
                {
                    if (_markupServices.GetElementTagId(context.Element) == tagId)
                    {
                        primaryTagIdMatch = true;
                        return(pointer);
                    }

                    if (terminatingTagId != _ELEMENT_TAG_ID.TAGID_NULL && terminatingTagId == _markupServices.GetElementTagId(context.Element))
                    {
                        return(pointer);
                    }
                }

                break;

                case _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope:
                case _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_NoScope:
                    break;

                case _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_Text:
                    return(null);
                }
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Returns true if there is text to the right of the current position.
        /// </summary>
        /// <returns></returns>
        protected bool hasTextRight(MarkupPointer pointer)
        {
            MarkupPointer start = pointer;
            MarkupPointer end   = ElementRange.End;

            IHTMLTxtRange textRange = EditorContext.MarkupServices.CreateTextRange(start, end);
            string        text      = textRange.text;

            if (text == null || text.Trim().Equals(String.Empty))
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Ejemplo n.º 22
0
        private IHTMLElement CreateNodeForCentering()
        {
            // Create markup services using the element's document that we are analyzing
            MshtmlMarkupServices MarkupServices = new MshtmlMarkupServices(_element.document as IMarkupServicesRaw);
            MarkupPointer        end            = MarkupServices.CreateMarkupPointer();
            MarkupPointer        start          = MarkupServices.CreateMarkupPointer();

            // Find the element that we will want to wrap.
            IHTMLElement elementToEncapsulate = _element;

            // If the elements parent is an A, we will also want to
            // wrap the A and not just the image inside
            if (_element.parentElement.tagName == "A")
            {
                elementToEncapsulate = _element.parentElement;
            }

            // Move the starting pointer to before the begining of the element we want to wrap
            start.MoveAdjacentToElement(elementToEncapsulate, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);

            // Find this elements parent
            IHTMLElement3 currentBlockScope = start.CurrentBlockScope() as IHTMLElement3;

            // If its parent is also the div that is around the post
            // we need to actually create a new div and just put it around the element

            // If it is splittable block, split it
            // e.g "<DIV>Blah<IMG/>Blah</DIV>" => "<DIV>Blah</DIV><DIV><IMG/></DIV><DIV>Blah</DIV>"
            if (!IsBodyElement(currentBlockScope))
            {
                // We are in a block that can be split so split it at the begining and end
                MarkupHelpers.SplitBlockForInsertionOrBreakout(MarkupServices, null, start);
                end.MoveAdjacentToElement(elementToEncapsulate, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                MarkupHelpers.SplitBlockForInsertionOrBreakout(MarkupServices, null, end);

                // Position start back to the beginning of our element
                start.MoveAdjacentToElement(elementToEncapsulate, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
            }

            // Now we can wrap it in an P tag (centering node)
            end.MoveAdjacentToElement(elementToEncapsulate, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
            IHTMLElement centeringElement = MarkupServices.CreateElement(_ELEMENT_TAG_ID.TAGID_P, string.Empty);

            MarkupServices.InsertElement(centeringElement, start, end);
            return(centeringElement);
        }
Ejemplo n.º 23
0
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            // get the list of files from the data meister
            FileItem[] files = DataMeister.FileData.Files;

            List <string> filePaths = new List <string>(DataMeister.FileData.Files.Length);

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

            return(DoInsertDataCore(filePaths, action, begin, end));
        }
 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
     }
 }
        private void HandleEnterKey(HtmlEventArgs e)
        {
            //pressing the enter key on an empty line is used as a gesture for exiting the blockquote
            //If this situation is encountered, move the current empty block element outside of the blockquote
            MarkupRange selection = EditorContext.Selection.SelectedMarkupRange;

            if (selection.IsEmpty())
            {
                MarkupPointer selectionPoint = EditorContext.MarkupServices.CreateMarkupPointer(selection.Start);
                selectionPoint.Cling = true;

                IHTMLElement currBlock      = selection.Start.CurrentBlockScope();
                MarkupRange  currBlockRange = EditorContext.MarkupServices.CreateMarkupRange(currBlock, false);
                if (currBlockRange.IsEmptyOfContent())
                {
                    currBlockRange.MoveToElement(currBlock, true);

                    // Make sure there is no content between the end of this block range and the end of the blockquote.
                    MarkupPointer afterEndCurrBlock   = EditorContext.MarkupServices.CreateMarkupPointer(currBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                    MarkupPointer beforeEndBlockQuote = EditorContext.MarkupServices.CreateMarkupPointer(HTMLElement, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeEnd);
                    MarkupRange   restOfBlockQuote    = EditorContext.MarkupServices.CreateMarkupRange(afterEndCurrBlock, beforeEndBlockQuote);
                    if (!restOfBlockQuote.IsEmpty() || !restOfBlockQuote.IsEmptyOfContent())
                    {
                        return;
                    }

                    //create a pointer for the new location that the block element will be moved to.
                    MarkupPointer insertionPoint =
                        EditorContext.MarkupServices.CreateMarkupPointer(HTMLElement, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);

                    //move the current empty block to the DOM location after the blockquote
                    EditorContext.MarkupServices.Move(currBlockRange.Start, currBlockRange.End, insertionPoint);
                    currBlockRange.MoveToElement(currBlock, false);

                    //adjust the selection to the new location of the block element.
                    currBlockRange.Start.MoveToPointer(selectionPoint);
                    currBlockRange.End.MoveToPointer(selectionPoint);
                    currBlockRange.ToTextRange().select();

                    //cancel the key down event so that the editor doesn't try to handle it
                    e.Cancel();
                }
            }
        }
        /// <summary>
        /// Disambiguates a set of title regions to determine which should be editable based on proximity to the main post body element.
        /// </summary>
        /// <param name="bodyElement"></param>
        /// <param name="doc"></param>
        /// <param name="titleElements"></param>
        /// <returns>The title region in closest proximity to the post body element.</returns>
        protected static IHTMLElement GetPrimaryEditableTitleElement(IHTMLElement bodyElement, IHTMLDocument doc, IHTMLElement[] titleElements)
        {
            IHTMLDocument2 doc2         = (IHTMLDocument2)doc;
            IHTMLElement   titleElement = titleElements[0];

            if (titleElements.Length > 1)
            {
                try
                {
                    MshtmlMarkupServices markupServices = new MshtmlMarkupServices((IMarkupServicesRaw)doc2);
                    MarkupRange          bodyRange      = markupServices.CreateMarkupRange(bodyElement, true);
                    MarkupPointer        titlePointer   = null;
                    MarkupPointer        tempPointer    = markupServices.CreateMarkupPointer();
                    foreach (IHTMLElement title in titleElements)
                    {
                        tempPointer.MoveAdjacentToElement(title, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
                        if (titlePointer == null)
                        {
                            titlePointer = markupServices.CreateMarkupPointer(title, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
                        }
                        else
                        {
                            tempPointer.MoveAdjacentToElement(title, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
                            if (tempPointer.IsLeftOf(bodyRange.End) && tempPointer.IsRightOf(titlePointer))
                            {
                                //the temp pointer is closer to the body element, so assume it is more appropriate
                                //to use as the title.
                                titleElement = title;
                                titlePointer.MoveToPointer(tempPointer);
                            }
                        }
                    }
                }
                catch (COMException ex)
                {
                    Trace.WriteLine("Failed to differentiate between multiple nodes with title text, using the first node.  Exception: " + ex);
                }
                catch (InvalidCastException ex)
                {
                    Trace.WriteLine("Failed to differentiate between multiple nodes with title text, using the first node.  Exception: " + ex);
                }
            }
            return(titleElement);
        }
Ejemplo n.º 27
0
        protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end)
        {
            //hack: drive the selection textRange to the caret (before calling InsertImages)
            EditorContext.MarkupServices.CreateMarkupRange(begin, end).ToTextRange().select();

            List <string> files = new List <string>();

            DirectoryLister lister = new DirectoryLister(DataMeister.FileData.Files[0].ContentsPath, false, true);

            foreach (string file in lister.GetFiles())
            {
                if (PathHelper.IsPathImage(file))
                {
                    files.Add(Path.Combine(lister.RootPath, file));
                }
            }

            return(DoInsertDataCore(files, action, begin, end));
        }
        /// <summary>
        /// Returns true if a word range is in this list that contains this markup pointer.
        /// </summary>
        public bool Contains(MarkupPointer p)
        {
            if (words.Count == 0)
            {
                return(false);
            }

            // Just being defensive
            if (!p.Positioned)
            {
                return(false);
            }

            int idx = BinarySearch(words.Keys, p.PointerRaw, new MarkupPointerComparer());

            if (idx >= 0)
            {
                return(true);
            }

            idx = ~idx;

            // really this could be "if (idx == words.Count)"--it's to handle the case
            // where p is larger than the values in the list
            while (idx >= words.Count)
            {
                idx--;
            }

            for (; idx >= 0; idx--)
            {
                MarkupRange wordRange = words.Values[idx];
                if (wordRange.InRange(p))
                {
                    return(true);
                }
                if (wordRange.End.IsLeftOf(p))
                {
                    break;
                }
            }
            return(false);
        }
Ejemplo n.º 29
0
        //iterates through a word range checking for spelling errors
        //return: whether the word range is finished (true) or not
        private bool ProcessWordRange(MshtmlWordRange wordRange)
        {
            if (wordRange.CurrentWordRange.Positioned)
            {
                //track where we will need to clear;
                MarkupPointer start = _markupServices.CreateMarkupPointer();
                start.MoveToPointer(wordRange.CurrentWordRange.End);
                ArrayList highlightwords = new ArrayList(NUMBER_OF_WORDS_TO_CHECK);

                int i = 0;
                //to do....the word range is losing its place when it stays in the queue
                while (wordRange.HasNext() && i < NUMBER_OF_WORDS_TO_CHECK)
                {
                    // advance to the next word
                    wordRange.Next();
                    // check the spelling
                    int offset, length;
                    if (ProcessWord(wordRange, out offset, out length))
                    {
                        MarkupRange highlightRange = wordRange.CurrentWordRange.Clone();
                        MarkupHelpers.AdjustMarkupRange(ref stagingTextRange, highlightRange, offset, length);

                        //note: cannot just push the current word range here, as it moves before we get to the highlighting step
                        highlightwords.Add(highlightRange);
                    }
                    i++;
                }
                MarkupPointer end = wordRange.CurrentWordRange.End;

                //got our words, clear the checked range and then add the misspellings
                ClearRange(start, end);
                foreach (MarkupRange word in highlightwords)
                {
                    HighlightWordRange(word);
                }

                return(!wordRange.HasNext());
            }
            else
            {
                return(true);
            }
        }
Ejemplo n.º 30
0
        /// <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;
            }
        }
Ejemplo n.º 31
0
 /// <summary>
 /// Create a TextRange that spans a set of pointers.
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end"></param>
 /// <returns></returns>
 public IHTMLTxtRange CreateTextRange(MarkupPointer start, MarkupPointer end)
 {
     Debug.Assert(start.Positioned && end.Positioned, "pointers are not positioned");
     IHTMLTxtRange range = start.Container.CreateTextRange(start, end);
     return range;
 }
Ejemplo n.º 32
0
 /// <summary>
 /// Positions pointers at the edges of an existing range.
 /// </summary>
 /// <param name="start">the pointer positioned at the start of the range</param>
 /// <param name="end">the pointer position at the end of the range</param>
 /// <param name="range">the text range to move</param>
 public void MoveRangeToPointers(MarkupPointer start, MarkupPointer end, IHTMLTxtRange range)
 {
     MarkupServices.MoveRangeToPointers(start.PointerRaw, end.PointerRaw, range);
 }
Ejemplo n.º 33
0
 /// <summary>
 /// Creates an instance of the IMarkupPointer object with an initial position
 /// at the same location as another pointer.
 /// </summary>
 /// <param name="initialPosition"></param>
 /// <returns></returns>
 public MarkupPointer CreateMarkupPointer(MarkupPointer initialPosition)
 {
     MarkupPointer pointer = CreateMarkupPointer();
     pointer.MoveToPointer(initialPosition);
     return pointer;
 }
Ejemplo n.º 34
0
 /// <summary>
 /// Positions pointers at the edges of an existing range.
 /// </summary>
 /// <param name="range">the text range to move to</param>
 /// <param name="start">the pointer to position at the start of the range</param>
 /// <param name="end">the pointer to position at the end of the range</param>
 public void MovePointersToRange(IHTMLTxtRange range, MarkupPointer start, MarkupPointer end)
 {
     MarkupServices.MovePointersToRange(range, start.PointerRaw, end.PointerRaw);
 }
Ejemplo n.º 35
0
 /// <summary>
 /// Create a MarkupRange from a set of MarkupPointers.
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end"></param>
 /// <returns></returns>
 public MarkupRange CreateMarkupRange(MarkupPointer start, MarkupPointer end)
 {
     MarkupRange markupRange = new MarkupRange(start, end, this);
     return markupRange;
 }