protected override void OnKeyDown(HtmlEventArgs e) { base.OnKeyDown(e); if (((Keys)e.htmlEvt.keyCode) == Keys.Back) { using (IUndoUnit undo = EditorContext.CreateUndoUnit()) { (HTMLElement as IHTMLDOMNode).removeNode(true); undo.Commit(); } e.Cancel(); } }
protected override void HandleTabKey(HtmlEventArgs e) { // don't handle ctrl or alt key combos if (e.htmlEvt.ctrlKey || e.htmlEvt.altKey) return; if (GlobalEditorOptions.SupportsFeature(ContentEditorFeature.TabAsIndent)) { if (!e.htmlEvt.shiftKey) _keyBoardHandler.MaybeHandleInsert('\t', () => InsertHtml(" ", true)); } else { IHtmlEditorCommandSource commandSource = this; if (e.htmlEvt.shiftKey) { if (commandSource.CanOutdent) commandSource.ApplyOutdent(); } else { if (commandSource.CanIndent) commandSource.ApplyIndent(); } } e.Cancel(); }
private void EditorContext_KeyDown(object o, HtmlEventArgs e) { if (Selected) { // Enter key if ((e.htmlEvt.keyCode == (int)Keys.Enter) && !e.htmlEvt.shiftKey && !e.htmlEvt.ctrlKey && !e.htmlEvt.altKey) { // insert a linebreak if we are not parented by a block element IHTMLElement blockScope = EditorContext.Selection.SelectedMarkupRange.Start.GetParentElement(ElementFilters.BLOCK_OR_TABLE_CELL_ELEMENTS); if (blockScope is IHTMLTableCell) { LastChanceKeyboardHook.OnBeforeKeyHandled(this, GetKeyEventArgs(e.htmlEvt)); TableEditor.InsertLineBreak(EditorContext); e.Cancel(); } } // tab key if ((e.htmlEvt.keyCode == (int)Keys.Tab) && !e.htmlEvt.ctrlKey && !e.htmlEvt.altKey) { // only hijack tab and shift-tab if we are not in a list IHTMLElement listItemScope = EditorContext.Selection.SelectedMarkupRange.Start.GetParentElement(ElementFilters.LIST_ITEM_ELEMENTS); if (listItemScope == null) { if (e.htmlEvt.shiftKey) { LastChanceKeyboardHook.OnBeforeKeyHandled(this, GetKeyEventArgs(e.htmlEvt)); TableEditor.SelectPreviousCell(EditorContext); e.Cancel(); } else { LastChanceKeyboardHook.OnBeforeKeyHandled(this, GetKeyEventArgs(e.htmlEvt)); TableEditor.SelectNextCell(EditorContext); e.Cancel(); } } } } }
protected override void HandleKeyboardNavigationKey(HtmlEventArgs e) { MarkupRange selection = Selection.SelectedMarkupRange; if (!selection.IsEmpty()) { // WinLive 196413: MSHTML seems to have a weird issue where if you have two hyperlinked images that // break onto two separate lines and you select the bottom image and hit the left arrow key, then // you'll end up between the anchor and the image (e.g. <a><img /></a><a>[caret]<img /></a>). // However, if you select the top image and hit the right arrow key, then you'll end up in the right // place -- in between the two anchors (e.g. <a><img /></a>[caret]<a><img></a>. if (e.htmlEvt.keyCode == (int)Keys.Left) { // If an image is currently selected. IHTMLElement imgElement = (IHTMLElement)Selection.SelectedImage; if (imgElement == null) return; // And it's parent is an anchor. IHTMLElement imgParentElement = imgElement.parentElement; if (!(imgParentElement is IHTMLAnchorElement)) return; // And there is no other HTML besides the anchor and the image. IHTMLElementCollection anchorChildren = (IHTMLElementCollection)imgParentElement.children; if (anchorChildren.length > 1 || !String.IsNullOrEmpty(imgParentElement.innerText)) return; // Move the caret outside the hyperlink. selection.Start.MoveAdjacentToElement(imgParentElement, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin); selection.Collapse(true); selection.ToTextRange().select(); e.Cancel(); } return; } }
protected override void HandleBackspaceKey(HtmlEventArgs e) { // This is a fix for an issue where hitting the backspace key deletes just an anchor tag around an image, // but does not delete the image as well. The repro for this issue is to insert an image in Writer (which // by default adds an anchor around the image), click on the empty space to the right of the image (or hit // End) and then hit backspace. if (SelectedMarkupRange != null && SelectedMarkupRange.IsEmpty()) { MarkupContext context = SelectedMarkupRange.Start.Left(false); // If we're backspacing over an anchor element. if (context.Element == null || context.Context != _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope || !(context.Element is IHTMLAnchorElement)) { return; } // And the anchor contains just a single child element. IHTMLElementCollection anchorChildren = (IHTMLElementCollection)context.Element.children; if (anchorChildren.length > 1 || !String.IsNullOrEmpty(context.Element.innerText)) { return; } // And that single child element is an image. IHTMLElementCollection childImgs = (IHTMLElementCollection)anchorChildren.tags("img"); if (childImgs != null && childImgs.length == 1) { using (IUndoUnit undoUnit = CreateUndoUnit()) { HTMLElementHelper.RemoveElement(context.Element); e.Cancel(); undoUnit.Commit(); } } return; } }
void _blogPostHtmlEditorControl_KeyPress(object o, HtmlEventArgs e) { using (ApplicationPerformance.LogEvent("PostEditorKeyPress")) { // These are important for helping to find bugs with autoreplace, but cause to much // noise with tests and testers even in debug mode. They can have many 'false positives' hits if (Debugger.IsAttached) { Debug.Assert(_delayedAutoReplaceAction == null, "Delayed autoreplace operation wasn't null!"); Debug.Assert(_typographicCharacterHandler == null, "Delayed typographic character operation wasn't null!"); } _delayedAutoReplaceAction = null; _typographicCharacterHandler = null; _lastActionWasReplace = 0; _ignoreNextSelectionChange = false; if (MaybeHandleKey(Convert.ToChar(e.htmlEvt.keyCode))) e.Cancel(); } }
void _blogPostHtmlEditorControl_KeyDown(object o, HtmlEventArgs e) { try { using (ApplicationPerformance.LogEvent("PostEditorKeyDown")) { if (HandleKey && Convert.ToChar(e.htmlEvt.keyCode) == 8) { _linkIgnoreWord = null; if (AutoLinkEnabled) { MarkupPointer blockBoundary; string htmlText = GetHtmlText(out blockBoundary); if (blockBoundary == null) return; MatchUrl(htmlText, IgnoreSuggestedUrl); } if (_lastActionWasReplace > 0) { _lastActionWasReplace--; _ignoreNextSelectionChange = true; _blogPostHtmlEditorControl.Undo(); e.Cancel(); } } } } catch (Exception ex) { Trace.Fail("Error while handling backspace key, suppressing autocomplete " + ex); _haltAutoReplace = true; throw; } }
private void HandleEnterKey(HtmlEventArgs e) { //pressing the enter key on an empty line is used as a gesture for exiting the blockquote //If this situation is encountered, move the current empty block element outside of the blockquote MarkupRange selection = EditorContext.Selection.SelectedMarkupRange; if (selection.IsEmpty()) { MarkupPointer selectionPoint = EditorContext.MarkupServices.CreateMarkupPointer(selection.Start); selectionPoint.Cling = true; IHTMLElement currBlock = selection.Start.CurrentBlockScope(); MarkupRange currBlockRange = EditorContext.MarkupServices.CreateMarkupRange(currBlock, false); if (currBlockRange.IsEmptyOfContent()) { currBlockRange.MoveToElement(currBlock, true); // Make sure there is no content between the end of this block range and the end of the blockquote. MarkupPointer afterEndCurrBlock = EditorContext.MarkupServices.CreateMarkupPointer(currBlock, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd); MarkupPointer beforeEndBlockQuote = EditorContext.MarkupServices.CreateMarkupPointer(HTMLElement, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeEnd); MarkupRange restOfBlockQuote = EditorContext.MarkupServices.CreateMarkupRange(afterEndCurrBlock, beforeEndBlockQuote); if (!restOfBlockQuote.IsEmpty() || !restOfBlockQuote.IsEmptyOfContent()) return; //create a pointer for the new location that the block element will be moved to. MarkupPointer insertionPoint = EditorContext.MarkupServices.CreateMarkupPointer(HTMLElement, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd); //move the current empty block to the DOM location after the blockquote EditorContext.MarkupServices.Move(currBlockRange.Start, currBlockRange.End, insertionPoint); currBlockRange.MoveToElement(currBlock, false); //adjust the selection to the new location of the block element. currBlockRange.Start.MoveToPointer(selectionPoint); currBlockRange.End.MoveToPointer(selectionPoint); currBlockRange.ToTextRange().select(); //cancel the key down event so that the editor doesn't try to handle it e.Cancel(); } } }