From 582db04da1bcf7d2f6ddc592c4b10d1d7347e117 Mon Sep 17 00:00:00 2001 From: Chris Duarte Date: Thu, 26 Oct 2017 09:52:41 -0700 Subject: [PATCH] Force url's to be normalized (#1058) * Force url's to be normalized * Refactor and move behind config flag --- app/components/markdown/markdown_link.js | 50 +++++++++++++++++++----- assets/base/config.json | 4 +- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/app/components/markdown/markdown_link.js b/app/components/markdown/markdown_link.js index 0ce662041..6bc9b115b 100644 --- a/app/components/markdown/markdown_link.js +++ b/app/components/markdown/markdown_link.js @@ -1,11 +1,13 @@ // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import React, {PureComponent} from 'react'; +import React, {Children, PureComponent} from 'react'; import PropTypes from 'prop-types'; import {Linking, Text} from 'react-native'; +import urlParse from 'url-parse'; import CustomPropTypes from 'app/constants/custom_prop_types'; +import Config from 'assets/config'; export default class MarkdownLink extends PureComponent { static propTypes = { @@ -20,13 +22,7 @@ export default class MarkdownLink extends PureComponent { handlePress = () => { // Android doesn't like the protocol being upper case - let url = this.props.href; - - const index = url.indexOf(':'); - if (index !== -1) { - const protocol = url.substring(0, index); - url = protocol.toLowerCase() + url.substring(index); - } + const url = this.props.href; Linking.canOpenURL(url).then((supported) => { if (supported) { @@ -35,13 +31,49 @@ export default class MarkdownLink extends PureComponent { }); }; + parseLinkLiteral = (literal) => { + let nextLiteral = literal; + + const WWW_REGEX = /\b^(?:www.)/i; + if (nextLiteral.match(WWW_REGEX)) { + nextLiteral = literal.replace(WWW_REGEX, 'www.'); + } + + const parsed = urlParse(nextLiteral, {}); + + return parsed.href; + } + + parseChildren = () => { + return Children.map(this.props.children, (child) => { + if (!child.props.literal || typeof child.props.literal !== 'string' || (child.props.context && child.props.context.length && !child.props.context.includes('link'))) { + return child; + } + + const {props, ...otherChildProps} = child; + const {literal, ...otherProps} = props; + + const nextProps = { + literal: this.parseLinkLiteral(literal), + ...otherProps + }; + + return { + props: nextProps, + ...otherChildProps + }; + }); + } + render() { + const children = Config.ExperimentalNormalizeMarkdownLinks ? this.parseChildren() : this.props.children; + return ( - {this.props.children} + {children} ); } diff --git a/assets/base/config.json b/assets/base/config.json index fbf60855f..584c797bd 100644 --- a/assets/base/config.json +++ b/assets/base/config.json @@ -23,7 +23,9 @@ "console": true } }, - + + "ExperimentalNormalizeMarkdownLinks": false, + "AutoSelectServerUrl": false, "EnableMobileClientUpgrade": false,