ScottyLabs / HackerHelp

TartanHacks 2017 mentor request and dispatch system
1 stars 0 forks source link

How to identify input boxes on Facebook, YouTube, etc. which are <div>s instead of <input> or <textarea> #22

Closed jchang504 closed 7 years ago

jchang504 commented 7 years ago

Hacker name(s): Jemmin Chang, Sung Kim, Rachel Min, Maxine Kwan Physical location: UC Connan Operating system(s): Chrome 56.0.2924.87 (running on Ubuntu 14.04, but irrelevant) Programming Langugage: JavaScript

Description

For our hack, we're writing a Chrome extension and part of the functionality requires capturing certain key combinations. We want to avoid capturing these keys when the user is focused on an input box (e.g. <input> or <textarea> element). Looking at Facebook, YouTube (and I'm sure other websites) though, I've noticed that they use <div>s (with custom JavaScript presumably) for input boxes. How can we detect that the user has clicked on one of these special input boxes to enter text so that we can stop listening for keys and let the normal text entry occur? Is there some distinctive class on <div>s used for this purpose that we can rely on robustly being present to identify these input boxes? There seem to be some framework-specific classes on them (e.g. aria-autocomplete, data-contents), but I don't know if we can reliably use these as indicators.

We know that this problem can be solved somehow, as the Vimium extension for Chrome does it (it detects all the input boxes on a normal Facebook page, even though they're <div>s).

Any ideas or suggestions? Thank you!

Screenshots

Post input box on TartanHacks event page on Facebook. Inspector shows it's a <div> rather than an <input> or <textarea>.

screenshot from 2017-02-10 22 54 03

weihang7 commented 7 years ago

See http://www.w3schools.com/tags/att_global_contenteditable.asp.

jez commented 7 years ago

Yeah to re-iterate was said in the article that @weihang7 linked:

You should be able to select for 'div[contenteditable="true"]' in addition to selecting for things like input or textarea.

contenteditable is a pretty complex API, but it gives much more control over the typing/editing experience than a simple input. Lots of apps (Medium, Gmail, Dropbox Paper, etc.) put a lot of work into making contenteditable easier to work with in order to build their apps. If your curious to learn about Medium's escapades with contenteditable, check out this article.

jchang504 commented 7 years ago

Thanks guys. This works great to identify these input elements, but now I'm realizing we still have a problem. We are trying to have our extension capture keypresses all the time, except when the user is entering text into some input element. With traditional <input> and <textarea>, this is easy by registering an event handler which turns off our keypress-listener when they focus the element and turns it back on when they blur. But according to JQuery docs, focus only applies to inherent input tags (<input>, <select>) and tags with the tabindex property set. Looking at Facebook's message box inputs, I don't see this property used on them. So I can't figure out what event to listen to know when to deactivate and reactive keypress-listening for these input elements. Any ideas? Thanks for the help.

jez commented 7 years ago

So not sure if this is still an issue for you guys or if you figured it out. One thing that you might have to do (which is certainly less than ideal) is this:

  1. register a listener for key events
  2. in that listener, get the "active element" (document.activeElement)
  3. check if the active element is contenteditable

(This is less than ideal because it means you're doing a bunch more DOM lookups than you maybe you'd like to, but I think it'd probably be correct. I only just learned about this document.activeElement property. From MDN:

Returns the currently focused element, that is, the element that will get keystroke events if the user types any. This attribute is read only.

You can read more about it here.

jchang504 commented 7 years ago

Thanks Jake. We ended up changing our approach, but this is really good to know about. This turned out to be a really interesting complex problem that will be good to look at with more time.