Ejemplo n.º 1
0
        /// <summary>
        /// Takes the source HTML and makes necessary modifications to keep the source formatting as if it were to be
        /// pasted into the destination range.
        /// </summary>
        /// <param name="sourceRange">The range containing the HTML that is being copied.</param>
        /// <param name="destinationRange">The range that the source HTML will be copied to.</param>
        /// <returns>A serialized string of the source HTML with necessary modifications to keep the source formatting
        /// or null if unsuccessful.</returns>
        private string KeepSourceFormatting(MarkupRange sourceRange, MarkupRange destinationRange)
        {
            Debug.Assert(sourceRange.Start.Container.GetOwningDoc() == destinationRange.Start.Container.GetOwningDoc(),
                "Ranges must share an owning document!");

            // We will temporarily add comments to the destination document to mark the destinationRange.
            IHTMLElement startComment = null;
            IHTMLElement endComment = null;

            try
            {
                // This is our true destination document.
                IHTMLDocument2 destinationDocument = destinationRange.Start.Container.Document;
                MshtmlMarkupServices destinationMarkupServices = new MshtmlMarkupServices((IMarkupServicesRaw)destinationDocument);

                // However, we'll use a temp destination because we don't want to paste anything into the real
                // document yet as it could fail, it would fire events, images would start loading, etc.
                MarkupContainer temporaryDestinationContainer = destinationMarkupServices.CreateMarkupContainer();
                MarkupPointer temporaryDestinationPointer = destinationMarkupServices.CreateMarkupPointer();
                temporaryDestinationPointer.MoveToContainer(temporaryDestinationContainer, true);

                // We add in comments to the destination document so that when we copy this range over to the fake
                // destination we'll be able to find the range again.
                destinationRange.Start.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Left;
                destinationRange.End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right;

                string startMarker = string.Format(CultureInfo.InvariantCulture, "<!--{0}-->", Guid.NewGuid());
                destinationMarkupServices.InsertHtml(startMarker, destinationRange.Start);
                startComment = destinationRange.Start.Right(false).Element;

                string endMarker = string.Format(CultureInfo.InvariantCulture, "<!--{0}-->", Guid.NewGuid());
                destinationMarkupServices.InsertHtml(endMarker, destinationRange.End);
                endComment = destinationRange.End.Left(false).Element;

                try
                {
                    // Copy over the entire destination document into the fake destination document.
                    MarkupRange destinationAll = SelectAll(destinationDocument);
                    destinationMarkupServices.Copy(destinationAll.Start, destinationAll.End, temporaryDestinationPointer);

                    // Find the original destination range in this copy.
                    MarkupRange temporaryDestinationRange = FindMarkedFragment(temporaryDestinationContainer.Document, startMarker, endMarker);

                    if (temporaryDestinationRange != null)
                    {
                        // Do the work to keep the source formatting.
                        MarkupRange inlinedRange = new KeepSourceFormatting(sourceRange, temporaryDestinationRange).Execute();
                        if (inlinedRange != null)
                        {
                            return inlinedRange.HtmlText;
                        }
                    }
                }
                finally
                {
                    // WinLive 249077: Clear the temporary destination container, otherwise behaviors may
                    // inadvertently attach to elements in the MarkupContainer.
                    temporaryDestinationContainer.Document.body.innerHTML = String.Empty;
                }
            }
            catch (Exception e)
            {
                // I really dont want some funky html on the clipboard that causes a problem with this code
                // to prevent a paste from going through.
                Trace.Fail("Failed to get inline css for selection: " + e);
            }
            finally
            {
                Debug.Assert(startComment is IHTMLCommentElement, "Didn't find start comment or it wasn't created.");
                if (startComment is IHTMLCommentElement)
                {
                    HTMLElementHelper.RemoveElement(startComment);
                }

                Debug.Assert(endComment is IHTMLCommentElement, "Didn't find end comment or it wasn't created.");
                if (endComment is IHTMLCommentElement)
                {
                    HTMLElementHelper.RemoveElement(endComment);
                }
            }

            return null;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Takes the source HTML and makes necessary modifications to keep the source formatting as if it were to be
        /// pasted into the destination range.
        /// </summary>
        /// <param name="sourceRange">The range containing the HTML that is being copied.</param>
        /// <param name="destinationRange">The range that the source HTML will be copied to.</param>
        /// <returns>A serialized string of the source HTML with necessary modifications to keep the source formatting
        /// or null if unsuccessful.</returns>
        private string KeepSourceFormatting(MarkupRange sourceRange, MarkupRange destinationRange)
        {
            Debug.Assert(sourceRange.Start.Container.GetOwningDoc() == destinationRange.Start.Container.GetOwningDoc(),
                         "Ranges must share an owning document!");

            // We will temporarily add comments to the destination document to mark the destinationRange.
            IHTMLElement startComment = null;
            IHTMLElement endComment   = null;

            try
            {
                // This is our true destination document.
                IHTMLDocument2       destinationDocument       = destinationRange.Start.Container.Document;
                MshtmlMarkupServices destinationMarkupServices = new MshtmlMarkupServices((IMarkupServicesRaw)destinationDocument);

                // However, we'll use a temp destination because we don't want to paste anything into the real
                // document yet as it could fail, it would fire events, images would start loading, etc.
                MarkupContainer temporaryDestinationContainer = destinationMarkupServices.CreateMarkupContainer();
                MarkupPointer   temporaryDestinationPointer   = destinationMarkupServices.CreateMarkupPointer();
                temporaryDestinationPointer.MoveToContainer(temporaryDestinationContainer, true);

                // We add in comments to the destination document so that when we copy this range over to the fake
                // destination we'll be able to find the range again.
                destinationRange.Start.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Left;
                destinationRange.End.Gravity   = _POINTER_GRAVITY.POINTER_GRAVITY_Right;

                string startMarker = string.Format(CultureInfo.InvariantCulture, "<!--{0}-->", Guid.NewGuid());
                destinationMarkupServices.InsertHtml(startMarker, destinationRange.Start);
                startComment = destinationRange.Start.Right(false).Element;

                string endMarker = string.Format(CultureInfo.InvariantCulture, "<!--{0}-->", Guid.NewGuid());
                destinationMarkupServices.InsertHtml(endMarker, destinationRange.End);
                endComment = destinationRange.End.Left(false).Element;

                try
                {
                    // Copy over the entire destination document into the fake destination document.
                    MarkupRange destinationAll = SelectAll(destinationDocument);
                    destinationMarkupServices.Copy(destinationAll.Start, destinationAll.End, temporaryDestinationPointer);

                    // Find the original destination range in this copy.
                    MarkupRange temporaryDestinationRange = FindMarkedFragment(temporaryDestinationContainer.Document, startMarker, endMarker);

                    if (temporaryDestinationRange != null)
                    {
                        // Do the work to keep the source formatting.
                        MarkupRange inlinedRange = new KeepSourceFormatting(sourceRange, temporaryDestinationRange).Execute();
                        if (inlinedRange != null)
                        {
                            return(inlinedRange.HtmlText);
                        }
                    }
                }
                finally
                {
                    // WinLive 249077: Clear the temporary destination container, otherwise behaviors may
                    // inadvertently attach to elements in the MarkupContainer.
                    temporaryDestinationContainer.Document.body.innerHTML = String.Empty;
                }
            }
            catch (Exception e)
            {
                // I really dont want some funky html on the clipboard that causes a problem with this code
                // to prevent a paste from going through.
                Trace.Fail("Failed to get inline css for selection: " + e);
            }
            finally
            {
                Debug.Assert(startComment is IHTMLCommentElement, "Didn't find start comment or it wasn't created.");
                if (startComment is IHTMLCommentElement)
                {
                    HTMLElementHelper.RemoveElement(startComment);
                }

                Debug.Assert(endComment is IHTMLCommentElement, "Didn't find end comment or it wasn't created.");
                if (endComment is IHTMLCommentElement)
                {
                    HTMLElementHelper.RemoveElement(endComment);
                }
            }

            return(null);
        }