Skip to content
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

Refactor word processors #43

Merged
merged 5 commits into from
Oct 7, 2017
Merged
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
6 changes: 6 additions & 0 deletions components/App/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@
html {
font: 15px/1.6 思源黑體, "Source Han Sans", "Noto Sans CJK TC", 蘋方-繁, "PingFang TC", 微軟正黑體, "Microsoft JhengHei", sans-serif;
}

a[target="_blank"]:after {
/* material-ui ic_open_in_new_black_12px.svg */
content: url("data:image/svg+xml,%3Csvg fill='%23666666' height='12' viewBox='0 0 24 24' width='12' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath d='M0 0h24v24H0z' fill='none'/%3E %3Cpath d='M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z'/%3E %3C/svg%3E");
margin: 0 4px;
}
4 changes: 2 additions & 2 deletions components/ExpandableText.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { nl2br } from '../util/text';
import { nl2br, linkify } from '../util/text';

export default class ExpandableText extends React.Component {
static defaultProps = {
Expand All @@ -26,7 +26,7 @@ export default class ExpandableText extends React.Component {
render() {
const { children, lines } = this.props;
const { isExpanded } = this.state;
const sentences = nl2br(children);
const sentences = nl2br(linkify(children));

if (sentences.length <= lines) {
return (
Expand Down
4 changes: 2 additions & 2 deletions components/ReplyConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TYPE_NAME, TYPE_DESC } from '../constants/replyType';
import { USER_REFERENCE } from '../constants/urls';
import moment from 'moment';
import ExpandableText from './ExpandableText';
import { nl2br } from '../util/text';
import { nl2br, linkify } from '../util/text';
import { sectionStyle } from './ReplyConnection.styles';

export default class ReplyConnection extends React.PureComponent {
Expand Down Expand Up @@ -128,7 +128,7 @@ export default class ReplyConnection extends React.PureComponent {
<h3>
{replyType === 'OPINIONATED' ? '不同意見' : '出處'}
</h3>
{reference ? nl2br(reference) : '⚠️️ 此回應沒有出處,請自行斟酌回應真實性。'}
{reference ? nl2br(linkify(reference)) : '⚠️️ 此回應沒有出處,請自行斟酌回應真實性。'}
<style jsx>{sectionStyle}</style>
</section>
);
Expand Down
8 changes: 6 additions & 2 deletions pages/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { compose } from 'redux';
import moment from 'moment';
import Head from 'next/head';
import stringSimilarity from 'string-similarity';
import { nl2br } from '../util/text';
import { nl2br, linkify } from '../util/text';

import app from '../components/App';
import ArticleInfo from '../components/ArticleInfo';
Expand Down Expand Up @@ -153,7 +153,11 @@ class ArticlePage extends React.Component {
<h2>訊息原文</h2>
<ArticleInfo article={article} />
</header>
<div className="message">{nl2br(article.get('text'))}</div>
<div className="message">
{nl2br(
linkify(article.get('text'), { props: { target: '_blank' } })
)}
</div>
</section>

<section
Expand Down
10 changes: 8 additions & 2 deletions pages/reply.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
updateReplyConnectionStatus,
} from '../redux/replyDetail';
import Head from 'next/head';
import { nl2br } from '../util/text';
import { nl2br, linkify } from '../util/text';

import app from '../components/App';
import ReplyConnection from '../components/ReplyConnection';
Expand Down Expand Up @@ -164,7 +164,13 @@ class ReplyPage extends React.Component {
<h2>訊息原文</h2>
{this.renderArticleLink()}
</header>
<div className="message">{nl2br(originalArticle.get('text'))}</div>
<div className="message">
{nl2br(
linkify(originalArticle.get('text'), {
props: { target: '_blank' },
})
)}
</div>
</section>

{this.renderReply()}
Expand Down
141 changes: 141 additions & 0 deletions util/__tests__/__snapshots__/text.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`text linkify attach link on arrays containing elements that has link 1`] = `
Array [
Array [
"Please go to ",
<a
href="http://google.com"
>
http://google.com
</a>,
"",
],
<span>
Please go to
<a
href="http://google.com"
>
http://google.com
</a>

</span>,
]
`;

exports[`text linkify attach link on nested elements containing links 1`] = `
<span>
Please go to
<span>

<a
href="http://google.com"
>
http://google.com
</a>

</span>
lalala
</span>
`;

exports[`text linkify attach link on simple elements containing links 1`] = `
<span>
Please go to
<a
href="http://google.com"
>
http://google.com
</a>

</span>
`;

exports[`text linkify attach link on strings containing links 1`] = `
Array [
"Please go to ",
<a
href="http://google.com"
>
http://google.com
</a>,
"",
]
`;

exports[`text linkify decodes URI encoded URLs 1`] = `
Array [
"Please go to ",
<a
href="http://www.rumtoast.com/5444/line%E7%BE%A4%E7%B5%84%E8%A1%8C%E5%8B%95%E6%A2%9D%E7%A2%BC%E9%82%80%E8%AB%8B-%E4%B8%80%E5%AE%9A%E8%A6%81%E9%97%9C%E6%8E%89%EF%BC%8C%E4%B8%8D%E7%84%B6%E9%A7%AD%E5%AE%A2%E6%9C%83%E5%85%A5%E4%BE%B5"
>
http://www.rumtoast.com/5444/line群組行動條碼邀請-一定要關掉,不然駭客會入侵
</a>,
"",
]
`;

exports[`text linkify decodes URLS that is too long 1`] = `
Array [
"Please go to ",
<a
href="http://www.rumtoast.com/5444/line%E7%BE%A4%E7%B5%84%E8%A1%8C%E5%8B%95%E6%A2%9D%E7%A2%BC%E9%82%80%E8%AB%8B-%E4%B8%80%E5%AE%9A%E8%A6%81%E9%97%9C%E6%8E%89%EF%BC%8C%E4%B8%8D%E7%84%B6%E9%A7%AD%E5%AE%A2%E6%9C%83%E5%85%A5%E4%BE%B5"
>
http:⋯駭客會入侵
</a>,
"",
]
`;

exports[`text linkify sets prop to link 1`] = `
Array [
"Please go to ",
<a
href="http://google.com"
target="_blank"
>
http://google.com
</a>,
"",
]
`;

exports[`text nl2br inserts <br> on line breaks in strings, with ending <br>s trimmed 1`] = `
Array [
"Foo",
<br />,
"Bar",
]
`;

exports[`text nl2br inserts <br> on line breaks in strings, with ending <br>s trimmed 2`] = `
Array [
"This should be first line with empty next line",
<br />,
<br />,
"This should be second line with no <br> afterwards",
]
`;

exports[`text nl2br inserts <br> on line breaks within elements 1`] = `
<p>
This should be first line
<br />
<br />
This should be second line with no &lt;br&gt; afterwards
</p>
`;

exports[`text nl2br preserves line ends on the end of tag 1`] = `
Array [
<a
href=""
>
http://www.appledaily.com.tw/realtimenews/article/new/20170817/1184132/
</a>,
Array [
<br />,
"15少年集體性侵驢子 全染上狂犬病",
],
]
`;
121 changes: 121 additions & 0 deletions util/__tests__/text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React from 'react';
import { linkify, nl2br } from '../text';

describe('text', () => {
describe('linkify', () => {
it('does nothing on strings, arrays and elements without links', () => {
expect(linkify('foo')).toBe('foo');

const singleLevelElem = <p>foo</p>;
expect(linkify(singleLevelElem)).toBe(singleLevelElem);

const nestedElem = <p>foo <span> bar </span> foo2</p>;
expect(linkify(nestedElem)).toBe(nestedElem);

const array = ['foo', 'bar', <span key="elem">lala</span>];
expect(linkify(array)).toEqual(array);
});

it('attach link on strings containing links', () => {
expect(linkify('Please go to http://google.com')).toMatchSnapshot();
});

it('attach link on simple elements containing links', () => {
expect(
linkify(<span>Please go to http://google.com</span>)
).toMatchSnapshot();
});

it('attach link on nested elements containing links', () => {
expect(
linkify(
<span>
Please go to <span>http://google.com</span> lalala
</span>
)
).toMatchSnapshot();
});

it('attach link on arrays containing elements that has link', () => {
expect(
linkify([
'Please go to http://google.com',
<span key="elem">Please go to http://google.com</span>,
])
).toMatchSnapshot();
});

it('decodes URI encoded URLs', () => {
expect(
linkify(
'Please go to http://www.rumtoast.com/5444/line%E7%BE%A4%E7%B5%84%E8%A1%8C%E5%8B%95%E6%A2%9D%E7%A2%BC%E9%82%80%E8%AB%8B-%E4%B8%80%E5%AE%9A%E8%A6%81%E9%97%9C%E6%8E%89%EF%BC%8C%E4%B8%8D%E7%84%B6%E9%A7%AD%E5%AE%A2%E6%9C%83%E5%85%A5%E4%BE%B5'
)
).toMatchSnapshot();
});

it('decodes URLS that is too long', () => {
expect(
linkify(
'Please go to http://www.rumtoast.com/5444/line%E7%BE%A4%E7%B5%84%E8%A1%8C%E5%8B%95%E6%A2%9D%E7%A2%BC%E9%82%80%E8%AB%8B-%E4%B8%80%E5%AE%9A%E8%A6%81%E9%97%9C%E6%8E%89%EF%BC%8C%E4%B8%8D%E7%84%B6%E9%A7%AD%E5%AE%A2%E6%9C%83%E5%85%A5%E4%BE%B5',
{ maxLength: 10 }
)
).toMatchSnapshot();
});

it('sets prop to link', () => {
expect(
linkify('Please go to http://google.com', {
props: { target: '_blank' },
})
).toMatchSnapshot();
});
});

describe('nl2br', () => {
it('does nothing on strings, arrays and elements without line breaks', () => {
expect(nl2br('foo')).toBe('foo');

const singleLevelElem = <p>foo</p>;
expect(nl2br(singleLevelElem)).toBe(singleLevelElem);

const nestedElem = <p>foo <span> bar </span> foo2</p>;
expect(nl2br(nestedElem)).toBe(nestedElem);

const array = ['foo', 'bar', <span key="elem">lala</span>];
expect(nl2br(array)).toEqual(array);
});

it('inserts <br> on line breaks in strings, with ending <br>s trimmed', () => {
expect(nl2br('Foo\nBar')).toMatchSnapshot();

expect(
nl2br(`This should be first line with empty next line

This should be second line with no <br> afterwards`)
).toMatchSnapshot();
});

it('inserts <br> on line breaks within elements', () => {
expect(
nl2br(
<p>
{`This should be first line

This should be second line with no <br> afterwards`}
</p>
)
).toMatchSnapshot();
});

it('preserves line ends on the end of tag', () => {
expect(
nl2br([
<a href="" key="link">
http://www.appledaily.com.tw/realtimenews/article/new/20170817/1184132/
</a>,
'\n15少年集體性侵驢子 全染上狂犬病',
])
).toMatchSnapshot();
});
});
});
Loading