Skip to content
Open
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
11 changes: 10 additions & 1 deletion doc/example/simple.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@ export default class Page extends PureComponent {
static propTypes = {};
static defaultProps = {};

onLinkPress = (url) => {
if (url) {
// some custom logic
}
// return true to open with `Linking.openURL
// return false to handle it yourself
return true
}

render() {
return (
<Markdown>{copy}</Markdown>
<Markdown onLinkPress={this.onLinkdPress}>{copy}</Markdown>
);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export default class Markdown extends Component {
static propTypes = {
children: PropTypes.node.isRequired,
renderer: PropTypes.oneOfType([PropTypes.func, PropTypes.instanceOf(AstRenderer)]),
onLinkPress: PropTypes.func,
rules: (props, propName, componentName) => {
let invalidProps = [];
const prop = props[propName];
Expand Down Expand Up @@ -163,7 +164,8 @@ export default class Markdown extends Component {
{
...styles,
...style,
}
},
props.onLinkPress
);
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/lib/AstRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export default class AstRenderer {
* @param {Object.<string, function>} renderRules
* @param {any} style
*/
constructor(renderRules, style) {
constructor(renderRules, style, onLinkPress) {
this._renderRules = renderRules;
this._style = style;
this._onLinkPress = onLinkPress;
}

/**
Expand Down Expand Up @@ -56,6 +57,10 @@ export default class AstRenderer {
return this.renderNode(value, parents);
});

if (node.type === "link" || node.type === "blocklink") {
return renderFunction(node, children, parentNodes, this._style, this._onLinkPress);
}

return renderFunction(node, children, parentNodes, this._style);
};

Expand Down
12 changes: 8 additions & 4 deletions src/lib/renderRules.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,21 @@ const renderRules = {
);
},
// a
link: (node, children, parent, styles) => {
link: (node, children, parent, styles, onLinkPress) => {
return (
<Text key={node.key} style={styles.link} onPress={() => openUrl(node.attributes.href)}>
<Text key={node.key} style={styles.link} onPress={() => openUrl(node.attributes.href, onLinkPress)}>
{children}
</Text>
);
},
// a with a non text element nested inside
blocklink: (node, children, parent, styles) => {
blocklink: (node, children, parent, styles, onLinkPress) => {
return (
<TouchableWithoutFeedback key={node.key} onPress={() => openUrl(node.attributes.href)} style={styles.blocklink}>
<TouchableWithoutFeedback
key={node.key}
onPress={() => openUrl(node.attributes.href, onLinkPress)}
style={styles.blocklink}
>
<View style={styles.image}>{children}</View>
</TouchableWithoutFeedback>
);
Expand Down
9 changes: 7 additions & 2 deletions src/lib/util/openUrl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { Linking } from 'react-native';

export default function openUrl(url) {
if (url) {
export default function openUrl(url, customCallback) {
if (customCallback) {
const result = customCallback(url);
if (url && result && typeof result === 'boolean') {
Linking.openURL(url);
}
} else if (url) {
Linking.openURL(url);
}
}