protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end) { // get the table and its cells IHTMLTable sourceTable = GetSourceTable(DataMeister); IHTMLElementCollection cells = (sourceTable as IHTMLElement2).getElementsByTagName("td"); // single-cell tables just get the innerHTML of the cell pasted at the selection if (cells.length == 1) { IHTMLElement cell = cells.item(0, 0) as IHTMLElement; EditorContext.InsertHtml(begin, end, cell.innerHTML, UrlHelper.GetBaseUrl(DataMeister.HTMLData.SourceURL)); } else { // if we are inside a table TableSelection tableSelection = new TableSelection(EditorContext.MarkupServices.CreateMarkupRange(begin, end)); if (tableSelection.Table != null) { // paste the source cells into the table PasteCellsIntoTable(sourceTable, tableSelection); } else { // get table html (make sure width matches # of rows selected) TableHelper.SynchronizeTableWidthForEditing(sourceTable); string html = (sourceTable as IHTMLElement).outerHTML; // insert the html (nests within an undo unit) EditorContext.InsertHtml(begin, end, html, UrlHelper.GetBaseUrl(DataMeister.HTMLData.SourceURL)); } } return true; }
/// <summary> /// Grabs HTML copied in the clipboard and pastes it into the document (pulls in a copy of embedded content too) /// </summary> protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end) { using (new WaitCursor()) { try { // get the list of files from the data meister FileItem[] files = DataMeister.FileData.Files; string[] filePaths = new string[files.Length]; // create an array of file entities to insert for (int i = 0; i < files.Length; i++) { filePaths[i] = files[i].ContentsPath; } string html = EditorContext.HtmlGenerationService.GenerateHtmlFromFiles(filePaths); EditorContext.InsertHtml(begin, end, html, null); //place the caret at the end of the inserted content //EditorContext.MoveCaretToMarkupPointer(end, true); return true; } catch (Exception e) { //bugfix 1696, put exceptions into the trace log. Trace.Fail("Exception while inserting HTML: " + e.Message, e.StackTrace); return false; } } }
/// <summary> /// Create a text range spanning the specified markup positions. /// </summary> /// <param name="start">the start point of the text range</param> /// <param name="end">the end point of the text range</param> /// <returns></returns> public IHTMLTxtRange CreateTextRange(MarkupPointer start, MarkupPointer end) { // when switching between wywiwyg and source view sometimes .body is null // and this throws a null ref exception that we catch (can be detected by enabling // exception breaking in the debugger) IHTMLTxtRange range = (Document.body as IHTMLBodyElement).createTextRange(); MarkupServices.MoveRangeToPointers(start, end, range); return range; }
public override bool ShouldMoveDropLocationRight(MarkupPointer dropLocation) { MarkupContext mc = new MarkupContext(); dropLocation.Right(false, mc); if (mc.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope && ElementFilters.IsBlockElement(mc.Element) && !ContentSourceManager.IsSmartContent(mc.Element)) { dropLocation.Left(false, mc); if (mc.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope && ElementFilters.IsBlockElement(mc.Element)) return true; } return false; }
public TypographicCharacterHandler(MarkupRange currentSelection, InsertHtml insertHtml, IBlogPostImageEditingContext imageEditingContext, IHTMLElement postBodyElement, char c, string htmlText, MarkupPointer blockBoundary) { _currentSelection = currentSelection.Clone(); _currentSelection.Start.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right; _currentSelection.End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Left; _insertHtml = insertHtml; _imageEditingContext = imageEditingContext; _postBodyElement = postBodyElement; this.c = c; this.htmlText = htmlText; this.blockBoundary = blockBoundary; }
/// <summary> /// Grabs text copied in the clipboard and pastes it into the document /// </summary> protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end) { try { // get the text data as a string string textData = DataMeister.TextData.Text; string html = EditorContext.HtmlGenerationService.GenerateHtmlFromPlainText(textData); //insert captured content into the document EditorContext.InsertHtml(begin, end, html, null); return true; } catch (Exception e) { //bugfix 1696, put exceptions into the trace log. Trace.Fail("Exception while inserting URL: " + e.Message, e.StackTrace); return false; } }
public static void TraceMoveToMarkupPointer(IDisplayPointerRaw displayPointer, MarkupPointer markupPointer) { try { if (displayPointer == null) throw new ArgumentException("Unexpected null display pointer."); if (markupPointer == null) throw new ArgumentException("Unexpected null markup pointer."); //position a display pointer on the same line as the markup pointer displayPointer.MoveToMarkupPointer(markupPointer.PointerRaw, null); } catch (Exception e) { Trace.Fail("Unexpected exception in TraceMoveToMarkupPointer: " + e.ToString()); throw; } }
private static void MoveUnitBounded(MarkupPointer p, MoveDirection direction, MoveContextFilter continueFilter, MarkupPointer boundary) { MarkupPointer p1 = p.Clone(); MarkupPointer lastGoodPosition = p.Clone(); MarkupContext context = new MarkupContext(); MoveFilterResult result = MoveFilterResult.CONTINUE; while (CheckMoveBoundary(p1, boundary, direction) && result == MoveFilterResult.CONTINUE) { lastGoodPosition.MoveToPointer(p1); MovePointer(p1, direction, context); result = continueFilter(context); } if (result == MoveFilterResult.CONTINUE) { //we hit the boundary, so position pointer at the boundary p1.MoveToPointer(boundary); } else if (result == MoveFilterResult.STOP_BACK) { p1.MoveToPointer(lastGoodPosition); } p.MoveToPointer(p1); }
public void MoveToWordStart(MarkupPointer p) { lock (_p) { _p.MoveToPointer(p); _p2.MoveToPointer(p); _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVWORDEND); _p2.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVWORDBEGIN); if (_p2.IsRightOfOrEqualTo(_p)) p.MoveToPointer(_p2); //else, the pointer is already at the start of the current word } }
public MarkupServicesWordHelper(MshtmlMarkupServices markupServices) { MarkupServices = markupServices; _p = MarkupServices.CreateMarkupPointer(); _p2 = MarkupServices.CreateMarkupPointer(); }
internal MarkupRange CreateDamageTrackingRange(MarkupPointer start, MarkupPointer end, bool includeAdjecentWords) { MarkupRange range = _mshtmlEditor.MshtmlControl.MarkupServices.CreateMarkupRange(); range.Start.MoveToPointer(start); range.Start.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Left; range.End.MoveToPointer(end); range.End.Gravity = _POINTER_GRAVITY.POINTER_GRAVITY_Right; _wordHelper.MoveToWordStart(range.Start); _wordHelper.MoveToWordEnd(range.End); if (includeAdjecentWords) { ExpandDamageToAdjacentWords(range); } return range; }
protected virtual bool ContentIsDeletableForInsert(MarkupPointer start, MarkupPointer end) { return true; }
private IHTMLElement GetNextElement(MarkupPointer start, MarkupRange boundaries, IHTMLElementFilter filter, bool forward) { start = start.Clone(); MarkupPointer boundary = forward ? boundaries.End : boundaries.Start; MarkupContext moveResult = new MarkupContext(); _MARKUP_CONTEXT_TYPE skipContext = _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_ExitScope; //advance the pointer if (forward) start.Right(true, moveResult); else start.Left(true, moveResult); while (forward ? start.IsLeftOf(boundary) : start.IsRightOf(boundary)) { if (moveResult.Element != null && moveResult.Context != skipContext && filter(moveResult.Element)) { return moveResult.Element; } //advance the pointer if (forward) start.Right(true, moveResult); else start.Left(true, moveResult); } return null; }
/// <summary> /// Inserts the extended entry break into the editor at the specified location. /// </summary> internal IHTMLElement InsertExtendedEntryBreak(MarkupPointer insertionPoint) { IHTMLElement entryBreakDiv = EditorContext.MarkupServices.CreateElement(_ELEMENT_TAG_ID.TAGID_DIV, null); IHTMLElement postBodyElement = HTMLElement; insertionPoint.PushCling(false); insertionPoint.PushGravity(_POINTER_GRAVITY.POINTER_GRAVITY_Right); try { //insert the entryBreak DIV into the beginning of the post body entryBreakDiv.id = EXTENDED_ENTRY_ID; entryBreakDiv.setAttribute("name", EXTENDED_ENTRY_ID, 0); MarkupRange markupRange = EditorContext.MarkupServices.CreateMarkupRange(); markupRange.MoveToElement(postBodyElement, false); markupRange.End.MoveToPointer(markupRange.Start); EditorContext.MarkupServices.InsertElement(entryBreakDiv, markupRange.Start, markupRange.End); //move all content that should stay above the extended entry line, above the entryBreakDiv //this effectively forces all open tags to be closed, and leaves the insertion point below //the extended entry line (with the pre-insert parent tree still intact. markupRange.Start.MoveAdjacentToElement(entryBreakDiv, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd); markupRange.End.MoveToPointer(insertionPoint); MarkupPointer target = EditorContext.MarkupServices.CreateMarkupPointer(entryBreakDiv, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin); EditorContext.MarkupServices.Move(markupRange.Start, markupRange.End, target); } finally { insertionPoint.PopCling(); insertionPoint.PopGravity(); } return entryBreakDiv; }
public bool IsAdjacentToWordEnd(MarkupPointer p) { lock (_p) { _p.MoveToPointer(p); _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTCHAR); _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVWORDEND); return _p.IsEqualTo(p); } }
private float GetFontSizeAt(MarkupPointer location) { IDisplayServicesRaw displayServices = (IDisplayServicesRaw)HTMLDocument; IHTMLComputedStyle computedStyle; displayServices.GetComputedStyle(location.PointerRaw, out computedStyle); float pixels = DisplayHelper.TwipsToPixelsY(computedStyle.fontSize); float points = HTMLElementHelper.PixelsToPointSize(pixels, true); return points; }
/// <summary> /// Delete the content between 2 pointers from the document. /// </summary> /// <param name="start"></param> /// <param name="end"></param> private void DeleteContent(MarkupPointer start, MarkupPointer end) { MarkupRange range = MarkupServices.CreateMarkupRange(start, end); DeleteContent(range); }
/// <summary> /// Utility for deleting a range of content while suppressing pointer cling. /// </summary> /// <param name="start"></param> /// <param name="end"></param> private void DeleteContentNoCling(MarkupPointer start, MarkupPointer end) { start.PushCling(false); end.PushCling(false); try { DeleteContent(start, end); } finally { start.PopCling(); end.PopCling(); } }
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(); } }
void IHtmlMarshallingTarget.InsertHtml(MarkupPointer start, MarkupPointer end, string html, string sourceUrl) { InsertHtml(start, end, html, sourceUrl, true); }
private bool OverwriteDestinationBlockIfEmpty(MarkupPointer destinationStart, MarkupRange bounds) { bool blockOverwritten = false; IHTMLElement parentBlockElement = destinationStart.GetParentElement(ElementFilters.BLOCK_ELEMENTS); if (parentBlockElement != null) { MarkupRange parentBlockRange = MarkupServices.CreateMarkupRange(parentBlockElement, false); if (bounds.InRange(parentBlockRange, false)) { if (PrimaryEditableBounds == null || PrimaryEditableBounds.InRange(parentBlockRange)) { if (parentBlockRange.IsEmptyOfContent()) { parentBlockRange.MoveToElement(parentBlockElement, true); DeleteContentNoCling(parentBlockRange.Start, parentBlockRange.End); // Check to see if the delete we just did caused the insertion point to be // to become a no longer positioned, and if it did we move it to the start // of what we deleted if (!destinationStart.Positioned) { //Debug.WriteLine("Invalid pointer after delete, moving the target pointer to the start of the deleted markup."); destinationStart.MoveToPointer(parentBlockRange.Start); } blockOverwritten = true; } } } } return blockOverwritten; }
public bool IsAdjacentToWordStart(MarkupPointer p) { lock (_p) { _p.MoveToPointer(p); _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_PREVCHAR); _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDBEGIN); return _p.IsEqualTo(p); } }
public void MoveToWordEnd(MarkupPointer p) { lock (_p) { _p.MoveToPointer(p); _p2.MoveToPointer(p); _p.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDBEGIN); _p2.MoveUnit(_MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDEND); // If CurrentScope is null, this means we have walked off the end of the // document, in that case we don't want to move the pointer, at is already // at the end of word. if (_p2.IsLeftOfOrEqualTo(_p) && _p.CurrentScope != null) p.MoveToPointer(_p2); //else, the pointer is already at the end of the current word } }
private IDisposable CreateDamageTracking(MarkupPointer end, bool p) { return _damageServices.CreateDamageTracker(end, end, true); }
/// <summary> /// Grabs HTML copied in the clipboard and pastes it into the document (pulls in a copy of embedded content too) /// </summary> protected override bool DoInsertData(DataAction action, MarkupPointer begin, MarkupPointer end) { using (new WaitCursor()) { try { //StringBuilder html = new StringBuilder(); //html.AppendFormat("<a href=\"{0}\">{1}</a>", DataMeister.URLData.URL, DataMeister.URLData.Title); string html = EditorContext.HtmlGenerationService.GenerateHtmlFromLink(Url, Title, Title, String.Empty, false); EditorContext.InsertHtml(begin, end, html, null); //place the caret at the end of the inserted content //EditorContext.MoveCaretToMarkupPointer(end, true); return true; } catch (Exception e) { //bugfix 1696, put exceptions into the trace log. Trace.Fail("Exception while inserting URL: " + e.Message, e.StackTrace); return false; } } }
public IDisposable CreateDamageTracker(MarkupPointer start, MarkupPointer end, bool includeAdjacentWords) { if (DamageTrackingEnabled) return new DamageTracker(this, start, end, includeAdjacentWords); else return null; }
private void DeleteInsertionTargetBlockIfEmpty(MarkupPointer insertionPoint) { //locate the parent block element (stop at post body element) IHTMLElement parent = insertionPoint.GetParentElement( ElementFilters.CreateCompoundElementFilter(ElementFilters.CreateElementEqualsFilter(HTMLElement), ElementFilters.BLOCK_ELEMENTS)); if (parent != null && parent.sourceIndex != HTMLElement.sourceIndex && //never remove the post body block EditorContext.MarkupServices.CreateMarkupRange(parent, false).IsEmptyOfContent()) { //delete the empty parent block element (parent as IHTMLDOMNode).removeNode(true); } }
public DamageTracker(HtmlEditorControlDamageServices damageServices, MarkupPointer start, MarkupPointer end, bool includeAdjacentWords) { _damageServices = damageServices; _damageRange = damageServices.wordRangeDamager.CreateDamageTrackingRange(start, end, includeAdjacentWords); }
public virtual bool ShouldMoveDropLocationRight(MarkupPointer dropLocation) { return false; }
private void EnsureNewLineAtDocEnd(MarkupPointer mpStart, MarkupPointer mpEnd) { // Add a <p></p> at the end of the document if there isn't one. MarkupPointer endBody = MarkupServices.CreateMarkupPointer(); endBody.MoveAdjacentToElement(PostBodyElement, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeEnd); // If we have to insert the <p> this is where we will do it, so save it for later MarkupPointer insertLocation = endBody.Clone(); // Move left one more time to find out if it is p with a space in it. endBody.Left(true); // Check to see if it a p with a space. We use innerHtml because if the html looked like // <p><img ...> </p> innerText only reports " " though this isnt really just a blank line. // We dont use HtmlUtils.HtmlToText because it will replace img tags as a space. if (endBody.CurrentScope.tagName != "P" || endBody.CurrentScope.innerHTML != " ") { // Move it into the real document IHTMLDocument2 docInsert = mpStart.GetDocument(); MarkupRange stagingRangeInsert = MarkupServices.CreateMarkupRange(mpStart, mpEnd); stagingRangeInsert.MoveToElement(docInsert.body, false); MarkupServices.Move(stagingRangeInsert.Start, stagingRangeInsert.End, insertLocation); } }