Closed mineminemine closed 3 years ago
<ol>
<li>Tea</li>
<li>Coffee</li>
<ul>
<li>Dog</li>
<li>Cat</li>
</ul>
</ol>
Now that I look at it again, having the ol and ul the other way around would also give unwanted result. https://snack.expo.dev/qDwgiy5Ti
@mineminemine Did you try to validate your HTML snippet against W3C validator such as recommended in our guidelines? The test fails because you can only have li
as children of ul
and ol
:
@mineminemine Since it is non-compliant, the parser library (htmlparser2) attempts a fix by wrapping ol
with li
element!
@jsamr Oh my god, truly sorry for this. This just goes to show that I've been doing nested list wrongly all these years.. I'll just close this issue since mistake was on my end. Sorry and thank you for your time.
@mineminemine no worries, we all make mistakes :-) Browsers are kind of unhelpful to learn those things because of their laxness...
Hello, I'm facing the same problem, and after reading this thread I found out that the issue is the malformed html and not the react-native-render-html.
Do you know any library or function that transforms an html with this format:
<ol>
<li>Tea</li>
<li>Coffee</li>
<ul>
<li>Dog</li>
<li>Cat</li>
</ul>
</ol>
to this (the right way):
<ol>
<li>Tea</li>
<li>Coffee
<ul>
<li>Dog</li>
<li>Cat</li>
</ul>
</li>
</ol>
Thank you, Federico
@federicoeventifica If you want to do this transformation front-wise, you could use DOM tempering features available in this library, see this documentation page: https://meliorence.github.io/react-native-render-html/docs/guides/dom-tampering
Hello, i have more questions after federicoeventifica's post the validator used above claims the following is invalid, as previously discussed.
<ul>
<li>Outer</li>
<ul>
<li>Inner</li>
</ul>
</ul>
but i would expect the right way to be the following:
<ul>
<li>Outer</li>
<li>
<ul>
<li>Inner</li>
</ul>
</li>
</ul>
that code passes validation using the tool but is still rendered incorrectly by the library
federicoeventifica's method above or putting the nested list inside of the previous element seems like a hack to me, but also passes validation so i tried it and theres an unexpected line break
<ul>
<li>Outer
<ul>
<li>Inner</li>
</ul>
</li>
</ul>
@KevinUreAtIndustryX0
that code passes validation using the tool but is still rendered incorrectly by the library
Below is a snapshot of this snippet rendered in Mozilla Firefox:
What are you expecting exactly?
there's an unexpected line break
By “rendering incorrectly” you mean “not as many User Agents would”, which is often a matter of how their embedded stylesheet looks like. Although we try to match popular browsers' styles more than we don't, there is no standard requirement regarding those styles and we don't claim such informal compliance.
If you don't want this behavior, you could implement a custom renderer which removes any top / bottom margins in nested lists such as (typescript example):
import React from 'react';
import {SafeAreaView, useWindowDimensions} from 'react-native';
import RenderHTML, {CustomBlockRenderer} from 'react-native-render-html';
const htmlContent = `
<ul>
<li>Outer
<ul>
<li>Inner</li>
</ul>
</li>
</ul>
`;
const CustomListRenderer: CustomBlockRenderer = ({
InternalRenderer,
...props
}) => {
const fixMarginStyle =
props.tnode.markers.olNestLevel >= 1 || props.tnode.markers.ulNestLevel >= 1
? {marginTop: 0, marginBottom: 0}
: null;
return (
<InternalRenderer {...props} style={{...props.style, ...fixMarginStyle}} />
);
};
const renderers = {
ol: CustomListRenderer,
ul: CustomListRenderer,
};
export default function App() {
const {width} = useWindowDimensions();
return (
<SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
<RenderHTML
renderers={renderers}
source={{html: htmlContent}}
contentWidth={width}
/>
</SafeAreaView>
);
}
PS: Note that with the upcoming v6.2 release, you'll be able to define user agent styles with more ease.
EDIT: added notes about compliance considerations.
@jsamr
If you don't want this behavior, you could implement a custom renderer which removes any top / bottom margins in nested lists such as (typescript example):
import React from 'react'; import {SafeAreaView, useWindowDimensions} from 'react-native'; import RenderHTML, {CustomBlockRenderer} from 'react-native-render-html'; const htmlContent = ` <ul> <li>Outer <ul> <li>Inner</li> </ul> </li> </ul> `; const CustomListRenderer: CustomBlockRenderer = ({ InternalRenderer, ...props }) => { const fixMarginStyle = props.tnode.markers.olNestLevel >= 1 || props.tnode.markers.ulNestLevel >= 1 ? {marginTop: 0, marginBottom: 0} : null; return ( <InternalRenderer {...props} style={{...props.style, ...fixMarginStyle}} /> ); }; const renderers = { ol: CustomListRenderer, ul: CustomListRenderer, }; export default function App() { const {width} = useWindowDimensions(); return ( <SafeAreaView style={{flex: 1, backgroundColor: 'white'}}> <RenderHTML renderers={renderers} source={{html: htmlContent}} contentWidth={width} /> </SafeAreaView> ); }
Awesome example here, as i dug into the library this was an outstanding question of mine, thank you
What are you expecting exactly?
I'm expecting the circled dot not to be there
@KevinUreAtIndustryX0 you're welcome :-)
I'm expecting the circled dot not to be there
Not sure there is much we can do here! The dot is mandated by the WHATWG standard; any <li>
element will have a marker painted before the block formatting context it creates... You can try this snippet in multiple browsers if you wish, I bet you will find out the dark dot will always be there!
@jsamr i checked in chrome and firefox and it does indeed render the extra dot with the strictly compliant html5 but i also checked it with the example that my CotS backend returns (the strictly invalid html)
<ul>
<li>Outer</li>
<ul>
<li>Inner</li>
</ul>
</ul>
and both of them render what my backend expects them to
so i guess my question is this: is there a way for me to change the behavior of rendered to remove that black dot thats on a line of its own? perhaps using the above custom block renderer?
@KevinUreAtIndustryX0 Unfortunately I don't see an easy workaround. You would have to implement your own custom ul
renderer and implement the feature yourself, or offer a PR to allow this "fault tolerant" behavior...
How to change the bullet icon but keep the content same as with new CustomRenderer(V6) we do not get the React DOM in CustomRendererProps the way we used to get it (V5).
I don't understand if this is still an issue? Is the extra bullet caused by the custom renderer? Because we don't see that with the default renderers with identically nested HTML lists.
I wrote this solution to "clean up" the nested lists, maybe need more styling on the final result, but it works
Funtion:
sanitizeListHTML: (element) => {
if (['ol', 'ul'].includes(element.tagName)) {
const { children } = element;
for (let i = 0; i < children.length; i++) {
const child = children[i];
let nextSibling = children[i + 1];
while (nextSibling && ['ol', 'ul'].includes(nextSibling.tagName)) {
child.children.push(nextSibling);
children.splice(i + 1, 1); // Remove the nested list from its original position
nextSibling = children[i + 1];
}
}
}
},
And usit like this on the component:
<RenderHTML
contentWidth={width}
source={{ html: props.text?.trim() }}
tagsStyles={tagsStyles}
domVisitors={{ onElement: helpers.sanitizeListHTML }}
/>
That's very nifty! Thanks for sharing!
Maybe I'm reading it wrong, but my interpretation is that you're un-nesting the lists, but then I'm confused how the indentation is being handled? The end result looks great though!
That's very nifty! Thanks for sharing!
Maybe I'm reading it wrong, but my interpretation is that you're un-nesting the lists, but then I'm confused how the indentation is being handled? The end result looks great though!
I'm using this https://github.com/meliorence/react-native-render-html/issues/522#issuecomment-946825772 as a solution, making the "correct" format for the HTML to be render.
Very cool! Thanks for taking the time to explain!
Decision Table
<yyy>
is not rendered”Good Faith Declaration
Description
I believe this is a similar issue to this one here #173 but the issue I'm posting now is the other way around.
Code:
Expected result:
Actual result:
React Native Information
RNRH Version
6.1.0
Tested Platforms
Reproduction Platforms
Minimal, Reproducible Example
https://snack.expo.dev/Kgn-_Ny45
Additional Notes
No response