Skip to content

feat(markdown): Add support for details tag #609

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions src/components/github-htmlview.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ const quotedEmailToggleStyle = {
marginTop: 3,
};

const detailsSummaryPrefixStyle = {
alignSelf: 'flex-start',
lineHeight: normalize(20),
fontSize: normalize(20),
marginRight: 3,
};

const styleSheet = StyleSheet.create(styles);

const { width } = Dimensions.get('window');
Expand Down Expand Up @@ -197,6 +204,8 @@ export class GithubHtmlView extends Component {
/<span class="email-hidden-toggle"><a href="#">…<\/a><\/span>/g,
''
)
.replace(/<\/summary>/g, '</summary><hidden>')
.replace(/<\/details>/g, '</hidden></details>')
// Remove links & spans around images
.replace(/<a[^>]+><img([^>]+)><\/a>/g, '<img$1>')
.replace(/<span[^>]*><img([^>]+)><\/span>/g, '<img$1>')
Expand Down Expand Up @@ -243,7 +252,7 @@ export class GithubHtmlView extends Component {
<View key={index}>{defaultRenderer(node.children, node)}</View>
),
code: (node, index, siblings, parent, defaultRenderer) => {
if (parent.name === 'pre') {
if (parent && parent.name === 'pre') {
return (
<SyntaxHighlighter
key={index}
Expand Down Expand Up @@ -294,6 +303,39 @@ export class GithubHtmlView extends Component {

return undefined;
},
details: (node, index, siblings, parent, defaultRenderer) => {
const tags = onlyTagsChildren(node);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice nice nice 🎉
Let's check that there are indeed two tags and that they are indeed summary and hidden.
Define them here with consts for later use

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I'm thinking how we should handle the case of no summary or no hidden tags in details tag.
May need a default summary and empty hidden for this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't really happen I think, but I'm ok with your suggestion
The goal is to avoid a crash on [1]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What [1] means?

const firstTag = tags[0] || {};
const secondTag = tags[1] || {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vitalkanev I was referring to these calls that were in the middle of the jsx

const summaryTag =
firstTag.name === 'summary'
? firstTag
: { type: 'text', data: 'details' };
const hiddenTag = secondTag.name === 'hidden' ? secondTag : {};

return (
<ToggleView
TouchableView={collapse => {
const prefix = collapse ? '▸' : '▾';

return [
<Text style={detailsSummaryPrefixStyle}> {prefix}</Text>,
defaultRenderer([summaryTag], node),
];
}}
TouchableStyle={{
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
}}
>
{defaultRenderer([hiddenTag], node)}
</ToggleView>
);
},
summary: (node, index, siblings, parent, defaultRenderer) => {
return <View>{defaultRenderer(node.children, parent)}</View>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <View> wrapper is not needed here

},
img: (node, index, siblings, parent, defaultRenderer) => {
if (hasAncestor(node, ['ol', 'ul', 'span'])) {
return (
Expand Down Expand Up @@ -385,7 +427,7 @@ export class GithubHtmlView extends Component {
</Text>
);
},
};
}; // end of renders object

if (_node.type === 'text') {
if (_node.data === '\n') {
Expand Down
21 changes: 16 additions & 5 deletions src/components/toggle-view.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export class ToggleView extends Component {
props: {
children: any,
TouchableView: any,
TouchableStyle: any,
};

state: {
Expand All @@ -24,15 +25,25 @@ export class ToggleView extends Component {
this.setState({ collapsed: !this.state.collapsed });
}

renderTouchableView() {
const { TouchableView } = this.props;

if (TouchableView instanceof Function) {
return TouchableView(this.state.collapsed);
}

return TouchableView;
}

render() {
const { children, TouchableStyle = {} } = this.props;

return (
<View>
<TouchableOpacity onPress={() => this._toggle()}>
{this.props.TouchableView}
<TouchableOpacity onPress={() => this._toggle()} style={TouchableStyle}>
{this.renderTouchableView()}
</TouchableOpacity>
<Collapsible collapsed={this.state.collapsed}>
{this.props.children}
</Collapsible>
<Collapsible collapsed={this.state.collapsed}>{children}</Collapsible>
</View>
);
}
Expand Down