Closed Bug 943944 Opened 11 years ago Closed 11 years ago

Caret positioning doesn't work in textarea elements

Categories

(Firefox for Android Graveyard :: Text Selection, defect)

28 Branch
ARM
Android
defect
Not set
normal

Tracking

(firefox25 affected, firefox26 affected, firefox27 affected, firefox28 affected, relnote-firefox 26+, fennec26+)

RESOLVED DUPLICATE of bug 934470
Tracking Status
firefox25 --- affected
firefox26 --- affected
firefox27 --- affected
firefox28 --- affected
relnote-firefox --- 26+
fennec 26+ ---

People

(Reporter: janjongboom, Assigned: Margaret)

References

()

Details

(Keywords: reproducible)

Go to this page in FF for Android beta: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea

Focus on the textarea, caret appears. Try to move the caret.

Caret repositions (and moves cursor) to 0,0 and then disappears.
Thanks for the report.

* In Firefox 25, I can reposition the handle and the cursor repositions to the selected character position but the handle disappears.
* In Firefox 26 and 27, I can reproduce this.
* In Firefox 28, we show no text-selection handle, but the cursor does react and reposition to character position in a text value

There seems to be a complete tossup of behaviour across channels.

Mike/Mark, do you know what the situation is here?
tracking-fennec: --- → ?
Keywords: reproducible
OS: Mac OS X → Android
Hardware: x86 → ARM
Summary: Text Selection doesn't work in textarea elements (FF Beta) → Text selection doesn't work in textarea elements
quick fyi - I was using my own test page recently with a couple (slightly) different textareas ... this seems to work fine for me .... so I'm looking at that page you linked ...

https://www.dropbox.com/s/p3cry1bauneen5k/bug938563name.html
It seems like disabling auto-correct on the keyboard is a workaround. As soon as I disabled auto-correct, I was able to move the text-selection handles and the cursor repositioned properly on Beta (Fx26).
I think this should be release-noted as a workaround for text-selection in a <textarea>.
relnote-firefox: --- → ?
I tried both the default keyboard and TouchPal, which seem to repro in the same way on both FF 26 and 28.

It seems the issue is caused when the handle order is reversed (i.e. the back handle is moved in front of the front handle in the text or vice versa), especially when the back handle is moved earlier in the text than the first. When you hold the handle and stop moving, auto-correct will activate on the IME. Sometimes, text will start to be removed (perhaps because auto-correct starts correcting?), which is pretty problematic.

