-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Provide a safe operation for the dialog #5860
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,7 +73,7 @@ export abstract class AbstractDialog<T> extends BaseWidget { | |
@inject(DialogProps) protected readonly props: DialogProps | ||
) { | ||
super(); | ||
this.id = 'theia-dialog-shell'; | ||
this.id = `theia-dialog-${(new Date()).getTime()}`; | ||
this.addClass('dialogOverlay'); | ||
this.toDispose.push(Disposable.create(() => { | ||
if (this.reject) { | ||
|
@@ -148,15 +148,30 @@ export abstract class AbstractDialog<T> extends BaseWidget { | |
this.addKeyListener(document.body, Key.ENTER, e => this.handleEnter(e)); | ||
} | ||
|
||
protected canHandleKeyboardEvent(event: KeyboardEvent): boolean { | ||
let result: boolean = false; | ||
if (this.id && event.currentTarget) { | ||
const dialogOverlay: HTMLElement = event.currentTarget as HTMLElement; | ||
if (dialogOverlay.lastElementChild && this.id.localeCompare(dialogOverlay.lastElementChild.id) === 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How can you be sure that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @akosyakov |
||
result = true; | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
protected handleEscape(event: KeyboardEvent): boolean | void { | ||
this.close(); | ||
if (this.canHandleKeyboardEvent(event)) { | ||
this.close(); | ||
} | ||
} | ||
|
||
protected handleEnter(event: KeyboardEvent): boolean | void { | ||
if (event.target instanceof HTMLTextAreaElement) { | ||
return false; | ||
if (this.canHandleKeyboardEvent(event)) { | ||
if (event.target instanceof HTMLTextAreaElement) { | ||
return false; | ||
} | ||
this.accept(); | ||
} | ||
this.accept(); | ||
} | ||
|
||
protected onActivateRequest(msg: Message): void { | ||
|
@@ -277,7 +292,6 @@ export class ConfirmDialog extends AbstractDialog<boolean> { | |
@inject(ConfirmDialogProps) protected readonly props: ConfirmDialogProps | ||
) { | ||
super(props); | ||
|
||
this.contentNode.appendChild(this.createMessageNode(this.props.msg)); | ||
this.appendCloseButton(props.cancel); | ||
this.appendAcceptButton(props.ok); | ||
|
@@ -324,7 +338,6 @@ export class SingleTextInputDialog extends AbstractDialog<string> { | |
@inject(SingleTextInputDialogProps) protected readonly props: SingleTextInputDialogProps | ||
) { | ||
super(props); | ||
|
||
this.inputField = document.createElement('input'); | ||
this.inputField.type = 'text'; | ||
this.inputField.setAttribute('style', 'flex: 0;'); | ||
|
@@ -363,4 +376,10 @@ export class SingleTextInputDialog extends AbstractDialog<string> { | |
this.inputField.focus(); | ||
} | ||
|
||
protected handleEnter(event: KeyboardEvent): boolean | void { | ||
if (event.target instanceof HTMLInputElement) { | ||
return super.handleEnter(event); | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure checking
this.id
is necessary asid
will always be defined by the parentAbstractDialog<T>
:https://github.com/theia-ide/theia/blob/cc51575a2c8660f13794ed9099ee14daaca982b9/packages/core/src/browser/dialogs.ts#L76
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vince-fugnitto I think it's necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify why it's necessary? (
this.id
is alwaystrue
)If no
id
is provided by a child, the parent'stheia-dialog-shell
will be used due tosuper(props)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vince-fugnitto
I have try add 'event.preventDefault();event.stopPropagation();' into handle func,but it does not work,to binding 'document.body' maybe too wide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am thinking of a way to solve the problem you mentioned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.id =
theia-dialog-${(new Date()).getTime()}
;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vince-fugnitto @akosyakov
In principle, each dialog should have a unique ID, similar to the processing of widgets in the application-shell
The current processing logic uses default timestamps to identify uniqueness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it stop propagation in wrong order?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akosyakov
It will start accepting responses from the first addition to the listen queue.