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  . MarkupRange range = MarkupServices.CreateMarkupRange(start, end); IHTMLTxtRange txtRange = range.ToTextRange(); txtRange.text = text; } undo.Commit(); } }
protected virtual void InsertHtml(MarkupPointer start, MarkupPointer end, string html, string sourceUrl, bool allowBlockBreakout) { MarkupRange range = MarkupServices.CreateMarkupRange(start, end); if (!IsValidContentInsertionPoint(range)) { DisplayMessage.Show(MessageId.InvalidInsertionPoint); return; } Trace.Assert(start.Positioned && end.Positioned, string.Format(CultureInfo.InvariantCulture, "Invalid pointer being used for insert. start:({0}),end:({1})", start.Positioned, end.Positioned)); // begin undo unit IUndoUnit undoUnit = CreateUndoUnit(); start.PushCling(true); end.PushCling(true); using (undoUnit) { // Any changes to the way we remove the content in the destination may need to be changed in // KeepSourceFormatting.PasteSourceOverDestination as well! MarkupPointerMoveHelper.PerformImageBreakout(start); MarkupPointerMoveHelper.PerformImageBreakout(end); //if the start and endpoints are not equal, then we need to paste over the selection //so delete the selected region (which will collapse the pointers to now be equal. if (!start.IsEqualTo(end)) { //delete the selected content if (ContentIsDeletableForInsert(start, end)) { // CT: There is currently a case where we leave empty blocks behind // see bug 628054. This happens when the start and end markup pointers don't completely // contain the selected blocks, like: <p>|line1</p><p>line2|</p>. In this case, calling // deleteNoContentNoClient will leave you with <p>|</p><p>|</p>. The next line collapses // the end pointer back to the start point since that is where selection started. DeleteContentNoCling(start, end); end.MoveToPointer(start); } } if (!string.IsNullOrEmpty(html)) { //Note: we use MarkupServices to insert the content so that IE doesn't try to fix up URLs. //Element.insertAdjacentHTML() is a no-no because it rewrites relaive URLs to include //the fullpath from the local filesytem. //MarkupServices.ParseString() doesn't attempt to fix up URLs, so its safe to use. //We will now stage the new content into a MarkupContainer, and then move it into //the working document. MarkupPointer sc1 = MarkupServices.CreateMarkupPointer(); MarkupPointer sc2 = MarkupServices.CreateMarkupPointer(); // Do the work ahead of time to get an <p></P> ready to be inserted // doing this work after the insert this html was called with sometimes // causes mshtml to not paint things until they are moused over(embeds) // BUG: 624122, 622715 MarkupPointer mpStart = MarkupServices.CreateMarkupPointer(); MarkupPointer mpEnd = MarkupServices.CreateMarkupPointer(); // Make a temp document and load our ending html into it. MarkupServices.ParseString(CONTENT_BODY_PADDING, mpStart, mpEnd); //Create a temporary document from the html and set the start/end pointers to the //start and end of the document. MarkupServices.ParseString(html, sc1, sc2); IHTMLDocument2 doc = sc1.GetDocument(); MarkupRange stagingRange = MarkupServices.CreateMarkupRange(sc1, sc2); stagingRange.MoveToElement(doc.body, false); // We only need to insert the ending new line if there was a div or image added bool allowNewLineInsert = ShouldAllowNewLineInsert(html); Trace.Assert(stagingRange.Positioned && stagingRange.Start.Positioned && stagingRange.End.Positioned && sc1.Positioned && sc2.Positioned, String.Format(CultureInfo.InvariantCulture, "Staging document is not ready. stagingRange:({0}),stagingRange.Start:({1}),stagingRange.End:({2}),sc1:({3}),sc2:({4})", stagingRange.Positioned, stagingRange.Start.Positioned, stagingRange.End.Positioned, sc1.Positioned, sc2.Positioned)); try { // Any changes to the way we remove the content in the destination may need to be changed in // KeepSourceFormatting.PasteSourceOverDestination as well! bool emptyBlockRemoved; if (stagingRange.ContainsElements(ElementFilters.IsBlockOrTableElement)) { // if the destination is an empty block element then just overwrite it emptyBlockRemoved = OverwriteDestinationBlockIfEmpty(start, PrimaryEditableBounds); if (!emptyBlockRemoved && allowBlockBreakout) { // otherwise split the destination block or move outside of the block MarkupHelpers.SplitBlockForInsertionOrBreakout(MarkupServices, PrimaryEditableBounds, start); } end.MoveToPointer(start); } } catch (COMException ex) { Trace.WriteLine(String.Format(CultureInfo.InvariantCulture, "RemoveBlockOrTableElement Failed ({0},{1},{2},{4}): {3}", stagingRange.Start.Positioned, stagingRange.End.Positioned, end.Positioned, ex, start.Positioned)); throw; } InflateEmptyParagraphs(stagingRange); FixUpStickyBrs(stagingRange); if (HTMLDocumentHelper.IsQuirksMode(HTMLDocument)) { ForceTablesToInheritFontColor(stagingRange); } Trace.Assert(stagingRange.Positioned && stagingRange.Start.Positioned && stagingRange.End.Positioned && sc1.Positioned && sc2.Positioned, String.Format(CultureInfo.InvariantCulture, "Staging document corrupt after RemoveBlockOrTableElement. stagingRange:({0}),stagingRange.Start:({1}),stagingRange.End:({2}),sc1:({3}),sc2:({4})", stagingRange.Positioned, stagingRange.Start.Positioned, stagingRange.End.Positioned, sc1.Positioned, sc2.Positioned)); IDisposable damageTracker = null; try { damageTracker = CreateDamageTracking(end, true); } catch (COMException ex) { Trace.WriteLine(String.Format(CultureInfo.InvariantCulture, "CreateDamageTracking Failed ({0}): {1}", end.Positioned, ex)); throw; } Trace.Assert(stagingRange.Positioned && stagingRange.Start.Positioned && stagingRange.End.Positioned && sc1.Positioned && sc2.Positioned, String.Format(CultureInfo.InvariantCulture, "Staging document corrupt after CreateDamageTracking. stagingRange:({0}),stagingRange.Start:({1}),stagingRange.End:({2}),sc1:({3}),sc2:({4})", stagingRange.Positioned, stagingRange.Start.Positioned, stagingRange.End.Positioned, sc1.Positioned, sc2.Positioned)); using (damageTracker) { // CT: Because we don't set gravity, these pointers can end up in indeterminant positions. // For example, when inserting HTML over a selection inside of a block, the start // pointer can end up on the right side of the end pointer. Pushing gravity onto // the pointers before we call this should provide consistent markup pointer behavior. try { start.PushGravity(_POINTER_GRAVITY.POINTER_GRAVITY_Left); end.PushGravity(_POINTER_GRAVITY.POINTER_GRAVITY_Right); Trace.Assert(stagingRange.Positioned && stagingRange.Start.Positioned && stagingRange.End.Positioned && sc1.Positioned && sc2.Positioned, String.Format(CultureInfo.InvariantCulture, "Staging document corrupt after applying gravity. stagingRange:({0}),stagingRange.Start:({1}),stagingRange.End:({2}),sc1:({3}),sc2:({4})", stagingRange.Positioned, stagingRange.Start.Positioned, stagingRange.End.Positioned, sc1.Positioned, sc2.Positioned)); try { MarkupServices.Move(stagingRange.Start, stagingRange.End, end); } catch (COMException ex) { Trace.WriteLine( String.Format(CultureInfo.InvariantCulture, "MarkupServices.Move Failed ({0},{1},{2}): {3}", stagingRange.Start.Positioned, stagingRange.End.Positioned, end.Positioned, ex)); throw; } } finally { end.PopGravity(); start.PopGravity(); } if (allowNewLineInsert && TidyWhitespace) { try { EnsureNewLineAtDocEnd(mpStart, mpEnd); } catch (Exception ex) { Trace.WriteLine("Failed to insert new line at end of document: " + ex); } } } } // note that we have completed our edit undoUnit.Commit(); start.PopCling(); end.PopCling(); } }