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

Android ignores unicode soft hyphen (u00AD) #28279

Closed
ccfz opened this issue Mar 10, 2020 · 15 comments
Closed

Android ignores unicode soft hyphen (u00AD) #28279

ccfz opened this issue Mar 10, 2020 · 15 comments
Labels

Comments

@ccfz
Copy link

ccfz commented Mar 10, 2020

Description:
On android soft-hyphen unicode u00AD is ignored, neither the word break nor the hyphen are displayed correctly. Using u200B is a workaround for getting better word wrapping results but is still missing the hyphen.

React Native version:

System:
    OS: macOS 10.15.3
    CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
    Memory: 108.98 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 13.10.1 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.13.7 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3, 29.0.0, 29.0.1
      System Images: android-28 | Google Play Intel x86 Atom, android-29 | Intel x86 Atom_64
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6241897
    Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.12.0 => 16.12.0 
    react-native: 0.61.5 => 0.61.5 
  npmGlobalPackages:
    react-native-cli: 2.0.1

Steps To Reproduce

Render the following on android vs. iOS

const testString = 'sup\u00ADer\u00ADfrag\u00ADilis\u00ADtice\u00ADxpial\u00ADidocious'

return (
  <View>
    <Text style={{ width: 100 }}>
      {testString}
    </Text>
  </View>
);

Expected Results

Screenshot from iOS
IMG_DB2643BEA609-1

Actual Result

Screenshot from Android
IMG_25E611476E59-1

@plaa
Copy link

plaa commented Apr 2, 2020

This makes it very hard / practically impossible to get proper when-needed hyphenation on Android. iOS works perfectly and is easy to make buttons that properly wrap the text only when needed.

@lennartdemeij
Copy link

What would the 'very hard' way be to get the hyphenation working on Android with this version of React Native? I'm experiencing the same bug...

@ccfz
Copy link
Author

ccfz commented Jun 16, 2020

Good question, you would need to build some kind of regex/matcher that checks for u200B followed by a new line and append "-" if it matches. Don't know if that is possible but it would be my first guess for a workaround.

@fabOnReact

This comment has been minimized.

@lennartdemeij
Copy link

lennartdemeij commented Jun 16, 2020

EDIT: I found a more-or-less workable solution: onTextLayout gives you the lines, now you can check the last character and change it. So I've replaced \u00AD with \u200B and then this code works:

<Text
 onTextLayout={({ nativeEvent: { lines } }) => {
  if (Platform.OS === "android") {
   this.hyphenAndroid(lines);
  }
 }}
>
 Some Long text
</Text>

------------

hyphenAndroid(lines) {
    let hyphenedText = "";
    lines.forEach((line) => {
      if (line.text.substr(line.text.length - 1) === "\u200B") {
        hyphenedText += line.text.substr(0, line.text.length - 1) + "- ";
      } else {
        hyphenedText += line.text;
      }
    });
   //Change the text of the element to hyphenedText
  }
}

@ochrstn
Copy link

ochrstn commented Jun 16, 2020

hyphenedText += line.text.substr(0, line.text.length - 1) + "- ";

With this solution I have some weird effects because the changed text (additional "- ") is triggering the onTextLayout again, which is performing changes again because the text has to change again ... in an endless loop 🔁

@lennartdemeij
Copy link

lennartdemeij commented Jun 16, 2020

I'm checking for that as well.

if (line.text.substr(line.text.length - 2) === "- ") {
 alreadyHyphenated = true;
}

and I don't change the text again if alreadyHyphenated === true

I know it's not perfect (yet), but it is a step in the right direction I think. Not it's just eliminating these quirks.
It also sometimes brings the hyphenated word to the next line because the added dash pushes it over the edge. I'll have to think of a solution for that as well...

@ochrstn
Copy link

ochrstn commented Jun 16, 2020

It also sometimes brings the hyphenated word to the next line because the added dash pushes it over the edge. I'll have to think of a solution for that as well...

Yes, that's what I'm experiencing right now too. Almost all dashes are within the words because the new lines breaks are different after adding the dashes.

@fabOnReact
Copy link
Contributor

fabOnReact commented Jun 17, 2020

as we can read in this medium article it is possible on android thanks to setHyphenationFrequency

so I solved this in native code like this in ReactTextView.java:

  const testString = 'sup\u00ADer\u00ADfrag\u00ADilis\u00ADtice\u00ADxpial\u00ADidocious'

renders as:

image

I'll write a pull request to add a prop <Text androidHyphenationFrequency="normal" />
You can then checkout my branch and install in your app the forked version of react-native that includes this fix, in 1-3 months they will publish an npm package and you can go back using the react-native master package.

https://github.com/facebook/react-native/wiki/Building-from-source#publish-your-own-version-of-react-native

Thanks a lot. Fabrizio

facebook-github-bot pushed a commit that referenced this issue Jul 2, 2020
Summary:
JoshuaGross This issue fixes #28279 as discussed in #29157 (comment)
Avoid calling [setHyphenationFrequency](https://developer.android.com/reference/android/widget/TextView#setHyphenationFrequency(int)) on Android Sdk < 23.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[Android] [Fixed] - do not call setHyphenationFrequency on AndroidSdk < 23
Pull Request resolved: #29258

Test Plan:
| **BEFORE** | **AFTER** |
|:-------------------------:|:-------------------------:|
|  <img src="https://user-images.githubusercontent.com/24992535/86214122-05bf0e00-bb7b-11ea-93b5-2174812bfec9.png"  width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/86214130-08216800-bb7b-11ea-9fc0-68b28638bf57.png" width="300" height="" /> |

The warning displayed with `adb logcat | grep -P "ReactTextAnchorViewManager"`

![image](https://user-images.githubusercontent.com/24992535/86214242-34d57f80-bb7b-11ea-9945-30ae25332bfb.png)

I remain available to do improvements. Thanks a lot. Fabrizio.

Reviewed By: JoshuaGross

Differential Revision: D22337095

Pulled By: mdvacca

fbshipit-source-id: d0943397af180929c48044ccbc7a9388549021b8
@fabOnReact
Copy link
Contributor

this functionality will be available with 0.64 https://github.com/react-native-community/releases/blob/20a632d3a61153f813c020ef2c6bca6910958a10/CHANGELOG.md Thanks 🙏

@AnisDerbel
Copy link

Can someone confirm here that this is working in react-native 0.64? because it is not working for me (tested with device > v23) cc @fabriziobertoglio1987

@leethree
Copy link

leethree commented May 6, 2021

it doesn't work for me either.

@henrik-d
Copy link

@fabriziobertoglio1987 It does not work for me either.

 const testString = 'sup\u00ADer\u00ADfrag\u00ADilis\u00ADtice\u00ADxpial\u00ADidocious';

  return (
    <Text style={{ fontSize: 32, color: 'white' }} android_hyphenationFrequency={'normal'}>
      {testString}
    </Text>
  );

The word is breaking superfragilisticexpiaid ocious and without hyphen. Is there something wrong with my code?

@fabOnReact
Copy link
Contributor

fabOnReact commented May 19, 2021

https://developer.android.com/reference/android/widget/TextView#setHyphenationFrequency(int)

setHyphenationFrequency
Sets the frequency of automatic hyphenation to use when determining word breaks.

seems that setHyphenationFrequency allows us to use automatic hyphenation

@luanccp
Copy link

luanccp commented Jun 8, 2021

it doesn't work for me either.
@fabriziobertoglio1987 do you have some code examples?

@facebook facebook locked as resolved and limited conversation to collaborators Oct 1, 2021
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Oct 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet