MM-17759 Add code highlighting (#3072)
* Add code highlighting * Fix code style * Add unit tests * Some layout adjustments and code style fixes * Fix failing test * Fix typo * Fixed import style * Update snapshot * Fix test * Remove comment * Add react-native-syntax-highlighter to NOTICE.txt * Remove duplicated key * Fix color issue on Android * Remove unnecessary style * Fix top spacing on Android * Add missing trailing comma * Revert highlighting in Android full-screen code * Fix margins on android full-screen code * Fix top padding on Android full-screen code * Fix font size on Android full-screen code * Improve top spacing on iOS full-screen code * Update package-lock.json * Update package-lock.json * Update react-native-syntax-highlighter * Revert away code highlighting on Android code block
This commit is contained in:
parent
3f3a7630cc
commit
26b999e885
7 changed files with 339 additions and 20 deletions
35
NOTICE.txt
35
NOTICE.txt
|
|
@ -2764,3 +2764,38 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## react-native-syntax-highlighter
|
||||
|
||||
This product contains 'react-native-syntax-highlighter' by Conor Hastings.
|
||||
|
||||
A syntax highlighter for react native using https://github.com/conorhastings/react-syntax-highlighter under the hood
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/conorhastings/react-native-syntax-highlighter#readme
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Conor Hastings
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
|
|||
|
|
@ -5,19 +5,22 @@ import {PropTypes} from 'prop-types';
|
|||
import React from 'react';
|
||||
import {intlShape} from 'react-intl';
|
||||
import {
|
||||
Platform,
|
||||
Clipboard,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import SyntaxHighlighter from 'react-native-syntax-highlighter';
|
||||
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
|
||||
import BottomSheet from 'app/utils/bottom_sheet';
|
||||
import {getDisplayNameForLanguage} from 'app/utils/markdown';
|
||||
import {getDisplayNameForLanguage, getCodeFont} from 'app/utils/markdown';
|
||||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme, getHighlightStyleFromTheme} from 'app/utils/theme';
|
||||
import mattermostManaged from 'app/mattermost_managed';
|
||||
import {goToScreen} from 'app/actions/navigation';
|
||||
|
||||
|
|
@ -40,11 +43,13 @@ export default class MarkdownCodeBlock extends React.PureComponent {
|
|||
};
|
||||
|
||||
handlePress = preventDoubleTap(() => {
|
||||
const {language, content} = this.props;
|
||||
const {language, content, textStyle} = this.props;
|
||||
const {intl} = this.context;
|
||||
const screen = 'Code';
|
||||
const passProps = {
|
||||
content,
|
||||
language,
|
||||
textStyle,
|
||||
};
|
||||
|
||||
const languageDisplayName = getDisplayNameForLanguage(language);
|
||||
|
|
@ -150,6 +155,26 @@ export default class MarkdownCodeBlock extends React.PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
let textComponent = null;
|
||||
if (Platform.OS === 'ios') {
|
||||
textComponent = (
|
||||
<SyntaxHighlighter
|
||||
language={this.props.language}
|
||||
style={getHighlightStyleFromTheme(this.props.theme)}
|
||||
highlighter={'hljs'}
|
||||
customStyle={{...style.codeText, ...this.props.textStyle}}
|
||||
>
|
||||
{content}
|
||||
</SyntaxHighlighter>
|
||||
);
|
||||
} else {
|
||||
textComponent = (
|
||||
<Text style={[style.codeText, this.props.textStyle]}>
|
||||
{content}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableWithFeedback
|
||||
onPress={this.handlePress}
|
||||
|
|
@ -164,9 +189,7 @@ export default class MarkdownCodeBlock extends React.PureComponent {
|
|||
</View>
|
||||
<View style={style.rightColumn}>
|
||||
<View style={style.code}>
|
||||
<Text style={[style.codeText, this.props.textStyle]}>
|
||||
{content}
|
||||
</Text>
|
||||
{textComponent}
|
||||
</View>
|
||||
{plusMoreLines}
|
||||
</View>
|
||||
|
|
@ -204,7 +227,15 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
paddingHorizontal: 6,
|
||||
paddingVertical: 4,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingVertical: 0,
|
||||
backgroundColor: getHighlightStyleFromTheme(theme).hljs.background,
|
||||
},
|
||||
android: {
|
||||
paddingVertical: 4,
|
||||
},
|
||||
}),
|
||||
},
|
||||
code: {
|
||||
flexDirection: 'row',
|
||||
|
|
@ -214,6 +245,12 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
color: changeOpacity(theme.centerChannelColor, 0.65),
|
||||
fontSize: 12,
|
||||
lineHeight: 18,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
fontFamily: getCodeFont(),
|
||||
paddingVertical: 6,
|
||||
},
|
||||
}),
|
||||
},
|
||||
plusMoreLinesText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.4),
|
||||
|
|
|
|||
|
|
@ -13,12 +13,17 @@ import {
|
|||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import SyntaxHighlighter from 'react-native-syntax-highlighter';
|
||||
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
import {getCodeFont} from 'app/utils/markdown';
|
||||
|
||||
import {
|
||||
changeOpacity,
|
||||
makeStyleSheetFromTheme,
|
||||
setNavigatorStyles,
|
||||
getKeyboardAppearanceFromTheme,
|
||||
getHighlightStyleFromTheme,
|
||||
} from 'app/utils/theme';
|
||||
import {popTopScreen} from 'app/actions/navigation';
|
||||
|
||||
|
|
@ -27,6 +32,8 @@ export default class Code extends React.PureComponent {
|
|||
componentId: PropTypes.string,
|
||||
theme: PropTypes.object.isRequired,
|
||||
content: PropTypes.string.isRequired,
|
||||
language: PropTypes.string,
|
||||
textStyle: CustomPropTypes.Style,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
|
|
@ -73,13 +80,20 @@ export default class Code extends React.PureComponent {
|
|||
let textComponent;
|
||||
if (Platform.OS === 'ios') {
|
||||
textComponent = (
|
||||
<TextInput
|
||||
editable={false}
|
||||
multiline={true}
|
||||
value={this.props.content}
|
||||
style={[style.codeText]}
|
||||
keyboardAppearance={getKeyboardAppearanceFromTheme(this.props.theme)}
|
||||
/>
|
||||
<SyntaxHighlighter
|
||||
language={this.props.language}
|
||||
style={getHighlightStyleFromTheme(this.props.theme)}
|
||||
highlighter={'hljs'}
|
||||
CodeTag={TextInput}
|
||||
codeTagProps={{
|
||||
editable: false,
|
||||
multiline: true,
|
||||
keyboardAppearance: getKeyboardAppearanceFromTheme(this.props.theme),
|
||||
style: {...style.codeText, ...this.props.textStyle},
|
||||
}}
|
||||
>
|
||||
{this.props.content}
|
||||
</SyntaxHighlighter>
|
||||
);
|
||||
} else {
|
||||
textComponent = (
|
||||
|
|
@ -145,6 +159,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
flexGrow: 0,
|
||||
flexShrink: 1,
|
||||
width: '100%',
|
||||
backgroundColor: getHighlightStyleFromTheme(theme).hljs.background,
|
||||
},
|
||||
code: {
|
||||
paddingHorizontal: 6,
|
||||
|
|
@ -152,9 +167,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
android: {
|
||||
paddingVertical: 4,
|
||||
},
|
||||
ios: {
|
||||
top: -4,
|
||||
},
|
||||
}),
|
||||
},
|
||||
codeText: {
|
||||
|
|
@ -164,8 +176,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
lineHeight: 18,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
top: -11,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {StyleSheet} from 'react-native';
|
|||
import tinyColor from 'tinycolor2';
|
||||
|
||||
import * as ThemeUtils from 'mattermost-redux/utils/theme_utils';
|
||||
import * as HighlightStyles from 'react-syntax-highlighter/styles/hljs';
|
||||
|
||||
import {mergeNavigationOptions} from 'app/actions/navigation';
|
||||
|
||||
|
|
@ -50,6 +51,14 @@ export function isThemeSwitchingEnabled(state) {
|
|||
return config.EnableThemeSelection === 'true';
|
||||
}
|
||||
|
||||
const snakeCaseToCamelCase = (str) => str.replace(
|
||||
/([-_][a-z])/g, (group) => group.toUpperCase().replace('-', '').replace('_', '')
|
||||
);
|
||||
|
||||
export function getHighlightStyleFromTheme(theme) {
|
||||
return HighlightStyles[snakeCaseToCamelCase(theme.codeTheme)] || HighlightStyles.github;
|
||||
}
|
||||
|
||||
export function getKeyboardAppearanceFromTheme(theme) {
|
||||
return tinyColor(theme.centerChannelBg).isLight() ? 'light' : 'dark';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,44 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getKeyboardAppearanceFromTheme} from 'app/utils/theme';
|
||||
import {getHighlightStyleFromTheme, getKeyboardAppearanceFromTheme} from 'app/utils/theme';
|
||||
import * as HighlightStyles from 'react-syntax-highlighter/styles/hljs';
|
||||
|
||||
describe('getHighlightStyleFromTheme', () => {
|
||||
const themes = [{
|
||||
codeTheme: 'github',
|
||||
}, {
|
||||
codeTheme: 'atom-one-light',
|
||||
}, {
|
||||
codeTheme: 'androidstudio',
|
||||
}, {
|
||||
codeTheme: 'invalid_theme',
|
||||
}];
|
||||
|
||||
it('should return github style for codeTheme="github"', () => {
|
||||
const theme = getHighlightStyleFromTheme(themes[0]);
|
||||
expect(theme).toBeTruthy();
|
||||
expect(theme).toBe(HighlightStyles.github);
|
||||
});
|
||||
|
||||
it('should return atomOneLight style for codeTheme="atom-one-light" (snake-case to camelCase)', () => {
|
||||
const theme = getHighlightStyleFromTheme(themes[1]);
|
||||
expect(theme).toBeTruthy();
|
||||
expect(theme).toBe(HighlightStyles.atomOneLight);
|
||||
});
|
||||
|
||||
it('should return androidstudio style for codeTheme="androidstudio" (no case conversion)', () => {
|
||||
const theme = getHighlightStyleFromTheme(themes[2]);
|
||||
expect(theme).toBeTruthy();
|
||||
expect(theme).toBe(HighlightStyles.androidstudio);
|
||||
});
|
||||
|
||||
it('should return github style by default for codeTheme="invalid_theme"', () => {
|
||||
const theme = getHighlightStyleFromTheme(themes[3]);
|
||||
expect(theme).toBeTruthy();
|
||||
expect(theme).toBe(HighlightStyles.github);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getKeyboardAppearanceFromTheme', () => {
|
||||
const themes = [{
|
||||
|
|
|
|||
189
package-lock.json
generated
189
package-lock.json
generated
|
|
@ -5541,6 +5541,21 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"character-entities": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz",
|
||||
"integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w=="
|
||||
},
|
||||
"character-entities-legacy": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz",
|
||||
"integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww=="
|
||||
},
|
||||
"character-reference-invalid": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz",
|
||||
"integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg=="
|
||||
},
|
||||
"chardet": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
|
||||
|
|
@ -5756,6 +5771,17 @@
|
|||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
|
||||
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
|
||||
},
|
||||
"clipboard": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
|
||||
"integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"good-listener": "^1.2.2",
|
||||
"select": "^1.1.2",
|
||||
"tiny-emitter": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
|
||||
|
|
@ -5838,6 +5864,11 @@
|
|||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"comma-separated-tokens": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz",
|
||||
"integrity": "sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ=="
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
|
||||
|
|
@ -6310,6 +6341,12 @@
|
|||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"delegate": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
|
|
@ -7522,6 +7559,14 @@
|
|||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fault": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fault/-/fault-1.0.3.tgz",
|
||||
"integrity": "sha512-sfFuP4X0hzrbGKjAUNXYvNqsZ5F6ohx/dZ9I0KQud/aiZNwg263r5L9yGB0clvXHCkzXh5W3t7RSHchggYIFmA==",
|
||||
"requires": {
|
||||
"format": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"fb-watchman": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz",
|
||||
|
|
@ -8376,6 +8421,11 @@
|
|||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"format": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
|
||||
"integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs="
|
||||
},
|
||||
"fragment-cache": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
|
||||
|
|
@ -9128,6 +9178,15 @@
|
|||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz",
|
||||
"integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg=="
|
||||
},
|
||||
"good-listener": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
||||
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"delegate": "^3.1.2"
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
|
||||
|
|
@ -9320,6 +9379,27 @@
|
|||
"is-stream": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hast-util-parse-selector": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz",
|
||||
"integrity": "sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw=="
|
||||
},
|
||||
"hastscript": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.0.tgz",
|
||||
"integrity": "sha512-7mOQX5VfVs/gmrOGlN8/EDfp1GqV6P3gTNVt+KnX4gbYhpASTM8bklFdFQCbFRAadURXAmw0R1QQdBdqp7jswQ==",
|
||||
"requires": {
|
||||
"comma-separated-tokens": "^1.0.0",
|
||||
"hast-util-parse-selector": "^2.2.0",
|
||||
"property-information": "^5.0.1",
|
||||
"space-separated-tokens": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.12.0",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz",
|
||||
"integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4="
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
|
||||
|
|
@ -9678,6 +9758,20 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"is-alphabetical": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz",
|
||||
"integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA=="
|
||||
},
|
||||
"is-alphanumerical": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz",
|
||||
"integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==",
|
||||
"requires": {
|
||||
"is-alphabetical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
|
|
@ -9751,6 +9845,11 @@
|
|||
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
|
||||
"dev": true
|
||||
},
|
||||
"is-decimal": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz",
|
||||
"integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ=="
|
||||
},
|
||||
"is-descriptor": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
|
||||
|
|
@ -9815,6 +9914,11 @@
|
|||
"is-extglob": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-hexadecimal": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz",
|
||||
"integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA=="
|
||||
},
|
||||
"is-installed-globally": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
|
||||
|
|
@ -13970,6 +14074,15 @@
|
|||
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
|
||||
"dev": true
|
||||
},
|
||||
"lowlight": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.9.2.tgz",
|
||||
"integrity": "sha512-Ek18ElVCf/wF/jEm1b92gTnigh94CtBNWiZ2ad+vTgW7cTmQxUY3I98BjHK68gZAJEWmybGBZgx9qv3QxLQB/Q==",
|
||||
"requires": {
|
||||
"fault": "^1.0.2",
|
||||
"highlight.js": "~9.12.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
|
||||
|
|
@ -15719,6 +15832,19 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"parse-entities": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz",
|
||||
"integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==",
|
||||
"requires": {
|
||||
"character-entities": "^1.0.0",
|
||||
"character-entities-legacy": "^1.0.0",
|
||||
"character-reference-invalid": "^1.0.0",
|
||||
"is-alphanumerical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0",
|
||||
"is-hexadecimal": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"parse-glob": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
|
||||
|
|
@ -16052,6 +16178,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz",
|
||||
"integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==",
|
||||
"requires": {
|
||||
"clipboard": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"private": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
|
||||
|
|
@ -16130,6 +16264,14 @@
|
|||
"retry": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"property-information": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-5.2.2.tgz",
|
||||
"integrity": "sha512-N2moasZmjn2mjVGIWpaqz5qnz6QyeQSGgGvMtl81gA9cPTWa6wpesRSe/quNnOjUHpvSH1oZx0pdz0EEckLFnA==",
|
||||
"requires": {
|
||||
"xtend": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
|
||||
|
|
@ -16681,6 +16823,14 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-9.4.0.tgz",
|
||||
"integrity": "sha512-IVJlVbS2dAPerPr927fEi4uXzrPXzlra5ddgyJXZZ2IKA2ZygyYWFZDM+vsQs+Vj20CfL8nOWszQQV57vdQgFg=="
|
||||
},
|
||||
"react-native-syntax-highlighter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-syntax-highlighter/-/react-native-syntax-highlighter-2.1.0.tgz",
|
||||
"integrity": "sha512-upu8gpKT2ZeslXn2d763KwtzzhM9OUHGgJjIKKIUw1JnFAzVwQmKCaFGoI6PkQa7T1LVggBW5k5VoaLFhZDb+g==",
|
||||
"requires": {
|
||||
"react-syntax-highlighter": "^6.0.4"
|
||||
}
|
||||
},
|
||||
"react-native-tab-view": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-1.3.5.tgz",
|
||||
|
|
@ -16981,6 +17131,18 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-syntax-highlighter": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-6.1.2.tgz",
|
||||
"integrity": "sha512-ahNwcZ0FhUd8U5TQYcmAqC/pec6Q308mUAATKMcLFmNYkvGhN9wfmoqxzjACcccGb2e85d5ZnGpOiCIIzGO3yA==",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.18.0",
|
||||
"highlight.js": "~9.12.0",
|
||||
"lowlight": "~1.9.1",
|
||||
"prismjs": "^1.8.4",
|
||||
"refractor": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"react-test-renderer": {
|
||||
"version": "16.8.6",
|
||||
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.6.tgz",
|
||||
|
|
@ -17477,6 +17639,16 @@
|
|||
"integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=",
|
||||
"dev": true
|
||||
},
|
||||
"refractor": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/refractor/-/refractor-2.10.0.tgz",
|
||||
"integrity": "sha512-maW2ClIkm9IYruuFYGTqKzj+m31heq92wlheW4h7bOstP+gf8bocmMec+j7ljLcaB1CAID85LMB3moye31jH1g==",
|
||||
"requires": {
|
||||
"hastscript": "^5.0.0",
|
||||
"parse-entities": "^1.1.2",
|
||||
"prismjs": "~1.17.0"
|
||||
}
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
|
||||
|
|
@ -18309,6 +18481,12 @@
|
|||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz",
|
||||
|
|
@ -18868,6 +19046,11 @@
|
|||
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
|
||||
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
|
||||
},
|
||||
"space-separated-tokens": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz",
|
||||
"integrity": "sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA=="
|
||||
},
|
||||
"spawn-wrap": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz",
|
||||
|
|
@ -19380,6 +19563,12 @@
|
|||
"integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
|
||||
"dev": true
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
|
||||
"optional": true
|
||||
},
|
||||
"tinycolor2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
"react-native-slider": "0.11.0",
|
||||
"react-native-status-bar-size": "0.3.3",
|
||||
"react-native-svg": "9.4.0",
|
||||
"react-native-syntax-highlighter": "2.1.0",
|
||||
"react-native-vector-icons": "6.4.2",
|
||||
"react-native-video": "4.4.1",
|
||||
"react-native-webview": "github:mattermost/react-native-webview#b5e22940a613869d3999feac9451ee65352f4fbe",
|
||||
|
|
|
|||
Loading…
Reference in a new issue