Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.9k
feat!: Make everything ISelectable focusable#9004
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
94d8c02cadf7d637757591f5a6f0f2bd02cbefa680fa7117c79cf32cd62a6a3386b762f133908b7c6aca66aaba36227b4aa574b3c0a6e716ac6f74bd431d8eFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -266,20 +266,14 @@ export class BlockSvg | ||
| /** Selects this block. Highlights the block visually. */ | ||
| select() { | ||
| if (this.isShadow()) { | ||
| this.getParent()?.select(); | ||
| return; | ||
| } | ||
| this.addSelect(); | ||
| common.fireSelectedEvent(this); | ||
| } | ||
| /** Unselects this block. Unhighlights the block visually. */ | ||
| unselect() { | ||
| if (this.isShadow()) { | ||
| this.getParent()?.unselect(); | ||
| return; | ||
| } | ||
| this.removeSelect(); | ||
| common.fireSelectedEvent(null); | ||
| } | ||
| /** | ||
| @@ -862,25 +856,6 @@ export class BlockSvg | ||
| blockAnimations.disposeUiEffect(this); | ||
| } | ||
| // Selecting a shadow block highlights an ancestor block, but that highlight | ||
| // should be removed if the shadow block will be deleted. So, before | ||
| // deleting blocks and severing the connections between them, check whether | ||
| // doing so would delete a selected block and make sure that any associated | ||
| // parent is updated. | ||
| const selection = common.getSelected(); | ||
| if (selection instanceof Block) { | ||
| let selectionAncestor: Block | null = selection; | ||
| while (selectionAncestor !== null) { | ||
| if (selectionAncestor === this) { | ||
| // The block to be deleted contains the selected block, so remove any | ||
| // selection highlight associated with the selected block before | ||
| // deleting them. | ||
| selection.unselect(); | ||
| } | ||
| selectionAncestor = selectionAncestor.getParent(); | ||
| } | ||
| } | ||
| super.dispose(!!healStack); | ||
| dom.removeNode(this.svgGroup); | ||
| } | ||
| @@ -893,8 +868,7 @@ export class BlockSvg | ||
| this.disposing = true; | ||
| super.disposeInternal(); | ||
| if (common.getSelected() === this) { | ||
| this.unselect(); | ||
| if (getFocusManager().getFocusedNode() === this) { | ||
maribethb marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| this.workspace.cancelCurrentGesture(); | ||
| } | ||
| @@ -1839,14 +1813,17 @@ export class BlockSvg | ||
| /** See IFocusableNode.onNodeFocus. */ | ||
| onNodeFocus(): void { | ||
| common.setSelected(this); | ||
| this.select(); | ||
| } | ||
| /** See IFocusableNode.onNodeBlur. */ | ||
| onNodeBlur(): void { | ||
| if (common.getSelected() === this) { | ||
| common.setSelected(null); | ||
| } | ||
| this.unselect(); | ||
| } | ||
| /** See IFocusableNode.canBeFocused. */ | ||
| canBeFocused(): boolean { | ||
| return true; | ||
| } | ||
| /** | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -80,11 +80,10 @@ export class TextInputBubble extends Bubble { | ||
| protected anchor: Coordinate, | ||
| protected ownerRect?: Rect, | ||
| ) { | ||
| super(workspace, anchor, ownerRect); | ||
| super(workspace, anchor, ownerRect, TextInputBubble.createTextArea()); | ||
| dom.addClass(this.svgRoot, 'blocklyTextInputBubble'); | ||
| ({inputRoot: this.inputRoot, textArea: this.textArea} = this.createEditor( | ||
| this.contentContainer, | ||
| )); | ||
| this.textArea = this.getFocusableElement() as HTMLTextAreaElement; | ||
| this.inputRoot = this.createEditor(this.contentContainer, this.textArea); | ||
| this.resizeGroup = this.createResizeHandle(this.svgRoot, workspace); | ||
| this.setSize(this.DEFAULT_SIZE, true); | ||
| } | ||
| @@ -131,11 +130,21 @@ export class TextInputBubble extends Bubble { | ||
| this.locationChangeListeners.push(listener); | ||
| } | ||
| /** Creates the editor UI for this bubble. */ | ||
| private createEditor(container: SVGGElement): { | ||
| inputRoot: SVGForeignObjectElement; | ||
| textArea: HTMLTextAreaElement; | ||
| } { | ||
| /** Creates and returns the editable text area for this bubble's editor. */ | ||
| private static createTextArea(): HTMLTextAreaElement { | ||
BenHenning marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| const textArea = document.createElementNS( | ||
| dom.HTML_NS, | ||
| 'textarea', | ||
| ) as HTMLTextAreaElement; | ||
| textArea.className = 'blocklyTextarea blocklyText'; | ||
| return textArea; | ||
| } | ||
| /** Creates and returns the UI container element for this bubble's editor. */ | ||
| private createEditor( | ||
| container: SVGGElement, | ||
| textArea: HTMLTextAreaElement, | ||
| ): SVGForeignObjectElement { | ||
| const inputRoot = dom.createSvgElement( | ||
| Svg.FOREIGNOBJECT, | ||
| { | ||
| @@ -149,22 +158,13 @@ export class TextInputBubble extends Bubble { | ||
| body.setAttribute('xmlns', dom.HTML_NS); | ||
| body.className = 'blocklyMinimalBody'; | ||
| const textArea = document.createElementNS( | ||
| dom.HTML_NS, | ||
| 'textarea', | ||
| ) as HTMLTextAreaElement; | ||
| textArea.className = 'blocklyTextarea blocklyText'; | ||
| textArea.setAttribute('dir', this.workspace.RTL ? 'RTL' : 'LTR'); | ||
| body.appendChild(textArea); | ||
| inputRoot.appendChild(body); | ||
| this.bindTextAreaEvents(textArea); | ||
| setTimeout(() => { | ||
| textArea.focus(); | ||
| }, 0); | ||
| return {inputRoot, textArea}; | ||
| return inputRoot; | ||
| } | ||
| /** Binds events to the text area element. */ | ||
| @@ -174,13 +174,6 @@ export class TextInputBubble extends Bubble { | ||
| e.stopPropagation(); | ||
| }); | ||
| browserEvents.conditionalBind( | ||
| textArea, | ||
| 'focus', | ||
| this, | ||
| this.onStartEdit, | ||
| true, | ||
| ); | ||
| browserEvents.conditionalBind(textArea, 'change', this, this.onTextChange); | ||
| } | ||
| @@ -314,17 +307,6 @@ export class TextInputBubble extends Bubble { | ||
| this.onSizeChange(); | ||
| } | ||
| /** | ||
| * Handles starting an edit of the text area. Brings the bubble to the front. | ||
| */ | ||
| private onStartEdit() { | ||
| if (this.bringToFront()) { | ||
| // Since the act of moving this node within the DOM causes a loss of | ||
| // focus, we need to reapply the focus. | ||
| this.textArea.focus(); | ||
| } | ||
| } | ||
| /** Handles a text change event for the text area. Calls event listeners. */ | ||
| private onTextChange() { | ||
| this.text = this.textArea.value; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -5,9 +5,9 @@ | ||
| */ | ||
| import {RenderedWorkspaceComment} from '../comments/rendered_workspace_comment.js'; | ||
| import * as common from '../common.js'; | ||
| import {EventType} from '../events/type.js'; | ||
| import * as eventUtils from '../events/utils.js'; | ||
| import {getFocusManager} from '../focus_manager.js'; | ||
| import {ICopyData} from '../interfaces/i_copyable.js'; | ||
| import {IPaster} from '../interfaces/i_paster.js'; | ||
| import * as commentSerialiation from '../serialization/workspace_comments.js'; | ||
| @@ -49,7 +49,7 @@ export class WorkspaceCommentPaster | ||
| if (eventUtils.isEnabled()) { | ||
| eventUtils.fire(new (eventUtils.get(EventType.COMMENT_CREATE))(comment)); | ||
| } | ||
| common.setSelected(comment); | ||
| getFocusManager().focusNode(comment); | ||
BenHenning marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| return comment; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.