Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix copy pasting with accessibility mode #234744

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import './nativeEditContext.css';
import { isFirefox } from '../../../../../base/browser/browser.js';
import { addDisposableListener, getActiveWindow, getWindow, getWindowId } from '../../../../../base/browser/dom.js';
import { addDisposableListener, getActiveWindow, getWindow, getWindowId, isHTMLElement } from '../../../../../base/browser/dom.js';
import { FastDomNode } from '../../../../../base/browser/fastDomNode.js';
import { StandardKeyboardEvent } from '../../../../../base/browser/keyboardEvent.js';
import { KeyCode } from '../../../../../base/common/keyCodes.js';
Expand Down Expand Up @@ -40,8 +40,10 @@ enum CompositionClassName {
export class NativeEditContext extends AbstractEditContext {

// Text area used to handle paste events
public static readonly domNodeClassName = `native-edit-context`;
public readonly textArea: FastDomNode<HTMLTextAreaElement>;
public readonly domNode: FastDomNode<HTMLDivElement>;

private readonly _editContext: EditContext;
private readonly _screenReaderSupport: ScreenReaderSupport;

Expand Down Expand Up @@ -74,7 +76,6 @@ export class NativeEditContext extends AbstractEditContext {
this.textArea = new FastDomNode(document.createElement('textarea'));
this.textArea.setClassName('native-edit-context-textarea');

this._register(NativeEditContextRegistry.registerTextArea(ownerID, this.textArea.domNode));

this._updateDomAttributes();

Expand Down Expand Up @@ -159,6 +160,7 @@ export class NativeEditContext extends AbstractEditContext {
}
viewController.paste(text, pasteOnNewLine, multicursorText, mode);
}));
this._register(NativeEditContextRegistry.register(ownerID, this));
}

// --- Public methods ---
Expand Down Expand Up @@ -454,11 +456,23 @@ export class NativeEditContext extends AbstractEditContext {
// When using a Braille display or NVDA for example, it is possible for users to reposition the
// system caret. This is reflected in Chrome as a `selectionchange` event and needs to be reflected within the editor.

return addDisposableListener(this.domNode.domNode.ownerDocument, 'selectionchange', () => {
return addDisposableListener(this.domNode.domNode.ownerDocument, 'selectionchange', (e) => {
const isScreenReaderOptimized = this._accessibilityService.isScreenReaderOptimized();
if (!this.isFocused() || !isScreenReaderOptimized) {
return;
}
const srcElement = e.srcElement;
if (srcElement && isHTMLElement(srcElement)) {
if (srcElement.className === NativeEditContext.domNodeClassName) {
return;
}
}
const targetElement = e.target;
if (targetElement && isHTMLElement(targetElement)) {
if (targetElement.className === NativeEditContext.domNodeClassName) {
return;
}
}
const screenReaderContentState = this._screenReaderSupport.screenReaderContentState;
if (!screenReaderContentState) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@
*--------------------------------------------------------------------------------------------*/

import { IDisposable } from '../../../../../base/common/lifecycle.js';
import { NativeEditContext } from './nativeEditContext.js';

class NativeEditContextRegistryImpl {

private _textAreaMapping: Map<string, HTMLTextAreaElement> = new Map();
private _nativeEditContextMapping: Map<string, NativeEditContext> = new Map();

registerTextArea(ownerID: string, textArea: HTMLTextAreaElement): IDisposable {
this._textAreaMapping.set(ownerID, textArea);
register(ownerID: string, nativeEditContext: NativeEditContext): IDisposable {
this._nativeEditContextMapping.set(ownerID, nativeEditContext);
return {
dispose: () => {
this._textAreaMapping.delete(ownerID);
this._nativeEditContextMapping.delete(ownerID);
}
};
}

getTextArea(ownerID: string): HTMLTextAreaElement | undefined {
return this._textAreaMapping.get(ownerID);
get(ownerID: string): NativeEditContext | undefined {
return this._nativeEditContextMapping.get(ownerID);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/vs/editor/contrib/clipboard/browser/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,9 @@ if (PasteAction) {
// Since we can not call execCommand('paste') on a dom node with edit context set
// we added a hidden text area that receives the paste execution
// see nativeEditContext.ts for more details
const textAreaDomNode = NativeEditContextRegistry.getTextArea(focusedEditor.getId());
if (textAreaDomNode) {
const nativeEditContext = NativeEditContextRegistry.get(focusedEditor.getId());
if (nativeEditContext) {
const textAreaDomNode = nativeEditContext.textArea.domNode;
const currentFocusedElement = getActiveWindow().document.activeElement;
textAreaDomNode.focus();
result = focusedEditor.getContainerDomNode().ownerDocument.execCommand('paste');
Expand Down
Loading