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

Would it be useful to have an activeEditContext property on document? #4

Open
travisleithead opened this issue Apr 21, 2022 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@travisleithead
Copy link
Member

This issue was transferred from MicrosoftEdge/MSEdgeExplainers#97

@snianu opened this issue on 2019-09-06

This question was raised in this thread and we want to see what others think about this scenario.

[continued on 2019-10-10]

We have been trying out different scenarios to test if the script re-entrancy would cause any side effects in EditContext or not. There is one test case where we had issues in how the EditContext was created inside an event handler which was created in a different realm than where the event got fired. Ex:

const child = document.createElement("iframe");
document.body.appendChild(child);
const childDocument = child.contentDocument;
const textarea = childDocument.createElement('textarea');
childDocument.body.appendChild(textarea);
textarea.addEventListener("focusin", e => {
    childDocument.childEditContext = new EditContext()
    childDocument.childEditContext.focus();
    childDocument.childEditContext.addEventListener("textupdate", e => {
      console.log("iframe textupdate event fired");
      child.remove();
    });
childDocument.childEditContext.addEventListener("textformatupdate", e => {
     console.log("iframe textformatupdate event fired");
    });
  });
textarea.focus();

In this scenario, the EditContext is being created on focusin event. This focusin event handler is defined in the context of the parent document so when this event is fired, the EditContext gets initialized and stored in the parent document instead of the contentDocument where it is supposed to be initialized. This leads EditContext to not fire any textupdate/textformatupdate events in the iframe when the user starts a composition inside the iframe. It does fire those events when the user starts the composition outside the iframe.
Based on this scenario we are proposing 3 potential solutions to this problem:

  1. Add an activeEditContext property in the document where the author wants the EditContext to be initialized. This solution requires the web authors to explicitly set the activeEditContext property in the document(also have to check which one is active/inactive) along with managing the focus and blur calls if the author has created multiple EditContexts in multiple documents which also leads to lot of confusion.
  2. Pass the document in the EditContext constructor. This is the solution we would like to pursue as it doesn't have the overhead of managing any properties on the document (active/inactive).
  3. Restrict the web authors to not allow this kind of initialization. This solution is definitely not the ideal and clean solution as the scenario that we mentioned above is a very common pattern used on the web.
    Please let us know your thoughts on this proposal.

@yosinch commented on 2019-10-11

Could you add examples for proposal 1 and 2?
How about EditContext.isActive property?

@snianu commented on 2019-10-15

For#1 We could have a property in the document like document.activeEditContext which is set to the focused EditContext. document.activeEditContext = new EditContext() or have multiple EditContexts and set this property to point to the active one const editContext = new EditContext(); document.activeEditContext = editContext;

For#2 const editContext = new EditContext(document); When editContext.focus() is called, the document in the editContext will be used to set the active EditContext if the document is the active document and fire events to this EditContext later when there is a composition event.
@BoCupp-Microsoft @gked if you want to add more info

@travisleithead commented on 2020-02-12

I like the idea of proceeding with your 2nd option. @snianu want to take a stab at an update for this?

@gdh1995
Copy link

gdh1995 commented Oct 22, 2023

I like this property, and I also expect a property like isInEditContext = true in children nodes of an "edit-context-ed" element:

  • as an web-extension developer, my extension aims to make simple keyboard keys work as shortcuts (like j and k to scroll down/up)
  • so it must detect whether a user is inputing text or not, before triggering its shortcuts
  • before this feature, we may:
    • find DocumentOrFragment::activeElement deeply inside any shadow DOMs
    • check whether it matches the input,textarea,[contenteditable]:not([contenteditable=false]) selector
    • and check its isContentEditable property
  • however, when EditContext is being bound, there's no easy way to detect whether an <a tabindex=0> is editable or not
    • if it's inside such a context, we have to visit all of its ancestor elements
const isInInsertMode = () => {
  const activeElement = visitNestedActiveElement(document)
  if (!(activeElement instanceof HTMLElement)) {
    return false;
  }
  if (activeElement.matches('input,textarea,[contenteditable]:not([contenteditable=false])')) {
    return true
  }
  if (activeElement.isContentEditable) {
    return true
  }
  for (let parent; parent = parent.parentElement; ) {
    if (activeElement.editContext != null) {
      return true
    }
  }
  return false
}

Besides, I expect thes properties (editContext and isInEditContext) is visible across JS worlds, so that my Chrome extension can read them.

@gdh1995
Copy link

gdh1995 commented Oct 22, 2023

(Just address the 2nd request of mine): I've tested Chrome 120 dev, and on http://localhost with document.body.editContext=new EditContext(), my extension's content scripts can not see any clue indicating <body> is editable - obviously editContext is not exposed to other JS worlds.

This is quite annoying, because this means my extension can only always treat keys as shortcuts and then break those rich-text editor web pages.

@dandclark dandclark added the enhancement New feature or request label Oct 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants