meliorence / react-native-render-html

iOS/Android pure javascript react-native component that renders your HTML into 100% native views
https://meliorence.github.io/react-native-render-html/
BSD 2-Clause "Simplified" License
3.47k stars 587 forks source link

Renderer does not support strike and underline (<s> and <u>) at the same time #529

Open swengle opened 2 years ago

swengle commented 2 years ago

Decision Table

Good Faith Declaration

Description

The renderer supports strike and underline, except when they are both together.

<html><head></head><body><p><s><u>The fox jumped</u></s></p></body></html>

Renders just the underline.

React Native Information

Expo CLI 4.12.0 environment info:
    System:
      OS: Linux 4.14 Amazon Linux 2
      Shell: 4.2.46 - /bin/bash
    Binaries:
      Node: 14.17.1 - ~/.nvm/versions/node/v14.17.1/bin/node
      npm: 6.14.13 - ~/.nvm/versions/node/v14.17.1/bin/npm
    npmPackages:
      expo: ~42.0.1 => 42.0.4 
      react: 16.13.1 => 16.13.1 
      react-dom: 16.13.1 => 16.13.1 
      react-native: https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz => 0.63.2 
      react-native-web: ~0.13.12 => 0.13.18 
    npmGlobalPackages:
      expo-cli: 4.12.0
    Expo Workflow: managed

RNRH Version

6.1.0

Tested Platforms

Reproduction Platforms

Minimal, Reproducible Example

"use strict";
import React from "react";
import { SafeAreaView } from 'react-native-safe-area-context';
import RenderHtml from 'react-native-render-html';
import { Dimensions } from 'react-native';

class simple_test_case extends React.Component {
  constructor(props, context) {
    super(props, context);
  }

  render() {
    const window_dimensions = Dimensions.get('window');
    return (
      <SafeAreaView style={{flex:1}}>
        <RenderHtml 
          source={{html: "<html><head></head><body><p><s><u>The fox jumped</u></s></p></body></html>"}}
          contentWidth={window_dimensions.width} 
        />
      </SafeAreaView>
    );
  }
}

export default simple_test_case;

Additional Notes

No response

jsamr commented 2 years ago

@swengle Thanks for your submission! Indeed there is an "underline line-through" value available in React Native textDecorationLine style property so a solution is technically possible. That will have to be handled in the @native-html/css-processor library. I am busy right now with the 6.2 release, but I will address this at some point.

jsamr commented 2 years ago

After reading more about the CSS3 specification (https://www.w3.org/TR/css-text-decor-3/#line-decoration), I realize that this specific CSS property does not follow the traditional inheritance scheme, where a close rule would override a distant rule, but instead relies on some sort of merging mechanism that propagates to the CSS box tree, while sometimes aborting, such as when hitting an out-of-flow box (think float: left or position: absolute). In the end, the propagation model is fairly complex:

Note that text decorations are not propagated to any out-of-flow descendants, nor to the contents of atomic inline-level descendants such as inline blocks and inline tables. They are also not propagated to inline children of inline boxes, although the decoration is applied to such boxes.

Note: Line decorations are propagated through the box tree, not through inheritance, and thus have no effect on descendants when specified on an element with display: contents.

This exception to the rule makes an implementation costly, because it would require a re-architecture of the CSS processor. For that very reason, I don't plan on providing this feature anytime soon! But I will let the issue open in the meantime.