/// <summary> /// Inserts the extended entry break into the editor. /// </summary> internal void InsertExtendedEntryBreak() { IHTMLDocument3 doc3 = (IHTMLDocument3)HTMLElement.document; IHTMLElement2 entryBreak = (IHTMLElement2)doc3.getElementById(EXTENDED_ENTRY_ID); if (entryBreak == null) { using (IUndoUnit undo = EditorContext.CreateUndoUnit()) { using (EditorContext.DamageServices.CreateDamageTracker(ElementRange.Clone(), true)) { MarkupPointer insertionPoint = EditorContext.MarkupServices.CreateMarkupPointer(EditorContext.Selection.SelectedMarkupRange.Start); //delete the parent block element of the insertion point if it is empty (bug 421500) DeleteInsertionTargetBlockIfEmpty(insertionPoint); IHTMLElement extendedEntryBreak = InsertExtendedEntryBreak(insertionPoint); //reselect the insertion point MarkupRange selection = EditorContext.MarkupServices.CreateMarkupRange(); insertionPoint.MoveAdjacentToElement(extendedEntryBreak, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd); MarkupPointerMoveHelper.MoveUnitBounded( insertionPoint, MarkupPointerMoveHelper.MoveDirection.RIGHT, MarkupPointerAdjacency.AfterEnterBlock | MarkupPointerAdjacency.BeforeText , HTMLElement); selection.Start.MoveToPointer(insertionPoint); selection.End.MoveToPointer(insertionPoint); selection.ToTextRange().select(); } undo.Commit(); } } }
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); }
/// <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); } }
private MarkupRange AdjustSelection() { MarkupRange selection = CreateMaxSafeRange(SelectedMarkupRange); if (selection.IsEmpty()) { MarkupRange editableRange = MarkupHelpers.GetEditableRange(selection.Start.CurrentScope, MarkupServices); MarkupPointerMoveHelper.MoveUnitBounded(selection.Start, MarkupPointerMoveHelper.MoveDirection.LEFT, MarkupPointerAdjacency.BeforeVisible | MarkupPointerAdjacency.BeforeEnterScope, editableRange.Start); selection.Collapse(true); } selection.ToTextRange().select(); return(selection); }
/// <summary> /// Fixes up a range that is contained in a single header element. /// </summary> /// <param name="range">A range that is contained in a single header element.</param> /// <param name="turnBold">Whether or not the text should be turning bold.</param> private void FixupHeaderRange(MarkupRange range, bool turnBold) { IHTMLElement parentHeaderElement = range.ParentBlockElement(); if (parentHeaderElement == null || !ElementFilters.IsHeaderElement(parentHeaderElement)) { Debug.Fail("Expected entire range to be inside a single header element."); return; } MarkupRange expandedRange = range.Clone(); // Make sure we expand the selection to include any <font> tags that may be wrapping us. MarkupPointerMoveHelper.MoveUnitBounded(expandedRange.Start, MarkupPointerMoveHelper.MoveDirection.LEFT, MarkupPointerAdjacency.BeforeVisible, parentHeaderElement); MarkupPointerMoveHelper.MoveUnitBounded(expandedRange.End, MarkupPointerMoveHelper.MoveDirection.RIGHT, MarkupPointerAdjacency.BeforeVisible, parentHeaderElement); // Walks in-scope elements and clears out any elements or styles that might affect the bold formatting. var elementsToRemove = new List <IHTMLElement>(); expandedRange.WalkRange( delegate(MarkupRange currentexpandedRange, MarkupContext context, string text) { IHTMLElement currentElement = context.Element; if (currentElement != null && context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope) { if (IsStrongOrBold(currentElement)) { elementsToRemove.Add(currentElement); } else if (IsFontableElement(currentElement) && HTMLElementHelper.IsBold((IHTMLElement2)currentElement) != turnBold) { currentElement.style.fontWeight = String.Empty; } } return(true); }, true); elementsToRemove.ForEach(e => markupServices.RemoveElement(e)); // Walks the range to find any segments of text that need to be fixed up. var rangesToWrap = new List <MarkupRange>(); range.WalkRange( delegate(MarkupRange currentRange, MarkupContext context, string text) { if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_Text) { TextStyles currentTextStyles = new TextStyles(currentRange.Start); if (currentTextStyles.Bold != turnBold) { rangesToWrap.Add(currentRange.Clone()); } } return(true); }, true); rangesToWrap.ForEach(r => WrapRangeInFontIfNecessary(r, turnBold)); }