I'm not sure what the cause might be.
That sounds like bug 908861 ... but I thought that got into v26
(In reply to Aaron Train [:aaronmt] from comment #4)
> I think this should be release-noted as a workaround for text-selection in a
> <textarea>.

i turned off auto-correct on my Nexus 4, Android 4.4 KitKat (Settings | Language and Input | Google Keyboard English (US) tap on the right | Auto-correction | Tap "Off") and the problem continues to occur in both FF 25.0.1 and FF 26 beta
We just completed bug 934470 which was causing loss of text selection"handles/caret" in a textarea ... I think this fix only made it to m-c so far and might be what you're seeing? 

Also, the original bug points out https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea which is a case of a textarea in an iframe that does appear to be a problem I hadn't seen yet ...

The auto-correction issue mentioned in comments #3 and #4 is similar to another open issue bug 927882
Also I note that the google keyboard setting "Show correction suggestions" if in use (not set to "Always Hide") causes this issue, similar to "auto-correction".
Thanks for the correction, yes that is what it's required.
Hmmm ... it seems that in the original comment, the <textarea> in an iframe causes SelectionHandler.js in the _getHandlePositions()/checkHidden() method to believe the handle/caret is "hidden".

http://mxr.mozilla.org/mozilla-central/source/mobile/android/chrome/content/SelectionHandler.js?mark=739-739#728

The "y" value passed in to checkHidden() includes (cursor.top + cursor.height) which is then compared (>) to the bounds.height and considered "hidden == true", or out of the iframe.

I wonder if we need to take into account the top position of the iframe or somesuch?
Flags: needinfo?(margaret.leibovic)
(In reply to Mark Capella [:capella] from comment #11)
> Hmmm ... it seems that in the original comment, the <textarea> in an iframe
> causes SelectionHandler.js in the _getHandlePositions()/checkHidden() method
> to believe the handle/caret is "hidden".
> 
> http://mxr.mozilla.org/mozilla-central/source/mobile/android/chrome/content/
> SelectionHandler.js?mark=739-739#728
> 
> The "y" value passed in to checkHidden() includes (cursor.top +
> cursor.height) which is then compared (>) to the bounds.height and
> considered "hidden == true", or out of the iframe.
> 
> I wonder if we need to take into account the top position of the iframe or
> somesuch?

This is about the time my brain starts to hurt, but maybe we need to use the offset in the checkHidden() call for TYPE_CURSOR. Currently we don't use it for the x/y we pass as the left/top values for the handle, since the cursor left/top already account for the sub-frame offset. Basically, I'm suggesting we do the opposite of what we do down below for TYPE_SELECTION.

Something like:

let offset = this._getViewOffset();
let x = cursor.left / window.devicePixelRatio;
let y = (cursor.top + cursor.height) / window.devicePixelRatio;
return [{ handle: this.HANDLE_TYPE_MIDDLE,
          left: x + scroll.X,
          top: y + scroll.Y,
          hidden: checkHidden(x - offset.x, y - offset.y) }];
Flags: needinfo?(margaret.leibovic)
Let's figure this out ASAP
tracking-fennec: ? → 26+
On release, I find that the handle disappears when I start to drag it in both inputs and textareas in this testcase:
http://people.mozilla.org/~mleibovic/test/text_select.html

I don't know how we missed this earlier :( Capella, I'll help you dig into figuring this out.
Can you verify this?

On my N7 with Google Keyboard, the selection handles work for me in all the text and input fields. The caret:move works for the first two editables.

For the two editables in the center/enclosed block, (especially noticable if I zoom in), the caret:move fails such that:
   In the first enclosed editable, the caret sticks to the left-most side of the field.
   In the second enclosed editable, it moves around in the two-row field, but stays stuck inside the top-edge.

I'm looking at testing your idea from above, and switching to my G3 and varying the keyboard, and etc.

fyi, the fix I posted for bug 947284 doesn't seem to be related to this problem. (Different issue)
Using the remote debugger (awesome for debugging this JS btw), I'm finding that we run into an exception where this._contentWindow is null in this._getScrollPosition when we're calling this._positionHandles() from the "TextSelection:Move" listener.

Looking through the changes to SelectionHandler.js that landed for 26, there are a lot, so it's hard to pinpoint what might have caused this regression, but I'm guessing we're calling _deactivate() when we don't mean to.

I'm going to continue to debug to see if I can find the culprit.

I'm testing with an N4 with Google Keyboard, and to clarify my previous comment, I'm only investigating the problem with the caret handle (not the normal text selection left/right handles).
Updating the summary to make the situation clearer.
Summary: Text selection doesn't work in textarea elements → Caret positioning doesn't work in textarea elements
Assignee: nobody → margaret.leibovic
fyi-

I thought I saw a situation where we can be calling _deactivate() before we need to be. It's possible in both the startSelection() and attachCaret() situations ...

Basically, we get an entry into SelectionHandler via one of those methods from browser.js ... each of those routines calls deeper to the _initTargetInfo() part ... there we set (this._targetElement) and then return ... but before we can return to either startSelection() or attachCaret() for method completion, javascript seems to pass control back to browser (I'm guess some asynch/lazy-load mech at work here).

At this point addEventListener("pagehide"); is enabled in SelectionHandler and allows those events to be heard in handleEvent() where we this._closeSelection(); (which does nothing due to this.activeType == this.TYPE_NONE(?))

|this._activeType| was never set to this.TYPE_SELECTION; or this.TYPE_CURSOR; due to the original call to startSelection() /or attachCaret() not receiving control back from the finished-but-interupted flow after _initTargetInfo() ...

So the new routine SelectionHandler().isSelectionActive() basically reports FALSE as (this._activeType == this.TYPE_SELECTION) isn't true for a brief period of time. This isn't actually true as we've started valid entry into SelectionHandler but not completed it.
 
When control gets back from _initTargetInfo() to startSelection() or attachCaret() to complete the process, |this.activeType| finally gets set to this.TYPE_SELECTION; or this.TYPE_CURSOR and SelectionHandler().isSelectionActive() starts reporting correctly.

It looks like to me, there is a window where we hear events while partially initialized.

I'm still looking ...
Aha, I think the carat issue here is a dupe of bug 934470, which just needs to be uplifted.

I just made a build of beta with that patch uplifted, and the carat seems to work great for me in inputs/textareas both outside and inside iframes. I'm going to request uplift for that patch to beta.

However, that means that if there's some problem here on 28/29, something else must have caused a regression. Let's continue to investigate this, perhaps we can track down a regression range.
It looks to me like uplifting bug 943944 will fix the problems we're seeing on 26/27, so I moved the tracking-fennec:26+ over to that bug. I'm re-noming this bug, since it sounds like it's more about an issue that appeared on 28.

Aaron (or anyone else), can you help me understand exactly what the problem is on 28/29? The only issue I'm seeing is that it take two taps for the caret handle to actually appear, but maybe that's intentional from the action bar changes?

We should update the summary (again) to represent what that new problem is.
tracking-fennec: 26+ → ?
Flags: needinfo?(aaron.train)
* Firefox 28 & 29 (Nightly/Aurora): Current state is a lot better, I can reposition the cursor handle anywhere in a <textarea> with content and I'm not seeing what's reported in comment #0

On both builds I am seeing a new issue in that on caret positioning, the caret will flash at the end character of the text value in the element and then reposition accordingly. New bug?

I am using: data:text/html,<textarea>testcase bug 943944</textarea> as a test-case.

Not seeing any difference using the MDN test-case in comment #0 either.
Flags: needinfo?(aaron.train)
Is that what we discussed earlier in comment 7 thorough 9? ... similar to bug 927882? ... bug 927882 is labelled a swiftkey problem, but I don't think the autoComplete/autoSuggest/etc is SwiftKeyboard specific ... also I'm not sure it's a text selection issue or a keyboard (GetkoEditable, InputConnection) issue there ...
tracking-fennec: ? → 26+
I'm duping this to bug 934470, since that actually fixed the big problem described here.

Let's file new bugs for any other issues that still exist, since it's hard to follow what's going on in this bug at this point :)
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → DUPLICATE
Product: Firefox for Android → Firefox for Android Graveyard
You need to log in before you can comment on or make changes to this bug.