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

Implement the code formatting shortcut #2613

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

trevinhofmann
Copy link
Collaborator

@trevinhofmann trevinhofmann commented Nov 23, 2024

Overview

This pull request implements #1957 by adding a shortcut to format selected text as code.

It currently uses the Bold icon as a placeholder. When the designer creates a dedicated icon and animation (most likely a </> icon), we can replace the placeholder.

Since the c key is already used for multiple shortcuts, this change uses k for the keyboard shortcut.

We are not able to use the same document.queryCommandState, so I updated getCommandState to also work for selected text for determining whether the shortcut icon should be active or inactive. The only change needed to make it work was to consider when the cursor is within text but not selecting any, which returns selected HTML such as <b><code></code></b> without any non-tag characters. With document.queryCommandState also being deprecated and non-standard, I also switched to using getCommandState for selected text (rather than only an entire selected thought) for the other commands as well.

We also cannot use document.execCommand within the formatSelection action, so I added a new formatWithTag action that manually adds/removes the provided tag. This is currently only used for <code>, but it could be reused for other commands that are not supported by document.execCommand.

Demo

Screen.Recording.2024-11-22.at.10.50.57.PM.mov

@trevinhofmann trevinhofmann self-assigned this Nov 23, 2024
@trevinhofmann trevinhofmann changed the title Draft: feat: implement the code formatting shortcut Draft: Implement the code formatting shortcut Nov 23, 2024
@trevinhofmann trevinhofmann changed the title Draft: Implement the code formatting shortcut Implement the code formatting shortcut Nov 23, 2024
Copy link
Contributor

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! This looks fantastic. Thanks for your thoroughness, and for fitting it in with the other formatting commands.

With document.queryCommandState also being deprecated and non-standard, I also switched to using getCommandState for selected text (rather than only an entire selected thought) for the other commands as well.

That sounds fine, thanks.

Fwiw, I did some research on queryCommandState before adding it to the codebase. Despite its deprecation status, it is very well supported and unlikely to be dropped. But if we have reliable alternatives that are performant and offer the same behavior then I'm happy to use them.


The only issue I found is that it does work in Context View. While Context View is admittedly incomplete, other formatting commands like bold, italic, underline do work there, so I think it's appropriate to add support for format as code. (Notably, text color does not work in Context View.)

Steps to Reproduce

- a
  - m
    - x
- b
  - m
    - y
  1. Set the cursor on a/m
  2. Activate Context View.
  3. Set the cursor on a/m~/a.
  4. Format as code.

Current Behavior

- a
  - <code>a</code>
    - x
- b
  - m
    - y

Expected Behavior

- <code>a</code>
  - m
    - x
- b
  - m
    - y

Comment on lines +24 to +25
const thoughtContentEditable = document.querySelector(`[aria-label="editable-${thought.id}"]`)
if (!thoughtContentEditable) return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't thoughtContentEditable guaranteed to exist if state.cursor is non-null? Or is there a situation I'm not thinking of?


Technically it's possible to have two elements with the same aria-label="editable-${thought.id}" rendered if the context view is open.

Instead, you can select the cursor editable as follows:

document.querySelector(`[data-editing="true"] [data-editable="true"]`)

Still, it would be better to avoid DOM access in the action creator if possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants