Skip to content

Commit

Permalink
Merge pull request #13 from fram-x/feature/handle-undefined-text
Browse files Browse the repository at this point in the history
Feature/handle undefined text
  • Loading branch information
bjornegil authored Oct 21, 2018
2 parents 09362c8 + ea03dda commit 5e1cad7
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 27 deletions.
3 changes: 1 addition & 2 deletions App.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class App extends Component<Props> {
return (
<View style={styles.container}>
<StyledText
text="Welcome to <b><u>React Native</u> <demo>Styled Text</demo></b> demo!"
text="Welcome to <b><u>React Native</u> <demo><i>Styled</i> Text</demo></b> demo!"
style={styles.welcome}
textStyles={textStyles}
/>
Expand Down Expand Up @@ -111,7 +111,6 @@ const textStyles = StyleSheet.create({
textShadowColor: '#555555',
textShadowRadius: 6,
fontSize: 18,
fontStyle: 'italic',
color: '#22AA44',
},
code: {
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { StyledText } from 'react-native-styled-text';

...
<StyledText
text="Happy <b>Styling</b>!"
text="Ha<i>pp</i>y <b>Styling</b>!"
style={styles.header}
/>
...
Expand Down Expand Up @@ -70,7 +70,7 @@ import { StyledText } from 'react-native-styled-text';

...
<StyledText
text="Welcome to <b>React Native <demo>Styled Text</demo></b> demo!"
text="Welcome to <b><u>React Native</u> <demo><i>Styled</i> Text</demo></b> demo!"
style={styles.welcome}
textStyles={textStyles}
/>
Expand All @@ -90,7 +90,6 @@ const textStyles = StyleSheet.create({
textShadowColor: '#555555',
textShadowRadius: 6,
fontSize: 24,
fontStyle: 'italic',
color: '#22AA44',
},
});
Expand Down
Binary file modified docs/example-android.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/example-ios.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/happyStyling.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/welcome.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions lib/StyledText/lexicalAnalyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const replaceCodes = (text: string) => {
}

export const scan = (text: string): Array<Token> => {
if (text === undefined || text === null || text === '') {
return [{ type: TOKEN_TEXT, lexeme: text }];
}

const tagRegex = /<([\w-]+)>|<\/([\w-]*)>/;
const tokens = [];

Expand Down
23 changes: 3 additions & 20 deletions lib/StyledText/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import { Text, StyleSheet } from 'react-native';

import { parse, Mixed } from './parser';
import { verifyTextStyles } from './utils';

const defaultStyles = {
b: {
Expand All @@ -15,26 +16,8 @@ const defaultStyles = {
}
};

const verifyTextStyles = (mixedText: Mixed, textStyles: Object) => {
const styleNames = [];
mixedText.map(element => {
if (typeof element !== 'string') {
const index = styleNames.indexOf(element.styleName);
if (index < 0) {
styleNames.push(element.styleName);
}
}
});

styleNames.forEach((styleName) => {
if (!textStyles[styleName] && !defaultStyles[styleName]) {
console.warn('react-native-styled-text: style "' + styleName + '" is not defined');
}
});
}

const renderMixedText = (mixedText: Mixed, textStyles: Object) => mixedText.map((element, index) => (
typeof element === 'string'
typeof element === 'string' || element === undefined || element === null
? element
: React.createElement(
Text,
Expand All @@ -49,7 +32,7 @@ const renderMixedText = (mixedText: Mixed, textStyles: Object) => mixedText.map(
export const renderStyledText = (text, style, textStyles) => {
const mixedText = parse(text);
const styles = textStyles || {}
verifyTextStyles(mixedText, styles);
verifyTextStyles(mixedText, styles, defaultStyles);

const textElements = renderMixedText(mixedText, styles);

Expand Down
35 changes: 35 additions & 0 deletions lib/StyledText/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Mixed } from './parser';

const findAllTextStyles = (
mixedText: Mixed,
accStyleNames: Array<string> = []
) : Array<string> => {
mixedText.map(element => {
if (!(typeof element === 'string' || element === undefined || element === null)) {
const index = accStyleNames.indexOf(element.styleName);
if (index < 0) {
accStyleNames.push(element.styleName);
}

accStyleNames = findAllTextStyles(element.mixedText, accStyleNames);
}
});

return accStyleNames;
}

const verifyTextStyles = (
mixedText: Mixed,
textStyles: Object,
defaultStyles: Object
) => {
const styleNames = findAllTextStyles(mixedText);

styleNames.forEach((styleName) => {
if (!textStyles[styleName] && !defaultStyles[styleName]) {
console.warn('react-native-styled-text: style "' + styleName + '" is not defined');
}
});
}

export { verifyTextStyles };
2 changes: 1 addition & 1 deletion lib/__tests__/lexicalAnalyzer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
TOKEN_TEXT,
} from '../StyledText/lexicalAnalyzer';

describe('components/FormattedText/lexicalAnalyzer', () => {
describe('StyledText/lexicalAnalyzer', () => {
describe('scan', () => {
it('should return text if plain text', () => {
const text = 'Testing <asdf adsf';
Expand Down
23 changes: 22 additions & 1 deletion lib/__tests__/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { parse } from '../StyledText/parser';
let warnings = [];
const warn = msg => warnings.push(msg);

describe('components/FormattedText/parser', () => {
describe('StyledText/parser', () => {
beforeAll(() => {
console['warn'] = warn;
});
Expand All @@ -19,6 +19,27 @@ describe('components/FormattedText/parser', () => {
expect(mixedText[0]).toBe(text);
});

it('should return undefined if undefined', () => {
const text = undefined;
const mixedText = parse(text);
expect(mixedText.length).toBe(1);
expect(mixedText[0]).toBe(text);
});

it('should return null if null', () => {
const text = undefined;
const mixedText = parse(text);
expect(mixedText.length).toBe(1);
expect(mixedText[0]).toBe(text);
});

it('should return "" if ""', () => {
const text = '';
const mixedText = parse(text);
expect(mixedText.length).toBe(1);
expect(mixedText[0]).toBe(text);
});

it('should handle text if enclosed in tags', () => {
const text = '<style1>Testing adsf</>';
const mixedText = parse(text);
Expand Down
86 changes: 86 additions & 0 deletions lib/__tests__/utils.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { verifyTextStyles } from '../StyledText/utils';

let warnings = [];
const warn = msg => warnings.push(msg);
const textStyles = {
style1: {},
style2: {},
};
const defaultStyles = {
b: {},
i: {},
u: {}
};

describe('StyledText/utils', () => {
beforeAll(() => {
console['warn'] = warn;
});
beforeEach(() => {
warnings = [];
});

describe('verifyTextStyles', () => {
it('should not give warning on undefined', () => {
const mixedText = [undefined];
verifyTextStyles(mixedText, textStyles, defaultStyles);
expect(warnings.length).toBe(0);
});

it('should not give warning on null', () => {
const mixedText = [null];
verifyTextStyles(mixedText, textStyles, defaultStyles);
expect(warnings.length).toBe(0);
});

it('should not give warning on ""', () => {
const mixedText = [''];
verifyTextStyles(mixedText, textStyles, defaultStyles);
expect(warnings.length).toBe(0);
});

it('should not give warning on "test"', () => {
const mixedText = ['test'];
verifyTextStyles(mixedText, textStyles, defaultStyles);
expect(warnings.length).toBe(0);
});

it('should not give warning on defined styles', () => {
const mixedText = [
'test',
{
styleName: 'style1',
mixedText: [
'test2',
{
styleName: 'b',
mixedText: ['test3']
}
]
}
];
verifyTextStyles(mixedText, textStyles, defaultStyles);
expect(warnings.length).toBe(0);
});

it('should not give warning on undefined styles', () => {
const mixedText = [
'test',
{
styleName: 'style3',
mixedText: [
'test2',
{
styleName: 'e',
mixedText: ['test3']
}
]
}
];
verifyTextStyles(mixedText, textStyles, defaultStyles);
expect(warnings.length).toBe(2);
expect(warnings[0]).toContain('"style3"');
expect(warnings[1]).toContain('"e"');
});
});
});

0 comments on commit 5e1cad7

Please sign in to comment.