This is Jovan ๐จโ๐ฉโ๐ง ๐๐๐ nice to meet you guys ๐งจ ๐ ๐ ๐ ๐ ๐ ๐
I'm a passionate software developer living in Xi'an ๐ China ๐จ๐ณ and would like โค๏ธโ๐ฅ to explore and learn new stuff...
This is a react demo application
License: MIT License
import { Component, Children } from 'react';
import PropTypes from 'prop-types';
import invariant from 'invariant';
import { shouldConfigComponentUpdate, filterProps } from '../utils';
import { configCfgPropTypes, configFormatPropTypes, configShape } from '../types';
import * as configFormats from '../format';
const configCfgPropNames = Object.keys(configCfgPropTypes);
const configFormatPropNames = Object.keys(configFormatPropTypes);
// These are not a static property on the ConfigProvider
class so the config
// cfg values can be inherited from an ancestor.
const defaultProps = {
configMessages: {},
};
export default class ConfigProvider extends Component {
static displayName = 'ConfigProvider';
static contextTypes = {
config: configShape,
};
static childContextTypes = {
config: configShape.isRequired,
};
static propTypes = {
...configCfgPropTypes,
children: PropTypes.element.isRequired,
initialNow: PropTypes.any,
};
constructor(props, context = {}) {
super(props, context);
const {config: configContext} = context;
// Used to stabilize time when performing an initial rendering so that
// all relative times use the same reference "now" time.
let initialNow;
if (isFinite(props.initialNow)) {
initialNow = Number(props.initialNow);
} else {
// When an `initialNow` isn't provided via `props`, look to see an
// <ConfigProvider> exists in the ancestry and call its `now()`
// function to propagate its value for "now".
initialNow = configContext ? configContext.now() : Date.now();
}
this.state = {
// Wrapper to provide stable "now" time for initial render.
now: () => {
return this._didDisplay ? Date.now() : initialNow;
},
};
}
getConfig() {
const {config: cofigContext} = this.context;
// Build a whitelisted config object from `props`, defaults, and
// `context.config`, if an <ConfigProvider> exists in the ancestry.
let config = filterProps(this.props, configCfgPropNames, cofigContext);
// Apply default props. This must be applied last after the props have
// been resolved and inherited from any <ConfigProvider> in the ancestry.
// This matches how React resolves `defaultProps`.
for (let propName in defaultProps) {
if (config[propName] === undefined) {
config[propName] = defaultProps[propName];
}
}
return config;
}
getBoundFormatFns(config, state) {
return configFormatPropNames.reduce((boundFormatFns, name) => {
boundFormatFns[name] = configFormats[name].bind(null, config, state);
return boundFormatFns;
}, {});
}
getChildContext() {
const config = this.getConfig();
const boundFormatFns = this.getBoundFormatFns(config, this.state);
const { now } = this.state;
return {
config: {
...config,
...boundFormatFns,
now,
},
};
}
shouldComponentUpdate(...next) {
return shouldConfigComponentUpdate(this, ...next);
}
componentDidMount() {
this._didDisplay = true;
}
render() {
return Children.only(this.props.children);
}
}
export { configShape } from './types';
export { default as injectConfig } from './inject';
export { default as ConfigProvider } from './components/provider';
import invariant from 'invariant';
import {
configStringDescriptorPropTypes,
configNumberDescriptorPropTypes,
configBooleanDescriptorPropTypes,
configArrayDescriptorPropTypes,
configObjectDescriptorPropTypes,
configFunctionDescriptorPropTypes,
} from './types';
import { escape, filterProps } from './utils';
const { keys } = Object;
const STRING_FORMAT_PROPS = keys(configStringDescriptorPropTypes);
const NUMBER_FORMAT_PROPS = keys(configNumberDescriptorPropTypes);
const BOOLEAN_FORMAT_PROPS = keys(configBooleanDescriptorPropTypes);
const ARRAY_FORMAT_PROPS = keys(configArrayDescriptorPropTypes);
const OBJECT_FORMAT_PROPS = keys(configObjectDescriptorPropTypes);
const FUNCTION_FORMAT_PROPS = keys(configFunctionDescriptorPropTypes);
/**
// id
is a required field of a Config String Descriptor.
invariant(id, '[React Config] An id
must be provided to config a string.');
if(configMessages[id] && typeof configMessages[id] !== 'string')
invariant(mockString,
[React Config] The retrieved value via getString must be provided to config a string.
);
if(!!defaultString && typeof defaultString !== 'string')
invariant(mockString, '[React Config] An defaultString
must be provided to config a string.');
return configMessages[id] || defaultString || id;
}
/**
// id
is a required field of a Config Number Descriptor.
invariant(id, '[React Config] An id
must be provided to config a number.');
if(configMessages[id] && typeof configMessages[id] !== 'number')
invariant(mockNumber,
[React Config] The retrieved value via getNumber must be provided to config a number.
);
if(!!defaultNumber && typeof defaultNumber !== 'number')
invariant(mockNumber, '[React Config] An defaultNumber
must be provided to config a number.');
if(
typeof configMessages[id] === 'undefined' &&
Object.is(defaultNumber, 0)
)
return defaultNumber;
return configMessages[id] || defaultNumber || id;
}
/**
// id
is a required field of a Config Boolean Descriptor.
invariant(id, '[React Config] An id
must be provided to config a boolean.');
if(configMessages[id] && typeof configMessages[id] !== 'boolean')
invariant(mockBoolean,
[React Config] The retrieved value via getBoolean must be provided to config a boolean.
);
if(defaultBoolean && typeof defaultBoolean !== 'boolean')
invariant(mockBoolean, '[React Config] An defaultBoolean
must be provided to config a boolean.');
const { is } = Object;
if(typeof configMessages[id] !== 'undefined')
return configMessages[id];
if(
typeof configMessages[id] === 'undefined' &&
typeof defaultBoolean !== 'undefined'
)
return defaultBoolean;
return id;
}
/**
// id
is a required field of a Config Array Descriptor.
invariant(id, '[React Config] An id
must be provided to config a array.');
if(configMessages[id] && !Array.isArray(configMessages[id]))
invariant(mockArray,
[React Config] The retrieved value via getArray must be provided to config a array.
);
if(!!defaultArray && !Array.isArray(defaultArray))
invariant(mockArray, '[React Config] An defaultArray
must be provided to config a array.');
return configMessages[id] || defaultArray || id;;
}
/**
// id
is a required field of a Config Object Descriptor.
invariant(id, '[React Config] An id
must be provided to config a object.');
if(configMessages[id] && typeof configMessages[id] !== 'object')
invariant(mockObject,
[React Config] The retrieved value via getObject must be provided to config a object.
);
if(!!defaultObject && typeof defaultObject !== 'object')
invariant(mockObject, '[React Config] An defaultObject
must be provided to config a object.');
return configMessages[id] || defaultObject || id;
}
/**
// id
is a required field of a Config Function Descriptor.
invariant(id, '[React Config] An id
must be provided to config a function.');
if(configMessages[id] && typeof configMessages[id] !== 'function')
invariant(mockFunction,
[React Config] The retrieved value via getFunction must be provided to config a function.
);
if(!!defaultFunction && typeof defaultFunction !== 'function')
invariant(mockFunction, '[React Config] An defaultFunction
must be provided to config a function.');
return configMessages[id] || defaultFunction || id;
}
export * from './react-config';
import React, { Component } from 'react';
import invariant from 'invariant';
import { configShape } from './types';
import { invariantConfigContext } from './utils';
const getDisplayName = Component =>
Component.displayName || Component.name || 'Component';
export default function injectConfig(WrappedComponent, options = {}) {
const { configPropName = 'config', withRef = false } = options;
class InjectConfig extends Component {
static displayName = injectConfig(${getDisplayName(WrappedComponent)})
;
static contextTypes = {
config: configShape,
};
static WrappedComponent = WrappedComponent;
constructor(props, context) {
super(props, context);
invariantConfigContext(context);
}
getWrappedInstance() {
invariant(
withRef,
'[React Config] To access the wrapped instance, ' +
'the `{withRef: true}` option must be set when calling: ' +
'`injectConfig()`'
);
return this.refs.wrappedInstance;
}
render() {
return (
<WrappedComponent
{...this.props}
{...{[configPropName]: this.context.config}}
ref={withRef ? 'wrappedInstance' : null}
/>
);
}
}
return InjectConfig;
}
import PropTypes from 'prop-types';
const {
string,
number,
bool,
array,
object,
func,
shape,
any,
oneOfType,
} = PropTypes;
const funcReq = func.isRequired;
export const configCfgPropTypes = {
configMessages: object,
};
export const configFormatPropTypes = {
getString: funcReq,
getNumber: funcReq,
getBoolean: funcReq,
getArray: funcReq,
getObject: funcReq,
getFunction: funcReq,
};
export const configShape = shape({
...configCfgPropTypes,
...configFormatPropTypes,
});
export const configStringDescriptorPropTypes = {
id: string.isRequired,
description: oneOfType([string, object]),
defaultString: string,
};
export const configNumberDescriptorPropTypes = {
id: string.isRequired,
description: oneOfType([string, object]),
defaultNumber: number,
};
export const configBooleanDescriptorPropTypes = {
id: string.isRequired,
description: oneOfType([string, object]),
defaultBoolean: bool,
};
export const configArrayDescriptorPropTypes = {
id: string.isRequired,
description: oneOfType([string, object]),
defaultArray: array,
};
export const configObjectDescriptorPropTypes = {
id: string.isRequired,
description: oneOfType([string, object]),
defaultObject: object,
};
export const configFunctionDescriptorPropTypes = {
id: string.isRequired,
description: oneOfType([string, object]),
defaultFunction: func,
};
import invariant from 'invariant';
import { configCfgPropTypes } from './types';
const configCfgPropNames = Object.keys(configCfgPropTypes);
const ESCAPED_CHARS = {
'&': '&',
'>': '>',
'<': '<',
'"': '"',
"'": ''',
};
const UNSAFE_CHARS_REGEX = /[&><"']/g;
export function escape(str) {
return ('' + str).replace(UNSAFE_CHARS_REGEX, match => ESCAPED_CHARS[match]);
}
export function filterProps(props, whitelist, defaults = {}) {
return whitelist.reduce((filtered, name) => {
if (props.hasOwnProperty(name)) {
filtered[name] = props[name];
} else if (defaults.hasOwnProperty(name)) {
filtered[name] = defaults[name];
}
return filtered;
}, {});
}
export function invariantConfigContext({config} = {}) {
invariant(
config,
'[React Config] Could not find required config
object. ' +
' needs to exist in the component ancestry.'
);
}
export function shallowEquals(objA, objB) {
if (objA === objB) {
return true;
}
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}
let keysA = Object.keys(objA);
let keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Test for A's keys different from B.
let bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
for (let i = 0; i < keysA.length; i++) {
if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
return false;
}
}
return true;
}
export function shouldConfigComponentUpdate(
{props, state, context = {}},
nextProps,
nextState,
nextContext = {}
) {
const {config = {}} = context;
const {config: nextConfig = {}} = nextContext;
return (
!shallowEquals(nextProps, props) ||
!shallowEquals(nextState, state) ||
!(
nextConfig === config ||
shallowEquals(
filterProps(nextConfig, configCfgPropNames),
filterProps(config, configCfgPropNames)
)
)
);
}
This is a react demo application
{
"presets": [
"env",
"react"
],
"plugins": [
"check-es2015-constants",
"transform-async-generator-functions",
"transform-async-to-generator",
"transform-async-to-module-method",
"transform-class-properties",
"transform-decorators",
"transform-do-expressions",
"transform-es2015-arrow-functions",
"transform-es2015-block-scoped-functions",
"transform-es2015-block-scoping",
"transform-es2015-classes",
"transform-es2015-computed-properties",
"transform-es2015-destructuring",
"transform-es2015-duplicate-keys",
"transform-es2015-for-of",
"transform-es2015-function-name",
"transform-es2015-literals",
"transform-es2015-object-super",
"transform-es2015-parameters",
"transform-es2015-shorthand-properties",
"transform-es2015-spread",
"transform-es2015-sticky-regex",
"transform-es2015-template-literals",
"transform-es2015-typeof-symbol",
"transform-es2015-unicode-regex",
"transform-eval",
"transform-exponentiation-operator",
"transform-export-extensions",
"transform-function-bind",
"transform-object-assign",
"transform-object-rest-spread"
]
}
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
node_modules/*
dist/*
public/*
coverage/*
reports/*
webpack.*
{
"parser": "babel-eslint",
"extends": "airbnb",
"env": {
"browser": true,
"node": true,
"mocha": true
},
"plugins": [
"react"
],
"rules": {
"global-require": 0,
"linebreak-style": 0,
"no-console": 0
}
}
*.pbxproj binary
*.docx diff=word
/node_modules
/coverage
/dist
/build
/reports/*
.DS_Store
.env
.project
.vscode/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.7z
*.zip
#debuglog
debug.log
#.stylelintignore
node_modules/*
dist/*
public/*
coverage/*
reports/*
{
"extends": "stylelint-config-standard",
"rules": {
}
}
module.exports = {
verbose: true,
}
module.exports = {
plugins: [
require('postcss-import')(),
require('postcss-apply')(),
require('postcss-extend')(),
require('precss'),
require('postcss-cssnext')
]
}
{
"name": "react-demo",
"version": "1.0.0",
"description": "Ihis is a react demo application",
"main": "index.js",
"keywords": [
"react",
"react-demo",
"demo"
],
"author": "Jovan L.",
"license": "MIT",
"homepage": "",
"repository": {
"type": "git",
"url": ""
},
"bugs": {
"url": ""
},
"contributors": [
{
"name": "Jovan L.",
ย ย ย "email": "[email protected]"
}
],
"scripts": {
"clean": "rimraf dist/",
"build": "npm run clean && webpack --progress --colors -d -p --display-error-details --config webpack/webpack.config.js",
"test": "jest --coverage --config ./jest.config.js ./sum.test.js",
"dev": "webpack-dev-server --progress --inline --hot --host localhost --port 3001 --config webpack/webpack.config.dev.js",
"lint": "eslint --debug --ext .jsx,.js src/ test/ -f html -o reports/ESLint-Report.html",
"lint-fix": "npm run lint -- --fix",
"stylelint": "stylelint src/**/.css src//*.scss",
"stylefmt": "stylefmt --config .stylelintrc.json --recursive src//.css src/**/.scss"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"classnames": "^2.2.5",
"fetch-jsonp": "^1.1.3",
"intl": "^1.2.5",
"jquery": "^3.2.1",
"json-server": "^0.12.1",
"prop-types": "^15.6.0",
"raf": "^3.4.0",
"raw-loader": "^0.5.1",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-intl": "^2.4.0",
"react-redux": "^5.0.6",
"react-router": "^3.2.0",
"react-router-redux": "^4.0.8",
"redux": "^3.7.2",
"redux-saga": "^0.16.0",
"whatwg-fetch": "^2.0.3"
},
"devDependencies": {
"autoprefixer": "^7.1.6",
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-jest": "^22.0.4",
"babel-loader": "^7.1.2",
"babel-plugin-check-es2015-constants": "^6.22.0",
"babel-plugin-transform-async-generator-functions": "^6.24.1",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-plugin-transform-async-to-module-method": "^6.24.1",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators": "^6.24.1",
"babel-plugin-transform-do-expressions": "^6.22.0",
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
"babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
"babel-plugin-transform-es2015-block-scoping": "^6.26.0",
"babel-plugin-transform-es2015-classes": "^6.24.1",
"babel-plugin-transform-es2015-computed-properties": "^6.24.1",
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
"babel-plugin-transform-es2015-duplicate-keys": "^6.24.1",
"babel-plugin-transform-es2015-for-of": "^6.23.0",
"babel-plugin-transform-es2015-function-name": "^6.24.1",
"babel-plugin-transform-es2015-literals": "^6.22.0",
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-plugin-transform-es2015-modules-systemjs": "^6.24.1",
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
"babel-plugin-transform-es2015-object-super": "^6.24.1",
"babel-plugin-transform-es2015-parameters": "^6.24.1",
"babel-plugin-transform-es2015-shorthand-properties": "^6.24.1",
"babel-plugin-transform-es2015-spread": "^6.22.0",
"babel-plugin-transform-es2015-sticky-regex": "^6.24.1",
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
"babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
"babel-plugin-transform-es2015-unicode-regex": "^6.24.1",
"babel-plugin-transform-eval": "^6.22.0",
"babel-plugin-transform-exponentiation-operator": "^6.24.1",
"babel-plugin-transform-export-extensions": "^6.22.0",
"babel-plugin-transform-function-bind": "^6.22.0",
"babel-plugin-transform-object-assign": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"copy-webpack-plugin": "^4.2.0",
"css-loader": "^0.28.7",
"enzyme": "^3.2.0",
"eslint": "^4.9.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-react": "^7.4.0",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"html-loader": "^0.5.1",
"html-webpack-plugin": "^2.30.1",
"ignore-styles": "^5.0.1",
"jest": "^22.0.5",
"jsdom": "^9.12.0",
"jsdom-global": "^2.1.1",
"json-loader": "^0.5.7",
"open-browser-webpack-plugin": "0.0.5",
"postcss": "^6.0.14",
"postcss-cssnext": "^3.0.2",
"postcss-loader": "^2.0.8",
"postcss-pseudoelements": "^5.0.0",
"precss": "^2.0.0",
"react-test-renderer": "^16.2.0",
"redux-logger": "^3.0.6",
"style-loader": "^0.19.0",
"stylefmt": "^6.0.0",
"stylelint": "^8.2.0",
"stylelint-config-standard": "^17.0.0",
"url-loader": "^0.6.2",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.3",
"webpack-hot-middleware": "^2.20.0"
}
}
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OpenBrowserPlugin = require('open-browser-webpack-plugin');
const pathConfig = require('./pathConfig');
const localPath = require('./publishPath').LOCAL_PATH;
const rootPath = pathConfig.rootPath;
const srcPath = pathConfig.srcPath;
const distPath = pathConfig.distPath;
module.exports = {
watch: true,
cache: true,
devtool: 'cheap-module-eval-source-map',
entry: {
app: ${srcPath}/index.js
,
vendor: [
'babel-polyfill',
'classnames',
'fetch-jsonp',
'intl',
'jquery',
'prop-types',
'react',
'react-dom',
'react-intl',
'react-redux',
'react-router',
'react-router-redux',
'redux',
'redux-saga',
'whatwg-fetch',
],
},
output: {
path: distPath,
publicPath: localPath,
filename: '[name].js',
chunkFilename: '[name].chunk.js',
sourceMapFilename: '[name].map',
},
devServer: {
contentBase: './dist',
compress: true,
historyApiFallback: true,
hot: true,
},
resolve: {
extensions: [ ' ', '.js', '.jsx', '.json', '.css', '.scss', '.less', '.sass', ],
},
module: {
rules: [
{
test: /.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract([ 'css-loader', 'postcss-loader' ]),
},
{
test: /.(jpg|png|jpeg|gif|svg)$/,
exclude: /node_modules/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
},
},
],
},
{
test: /.(woff|ttf)$/,
exclude: /node_modules/,
use: 'file-loader',
},
{
test: /.(wav|mp3|mpeg|mp4|webm|ogv)$/,
exclude: /node_modules/,
use: 'file-loader',
},
{
test: /.(json|json5)$/,
exclude: /node_modules/,
use: 'json-loader',
},
{
test: /.txt$/,
exclude: /node_modules/,
use: 'raw-loader',
},
{
test: /.(html|htm|md|markdown)$/,
exclude: /node_modules/,
use: 'html-loader',
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'FX Order Watching',
filename: 'index.html',
favicon: ${pathConfig.publicPath}/favicon.ico
,
template: ${pathConfig.publicPath}/index.html
,
inject: 'body',
hash: true,
cache: false,
showErrors: true,
minify: {
removeComments: true,
collapseWhitespace: true,
},
}),
new OpenBrowserPlugin({
url: localPath,
delay: 0,
browser: 'chrome',
ignoreErrors: false,
}),
new webpack.ProvidePlugin({
React: 'react',
ReactDOM: 'react-dom',
PropTypes: 'prop-types',
}),
new webpack.optimize.CommonsChunkPlugin({
names: ['app', 'vendor', 'manifest'],
filename: '[name].js',
}),
new ExtractTextPlugin({
filename: 'style.css',
allChunks: true,
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development'),
},
path: {
srcPath: JSON.stringify(srcPath),
},
}),
],
};
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.