public static void InsertEditorHtmlIntoElement(IContentSourceSidebarContext contentSourceContext, SmartContentSource source, ISmartContent sContent, IHTMLElement element)
        {
            string content = source.GenerateEditorHtml(sContent, contentSourceContext);

            // If the plugin returned null has the HTML it would like to insert, remove the element from the editor
            if (content == null)
            {
                HTMLElementHelper.RemoveElement(element);
            }
            else
            {
                InsertContentIntoElement(content, sContent, contentSourceContext, element);
            }
        }
Beispiel #2
0
        private static void ProcessInitializedImages(List <NewImageInfo> newImages, IBlogPostHtmlEditor currentEditor, ContentEditor editor, Control owner, bool selectLastImage)
        {
            // Remove all invalid images first
            List <NewImageInfo> newImagesToUpdate = new List <NewImageInfo>();

            for (int i = 0; i < newImages.Count; i++)
            {
                NewImageInfo info = newImages[i];

                if (info.Remove)
                {
                    using (ContentEditor.EditorUndoUnit undo = new ContentEditor.EditorUndoUnit(currentEditor, true))
                    {
                        info.DisabledImageBehavior.DetachFromElement();
                        HTMLElementHelper.RemoveElement(info.Element);
                        undo.Commit();
                    }
                }
                else
                {
                    newImagesToUpdate.Add(info);
                }
            }

            // Queue up processing for any remaining valid images
            MultiTaskHelper tasks = new MultiTaskHelper(30);

            for (int i = 0; i < newImagesToUpdate.Count; i++)
            {
                bool         lastElement = i == (newImagesToUpdate.Count - 1);
                NewImageInfo info        = newImagesToUpdate[i];

                tasks.AddWork(delegate
                {
                    // WinLive 214012: If the original insertion operation is undone before we get to this point make
                    // sure we don't attempt to update the HTML. Elements that are removed via an undo, but that we
                    // still hold a reference to, are put into another document whose readyState is "uninitialized".
                    // It's also possible that the picture has already been updated if a user undoes and redoes the
                    // initial insertion multiple times.
                    IHTMLDocument2 doc = (IHTMLDocument2)info.Element.document;
                    if (doc == null || doc.readyState.Equals("uninitialized", StringComparison.OrdinalIgnoreCase) ||
                        BlogPostImageDataList.LookupImageDataByInlineUri(editor.ImageList, info.ImageData.InlineImageFile.Uri) != null)
                    {
                        info.DisabledImageBehavior.DetachFromElement();
                        return;
                    }

                    using (new QuickTimer("ProcessInitializedImage"))
                        using (ContentEditor.EditorUndoUnit undo = new ContentEditor.EditorUndoUnit(currentEditor, true))
                        {
                            editor.ImageList.AddImage(info.ImageData);

                            info.Element.setAttribute("src", UrlHelper.SafeToAbsoluteUri(info.ImageData.InlineImageFile.Uri), 0);
                            info.Element.removeAttribute("srcDelay", 0);
                            // Create the decorators
                            ImageEditingPropertyHandler.UpdateImageSource(info.ImageInfo, info.Element, editor, new ImageInsertHandler(), ImageDecoratorInvocationSource.InitialInsert);

                            // Manually detach the behavior so that the image can be selected and resized.
                            info.DisabledImageBehavior.DetachFromElement();

                            if (lastElement)
                            {
                                ApplicationPerformance.EndEvent("InsertImage");
                                HandleNewImage((BlogPostHtmlEditorControl)currentEditor, owner, info.Element, selectLastImage);
                            }

                            undo.Commit();

                            if (editor.ETWProvider != null)
                            {
                                editor.ETWProvider.WriteEvent("InlinePhotoEnd");
                            }
                        }
                });
            }

            // If there were no images to update, stop the perf timer
            if (newImagesToUpdate.Count == 0)
            {
                ApplicationPerformance.EndEvent("InsertImage");
            }

            // When the editor is closing, or changing to a new blog post we need to get rid of this object
            // which will then stop all the unfinished images from continuing to load.
            editor.DisposeOnEditorChange(tasks);
            tasks.Start();
        }
Beispiel #3
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);
        }