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();
                }
            }
        }