You're Invited: Meet the Socket team at BSidesSF and RSAC - April 27 - May 1.RSVP →

react-markdown-github

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-markdown-github - npm Package Compare versions

Comparing version

to
3.0.0

# `react-markdown-github`
### 3.0.0
- [#4] improving headline ID/anchor rendering to be more GH compliant
- [#5] **BREAKING** Change `resolver` prop to `transformLinkUri` to be consistent with `react-markdown`
- Create prop pass-through to provide props to `react-markdown`
### 2.0.0

@@ -20,1 +26,6 @@

- Initial release
[#1]: https://github.com/godaddy/react-markdown-github/pull/1
[#2]: https://github.com/godaddy/react-markdown-github/pull/2
[#3]: https://github.com/godaddy/react-markdown-github/pull/3
[#5]: https://github.com/godaddy/react-markdown-github/pull/5
{
"name": "react-markdown-github",
"description": "React component that renders Markdown similarly to Github's formatting",
"version": "2.0.0",
"main": "lib/index.js",
"browser": "lib/index.js",
"module": "src/index.js",
"version": "3.0.0",
"main": "./lib/index.js",
"browser": "./lib/index.js",
"module": "./src/index.js",
"babel": {

@@ -19,3 +19,3 @@ "plugins": [

"lint": "eslint-godaddy-react src/*.js test/*.js",
"prepublishOnly": "mkdir -p lib && babel -o lib/index.js src/index.js",
"prepublishOnly": "mkdir -p lib && babel -d ./lib src/*.js",
"pretest": "npm run lint",

@@ -64,5 +64,4 @@ "test": "nyc --reporter=text --reporter=json-summary npm run test:mocha",

"react-markdown": "^3.3.0",
"slugify": "^1.2.9",
"url-parse": "^1.4.0"
}
}

@@ -21,3 +21,3 @@ # `react-markdown-github`

  sourceUri='https://github.mycorp.com/org/component/blob/master/README.md'
  resolver={ ({ uri, github, org, repo, filename, filepath }) => { } }
  transformLinkUri={ ({ uri, github, org, repo, filename, filepath }) => { } }
transformImageUri={ ({ uri, github, org, repo, filename }) => {} }

@@ -32,3 +32,3 @@ renderers={ code: myCodeFormatter }

resolved relative to this URL.
- `resolver` URL resolver function. To override the URL resolver and point a url
- `transformLinkUri` URL resolver function. To override the URL resolver and point a url
to an alternate location.

@@ -35,0 +35,0 @@ - `transformImageUri` image URL resolver function. Default behavior is to not modify image urls.

@@ -1,208 +0,7 @@

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactMarkdown from 'react-markdown';
import slugify from 'slugify';
import URL from 'url-parse';
import ReactMarkdownGithub from './component.js';
import GithubSlugify from './gh-slugify.js';
const isHash = /^#/;
/**
* A react component that wraps [react-markdown](react-markdown) that:
* - links all headers with an anchor link.
* - resolves all relative links to absolute Github URLs based on the sourceUri of the document.
* e.g. /foo/bar.md becomes https://github.mycorp.com/org/component/blob/master/foo/bar.md
* - allows the parent component to override the resolved url
*
* @class ReactMarkdownGithub
* @api public
*/
export default class ReactMarkdownGithub extends Component {
constructor() {
super(...arguments);
this.transformLinkUri = this.transformLinkUri.bind(this);
this.renderHeading = this.renderHeading.bind(this);
this.transformImageUri = this.transformImageUri.bind(this);
this.slugs = {};
this.state = {};
}
/**
* Parses url into usable github components.
* @param {String} uri - a valid Github url.
* @returns {Object} { github, org, repo, filename, filepath }
* @api private
*/
static normalizeGithubUrl(uri) {
const { origin, pathname } = new URL(uri);
const parts = pathname.split('/');
const [, org, repo] = parts;
const filepath = `/${parts.slice(5).join('/')}`;
const filename = parts[parts.length - 1];
return {
github: `${origin}/`,
filepath,
filename,
org,
repo
};
}
/**
* React lifecyle method to ensure that the github url prop is parsed each time
* it is updated.
* @param {Object} nextProps - new component props
* @param {Object} prevState - prior component state
* @returns {Object} returns new state or null if not modified.
* @api private
*/
static getDerivedStateFromProps({ sourceUri }, prevState) {
if (sourceUri !== prevState.sourceUri) {
return {
sourceUri: sourceUri,
...ReactMarkdownGithub.normalizeGithubUrl(sourceUri)
};
}
return null;
}
/**
* Converts the passed url until an absolute url. If the passed URL is absolute
* it will be returned unmodified. If the URL is realitive then it will be
* merged with the current `sourceUri` property.
*
* @param {String} uri - absolute or realitive URL.
* @returns {url} - will return a absolute URL.
* @api private
*/
normalizeLinkUri(uri) {
// Do not attempt to parse "pure" hashes since they
// are not fully qualified URLs by definition. This will
// not work for querystring plus hash, but Github does not
// support querystring so this is by design.
if (isHash.test(uri)) {
return uri;
}
const withinFile = new RegExp(`.?/?${this.state.filename}#(.*)$`, 'i');
const parsed = new URL(uri, this.props.sourceUri);
const isWithinFile = withinFile.test(uri);
return isWithinFile
? parsed.hash
: parsed.href;
}
/**
* The callback handler from `ReactMarkdown` .
*
* @param {String} uri - Markdown link URL.
* @param {Object} children - Child Elements of the link.
* @param {String} title - link title.
* @returns {url} - will return a absolute URL.
* @api private
*/
transformLinkUri(uri, children, title) {
const { resolver } = this.props;
const normalized = this.normalizeLinkUri(uri);
const opts = { ...this.state, uri: normalized, children, title };
return resolver && resolver(opts) || normalized;
}
/**
* The callback handler from `ReactMarkdown` .
*
* @param {String} uri - Markdown image URL.
* @returns {url} - will return a absolute URL.
* @api private
*/
transformImageUri(uri) {
const { transformImageUri } = this.props;
const opts = { ...this.state, uri };
return transformImageUri && transformImageUri(opts) || uri;
}
/**
* The callback handler from `ReactMarkdown` . Generates an `A` anchor link
* around the Header text
*
* @param {Object} props - properties passed from `ReactMarkdown`
* @param {Int} props.level - The level of the header to render. used for
* generating <h{1-n}>
* @param {Array} props.children - Array of strings from the heading
* @returns {Component} - A react component for the linked header.
* @api private
*/
renderHeading(props) {
let title = '';
props.children.forEach((child) => {
if (child.props && child.props.children) {
title += child.props.children + ' ';
} else {
title += child;
}
});
const slug = slugify(title, { lower: true });
let uniqueSlug = slug;
this.slugs[slug] = this.slugs[slug] || 0;
if (this.slugs[slug]) {
uniqueSlug = `${slug}${this.slugs[slug]}`;
}
this.slugs[slug] += 1;
// eslint-disable-next-line react/no-children-prop
return React.createElement(`h${props.level}`, {
id: uniqueSlug,
className: 'headline-primary',
children: <a href={ `#${uniqueSlug}` }>
{ props.children }
</a>
});
}
/**
* @returns {ReactMarkdown} react tree
* @api private
*/
render() {
const { className, source, resolver } = this.props;
const renderers = {
heading: this.renderHeading,
...this.props.renderers
};
return (
<ReactMarkdown
source={ source }
renderers={ renderers }
className={ className }
resolver={ resolver }
transformLinkUri={ this.transformLinkUri }
transformImageUri={ this.transformImageUri } />
);
}
}
ReactMarkdownGithub.propTypes = {
/** {source} The Markdown content to be rendered by `ReactMarkdown` */
source: PropTypes.string,
/** {sourceUri} The absolute url to the Github source document. All
* relative urls will be assumed to be realitve to this file:
* e.g. https://github.mycorp.com/org/component/blob/master/README.md'
*/
sourceUri: PropTypes.string,
/** {resolver} The callback function executed for each found URL */
resolver: PropTypes.func,
/** {transformImageUri} The callback function executed for each found image */
transformImageUri: PropTypes.func,
/** {renderers} the collection of resolvers to pass to `ReactMarkdown` */
renderers: PropTypes.object,
/** {className} the css class to to pass to `ReactMarkdown` */
className: PropTypes.string
export {
ReactMarkdownGithub,
GithubSlugify
};