private void Init(IHTMLDocument document, MshtmlMarkupServices markupServices, MarkupRange selectionRange, MarkupRangeFilter filter, DamageFunction damageFunction, bool expandRange) { // save references this.htmlDocument = document; this.markupServices = markupServices; this.selectionRange = selectionRange; this.filter = filter; this.damageFunction = damageFunction; // If the range is already the body, don't expand it or else it will be the whole document if (expandRange) { ExpandRangeToWordBoundaries(selectionRange); } // initialize pointer to beginning of selection range MarkupPointer wordStart = MarkupServices.CreateMarkupPointer(selectionRange.Start); MarkupPointer wordEnd = MarkupServices.CreateMarkupPointer(selectionRange.Start); //create the range for holding the current word. //Be sure to set its gravity so that it stays around text that get replaced. currentWordRange = MarkupServices.CreateMarkupRange(wordStart, wordEnd); currentWordRange.Start.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Left; currentWordRange.End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right; currentVirtualPosition = currentWordRange.End.Clone(); }
/// <summary> /// Creates a clone that spans the same range as this MarkupRange. /// Note: The clone can be manipulated without changing the position of this range. /// </summary> /// <returns></returns> public MarkupRange Clone() { MarkupRange clone = MarkupServices.CreateMarkupRange(); clone.Start.MoveToPointer(Start); clone.Start.Cling = Start.Cling; clone.Start.Gravity = Start.Gravity; clone.End.MoveToPointer(End); clone.End.Cling = End.Cling; clone.End.Gravity = End.Gravity; return(clone); }
//this is similar to the GetTopLevelElements except will also return table cells if correct filter // is set and recurse is equal to true public IHTMLElement[] GetTopLevelBlocksAndCells(IHTMLElementFilter filter, bool recurse) { ArrayList list = new ArrayList(); Hashtable usedElements = new Hashtable(); MarkupPointer p = MarkupServices.CreateMarkupPointer(Start); MarkupContext context = p.Right(false); //move p through the range to locate each of the top level elements while (p.IsLeftOf(End)) { if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope || context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_NoScope) { p.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd); if (usedElements[context.Element] == null) { if (p.IsLeftOfOrEqualTo(End) && (filter == null || filter(context.Element))) { list.Add(context.Element); } //special case--inside of a table element, want to get out the cells inside else if (recurse && ElementFilters.TABLE_ELEMENTS(context.Element)) { MarkupRange newRange = MarkupServices.CreateMarkupRange(context.Element); newRange.Start.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin); if (newRange.Start.IsLeftOf(Start)) { newRange.Start.MoveToPointer(Start); } if (newRange.End.IsRightOf(End)) { newRange.End.MoveToPointer(End); } //recursively check inside table element for table cells list.AddRange(newRange.GetTopLevelBlocksAndCells(filter, true)); } //cache the fact that we've already tested this element. usedElements[context.Element] = context.Element; } } p.Right(true, context); } return(HTMLElementHelper.ToElementArray(list)); }
/// <summary> /// Expands this range out to the next parent shared by the start and end points /// if there there are no non-empty text elements between them. /// </summary> /// <returns></returns> public bool MoveOutwardIfNo(RangeFilter rangeFilter) { MarkupRange newRange = MarkupServices.CreateMarkupRange(); IHTMLElement sharedParent = GetSharedParent(Start, End); // If share a common parent, we will take the shared parent's parent so we can see if we want to grab // all the html inside of it, unless the shared parent is the body element, in which case we don't want to // epxand outward anymore if (Start.CurrentScope == sharedParent && End.CurrentScope == sharedParent && !(sharedParent is IHTMLBodyElement)) { sharedParent = sharedParent.parentElement; } //expand to the inside of the shared parent first. If this matches the current placement //of the pointers, then expand to the outside of the parent. This allows the outter selection //to grow incrementally in such a way as to allow the shared parent to be tested between //each iteration of this operation. newRange.Start.MoveAdjacentToElement(sharedParent, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin); newRange.End.MoveAdjacentToElement(sharedParent, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeEnd); if (newRange.IsEmpty() || newRange.Start.IsRightOf(Start) || newRange.End.IsLeftOf(End)) { newRange.Start.MoveAdjacentToElement(sharedParent, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin); newRange.End.MoveAdjacentToElement(sharedParent, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd); } if (!rangeFilter(newRange.Start, Start) && !rangeFilter(End, newRange.End) && !(Start.IsEqualTo(newRange.Start) && End.IsEqualTo(newRange.End))) { Start.MoveToPointer(newRange.Start); End.MoveToPointer(newRange.End); return(true); } else { //span the start and end pointers as siblings by finding the parents of start and end //pointers that are direct children of the sharedParent IHTMLElement child = GetOuterMostChildOfParent(Start, true, sharedParent); if (child != null) { newRange.Start.MoveAdjacentToElement(child, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin); } else { newRange.Start = Start; } child = GetOuterMostChildOfParent(End, false, sharedParent); if (child != null) { newRange.End.MoveAdjacentToElement(child, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd); } else { newRange.End = End; } if (!rangeFilter(newRange.Start, Start) && !rangeFilter(End, newRange.End) && !(Start.IsEqualTo(newRange.Start) && End.IsEqualTo(newRange.End))) { Start.MoveToPointer(newRange.Start); End.MoveToPointer(newRange.End); return(true); } else { //the range didn't change, so return false. return(false); } } }
public bool InRange(IHTMLElement e) { Debug.Assert(e != null, "Unexpected null element."); return(InRange(MarkupServices.CreateMarkupRange(e, true))); }
/// <summary> /// Get current selection pointers /// </summary> /// <returns>selection pointers</returns> public MarkupRange GetSelectedMarkupRange() { return(MarkupServices.CreateMarkupRange(SelectedRange)); }