├── website
├── CNAME
├── bg.mp4
├── playground
│ └── images
│ │ └── iphone.png
├── package.json
├── 404.html
└── README.md
├── packages
├── weex-rax-framework
│ ├── .gitignore
│ ├── src
│ │ ├── builtin.js
│ │ ├── define.weex.js
│ │ ├── require.weex.js
│ │ ├── performance.weex.js
│ │ ├── timer.weex.js
│ │ └── semver.js
│ ├── package.json
│ └── build
├── rax
│ ├── src
│ │ ├── version.js
│ │ ├── server
│ │ │ ├── renderer.js
│ │ │ ├── escapeText.js
│ │ │ ├── __tests__
│ │ │ │ └── escapeText.js
│ │ │ └── renderToString.js
│ │ ├── check.js
│ │ ├── findComponentInstance.js
│ │ ├── debug
│ │ │ ├── devtools.js
│ │ │ └── hook.js
│ │ ├── vdom
│ │ │ ├── host.js
│ │ │ ├── root.js
│ │ │ ├── stateless.js
│ │ │ ├── getElementKeyName.js
│ │ │ ├── shouldUpdateComponent.js
│ │ │ ├── scheduler.js
│ │ │ ├── instantiateComponent.js
│ │ │ ├── empty.js
│ │ │ ├── shallowEqual.js
│ │ │ ├── __tests__
│ │ │ │ └── text.js
│ │ │ └── ref.js
│ │ ├── purecomponent.js
│ │ ├── unmountComponentAtNode.js
│ │ ├── component.js
│ │ ├── index.js
│ │ ├── render.js
│ │ ├── style
│ │ │ ├── styleToCSS.js
│ │ │ └── __tests__
│ │ │ │ ├── styleToCSS.js
│ │ │ │ └── flexbox.js
│ │ ├── setNativeProps.js
│ │ ├── __tests__
│ │ │ ├── proptypes.js
│ │ │ ├── setNativeProps.js
│ │ │ ├── unmountComponentAtNode.js
│ │ │ └── component.js
│ │ ├── testing
│ │ │ ├── renderer.js
│ │ │ └── __tests__
│ │ │ │ ├── __snapshots__
│ │ │ │ └── snapshot.js.snap
│ │ │ │ └── snapshot.js
│ │ ├── findDOMNode.js
│ │ ├── proptypes.js
│ │ └── inject.js
│ ├── .npmignore
│ ├── package.json
│ └── README.md
├── runtime-shared
│ ├── README.md
│ ├── src
│ │ └── fontface.js
│ └── package.json
├── weex-rax-examples
│ ├── README.md
│ ├── components
│ │ ├── a.js
│ │ └── input.js
│ ├── package.json
│ ├── common
│ │ ├── StyleItem.js
│ │ └── Tip.js
│ ├── syntax
│ │ └── hello-world.js
│ ├── index.js
│ └── style
│ │ └── index.js
├── babel-preset-rax
│ ├── .npmignore
│ ├── src
│ │ ├── resolvePlugins.js
│ │ └── index.js
│ ├── README.md
│ └── package.json
├── rax-webpack-plugin
│ ├── .npmignore
│ ├── src
│ │ ├── __tests__
│ │ │ └── fixtures
│ │ │ │ ├── umd
│ │ │ │ ├── index.js
│ │ │ │ └── webpack.config.js
│ │ │ │ ├── bundle
│ │ │ │ ├── index.js
│ │ │ │ └── webpack.config.js
│ │ │ │ ├── factory
│ │ │ │ ├── index.js
│ │ │ │ └── webpack.config.js
│ │ │ │ ├── function
│ │ │ │ ├── index.js
│ │ │ │ └── webpack.config.js
│ │ │ │ ├── module
│ │ │ │ ├── index.js
│ │ │ │ └── webpack.config.js
│ │ │ │ ├── bundle-compatible
│ │ │ │ ├── index.js
│ │ │ │ └── webpack.config.js
│ │ │ │ └── factory-factoryGlobals
│ │ │ │ ├── index.js
│ │ │ │ └── webpack.config.js
│ │ └── BuiltinModules.js
│ └── package.json
├── element-loader
│ ├── src
│ │ ├── defaultKey.js
│ │ ├── __mocks__
│ │ │ └── fs.js
│ │ ├── __tests__
│ │ │ ├── getBabelConfig.js
│ │ │ ├── parserHTML.js
│ │ │ └── transformer.js
│ │ ├── getBabelConfig.js
│ │ ├── node-loader.js
│ │ └── template-loader.js
│ └── package.json
├── rax-test-renderer
│ ├── src
│ │ └── index.js
│ ├── package.json
│ └── README.md
├── rax-server-renderer
│ ├── src
│ │ └── index.js
│ ├── package.json
│ └── README.md
├── rax-image
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── __tests__
│ │ └── Image.weex.js
├── rax-link
│ ├── README.md
│ ├── package.json
│ └── src
│ │ ├── __tests__
│ │ ├── Link.weex.js
│ │ └── Link.js
│ │ └── index.js
├── rax-redux
│ ├── README.md
│ ├── src
│ │ ├── index.js
│ │ ├── utils
│ │ │ ├── wrapActionCreators.js
│ │ │ ├── storeShape.js
│ │ │ ├── warning.js
│ │ │ └── hoistNonRaxStatics.js
│ │ └── components
│ │ │ └── Provider.js
│ └── package.json
├── rax-text
│ ├── README.md
│ ├── src
│ │ └── __tests__
│ │ │ ├── Text.weex.js
│ │ │ └── Text.js
│ └── package.json
├── rax-video
│ ├── README.md
│ ├── src
│ │ ├── __tests__
│ │ │ ├── Video.weex.js
│ │ │ └── Video.js
│ │ └── index.js
│ └── package.json
├── rax-view
│ ├── README.md
│ ├── src
│ │ ├── __tests__
│ │ │ ├── View.weex.js
│ │ │ └── View.js
│ │ └── index.js
│ └── package.json
├── rax-button
│ ├── README.md
│ ├── package.json
│ └── src
│ │ ├── __tests__
│ │ ├── Button.js
│ │ └── __snapshots__
│ │ │ └── Button.js.snap
│ │ └── index.js
├── rax-slider
│ ├── README.md
│ ├── src
│ │ ├── index.js
│ │ └── __tests__
│ │ │ └── Slider.weex.js
│ └── package.json
├── rax-switch
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── __tests__
│ │ ├── Switch.weex.js
│ │ └── Switch.js
├── weex-builtin-globals-service-template
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── index.js
├── weex-builtin-modules-service-template
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── index.js
├── rax-animated
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── mapStyle.js
├── rax-listview
│ ├── README.md
│ ├── src
│ │ ├── __tests__
│ │ │ └── ListView.js
│ │ └── index.js
│ └── package.json
├── rax-cli
│ ├── src
│ │ ├── generator
│ │ │ ├── templates
│ │ │ │ ├── src
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── App.css
│ │ │ │ │ └── App.js
│ │ │ │ ├── README.md
│ │ │ │ ├── public
│ │ │ │ │ └── index.html
│ │ │ │ └── package.json
│ │ │ └── index.js
│ │ └── index.js
│ ├── README.md
│ └── package.json
├── rax-components
│ ├── README.md
│ ├── src
│ │ └── index.js
│ └── package.json
├── rax-scrollview
│ ├── README.md
│ └── package.json
├── rax-textinput
│ ├── README.md
│ ├── src
│ │ └── __tests__
│ │ │ ├── TextInput.weex.js
│ │ │ └── TextInput.js
│ └── package.json
├── rax-touchable
│ ├── README.md
│ ├── src
│ │ ├── __tests__
│ │ │ ├── Touchable.weex.js
│ │ │ └── Touchable.js
│ │ └── index.js
│ └── package.json
├── rax-recyclerview
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── __tests__
│ │ └── RecyclerView.js
├── rax-refreshcontrol
│ ├── README.md
│ ├── src
│ │ └── index.js
│ └── package.json
├── universal-platform
│ ├── src
│ │ ├── index.js
│ │ └── __tests__
│ │ │ └── index.js
│ ├── package.json
│ └── README.md
├── universal-stylesheet
│ ├── src
│ │ ├── index.js
│ │ ├── flattenStyle.js
│ │ └── __tests__
│ │ │ └── flattenStyle.js
│ └── package.json
├── universal-env
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── index.js
├── web-rax-framework
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── index.js
├── universal-perf
│ ├── package.json
│ ├── src
│ │ └── getTreeSnapshot.js
│ └── README.md
├── universal-toast
│ ├── src
│ │ └── __tests__
│ │ │ ├── index.weex.js
│ │ │ └── index.web.js
│ ├── package.json
│ └── README.md
├── universal-jsonp
│ ├── package.json
│ ├── README.md
│ └── src
│ │ └── __tests__
│ │ └── index.web.js
├── universal-transition
│ ├── package.json
│ ├── src
│ │ ├── __tests__
│ │ │ ├── index.weex.js
│ │ │ └── index.js
│ │ └── index.js
│ └── README.md
├── universal-panresponder
│ └── package.json
├── stylesheet-loader
│ ├── package.json
│ └── src
│ │ ├── TextStylePropTypes.js
│ │ ├── ColorPropTypes.js
│ │ ├── promptMessage.js
│ │ ├── FlexboxPropTypes.js
│ │ ├── __tests__
│ │ └── PropTypes.js
│ │ ├── BoxModelPropTypes.js
│ │ └── Validation.js
└── babel-plugin-transform-jsx-stylesheet
│ └── package.json
├── scripts
├── jest.js
├── authors
├── link.js
└── mapCoverage.js
├── .eslintignore
├── examples
├── uikit
│ ├── index.js
│ ├── colors.js
│ ├── Divider.js
│ ├── Text.js
│ ├── index.html
│ └── UIKit.js
├── game2048
│ ├── index.js
│ └── index.html
├── hello
│ ├── index.js
│ └── index.html
├── drag
│ └── index.html
├── perf
│ └── index.html
├── profile
│ └── index.html
├── redux
│ └── index.html
├── parallax
│ └── index.html
├── tictactoe
│ └── index.html
└── components
│ ├── index.html
│ ├── VideoDemo.js
│ └── SwitchDemo.js
├── .babelrc
├── lerna.json
├── .gitignore
├── .travis.yml
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── ISSUE_TEMPLATE.md
└── GIT_COMMIT_SPECIFIC.md
├── docs
├── README.md
├── publishing.md
├── zh-Hans
│ └── use-class-name-in-jsx.md
├── jsx.md
├── difference-with-react.md
└── driver-spec.md
├── AUTHORS
└── LICENSE
/website/CNAME:
--------------------------------------------------------------------------------
1 | rax.taobaofed.org
--------------------------------------------------------------------------------
/packages/weex-rax-framework/.gitignore:
--------------------------------------------------------------------------------
1 | weex
2 |
--------------------------------------------------------------------------------
/packages/rax/src/version.js:
--------------------------------------------------------------------------------
1 | export default '0.2.2';
2 |
--------------------------------------------------------------------------------
/packages/runtime-shared/README.md:
--------------------------------------------------------------------------------
1 | # runtime-shared
2 |
--------------------------------------------------------------------------------
/packages/rax/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | build
4 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/README.md:
--------------------------------------------------------------------------------
1 | # weex-rax-examples
2 |
--------------------------------------------------------------------------------
/packages/babel-preset-rax/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | src
4 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | src
4 | test
5 |
--------------------------------------------------------------------------------
/scripts/jest.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | global.__weex_require__ = require;
3 |
--------------------------------------------------------------------------------
/website/bg.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/functions/rax/master/website/bg.mp4
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/umd/index.js:
--------------------------------------------------------------------------------
1 | console.log('it work!');
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/bundle/index.js:
--------------------------------------------------------------------------------
1 | console.log('it work!');
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/factory/index.js:
--------------------------------------------------------------------------------
1 | console.log('it work!');
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/function/index.js:
--------------------------------------------------------------------------------
1 | console.log('it work!');
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/module/index.js:
--------------------------------------------------------------------------------
1 | console.log('it work!');
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/BuiltinModules.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'rax': ['rax']
3 | };
4 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/bundle-compatible/index.js:
--------------------------------------------------------------------------------
1 | console.log('it work!');
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | gh-pages
3 | lib
4 | dist
5 | build
6 | coverage
7 | weex
8 | expected
9 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/factory-factoryGlobals/index.js:
--------------------------------------------------------------------------------
1 | console.log('it work!');
--------------------------------------------------------------------------------
/packages/element-loader/src/defaultKey.js:
--------------------------------------------------------------------------------
1 | export const IF_KEY = ':if';
2 | export const FOR_KEY = ':for';
3 |
--------------------------------------------------------------------------------
/website/playground/images/iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/functions/rax/master/website/playground/images/iphone.png
--------------------------------------------------------------------------------
/packages/rax-test-renderer/src/index.js:
--------------------------------------------------------------------------------
1 | import renderer from 'rax/lib/testing/renderer';
2 |
3 | module.exports = renderer;
4 |
--------------------------------------------------------------------------------
/examples/uikit/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, render} from 'rax';
2 | import UIKit from './UIKit';
3 |
4 | render();
5 |
--------------------------------------------------------------------------------
/packages/rax-server-renderer/src/index.js:
--------------------------------------------------------------------------------
1 | import renderer from 'rax/lib/server/renderer';
2 |
3 | module.exports = renderer;
4 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/src/builtin.js:
--------------------------------------------------------------------------------
1 | export let ModuleFactories = {
2 | 'rax': require('rax/dist/rax.factory')
3 | };
4 |
--------------------------------------------------------------------------------
/packages/rax-image/README.md:
--------------------------------------------------------------------------------
1 | # rax-image [](https://www.npmjs.com/package/rax-image)
2 |
--------------------------------------------------------------------------------
/packages/rax-link/README.md:
--------------------------------------------------------------------------------
1 | # rax-link [](https://www.npmjs.com/package/rax-link)
2 |
--------------------------------------------------------------------------------
/packages/rax-redux/README.md:
--------------------------------------------------------------------------------
1 | # rax-redux [](https://www.npmjs.com/package/rax-redux)
2 |
--------------------------------------------------------------------------------
/packages/rax-text/README.md:
--------------------------------------------------------------------------------
1 | # rax-text [](https://www.npmjs.com/package/rax-text)
2 |
--------------------------------------------------------------------------------
/packages/rax-video/README.md:
--------------------------------------------------------------------------------
1 | # rax-video [](https://www.npmjs.com/package/rax-video)
2 |
--------------------------------------------------------------------------------
/packages/rax-view/README.md:
--------------------------------------------------------------------------------
1 | # rax-view [](https://www.npmjs.com/package/rax-view)
2 |
--------------------------------------------------------------------------------
/examples/game2048/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, render} from 'rax';
2 | import Game2048 from './Game2048';
3 |
4 | render();
5 |
--------------------------------------------------------------------------------
/packages/rax-button/README.md:
--------------------------------------------------------------------------------
1 | # rax-button [](https://www.npmjs.com/package/rax-button)
2 |
--------------------------------------------------------------------------------
/packages/rax-slider/README.md:
--------------------------------------------------------------------------------
1 | # rax-slider [](https://www.npmjs.com/package/rax-slider)
2 |
--------------------------------------------------------------------------------
/packages/rax-switch/README.md:
--------------------------------------------------------------------------------
1 | # rax-switch [](https://www.npmjs.com/package/rax-switch)
2 |
--------------------------------------------------------------------------------
/packages/rax/src/server/renderer.js:
--------------------------------------------------------------------------------
1 | import renderToString from './renderToString';
2 |
3 | export default {
4 | renderToString
5 | };
6 |
--------------------------------------------------------------------------------
/packages/weex-builtin-globals-service-template/README.md:
--------------------------------------------------------------------------------
1 | # weex-builtin-globals-service-template
2 | > weex builtin globals service template
3 |
--------------------------------------------------------------------------------
/packages/weex-builtin-globals-service-template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weex-builtin-global-service-template",
3 | "private": true
4 | }
5 |
--------------------------------------------------------------------------------
/packages/weex-builtin-modules-service-template/README.md:
--------------------------------------------------------------------------------
1 | # weex-builtin-modules-service-template
2 | > weex builtin modules service template
3 |
--------------------------------------------------------------------------------
/packages/weex-builtin-modules-service-template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weex-builtin-modules-service-template",
3 | "private": true
4 | }
5 |
--------------------------------------------------------------------------------
/packages/rax-animated/README.md:
--------------------------------------------------------------------------------
1 | # rax-animated [](https://www.npmjs.com/package/rax-animated)
2 |
--------------------------------------------------------------------------------
/packages/rax-listview/README.md:
--------------------------------------------------------------------------------
1 | # rax-listview [](https://www.npmjs.com/package/rax-listview)
2 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/generator/templates/src/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, render} from 'rax';
2 | import App from './App';
3 |
4 | render();
5 |
--------------------------------------------------------------------------------
/packages/rax-components/README.md:
--------------------------------------------------------------------------------
1 | # rax-components [](https://www.npmjs.com/package/rax-components)
2 |
--------------------------------------------------------------------------------
/packages/rax-scrollview/README.md:
--------------------------------------------------------------------------------
1 | # rax-scrollview [](https://www.npmjs.com/package/rax-scrollview)
2 |
--------------------------------------------------------------------------------
/packages/rax-textinput/README.md:
--------------------------------------------------------------------------------
1 | # rax-textinput [](https://www.npmjs.com/package/rax-textinput)
2 |
--------------------------------------------------------------------------------
/packages/rax-touchable/README.md:
--------------------------------------------------------------------------------
1 | # rax-touchable [](https://www.npmjs.com/package/rax-touchable)
2 |
--------------------------------------------------------------------------------
/packages/rax-recyclerview/README.md:
--------------------------------------------------------------------------------
1 | # rax-recyclerview [](https://www.npmjs.com/package/rax-recyclerview)
2 |
--------------------------------------------------------------------------------
/packages/rax-redux/src/index.js:
--------------------------------------------------------------------------------
1 | import Provider from './components/Provider';
2 | import connect from './components/connect';
3 |
4 | export {Provider, connect};
5 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "es2015",
4 | "rax"
5 | ],
6 | "ignore": [
7 | "src/generator/templates",
8 | "__mockc__"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "lerna": "2.0.0-beta.37",
3 | "version": "0.2.2",
4 | "commands": {
5 | "publish": {
6 | "skipGit": true
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/rax-refreshcontrol/README.md:
--------------------------------------------------------------------------------
1 | # rax-refreshcontrol [](https://www.npmjs.com/package/rax-refreshcontrol)
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *.swp
3 | .DS_STORE
4 | npm-debug.log
5 | lerna-debug.log
6 | npm-debug.log*
7 | lib/
8 | dist/
9 | build/
10 | coverage/
11 | node_modules/
12 | examples/test
13 |
--------------------------------------------------------------------------------
/packages/rax/src/check.js:
--------------------------------------------------------------------------------
1 | if (typeof window !== 'undefined') {
2 | if (window.Rax) {
3 | console.warn('Multiple (conflicting) copies of Rax loaded, make sure to use only one.');
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/runtime-shared/src/fontface.js:
--------------------------------------------------------------------------------
1 | class FontFace {
2 | constructor(family, source) {
3 | this.family = family;
4 | this.source = source;
5 | }
6 | }
7 |
8 | module.exports = FontFace;
--------------------------------------------------------------------------------
/packages/element-loader/src/__mocks__/fs.js:
--------------------------------------------------------------------------------
1 | export default {
2 | readFileSync() {
3 | let content = {
4 | presets: ['rax']
5 | };
6 | return JSON.stringify(content);
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 |
3 | language: node_js
4 |
5 | node_js:
6 | - "6"
7 | - "7"
8 |
9 | before_script:
10 | - npm run setup
11 |
12 | script:
13 | - npm run lint:nofix
14 | - npm test
15 |
--------------------------------------------------------------------------------
/packages/rax-redux/src/utils/wrapActionCreators.js:
--------------------------------------------------------------------------------
1 | import {bindActionCreators} from 'redux';
2 |
3 | export default function wrapActionCreators(actionCreators) {
4 | return dispatch => bindActionCreators(actionCreators, dispatch);
5 | }
6 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/index.js:
--------------------------------------------------------------------------------
1 | var generate = require('./generator');
2 |
3 | function init(projectDir, projectName, verbose) {
4 | generate(projectDir, projectName, verbose);
5 | }
6 |
7 | module.exports = {
8 | init: init,
9 | };
10 |
--------------------------------------------------------------------------------
/packages/rax-redux/src/utils/storeShape.js:
--------------------------------------------------------------------------------
1 | import {PropTypes} from 'rax';
2 |
3 | export default PropTypes.shape({
4 | subscribe: PropTypes.func.isRequired,
5 | dispatch: PropTypes.func.isRequired,
6 | getState: PropTypes.func.isRequired
7 | });
8 |
--------------------------------------------------------------------------------
/packages/rax/src/findComponentInstance.js:
--------------------------------------------------------------------------------
1 | import instance from './vdom/instance';
2 |
3 | function findComponentInstance(node) {
4 | if (node == null) {
5 | return null;
6 | }
7 | return instance.get(node);
8 | }
9 |
10 | export default findComponentInstance;
11 |
--------------------------------------------------------------------------------
/website/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "start": "http-server",
5 | "deploy": "surge --project ./ --domain rax.taobaofed.org"
6 | },
7 | "devDependencies": {
8 | "http-server": "^0.9.0",
9 | "surge": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/umd/webpack.config.js:
--------------------------------------------------------------------------------
1 | import RaxWebpackPlugin from '../../../index';
2 |
3 | module.exports = {
4 | entry: {
5 | 'index.umd': './index',
6 | },
7 | plugins: [
8 | new RaxWebpackPlugin({
9 | target: 'umd'
10 | })
11 | ]
12 | };
13 |
--------------------------------------------------------------------------------
/packages/rax/src/debug/devtools.js:
--------------------------------------------------------------------------------
1 | import Hook from './hook';
2 |
3 | /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
4 | if (
5 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
6 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
7 | __REACT_DEVTOOLS_GLOBAL_HOOK__.inject(Hook);
8 | }
9 |
--------------------------------------------------------------------------------
/packages/universal-platform/src/index.js:
--------------------------------------------------------------------------------
1 | let OS;
2 |
3 | if (typeof navigator === 'object') {
4 | OS = navigator.platform.toLowerCase();
5 | } else if (typeof WXEnvironment === 'object') {
6 | OS = WXEnvironment.platform;
7 | }
8 |
9 | export default {
10 | OS,
11 | select: obj => obj[OS]
12 | };
13 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/module/webpack.config.js:
--------------------------------------------------------------------------------
1 | import RaxWebpackPlugin from '../../../index';
2 |
3 | module.exports = {
4 | entry: {
5 | 'index.module': './index',
6 | },
7 | plugins: [
8 | new RaxWebpackPlugin({
9 | target: 'module',
10 | })
11 | ]
12 | };
13 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/host.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Stateful things in runtime
3 | */
4 | export default {
5 | component: null,
6 | mountID: 1,
7 | sandbox: true,
8 | // Roots
9 | rootComponents: {},
10 | rootInstances: {},
11 | // Inject
12 | hook: null,
13 | driver: null,
14 | monitor: null
15 | };
16 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/factory/webpack.config.js:
--------------------------------------------------------------------------------
1 | import RaxWebpackPlugin from '../../../index';
2 |
3 | module.exports = {
4 | entry: {
5 | 'index.factory': './index',
6 | },
7 | plugins: [
8 | new RaxWebpackPlugin({
9 | target: 'factory'
10 | })
11 | ]
12 | };
13 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/function/webpack.config.js:
--------------------------------------------------------------------------------
1 | import RaxWebpackPlugin from '../../../index';
2 |
3 | module.exports = {
4 | entry: {
5 | 'index.function': './index',
6 | },
7 | plugins: [
8 | new RaxWebpackPlugin({
9 | target: 'function',
10 | })
11 | ]
12 | };
13 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/bundle-compatible/webpack.config.js:
--------------------------------------------------------------------------------
1 | import RaxWebpackPlugin from '../../../index';
2 |
3 | module.exports = {
4 | entry: {
5 | 'index.bundle': './index',
6 | },
7 | plugins: [
8 | new RaxWebpackPlugin({
9 | target: 'bundle',
10 | })
11 | ]
12 | };
13 |
--------------------------------------------------------------------------------
/packages/rax/src/purecomponent.js:
--------------------------------------------------------------------------------
1 | import Component from './component';
2 |
3 | /**
4 | * Pure component class.
5 | */
6 | class PureComponent extends Component {
7 | constructor(props, context) {
8 | super(props, context);
9 | }
10 |
11 | isPureComponentClass() {}
12 | }
13 |
14 | export default PureComponent;
15 |
--------------------------------------------------------------------------------
/scripts/authors:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # Generate an AUTHORS file based on the output of git shortlog. It uses ABC
4 | # order, strips out leading spaces and numbers, then filters out specific
5 | # authors.
6 |
7 | git shortlog -se \
8 | | perl -spe 's/^\s+\d+\s+//' \
9 | | sed -e '/^CommitSyncScript.*$/d' \
10 | > AUTHORS
11 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/bundle/webpack.config.js:
--------------------------------------------------------------------------------
1 | import RaxWebpackPlugin from '../../../index';
2 |
3 | module.exports = {
4 | entry: {
5 | 'index.bundle': './index',
6 | },
7 | plugins: [
8 | new RaxWebpackPlugin({
9 | target: 'bundle',
10 | bundle: 'bundle'
11 | })
12 | ]
13 | };
14 |
--------------------------------------------------------------------------------
/packages/rax-slider/src/index.js:
--------------------------------------------------------------------------------
1 | import {Component, createElement, PropTypes} from 'rax';
2 | import {isWeex} from 'universal-env';
3 |
4 | class Slider extends Component {
5 |
6 | render() {
7 | if (isWeex) {
8 | return ;
9 | } else {
10 | // TODO
11 | }
12 | }
13 | }
14 |
15 | export default Slider;
16 |
--------------------------------------------------------------------------------
/packages/rax/src/unmountComponentAtNode.js:
--------------------------------------------------------------------------------
1 | import instance from './vdom/instance';
2 |
3 | export default function unmountComponentAtNode(node) {
4 | let component = instance.get(node);
5 |
6 | if (!component) {
7 | return false;
8 | }
9 |
10 | instance.remove(node);
11 | component._internal.unmountComponent();
12 |
13 | return true;
14 | };
15 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/src/__tests__/fixtures/factory-factoryGlobals/webpack.config.js:
--------------------------------------------------------------------------------
1 | import RaxWebpackPlugin from '../../../index';
2 |
3 | module.exports = {
4 | entry: {
5 | 'index.factory': './index',
6 | },
7 | plugins: [
8 | new RaxWebpackPlugin({
9 | target: 'factory',
10 | factoryGlobals: ['weex'],
11 | })
12 | ]
13 | };
14 |
--------------------------------------------------------------------------------
/packages/universal-stylesheet/src/index.js:
--------------------------------------------------------------------------------
1 | import flattenStyle from './flattenStyle';
2 |
3 | const absoluteFillObject = {
4 | position: 'absolute',
5 | left: 0,
6 | right: 0,
7 | top: 0,
8 | bottom: 0,
9 | };
10 |
11 | export default {
12 | hairlineWidth: 1,
13 | absoluteFillObject,
14 |
15 | flatten: flattenStyle,
16 | create: styles => styles
17 | };
18 |
--------------------------------------------------------------------------------
/packages/universal-env/README.md:
--------------------------------------------------------------------------------
1 | # universal-env [](https://www.npmjs.com/package/universal-env)
2 |
3 | > Judge runtime environment
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm install universal-env --save
9 | ```
10 |
11 | ## Usage
12 |
13 | ```js
14 | import {isWeex, isWeb, isReactNative, isNode} from 'universal-env';
15 | ```
--------------------------------------------------------------------------------
/packages/rax/src/server/escapeText.js:
--------------------------------------------------------------------------------
1 | const ESCAPE_LOOKUP = {
2 | '&': '&',
3 | '>': '>',
4 | '<': '<',
5 | '"': '"',
6 | '\'': ''',
7 | };
8 |
9 | const ESCAPE_REGEX = /[&><"']/g;
10 |
11 | function escaper(match) {
12 | return ESCAPE_LOOKUP[match];
13 | }
14 |
15 | export default function escapeText(text) {
16 | return String(text).replace(ESCAPE_REGEX, escaper);
17 | }
18 |
--------------------------------------------------------------------------------
/examples/hello/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component, render} from 'rax';
2 | import {Text} from 'rax-components';
3 |
4 | class Hello extends Component {
5 | render() {
6 | return Hello {this.props.name};
7 | }
8 | }
9 |
10 | const styles = {
11 | title: {
12 | color: '#ff4400',
13 | fontSize: 48,
14 | fontWeight: 'bold',
15 | }
16 | };
17 |
18 | render();
19 |
--------------------------------------------------------------------------------
/packages/web-rax-framework/README.md:
--------------------------------------------------------------------------------
1 | # web-rax-framework
2 |
3 | ## Global API Rax Framework provide
4 |
5 | * `document`
6 | * fonts
7 | * add
8 |
9 |
10 | * `FontFace`
11 | ```js
12 | API:
13 | var iconFontFace = new FontFace('iconfont', 'url(http://at.alicdn.com/t/font_pkm0oq8is8fo5hfr.ttf)');
14 | document.fonts.add(iconFontFace);
15 |
16 | ELEMENT:
17 | {'\uE601'}
18 | ```
19 |
--------------------------------------------------------------------------------
/packages/weex-builtin-globals-service-template/src/index.js:
--------------------------------------------------------------------------------
1 | const builtinGlobalsService = {
2 |
3 | create: (id, env, config) => {
4 | const builtinGlobals = {
5 | // jQuery: 'jquery'
6 | };
7 |
8 | return {
9 | instance: {
10 | builtinGlobals
11 | }
12 | };
13 | },
14 |
15 | destroy: (id, env) => {
16 | }
17 | };
18 |
19 | global.registerService('builtinGlobalsService', builtinGlobalsService);
20 |
--------------------------------------------------------------------------------
/packages/runtime-shared/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "runtime-shared",
3 | "version": "0.2.2",
4 | "description": "Shared Runtime.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme"
15 | }
16 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/src/define.weex.js:
--------------------------------------------------------------------------------
1 | module.exports = function(modules) {
2 | function define(name, deps, factory) {
3 | if (deps instanceof Function) {
4 | factory = deps;
5 | deps = [];
6 | }
7 |
8 | modules[name] = {
9 | factory: factory,
10 | deps: deps,
11 | module: {exports: {}},
12 | isInitialized: false,
13 | hasError: false,
14 | };
15 | }
16 |
17 | return define;
18 | };
19 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | *Before* submitting a pull request, please make sure the following is done...
2 |
3 | 1. Fork the repo and create your branch from `master`.
4 | 2. If you've added code that should be tested, add tests!
5 | 3. If you've changed APIs, update the documentation.
6 | 4. Ensure the test suite passes (`npm test`).
7 | 5. Make sure your code lints (`npm run lint`) - we've done our best to make sure these rules match our internal linting guidelines.
8 |
--------------------------------------------------------------------------------
/examples/uikit/colors.js:
--------------------------------------------------------------------------------
1 | export default {
2 | primary: '#9E9E9E',
3 | primary1: '#4d86f7',
4 | primary2: '#6296f9',
5 | secondary: '#8F0CE8',
6 | secondary2: '#00B233',
7 | secondary3: '#00FF48',
8 | grey0: '#393e42',
9 | grey1: '#43484d',
10 | grey2: '#5e6977',
11 | grey3: '#86939e',
12 | grey4: '#bdc6cf',
13 | grey5: '#e1e8ee',
14 | dkGreyBg: '#232323',
15 | greyOutline: '#cbd2d9',
16 | searchBg: '#303337',
17 | disabled: '#dadee0',
18 | };
19 |
--------------------------------------------------------------------------------
/packages/rax-cli/README.md:
--------------------------------------------------------------------------------
1 | # rax-cli [](https://www.npmjs.com/package/rax-cli) [](https://david-dm.org/alibaba/rax.svg?path=packages/rax-cli) [](https://snyk.io/test/npm/rax-cli)
2 |
3 | > The Rax CLI tools.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ npm install -g rax-cli
9 | ```
10 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/generator/templates/src/App.css:
--------------------------------------------------------------------------------
1 | .app {
2 | flex: 1;
3 | justify-content: center;
4 | align-items: center;
5 | }
6 |
7 | .appHeader {
8 | background-color: #222;
9 | height: 160;
10 | padding: 40;
11 | }
12 |
13 | .appBanner, .appIntro {
14 | text-align: center;
15 | }
16 |
17 | .appBanner {
18 | font-size: 80;
19 | color: white;
20 | }
21 |
22 | .appIntro {
23 | margin-top: 40;
24 | font-size: 40;
25 | line-height: 60;
26 | }
27 |
--------------------------------------------------------------------------------
/packages/universal-env/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-env",
3 | "version": "0.2.2",
4 | "description": "A universal environment utilities.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme"
15 | }
16 |
--------------------------------------------------------------------------------
/packages/universal-env/src/index.js:
--------------------------------------------------------------------------------
1 | // https://www.w3.org/TR/html5/webappapis.html#dom-navigator-appcodename
2 | export const isWeb = typeof navigator === 'object' && (navigator.appCodeName === 'Mozilla' || navigator.product === 'Gecko');
3 | export const isNode = typeof process !== 'undefined' && !!(process.versions && process.versions.node);
4 | export const isWeex = typeof callNative === 'function';
5 | export const isReactNative = typeof __fbBatchedBridgeConfig !== 'undefined';
6 |
--------------------------------------------------------------------------------
/packages/universal-stylesheet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-stylesheet",
3 | "version": "0.2.2",
4 | "description": "A universal StyleSheet API.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme"
15 | }
16 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/root.js:
--------------------------------------------------------------------------------
1 | import Component from '../component';
2 |
3 | let rootCounter = 1;
4 |
5 | class Root extends Component {
6 | rootID = rootCounter++;
7 | isRootComponent() {}
8 | render() {
9 | return this.props.children;
10 | }
11 | getPublicInstance() {
12 | return this.getRenderedComponent().getPublicInstance();
13 | }
14 | getRenderedComponent() {
15 | return this._internal._renderedComponent;
16 | }
17 | }
18 |
19 | export default Root;
20 |
--------------------------------------------------------------------------------
/packages/universal-perf/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-perf",
3 | "version": "0.2.2",
4 | "description": "A universal Perf tools.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {}
16 | }
17 |
--------------------------------------------------------------------------------
/packages/universal-platform/src/__tests__/index.js:
--------------------------------------------------------------------------------
1 |
2 | jest.autoMockOff();
3 |
4 | describe('OS', () => {
5 | Object.defineProperty(navigator, 'platform', {
6 | value: 'MacIntel'
7 | });
8 |
9 | it('should use navigator platform', () => {
10 | const Platform = require('../index');
11 | const selectOS = Platform.select({
12 | macintel: 'test'
13 | });
14 |
15 | expect(Platform.OS).toEqual('macintel');
16 | expect(selectOS).toEqual('test');
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/website/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
21 |
22 |
23 | 404
24 | Go Home
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/uikit/Divider.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import {View} from 'rax-components';
3 | import StyleSheet from 'universal-stylesheet';
4 | import colors from './colors';
5 |
6 | function Divider({style}) {
7 | return (
8 |
9 | );
10 | }
11 |
12 | const styles = StyleSheet.create({
13 | container: {
14 | height: StyleSheet.hairlineWidth,
15 | backgroundColor: colors.grey5
16 | }
17 | });
18 |
19 | export default Divider;
20 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Docs
2 |
3 | ## Quick Start
4 | * [Getting Started](./getting-started.md)
5 | * [Hello World](./tutorial.md)
6 | * [Key Concepts](./concepts.md)
7 | * [JSX](./jsx.md)
8 | * [Networking](./networking.md)
9 | * [Components, Props and State](./components-props-and-state.md)
10 | * [Publishing Project](./publishing.md)
11 | * [Top Level APIs](./top-level-api.md)
12 | * [Differences with React](./difference-with-react.md)
13 |
14 | ## Advanced Guides
15 | * [Driver Specification](./driver-spec.md)
16 |
--------------------------------------------------------------------------------
/packages/rax-video/src/__tests__/Video.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Video from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | describe('Video in weex', () => {
12 | it('render tag Video', () => {
13 | const component = renderer.create(
14 |
15 | );
16 | let tree = component.toJSON();
17 |
18 | expect(tree.tagName).toEqual('VIDEO');
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/stateless.js:
--------------------------------------------------------------------------------
1 | import Host from './host';
2 |
3 | /**
4 | * Stateless Component Class Wrapper
5 | */
6 | class StatelessComponent {
7 | constructor(pureRender) {
8 | // A stateless function
9 | this.pureRender = pureRender;
10 | }
11 | render() {
12 | if (process.env.NODE_ENV !== 'production') {
13 | Host.measurer && Host.measurer.beforeRender();
14 | }
15 |
16 | return this.pureRender(this.props, this.context);
17 | }
18 | }
19 |
20 | export default StatelessComponent;
21 |
--------------------------------------------------------------------------------
/packages/universal-toast/src/__tests__/index.weex.js:
--------------------------------------------------------------------------------
1 | import Toast from '../index';
2 |
3 | const mockWeexToast = jest.fn();
4 |
5 | jest.mock('@weex-module/modal', () => {
6 | return {
7 | toast: mockWeexToast
8 | };
9 | }, {virtual: true});
10 |
11 | jest.mock('universal-env', () => {
12 | return {
13 | isWeex: true
14 | };
15 | });
16 |
17 | describe('toast in weex', () => {
18 | it('weex toast to be called', () => {
19 | Toast.show('Hello');
20 | expect(mockWeexToast).toBeCalled();
21 | });
22 | });
--------------------------------------------------------------------------------
/packages/universal-toast/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-toast",
3 | "version": "0.2.2",
4 | "description": "A universal Toast API.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {
16 | "universal-env": "^0.2.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/universal-jsonp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-jsonp",
3 | "version": "0.2.2",
4 | "description": "A universal JSONP utilities.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {
16 | "universal-env": "^0.2.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/rax-slider/src/__tests__/Slider.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Slider from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | describe('Slider in weex', () => {
12 | it('should render a slider', () => {
13 | const component = renderer.create(
14 | Example
15 | );
16 | let tree = component.toJSON();
17 | expect(tree.tagName).toEqual('SLIDER');
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/packages/rax-test-renderer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-test-renderer",
3 | "version": "0.2.2",
4 | "description": "Rax renderer for snapshot testing.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "peerDependencies": {
16 | "rax": "0.x"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/universal-platform/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-platform",
3 | "version": "0.2.2",
4 | "description": "A universal Platform API.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {
16 | "universal-env": "^0.2.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/element-loader/src/__tests__/getBabelConfig.js:
--------------------------------------------------------------------------------
1 | import getBabelConfig from '../getBabelConfig';
2 |
3 | jest.mock('fs');
4 | describe('getBabelConfig', () => {
5 | it('should get babel config', () => {
6 | expect(getBabelConfig({
7 | babel: {
8 | presets: ['rax']
9 | }
10 | })).toEqual({
11 | presets: ['rax']
12 | });
13 | });
14 |
15 | it('should read .babelrc when no babel query', () => {
16 | expect(getBabelConfig({})).toEqual({
17 | presets: ['rax']
18 | });
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/packages/rax-server-renderer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-server-renderer",
3 | "version": "0.2.2",
4 | "description": "Rax renderer for server-side render.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "peerDependencies": {
16 | "rax": "0.x"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/universal-transition/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-transition",
3 | "version": "0.2.2",
4 | "description": "A universal transition API.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {
16 | "universal-env": "^0.2.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/babel-preset-rax/src/resolvePlugins.js:
--------------------------------------------------------------------------------
1 | export default function resolvePlugins(plugins) {
2 | return plugins.map(function(plugin) {
3 | // Normalise plugin to an array.
4 | if (!Array.isArray(plugin)) {
5 | plugin = [plugin];
6 | }
7 | // Only resolve the plugin if it's a string reference.
8 | if (typeof plugin[0] === 'string') {
9 | plugin[0] = require('babel-plugin-' + plugin[0]);
10 | plugin[0] = plugin[0].__esModule ? plugin[0].default : plugin[0];
11 | }
12 | return plugin;
13 | });
14 | }
15 |
--------------------------------------------------------------------------------
/packages/rax/src/component.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Base component class.
3 | */
4 | class Component {
5 | constructor(props, context, updater) {
6 | this.props = props;
7 | this.context = context;
8 | this.refs = {};
9 | this.updater = updater;
10 | }
11 |
12 | isComponentClass() {}
13 |
14 | setState(partialState, callback) {
15 | this.updater.setState(this, partialState, callback);
16 | }
17 |
18 | forceUpdate(callback) {
19 | this.updater.forceUpdate(this, callback);
20 | }
21 | }
22 |
23 | export default Component;
24 |
--------------------------------------------------------------------------------
/packages/universal-panresponder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "universal-panresponder",
3 | "version": "0.2.2",
4 | "description": "A universal PanResponder API.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {
16 | "universal-env": "^0.2.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/universal-stylesheet/src/flattenStyle.js:
--------------------------------------------------------------------------------
1 | export default function flattenStyle(style) {
2 | if (!style) {
3 | return undefined;
4 | }
5 |
6 | if (!Array.isArray(style)) {
7 | return style;
8 | } else {
9 | let result = {};
10 | for (let i = 0; i < style.length; ++i) {
11 | let computedStyle = flattenStyle(style[i]);
12 | if (computedStyle) {
13 | for (let key in computedStyle) {
14 | result[key] = computedStyle[key];
15 | }
16 | }
17 | }
18 | return result;
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/examples/uikit/Text.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import {Text} from 'rax-components';
3 | import normalize from './normalizeText';
4 |
5 | const TextElement = ({style, children, h1, h2, h3, h4, h5, h6, fontFamily}) =>
6 | {children}
15 | ;
16 |
17 | export default TextElement;
18 |
--------------------------------------------------------------------------------
/packages/rax/src/index.js:
--------------------------------------------------------------------------------
1 | import './debug/devtools';
2 |
3 | export {createElement, cloneElement, isValidElement, createFactory} from './element';
4 | export Component from './component';
5 | export PureComponent from './purecomponent';
6 | export PropTypes from './proptypes';
7 | export render from './render';
8 | export findDOMNode from './findDOMNode';
9 | export unmountComponentAtNode from './unmountComponentAtNode';
10 | export findComponentInstance from './findComponentInstance';
11 | export setNativeProps from './setNativeProps';
12 | export version from './version';
13 |
--------------------------------------------------------------------------------
/packages/rax-text/src/__tests__/Text.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Text from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | describe('Text in weex', () => {
12 | it('render tag Text', () => {
13 | const component = renderer.create(
14 | Example
15 | );
16 | let tree = component.toJSON();
17 | expect(tree.tagName).toEqual('TEXT');
18 | expect(tree.attributes.value).toEqual('Example');
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/packages/rax-view/src/__tests__/View.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import View from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | describe('View in weex', () => {
12 | it('render tag view', () => {
13 | const component = renderer.create(
14 | Example
15 | );
16 | let tree = component.toJSON();
17 |
18 | expect(tree.tagName).toEqual('DIV');
19 | expect(tree.children[0]).toEqual('Example');
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/rax/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax",
3 | "version": "0.2.2",
4 | "description": "A universal React-compatible render engine.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "dependencies": {
19 | "universal-env": "^0.2.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/rax-textinput/src/__tests__/TextInput.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import TextInput from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | describe('TextInput in weex', () => {
12 | it('render tag TextInput', () => {
13 | const component = renderer.create(
14 |
15 | );
16 | let tree = component.toJSON();
17 |
18 | expect(tree.tagName).toEqual('INPUT');
19 | expect(tree.attributes.disabled).toEqual(false);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/rax-touchable/src/__tests__/Touchable.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Touchable from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | describe('Touchable in weex', () => {
12 | it('render tag Touchable', () => {
13 | const component = renderer.create(
14 | Example
15 | );
16 | let tree = component.toJSON();
17 |
18 | expect(tree.tagName).toEqual('DIV');
19 | expect(tree.children[0]).toEqual('Example');
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/stylesheet-loader/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stylesheet-loader",
3 | "version": "0.2.2",
4 | "description": "Stylesheet loader.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {
16 | "camelcase": "^3.0.0",
17 | "chalk": "^1.1.3",
18 | "css": "^2.2.1",
19 | "loader-utils": "^0.2.16"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/rax-refreshcontrol/src/index.js:
--------------------------------------------------------------------------------
1 | import {Component, createElement, PropTypes} from 'rax';
2 | import {isWeex} from 'universal-env';
3 |
4 | class RefreshControl extends Component {
5 | render() {
6 | if (isWeex) {
7 | let displayRefresh = this.props.refreshing ? 'show' : 'hide';
8 | return (
9 |
10 | {this.props.children}
11 |
12 | );
13 | } else {
14 | return null;
15 | }
16 | }
17 | }
18 |
19 | export default RefreshControl;
20 |
--------------------------------------------------------------------------------
/packages/universal-toast/README.md:
--------------------------------------------------------------------------------
1 | # universal-toast [](https://www.npmjs.com/package/universal-toast)
2 |
3 | > An universal toast
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm install universal-toast --save
9 | ```
10 |
11 | ## Usage
12 |
13 | ```js
14 | import Toast from 'universal-toast';
15 |
16 | Toast.show('Hi');
17 | ```
18 |
19 | ## APIS
20 |
21 | ### `Toast.show(message, duration)`
22 |
23 | - message: Required, String, the text to toast
24 | - duration: Optional, Number, unit ms, the duration of the toast. May be Toast.SHORT(2500ms) or Toast.LONG(3500ms)
--------------------------------------------------------------------------------
/packages/stylesheet-loader/src/TextStylePropTypes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import PropTypes from './PropTypes';
4 |
5 | const TextStylePropTypes = {
6 | fontSize: PropTypes.length,
7 | fontStyle: PropTypes.oneOf(['normal', 'italic']),
8 | fontWeight: PropTypes.oneOf(['normal', 'bold', 'lighter', 'bolder', '100', '200', '300', '400', '500', '600', '700', '800', '900']),
9 | textDecoration: PropTypes.oneOf(['underline', 'line-through']),
10 | lineHeight: PropTypes.length,
11 | textAlign: PropTypes.oneOf(['left', 'center', 'right']),
12 | lines: PropTypes.integer
13 | };
14 |
15 | export default TextStylePropTypes;
16 |
--------------------------------------------------------------------------------
/packages/web-rax-framework/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "web-rax-framework",
3 | "version": "0.2.2",
4 | "description": "Rax framework for web.",
5 | "license": "BSD-3-Clause",
6 | "main": "dist/framework.web.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "dependencies": {
16 | "raf": "^3.3.0",
17 | "runtime-shared": "^0.2.2",
18 | "rax": "^0.2.2",
19 | "whatwg-fetch": "^2.0.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/components/a.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component, render} from 'rax';
2 | import Panel from '../common/Panel';
3 | import Tip from '../common/Tip';
4 |
5 | class Example extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 | );
17 | }
18 | }
19 |
20 | render();
21 |
--------------------------------------------------------------------------------
/packages/weex-builtin-modules-service-template/src/index.js:
--------------------------------------------------------------------------------
1 | // import foo from 'foo/dist/foo.factory';
2 |
3 | const builtinModulesService = {
4 |
5 | create: (id, env, config) => {
6 | // Modules should wrap as module factory format, see: rax-webpack-plugin
7 | const builtinModules = {
8 | // `rax` have been build in framework, do not need add here
9 | // foo
10 | };
11 |
12 | return {
13 | instance: {
14 | builtinModules
15 | }
16 | };
17 | },
18 |
19 | destroy: (id, env) => {
20 | }
21 | };
22 |
23 | global.registerService('builtinModulesService', builtinModulesService);
24 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/generator/templates/src/App.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import View from 'rax-view';
3 | import Text from 'rax-text';
4 | import styles from './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | return (
9 |
10 |
11 | Welcome to Rax
12 |
13 |
14 | To get started, edit src/App.js and save to reload.
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/packages/stylesheet-loader/src/ColorPropTypes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import PropTypes from './PropTypes';
4 |
5 | const TextPropTypes = {
6 | color: PropTypes.color,
7 | backgroundColor: PropTypes.color,
8 | borderColor: PropTypes.color,
9 | borderTopColor: PropTypes.color,
10 | borderRightColor: PropTypes.color,
11 | borderBottomColor: PropTypes.color,
12 | borderLeftColor: PropTypes.color,
13 | itemColor: PropTypes.color,
14 | itemSelectedColor: PropTypes.color,
15 | textColor: PropTypes.color,
16 | timeColor: PropTypes.color,
17 | textHighlightColor: PropTypes.color
18 | };
19 |
20 | export default TextPropTypes;
21 |
--------------------------------------------------------------------------------
/packages/rax-touchable/src/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import {isWeex} from 'universal-env';
3 | import View from 'rax-view';
4 |
5 | class Touchable extends Component {
6 | render() {
7 | let props = this.props;
8 | let nativeProps = {
9 | ...props,
10 | style: {
11 | ...styles.initial,
12 | ...props.style
13 | },
14 | onClick: props.onPress
15 | };
16 |
17 | delete nativeProps.onPress;
18 |
19 | return ;
20 | }
21 | }
22 |
23 | const styles = {
24 | initial: {
25 | cursor: 'pointer'
26 | }
27 | };
28 |
29 | export default Touchable;
30 |
--------------------------------------------------------------------------------
/packages/stylesheet-loader/src/promptMessage.js:
--------------------------------------------------------------------------------
1 | let warnMessages = '';
2 | let errorMessages = '';
3 |
4 | export const getWarnMessages = () => {
5 | return warnMessages;
6 | };
7 |
8 | export const getErrorMessages = () => {
9 | return errorMessages;
10 | };
11 |
12 | export const pushWarnMessage = (message) => {
13 | message = message.replace(/`/g, '\\`');
14 | warnMessages += `${message}\\n`;
15 | };
16 |
17 | export const pushErrorMessage = (message) => {
18 | message = message.replace(/`/g, '\\`');
19 | errorMessages += `${message}\\n`;
20 | };
21 |
22 | export const resetMessage = () => {
23 | warnMessages = '';
24 | errorMessages = '';
25 | };
26 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weex-rax-examples",
3 | "version": "0.2.2",
4 | "description": "Rax examples for weex.",
5 | "license": "BSD-3-Clause",
6 | "main": "index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "scripts": {
15 | "test": "babel-node ./test/index.js"
16 | },
17 | "homepage": "https://github.com/alibaba/rax#readme",
18 | "dependencies": {
19 | "universal-env": "^0.2.2",
20 | "universal-transition": "^0.2.2",
21 | "rax": "^0.2.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/element-loader/src/getBabelConfig.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 |
3 | export default function getBabelConfig(query = {}) {
4 | let result = {};
5 | const BABELRC_FILE = process.cwd() + '/.babelrc';
6 |
7 | if (query.babel) {
8 | result = query.babel;
9 | } else {
10 | let content = fs.readFileSync(BABELRC_FILE);
11 | try {
12 | let config = JSON.parse(content);
13 | result = config;
14 | } catch (e) {
15 | console.error('`.babelrc` config error');
16 | }
17 | }
18 |
19 | if (!result.presets && !result.plugins) {
20 | console.error('please config `.babelrc` or `webpack.config.js` loader query');
21 | }
22 | return result;
23 | };
24 |
--------------------------------------------------------------------------------
/website/README.md:
--------------------------------------------------------------------------------
1 | # Install prerequisites
2 |
3 | Before running the website, make sure you've run the following:
4 |
5 | ```sh
6 | git clone https://github.com/alibaba/rax.git
7 | cd rax
8 | npm install
9 | ```
10 |
11 | # Run the website server
12 |
13 | The first time, get all the website dependencies loaded via
14 |
15 | ```sh
16 | cd website
17 | npm install
18 | ```
19 |
20 | Then, run the server via
21 |
22 | ```sh
23 | cd website
24 | npm start
25 | open http://localhost:3000/
26 | ```
27 |
28 | Anytime you change the contents, just refresh the page and it's going to be updated.
29 |
30 | # Publish the website
31 |
32 | ```sh
33 | cd website
34 |
35 | npm run deploy
36 | ```
37 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Help us to manage our issues by answering the following:
2 |
3 | 1. How would you tag this issue?
4 |
5 | - Question
6 | - Bug
7 | - Discussion
8 | - Feature request
9 | - Tip
10 | - Enhancement
11 | - Performance
12 |
13 | 2. Describe your issue:
14 |
15 | - What is the current behavior?
16 | - What is the expected behavior?
17 | - Which versions of Rax, and which browser / OS are affected by this issue?
18 | - Did this work in previous versions of Rax?
19 |
20 | 3. If your issue is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via [Bug Report Template](http://codepen.io/taobaofed/pen/oByQGb) on CodePen
21 | .
22 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/getElementKeyName.js:
--------------------------------------------------------------------------------
1 | export default (children, element, index) => {
2 | const elementKey = element && element.key;
3 | const hasKey = typeof elementKey === 'string';
4 | const defaultName = '.' + index.toString(36);
5 |
6 | if (hasKey) {
7 | let keyName = '$' + elementKey;
8 | // Child keys must be unique.
9 | let keyUnique = children[keyName] === undefined;
10 | // Only the first child will be used when encountered two children with the same key
11 | if (!keyUnique) console.warn(`Encountered two children with the same key "${elementKey}".`);
12 |
13 | return keyUnique ? keyName : defaultName;
14 | } else {
15 | return defaultName;
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/packages/rax/README.md:
--------------------------------------------------------------------------------
1 | # rax [](https://www.npmjs.com/package/rax) [](https://david-dm.org/alibaba/rax.svg?path=packages/rax) [](https://snyk.io/test/npm/rax)
2 |
3 | > A universal React-compatible render engine
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ npm install --save rax
9 | ```
10 |
11 | ## Usage
12 |
13 | ```jsx
14 | import {createElement, Component, render} from 'rax';
15 |
16 | class MyComponent extends Component {
17 | render() {
18 | return Hello World
;
19 | }
20 | }
21 |
22 | render();
23 | ```
24 |
--------------------------------------------------------------------------------
/packages/rax/src/render.js:
--------------------------------------------------------------------------------
1 | import inject from './inject';
2 | import instance from './vdom/instance';
3 | import {setRem} from './style/unit';
4 | import Host from './vdom/host';
5 |
6 | function render(element, container, options, callback) {
7 | // Compatible with `render(element, container, callback)`
8 | if (typeof options === 'function') {
9 | callback = options;
10 | options = null;
11 | }
12 |
13 | // Init inject
14 | inject(options);
15 |
16 | let rootComponent = instance.render(element, container);
17 | let component = rootComponent.getPublicInstance();
18 |
19 | if (callback) {
20 | callback.call(component);
21 | }
22 |
23 | return component;
24 | }
25 |
26 | export default render;
27 |
--------------------------------------------------------------------------------
/packages/rax/src/style/styleToCSS.js:
--------------------------------------------------------------------------------
1 | import {convertUnit} from './unit';
2 |
3 | // TODO process flexbox polyfill
4 | export default function styleToCSS(style, disableConvertUnit) {
5 | let css = '';
6 | for (let prop in style) {
7 | if (style.hasOwnProperty(prop)) {
8 | let val = style[prop];
9 | if (val != null) {
10 | css += `${prop.replace(/([A-Z])/g, '-$1').toLowerCase()}:`;
11 | if (!disableConvertUnit) {
12 | // If in server-side render should not convert rem unit that depends on client width
13 | css += convertUnit(val, prop);
14 | } else {
15 | css += `${val}`;
16 | }
17 | css += ';';
18 | }
19 | }
20 | }
21 | return css;
22 | }
23 |
--------------------------------------------------------------------------------
/packages/rax-redux/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-redux",
3 | "version": "0.2.2",
4 | "description": "Official Rax bindings for Redux.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "dependencies": {
19 | "invariant": "^2.0.0",
20 | "lodash.isplainobject": "^4.0.6",
21 | "shallowequal": "^0.2.2",
22 | "redux": "^3.6.0"
23 | },
24 | "peerDependencies": {
25 | "rax": "0.x"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weex-rax-framework",
3 | "version": "0.2.2",
4 | "description": "Rax framework for weex.",
5 | "license": "BSD-3-Clause",
6 | "main": "dist/framework.weex.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "scripts": {
12 | "build:jsfm": "./build"
13 | },
14 | "bugs": {
15 | "url": "https://github.com/alibaba/rax/issues"
16 | },
17 | "homepage": "https://github.com/alibaba/rax#readme",
18 | "dependencies": {
19 | "runtime-shared": "^0.2.2",
20 | "rax": "^0.2.2"
21 | },
22 | "devDependencies": {
23 | "weex-runtime-js": "^0.19.8",
24 | "weex-vdom-tester": "^0.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/rax-redux/src/utils/warning.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Prints a warning in the console if it exists.
3 | *
4 | * @param {String} message The warning message.
5 | * @returns {void}
6 | */
7 | export default function warning(message) {
8 | /* eslint-disable no-console */
9 | if (typeof console !== 'undefined' && typeof console.error === 'function') {
10 | console.error(message);
11 | }
12 | /* eslint-enable no-console */
13 | try {
14 | // This error was thrown as a convenience so that if you enable
15 | // "break on all exceptions" in your console,
16 | // it would pause the execution at this line.
17 | throw new Error(message);
18 | /* eslint-disable no-empty */
19 | } catch (e) {}
20 | /* eslint-enable no-empty */
21 | }
22 |
--------------------------------------------------------------------------------
/packages/babel-plugin-transform-jsx-stylesheet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "babel-plugin-transform-jsx-stylesheet",
3 | "version": "0.2.2",
4 | "description": "Transform stylesheet selector to style in JSX Elements.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "devDependencies": {
19 | "babel-core": "^6.23.1",
20 | "babel-plugin-syntax-jsx": "^6.18.0"
21 | },
22 | "dependencies": {
23 | "camelcase": "^4.0.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/stylesheet-loader/src/FlexboxPropTypes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import PropTypes from './PropTypes';
4 |
5 | const FlexboxPropTypes = {
6 | flexDirection: PropTypes.oneOf(['row', 'row-reverse', 'column', 'column-reverse' ]),
7 | flexWrap: PropTypes.oneOf(['wrap', 'nowrap', 'wrap-reverse']),
8 | justifyContent: PropTypes.oneOf(['flex-start', 'flex-end', 'center', 'space-between', 'space-around']),
9 | alignItems: PropTypes.oneOf(['flex-start', 'flex-end', 'center', 'stretch']),
10 | alignContent: PropTypes.oneOf(['stretch', 'flex-start', 'flex-end', 'center', 'space-between', 'space-around']),
11 | alignSelf: PropTypes.oneOf(['auto', 'flex-start', 'flex-end', 'center', 'stretch']),
12 | flex: PropTypes.integer
13 | };
14 |
15 | export default FlexboxPropTypes;
16 |
--------------------------------------------------------------------------------
/packages/universal-transition/src/__tests__/index.weex.js:
--------------------------------------------------------------------------------
1 | import transition from '../index';
2 |
3 | jest.mock('universal-env', () => {
4 | return {
5 | isWeex: true
6 | };
7 | });
8 |
9 | jest.mock('@weex-module/animation', () => {
10 | return {
11 | transition: (ref, options, callback) => {
12 | callback();
13 | }
14 | };
15 | }, {virtual: true});
16 |
17 | describe('transition in weex', () => {
18 | it('can trigger callback', () => {
19 | const mockFn = jest.fn();
20 | transition(document.body, {
21 | transform: 'translate(10px, 20px) scale(1.5, 1.5) rotate(90deg)'
22 | }, {
23 | timingFunction: 'ease',
24 | duration: 1000,
25 | delay: 1000
26 | }, mockFn);
27 |
28 | expect(mockFn).toBeCalled();
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/packages/rax-cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-cli",
3 | "version": "0.2.2",
4 | "license": "BSD-3-Clause",
5 | "description": "The Rax CLI tools",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "bin": {
16 | "rax": "bin/rax.js"
17 | },
18 | "engines": {
19 | "npm": ">=3.0.0"
20 | },
21 | "dependencies": {
22 | "chalk": "^1.1.1",
23 | "cross-spawn": "^4.0.2",
24 | "easyfile": "^0.1.1",
25 | "minimist": "^1.2.0",
26 | "prompt": "^0.2.14",
27 | "semver": "^5.3.0",
28 | "update-notifier": "^1.0.3"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/universal-perf/src/getTreeSnapshot.js:
--------------------------------------------------------------------------------
1 | import getComponentTree from './getComponentTree';
2 | let treeSnapshot = {};
3 |
4 | export default function getTreeSnapshot(roots, tree) {
5 | const rootIDs = Object.getOwnPropertyNames(roots);
6 |
7 | for (const rootID of rootIDs) {
8 | treeSnapshot[rootID] = getComponentData(tree[rootID], 0);
9 | }
10 |
11 | return treeSnapshot;
12 | }
13 |
14 | function getComponentData(element, parentID) {
15 | const data = getComponentTree(element);
16 |
17 | for (const child of data.children || []) {
18 | treeSnapshot[child._mountID] = getComponentData(child, element._mountID);
19 | }
20 |
21 | return {
22 | ...data,
23 | parentID: parentID,
24 | ownerID: element._mountID,
25 | displayName: data.name
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/packages/rax-components/src/index.js:
--------------------------------------------------------------------------------
1 | export View from 'rax-view';
2 | export Text from 'rax-text';
3 | export Image from 'rax-image';
4 | export Link from 'rax-link';
5 | export TextInput from 'rax-textinput';
6 | export Button from 'rax-button';
7 | export Switch from 'rax-switch';
8 | export Video from 'rax-video';
9 | export ScrollView from 'rax-scrollview';
10 | export Slider from 'rax-slider';
11 | export ListView from 'rax-listview';
12 | export RecyclerView from 'rax-recyclerview';
13 | export RefreshControl from 'rax-refreshcontrol';
14 | export TouchableHighlight from 'rax-touchable';
15 | export TouchableOpacity from 'rax-touchable';
16 | export TouchableWithoutFeedback from 'rax-touchable';
17 | export TouchableNativeFeedback from 'rax-touchable';
18 | export TouchableBounce from 'rax-touchable';
19 |
--------------------------------------------------------------------------------
/packages/rax-text/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-text",
3 | "version": "0.2.2",
4 | "description": "Text component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "universal-env": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | },
29 | "devDependencies": {
30 | "rax-test-renderer": "^0.2.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/rax-video/src/index.js:
--------------------------------------------------------------------------------
1 | import {Component, createElement} from 'rax';
2 | import {isWeex} from 'universal-env';
3 |
4 | class Video extends Component {
5 | render() {
6 | let props = this.props;
7 |
8 | if (isWeex) {
9 | return ;
10 | } else {
11 | let nativeProps = {
12 | ...props,
13 | controls: true,
14 | };
15 |
16 | delete nativeProps.autoPlay;
17 | delete nativeProps.src;
18 |
19 | if (props.autoPlay) {
20 | nativeProps.autoPlay = props.autoPlay;
21 | }
22 | let src = props.src;
23 |
24 | return ;
29 | }
30 | }
31 | }
32 |
33 | export default Video;
34 |
--------------------------------------------------------------------------------
/packages/rax-view/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-view",
3 | "version": "0.2.2",
4 | "description": "View component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "universal-env": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | },
29 | "devDependencies": {
30 | "rax-test-renderer": "^0.2.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/common/StyleItem.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 |
3 | class StyleItem extends Component {
4 | static defaultProps = {
5 | value: '',
6 | type: 0
7 | };
8 | render() {
9 | const {value, type, style} = this.props;
10 |
11 | return (
12 |
16 | );
17 | }
18 | }
19 |
20 |
21 | const styles = {
22 | item: {
23 | marginRight: 10,
24 | /* margin-bottom: 10px; */
25 | width: 160,
26 | height: 75,
27 | paddingLeft: 8,
28 | paddingRight: 8,
29 | paddingTop: 8,
30 | paddingBottom: 8,
31 | color: '#eeeeee'
32 | }
33 | };
34 |
35 | export default StyleItem;
36 |
--------------------------------------------------------------------------------
/packages/rax-animated/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-animated",
3 | "version": "0.2.2",
4 | "description": "Declarative Animations Library for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "dependencies": {
19 | "animated": "0.1.3",
20 | "invariant": "2.2.1",
21 | "rax-text": "^0.2.2",
22 | "rax-view": "^0.2.2",
23 | "rax-image": "^0.2.2",
24 | "rax-scrollview": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/rax-video/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-video",
3 | "version": "0.2.2",
4 | "description": "Video component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "universal-env": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | },
29 | "devDependencies": {
30 | "rax-test-renderer": "^0.2.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/rax-slider/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-slider",
3 | "version": "0.2.2",
4 | "description": "Slider component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "universal-env": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | },
29 | "devDependencies": {
30 | "rax-test-renderer": "^0.2.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/rax-switch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-switch",
3 | "version": "0.2.2",
4 | "description": "Switch component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "universal-env": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | },
29 | "devDependencies": {
30 | "rax-test-renderer": "^0.2.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/rax-video/src/__tests__/Video.js:
--------------------------------------------------------------------------------
1 | global.callNative = null;
2 | import {createElement} from 'rax';
3 | import renderer from 'rax-test-renderer';
4 | import Video from '../';
5 |
6 | describe('Video', () => {
7 | it('render tag Video', () => {
8 | const component = renderer.create(
9 |
10 | );
11 | let tree = component.toJSON();
12 | expect(tree.tagName).toEqual('VIDEO');
13 | expect(tree.children[0].tagName).toEqual('SOURCE');
14 | });
15 |
16 | it('props on Video', () => {
17 | const mockPress = jest.fn();
18 | const component = renderer.create(
19 |
20 | );
21 | let tree = component.toJSON();
22 | expect(tree.attributes.controls).toBe(true);
23 | expect(tree.attributes['webkit-playsinline']).toBe(true);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/packages/rax-textinput/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-textinput",
3 | "version": "0.2.2",
4 | "description": "TextInput component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "universal-env": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | },
29 | "devDependencies": {
30 | "rax-test-renderer": "^0.2.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/shouldUpdateComponent.js:
--------------------------------------------------------------------------------
1 | function shouldUpdateComponent(prevElement, nextElement) {
2 | // TODO: prevElement and nextElement could be array
3 | let prevEmpty = prevElement === null;
4 | let nextEmpty = nextElement === null;
5 | if (prevEmpty || nextEmpty) {
6 | return prevEmpty === nextEmpty;
7 | }
8 |
9 | let prevType = typeof prevElement;
10 | let nextType = typeof nextElement;
11 | if (prevType === 'string' || prevType === 'number') {
12 | return nextType === 'string' || nextType === 'number';
13 | } else {
14 | return (
15 | prevType === 'object' &&
16 | nextType === 'object' &&
17 | prevElement.type === nextElement.type &&
18 | prevElement.key === nextElement.key
19 | );
20 | }
21 | }
22 |
23 | export default shouldUpdateComponent;
24 |
--------------------------------------------------------------------------------
/packages/rax-view/src/index.js:
--------------------------------------------------------------------------------
1 | import {Component, createElement} from 'rax';
2 | import {isWeex} from 'universal-env';
3 |
4 | class View extends Component {
5 | render() {
6 | let props = this.props;
7 | if (isWeex) {
8 | // TODO: do not pass object value in props
9 | return ;
10 | } else {
11 | let styleProps = {
12 | ...styles.initial,
13 | ...props.style
14 | };
15 | return ;
16 | }
17 | }
18 | }
19 |
20 | const styles = {
21 | initial: {
22 | border: '0 solid black',
23 | position: 'relative',
24 | boxSizing: 'border-box',
25 | display: 'flex',
26 | flexDirection: 'column',
27 | alignContent: 'flex-start',
28 | flexShrink: 0
29 | }
30 | };
31 |
32 | export default View;
33 |
--------------------------------------------------------------------------------
/packages/rax-refreshcontrol/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-refreshcontrol",
3 | "version": "0.2.2",
4 | "description": "RefreshControl component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "universal-env": "^0.2.2"
25 | },
26 | "peerDependencies": {
27 | "rax": "0.x"
28 | },
29 | "devDependencies": {
30 | "rax-test-renderer": "^0.2.2"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/universal-platform/README.md:
--------------------------------------------------------------------------------
1 | # universal-platform [](https://www.npmjs.com/package/universal-platform)
2 |
3 | > Get runtime OS name
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm install universal-platform --save
9 | ```
10 |
11 | ## Usage
12 |
13 | ```js
14 | import {OS} from 'universal-platform';
15 |
16 | // maybe ios, android, or web
17 | console.log(OS);
18 | ```
19 |
20 | ## APIS
21 |
22 | ### `select(obj)`
23 |
24 | Use it to return platform specific component, like below:
25 |
26 | ```js
27 | import {select} from 'universal-platform';
28 |
29 | import AndroidComponent from './AndroidComponent';
30 | import IOSComponent from './IOSComponent';
31 |
32 | const DestComponent = select({
33 | ios: IOSComponent,
34 | android: AndroidComponent
35 | });
36 | ```
--------------------------------------------------------------------------------
/packages/rax-image/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-image",
3 | "version": "0.2.2",
4 | "description": "Image component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "rax-view": "^0.2.2",
25 | "universal-env": "^0.2.2"
26 | },
27 | "peerDependencies": {
28 | "rax": "0.x"
29 | },
30 | "devDependencies": {
31 | "rax-test-renderer": "^0.2.2"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/rax-link/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-link",
3 | "version": "0.2.2",
4 | "description": "Link component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "rax-text": "^0.2.2",
25 | "universal-env": "^0.2.2"
26 | },
27 | "peerDependencies": {
28 | "rax": "0.x"
29 | },
30 | "devDependencies": {
31 | "rax-test-renderer": "^0.2.2"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/universal-stylesheet/src/__tests__/flattenStyle.js:
--------------------------------------------------------------------------------
1 | import flattenStyle from '../flattenStyle';
2 |
3 | describe('flattenStyle', () => {
4 | it('should merge objects', () => {
5 | const style1 = {
6 | width: 20
7 | };
8 | const style2 = {
9 | height: 50
10 | };
11 | const flatStyle = flattenStyle([style1, style2]);
12 | expect(flatStyle.width).toBe(20);
13 | expect(flatStyle.height).toBe(50);
14 | });
15 |
16 | it('should override before style properties', () => {
17 | const style1 = {
18 | width: 50,
19 | height: 60
20 | };
21 | const style2 = {
22 | width: 20,
23 | height: 10
24 | };
25 | const flatStyle = flattenStyle([style1, style2]);
26 | expect(flatStyle.width).toBe(20);
27 | expect(flatStyle.height).toBe(10);
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/packages/rax-scrollview/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-scrollview",
3 | "version": "0.2.2",
4 | "description": "ScrollView component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "rax-view": "^0.2.2",
25 | "universal-env": "^0.2.2"
26 | },
27 | "peerDependencies": {
28 | "rax": "0.x"
29 | },
30 | "devDependencies": {
31 | "rax-test-renderer": "^0.2.2"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/rax-touchable/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-touchable",
3 | "version": "0.2.2",
4 | "description": "Touchable component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "rax-view": "^0.2.2",
25 | "universal-env": "^0.2.2"
26 | },
27 | "peerDependencies": {
28 | "rax": "0.x"
29 | },
30 | "devDependencies": {
31 | "rax-test-renderer": "^0.2.2"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/src/require.weex.js:
--------------------------------------------------------------------------------
1 | module.exports = function(modules) {
2 | function require(name) {
3 | var mod = modules[name];
4 |
5 | if (mod && mod.isInitialized) {
6 | return mod.module.exports;
7 | }
8 |
9 | if (!mod) {
10 | throw new Error(
11 | 'Requiring unknown module "' + name + '"'
12 | );
13 | }
14 |
15 | if (mod.hasError) {
16 | throw new Error(
17 | 'Requiring module "' + name + '" which threw an exception'
18 | );
19 | }
20 |
21 | try {
22 | mod.isInitialized = true;
23 | mod.factory(require, mod.module.exports, mod.module);
24 | } catch (e) {
25 | mod.hasError = true;
26 | mod.isInitialized = false;
27 | throw e;
28 | }
29 |
30 | return mod.module.exports;
31 | }
32 |
33 | return require;
34 | };
35 |
--------------------------------------------------------------------------------
/packages/rax-listview/src/__tests__/ListView.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import ListView from '../';
4 |
5 | class ListViewTest extends Component {
6 | componentDidMount() {
7 | this.refs.scrollview.scrollTo();
8 | }
9 | render() {
10 | return {
11 | return {num};
12 | }} dataSource={[1, 2, 3]} />;
13 | }
14 | }
15 |
16 | describe('ListView', () => {
17 | let component;
18 |
19 | beforeEach(() => {
20 | component = renderer.create(
21 |
22 | );
23 | });
24 |
25 | it('should render a ListView', () => {
26 | let tree = component.toJSON();
27 | expect(tree.tagName).toEqual('DIV');
28 | expect(tree.children[0].children.length).toEqual(3);
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/packages/rax-animated/src/mapStyle.js:
--------------------------------------------------------------------------------
1 | // { scale: 2 } => 'scale(2)'
2 | function mapTransform(t) {
3 | var k = Object.keys(t)[0];
4 | var unit = '';
5 | // Only process translateX translateY translateZ
6 | if (k.indexOf('translate') === 0) {
7 | unit = 'rem';
8 | }
9 | return `${k}(${t[k]}${unit})`;
10 | }
11 |
12 | // NOTE(lmr):
13 | // Since this is a hot code path, right now this is mutative...
14 | // As far as I can tell, this shouldn't cause any unexpected behavior.
15 | function mapStyle(style) {
16 | if (style && style.transform && typeof style.transform !== 'string') {
17 | // Use vendor prefixed styles
18 | let convertedValue = style.transform.map(mapTransform).join(' ');
19 | style.webkitTransform = convertedValue;
20 | style.transform = convertedValue;
21 | }
22 |
23 | return style;
24 | }
25 |
26 | export default mapStyle;
27 |
--------------------------------------------------------------------------------
/packages/rax-button/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-button",
3 | "version": "0.2.2",
4 | "description": "Button component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "rax-touchable": "^0.2.2",
25 | "rax-text": "^0.2.2",
26 | "universal-env": "^0.2.2"
27 | },
28 | "peerDependencies": {
29 | "rax": "0.x"
30 | },
31 | "devDependencies": {
32 | "rax-test-renderer": "^0.2.2"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/scheduler.js:
--------------------------------------------------------------------------------
1 | const synchronousScheduler = job => job();
2 |
3 | const requestAnimationFramePolyfill = job => setTimeout(job, 16);
4 | const animationScheduler = typeof requestAnimationFrame === 'undefined' ?
5 | typeof webkitRequestAnimationFrame === 'undefined' ?
6 | requestAnimationFramePolyfill :
7 | webkitRequestAnimationFrame : requestAnimationFrame;
8 |
9 | const requestIdleCallbackPolyfill = job => setTimeout(job, 1024); // 1s
10 | const backgroundScheduler = typeof requestIdleCallback === 'undefined' ?
11 | requestIdleCallbackPolyfill : requestIdleCallback;
12 |
13 | let currentScheduler = synchronousScheduler;
14 |
15 | export default {
16 | getScheduler: () => currentScheduler,
17 | setScheduler: scheduler => currentScheduler = scheduler,
18 | synchronousScheduler,
19 | animationScheduler,
20 | backgroundScheduler,
21 | };
22 |
--------------------------------------------------------------------------------
/packages/rax/src/style/__tests__/styleToCSS.js:
--------------------------------------------------------------------------------
1 | import styleToCSS from '../styleToCSS';
2 | import {setRem} from '../unit';
3 |
4 | describe('StyleToCSS', () => {
5 | it('convert unitless style to css', () => {
6 | let css = styleToCSS({
7 | background: 'black'
8 | });
9 |
10 | expect(css).toBe('background:black;');
11 | });
12 |
13 | it('convert rem unit style to css', () => {
14 | setRem(1);
15 |
16 | let css = styleToCSS({
17 | width: '750rem'
18 | });
19 |
20 | expect(css).toBe('width:750px;');
21 |
22 | let css2 = styleToCSS({
23 | width: '750rem'
24 | }, true);
25 | expect(css2).toBe('width:750rem;');
26 | });
27 |
28 | it('convert vendor prefix style to css', () => {
29 | let css = styleToCSS({
30 | WebkitBorder: 1
31 | });
32 | expect(css).toBe('-webkit-border:1px;');
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/generator/templates/README.md:
--------------------------------------------------------------------------------
1 | # rax-starter-kit
2 |
3 | ## Getting Started
4 |
5 | ### `npm run start`
6 |
7 | Runs the app in development mode.
8 |
9 | Open [http://localhost:8080](http://localhost:8080) to view it in the browser.
10 |
11 | The page will reload if you make edits.
12 |
13 | ### `npm run lint`
14 |
15 | You will see the lint errors in the console.
16 |
17 | ### `npm run build`
18 |
19 | Builds the app for production to the `build` folder.
20 |
21 | ## Universal "Gotchas"
22 |
23 | - DOM & DOM like **`window`** & **`document`** do not exist on the server - so using them, or any library that uses them (jQuery for example) will not work.
24 | - If you need to use them, consider limiting them to wrapping them situationally with the imported *isWeb / isNode / isWeex* features from Universal. `import {isWeb, isWeex, isNode} from 'universal-env'`;
25 |
--------------------------------------------------------------------------------
/packages/rax-listview/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-listview",
3 | "version": "0.2.2",
4 | "description": "ListView component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "rax-view": "^0.2.2",
25 | "rax-recyclerview": "^0.2.2",
26 | "universal-env": "^0.2.2"
27 | },
28 | "peerDependencies": {
29 | "rax": "0.x"
30 | },
31 | "devDependencies": {
32 | "rax-test-renderer": "^0.2.2"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/generator/templates/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax App
10 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/packages/rax-link/src/__tests__/Link.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Link from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | // Could not mock universal-env in rax-text current,
12 | // because universal-env is not peer ependencies
13 | jest.mock('rax-text', () => {
14 | return function(props) {
15 | return ;
16 | };
17 | });
18 |
19 | describe('Link in weex', () => {
20 | it('should render a link', () => {
21 | const component = renderer.create(
22 | Example
23 | );
24 | let tree = component.toJSON();
25 | expect(tree.tagName).toEqual('A');
26 | expect(tree.children[0].tagName).toEqual('TEXT');
27 | expect(tree.children[0].attributes.value).toEqual('Example');
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/examples/drag/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/perf/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/packages/rax/src/setNativeProps.js:
--------------------------------------------------------------------------------
1 | import Host from './vdom/host';
2 | import findDOMNode from './findDOMNode';
3 |
4 | const STYLE = 'style';
5 | const CHILDREN = 'children';
6 |
7 | export default function setNativeProps(node, props, disableSetStyles) {
8 | node = findDOMNode(node);
9 |
10 | for (let prop in props) {
11 | let value = props[prop];
12 | if (prop === CHILDREN) {
13 | continue;
14 | }
15 |
16 | if (value != null) {
17 | if (prop === STYLE) {
18 | if (disableSetStyles) {
19 | continue;
20 | }
21 | Host.driver.setStyles(node, value);
22 | } else if (prop.substring(0, 2) === 'on') {
23 | let eventName = prop.slice(2).toLowerCase();
24 | Host.driver.addEventListener(node, eventName, value);
25 | } else {
26 | Host.driver.setAttribute(node, prop, value);
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/hello/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/profile/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/redux/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/uikit/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/packages/rax-server-renderer/README.md:
--------------------------------------------------------------------------------
1 | # rax-server-renderer [](https://www.npmjs.com/package/rax-server-renderer) [](https://david-dm.org/alibaba/rax.svg?path=packages/rax-server-renderer) [](https://snyk.io/test/npm/rax-server-renderer)
2 |
3 | > Rax renderer for server-side render.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ npm install --save rax-server-renderer
9 | ```
10 |
11 | ## Usage
12 |
13 | ```jsx
14 | import {createElement, Component} from 'rax';
15 | import renderer from 'rax-server-renderer';
16 |
17 | class MyComponent extends Component {
18 | render() {
19 | return Hello World
;
20 | }
21 | }
22 |
23 | renderer.renderToString();
24 | ```
25 |
--------------------------------------------------------------------------------
/scripts/link.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const spawnSync = require('child_process').spawnSync;
6 | const PACKAGES_DIR = path.resolve(__dirname, '../packages');
7 |
8 | function getPackages() {
9 | return fs.readdirSync(PACKAGES_DIR)
10 | .map(file => path.resolve(PACKAGES_DIR, file))
11 | .filter(f => fs.lstatSync(path.resolve(f)).isDirectory());
12 | }
13 |
14 | getPackages().forEach((p) => {
15 | // Skip link starter kit
16 | if (p.indexOf('babel-preset-rax') > 0 || p.indexOf('babel-plugin-transform-jsx-stylesheet') > 0) return;
17 | const linkArgv = ['link', p];
18 | // Skip install devDependencies
19 | if (p.endsWith('rax-test-renderer')) linkArgv.push('--production');
20 | if (p.endsWith('rax-components')) linkArgv.push('--production');
21 | console.log('npm', linkArgv.join(' '));
22 | spawnSync('npm', linkArgv);
23 | });
24 |
--------------------------------------------------------------------------------
/examples/game2048/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/parallax/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/tictactoe/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/packages/rax-redux/src/utils/hoistNonRaxStatics.js:
--------------------------------------------------------------------------------
1 | const RAX_STATICS = {
2 | childContextTypes: true,
3 | contextTypes: true,
4 | defaultProps: true,
5 | displayName: true,
6 | propTypes: true,
7 | type: true
8 | };
9 |
10 | const KNOWN_STATICS = {
11 | name: true,
12 | length: true,
13 | prototype: true,
14 | caller: true,
15 | arguments: true,
16 | arity: true
17 | };
18 |
19 | export default function hoistNonReactStatics(targetComponent, sourceComponent) {
20 | if (typeof sourceComponent !== 'string') {
21 | var keys = Object.getOwnPropertyNames(sourceComponent);
22 | for (var i = 0; i < keys.length; ++i) {
23 | if (!RAX_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]]) {
24 | try {
25 | targetComponent[keys[i]] = sourceComponent[keys[i]];
26 | } catch (error) {
27 |
28 | }
29 | }
30 | }
31 | }
32 |
33 | return targetComponent;
34 | }
--------------------------------------------------------------------------------
/examples/components/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Rax Example
10 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/packages/rax-recyclerview/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-recyclerview",
3 | "version": "0.2.2",
4 | "description": "RecyclerView component for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "keywords": [
12 | "Rax",
13 | "rax-component",
14 | "react-component"
15 | ],
16 | "bugs": {
17 | "url": "https://github.com/alibaba/rax/issues"
18 | },
19 | "homepage": "https://github.com/alibaba/rax#readme",
20 | "engines": {
21 | "npm": ">=3.0.0"
22 | },
23 | "dependencies": {
24 | "rax-scrollview": "^0.2.2",
25 | "rax-refreshcontrol": "^0.2.2",
26 | "rax-view": "^0.2.2",
27 | "universal-env": "^0.2.2"
28 | },
29 | "peerDependencies": {
30 | "rax": "0.x"
31 | },
32 | "devDependencies": {
33 | "rax-test-renderer": "^0.2.2"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/universal-jsonp/README.md:
--------------------------------------------------------------------------------
1 | # universal-jsonp [](https://www.npmjs.com/package/universal-jsonp)
2 |
3 | > jsonp like standard Fetch API
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm install universal-jsonp --save
9 | ```
10 |
11 | ## Usage
12 |
13 | ```js
14 | import jsonp from 'universal-jsonp';
15 |
16 | jsonp('/users.jsonp')
17 | .then(function(response) {
18 | return response.json()
19 | }).then(function(json) {
20 | console.log('parsed json', json)
21 | }).catch(function(err) {
22 | console.log('parsing failed', err)
23 | });
24 | ```
25 |
26 | ## APIS
27 |
28 | ### `jsonp(url, options)`
29 |
30 | - url: Required, String, jsonp url
31 | - options: Optional, Object, options attributes:
32 | - timeout: Number, default 5000ms
33 | - jsonpCallback: String, default `callback`
34 | - jsonpCallbackFunctionName: String, default randomly generated
35 |
36 |
--------------------------------------------------------------------------------
/packages/babel-preset-rax/README.md:
--------------------------------------------------------------------------------
1 | # babel-preset-rax [](https://www.npmjs.com/package/babel-preset-rax) [](https://david-dm.org/alibaba/rax.svg?path=packages/babel-preset-rax) [](https://snyk.io/test/npm/babel-preset-rax)
2 |
3 | > Babel preset for all Rax plugins.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ npm install --save-dev babel-preset-rax
9 | ```
10 |
11 | ## Usage
12 |
13 | ### Via `.babelrc` (Recommended)
14 |
15 | **.babelrc**
16 |
17 | ```json
18 | {
19 | "presets": ["rax"]
20 | }
21 | ```
22 |
23 | ### Via CLI
24 |
25 | ```sh
26 | $ babel script.js --presets rax
27 | ```
28 |
29 | ### Via Node API
30 |
31 | ```javascript
32 | require('babel-core').transform('code', {
33 | presets: ['rax']
34 | });
35 | ```
36 |
--------------------------------------------------------------------------------
/packages/rax-webpack-plugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-webpack-plugin",
3 | "version": "0.2.2",
4 | "description": "Webpack plugin for Rax framework.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "devDependencies": {
19 | "webpack": "^2.2.1"
20 | },
21 | "dependencies": {
22 | "babel-code-frame": "^6.22.0",
23 | "babel-generator": "^6.19.0",
24 | "babel-traverse": "^6.19.0",
25 | "babel-types": "^6.19.0",
26 | "babylon": "^6.14.1",
27 | "loader-utils": "^0.2.16",
28 | "lodash.clonedeep": "^4.5.0",
29 | "source-map": "^0.5.6",
30 | "webpack-sources": "^0.1.4"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/docs/publishing.md:
--------------------------------------------------------------------------------
1 | # Publishing Your Project
2 |
3 | ## Building a production release
4 |
5 | Once you've built a application, chances are you'll want to share it on the web. Rax ships with a script to package everything up into a few files that you can place on your web server. From the root directory of your project, run the following:
6 | ```sh
7 | $ npm run build
8 | ```
9 | This creates a new directory in root directory called `build`. Inside are the compiled versions of your application files. These can be placed on a web server and should work without any changes as long as they are placed in the same directory.
10 | ```sh
11 | build
12 | |-- index.html
13 | `-- js
14 | |-- index.bundle.min.js
15 | `-- index.bundle.min.js.map
16 | ```
17 | If you want to host your JavaScript files from a separate location, you can do so by modifying the contents of `index.html`. Make sure the script tag at the top points to the correct location for `index.bundle.min.js`.
18 |
--------------------------------------------------------------------------------
/packages/element-loader/src/node-loader.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import parser from './parserHTML';
3 | import loaderUtils from 'loader-utils';
4 |
5 | module.exports = function(content) {
6 | this.cacheable();
7 | const query = loaderUtils.parseQuery(this.query);
8 | const type = query.type;
9 | const filename = path.basename(this.resourcePath);
10 | const parts = parser(content);
11 | let part = parts[type];
12 | let output = '';
13 | let source;
14 |
15 | if (Array.isArray(part)) {
16 | part = part[query.index];
17 | }
18 |
19 | if (type !== 'script') {
20 | output = part.content;
21 | source = parts;
22 | } else {
23 | output = `${query.banner}\n${part.content || defaultComponent}`;
24 | }
25 |
26 | this.callback(null, output, source);
27 | };
28 |
29 | const defaultComponent = `
30 | export default class extends Component {
31 | constructor(props) {
32 | super(props);
33 | }
34 | }
35 | `;
36 |
--------------------------------------------------------------------------------
/packages/rax-button/src/__tests__/Button.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Button from '../';
4 |
5 | class ButtonTest extends Component {
6 | state = {
7 | buttonText: 'normal'
8 | };
9 | render() {
10 | return ;
15 | }
16 | }
17 | describe('Button', () => {
18 | it('should render a button', () => {
19 | const component = renderer.create(
20 |
21 | );
22 | let tree = component.toJSON();
23 |
24 | expect(tree.tagName).toEqual('DIV');
25 | expect(tree.children[0].children[0]).toEqual('normal');
26 | expect(tree).toMatchSnapshot();
27 |
28 | tree.eventListeners.click();
29 |
30 | tree = component.toJSON();
31 | expect(tree.children[0].children[0]).toEqual('click');
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/docs/zh-Hans/use-class-name-in-jsx.md:
--------------------------------------------------------------------------------
1 | # 在 JSX 中使用 className
2 |
3 | 使用 CSS 已经非常方便,但我们觉得可以往标准更进一步,我们实现了在 JSX 中可以直接使用 className,更进一步提升书写样式的开发体验。
4 |
5 | ## 引入 className
6 |
7 | CSS 的写法和上篇一中介绍的一样并没有变化,主要变化出现在 JS 中:
8 |
9 | ```js
10 | import './foo.css';
11 |
12 | function Foo() {
13 | return
14 | hello world
15 |
;
16 | }
17 |
18 | export default Foo;
19 | ```
20 |
21 | 和之前主要有两个不同点:
22 |
23 | 1. 不用再引入 styles 变量了
24 | 2. JSX 中 style 属性变成 className,值改成字符串的形式
25 |
26 | ## 配置
27 |
28 | 使用上述特性必须安装 `babel-plugin-transform-jsx-stylesheet` 插件
29 |
30 | ```sh
31 | npm install --save-dev babel-plugin-transform-jsx-stylesheet
32 | ```
33 |
34 | 并且在所在项目的 `.babelrc` 加入以下配置:
35 |
36 | ```json
37 | {
38 | "plugins": ["transform-jsx-stylesheet"]
39 | }
40 | ```
41 |
42 | 更多细节查看[babel-plugin-transform-jsx-stylesheet](https://github.com/alibaba/rax/blob/master/packages/babel-plugin-transform-jsx-stylesheet/README.md)
43 |
--------------------------------------------------------------------------------
/packages/universal-jsonp/src/__tests__/index.web.js:
--------------------------------------------------------------------------------
1 | import jsonp from '../index';
2 |
3 | const mockReturnedObject = {
4 | a: 1
5 | };
6 |
7 | const URL = 'http://XXX/jsonp/';
8 |
9 | describe('jsonp in web', () => {
10 | it('should fetch jsonp data', (done) => {
11 | jsonp(URL, {
12 | jsonpCallbackFunctionName: 'jsonpCb'
13 | }).then(function(response) {
14 | return response.json();
15 | }).then(function(json) {
16 | expect(json).toEqual(mockReturnedObject);
17 | done();
18 | });
19 |
20 | window.jsonpCb(mockReturnedObject);
21 | });
22 |
23 | it('should fail when time out', (done) => {
24 | jsonp(URL, {
25 | timeout: 0
26 | }).then(function(response) {
27 | return response.json();
28 | }).then((json) => {
29 | expect(json).not.toBeNull();
30 | done();
31 | }).catch(function(ex) {
32 | expect(ex.message).toEqual(`JSONP request to ${URL}? timed out`);
33 | done();
34 | });
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/packages/rax/src/__tests__/proptypes.js:
--------------------------------------------------------------------------------
1 | /* @jsx createElement */
2 |
3 | import PropTypes from '../proptypes';
4 |
5 | describe('PropTypes', () => {
6 | it('Primitive types should be defined', () => {
7 | expect(PropTypes.array).toBeDefined();
8 | expect(PropTypes.bool).toBeDefined();
9 | expect(PropTypes.func).toBeDefined();
10 | expect(PropTypes.number).toBeDefined();
11 | expect(PropTypes.object).toBeDefined();
12 | expect(PropTypes.string).toBeDefined();
13 | expect(PropTypes.symbol).toBeDefined();
14 | });
15 |
16 | it('Custom types should be defined', () => {
17 | expect(PropTypes.node).toBeDefined();
18 | expect(PropTypes.element).toBeDefined();
19 | expect(PropTypes.instanceOf).toBeDefined();
20 | expect(PropTypes.oneOf).toBeDefined();
21 | expect(PropTypes.oneOfType).toBeDefined();
22 | expect(PropTypes.arrayOf).toBeDefined();
23 | expect(PropTypes.objectOf).toBeDefined();
24 | expect(PropTypes.shape).toBeDefined();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/packages/rax-components/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rax-components",
3 | "version": "0.2.2",
4 | "description": "Base components for Rax.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "dependencies": {
19 | "rax-touchable": "^0.2.2",
20 | "rax-text": "^0.2.2",
21 | "rax-textinput": "^0.2.2",
22 | "rax-image": "^0.2.2",
23 | "rax-link": "^0.2.2",
24 | "rax-button": "^0.2.2",
25 | "rax-view": "^0.2.2",
26 | "rax-scrollview": "^0.2.2",
27 | "rax-recyclerview": "^0.2.2",
28 | "rax-listview": "^0.2.2",
29 | "rax-refreshcontrol": "^0.2.2",
30 | "rax-switch": "^0.2.2",
31 | "rax-slider": "^0.2.2",
32 | "rax-video": "^0.2.2"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/instantiateComponent.js:
--------------------------------------------------------------------------------
1 | import Host from './host';
2 |
3 | function instantiateComponent(element) {
4 | let instance;
5 |
6 | if (element === undefined || element === null || element === false || element === true) {
7 | instance = new Host.EmptyComponent();
8 | } else if (Array.isArray(element)) {
9 | instance = new Host.FragmentComponent(element);
10 | } else if (typeof element === 'object' && element.type) {
11 | // Special case string values
12 | if (typeof element.type === 'string') {
13 | instance = new Host.NativeComponent(element);
14 | } else {
15 | instance = new Host.CompositeComponent(element);
16 | }
17 | } else if (typeof element === 'string' || typeof element === 'number') {
18 | instance = new Host.TextComponent(element);
19 | } else {
20 | throw Error(`Invalid element type ${JSON.stringify(element)}`);
21 | }
22 |
23 | instance._mountIndex = 0;
24 |
25 | return instance;
26 | }
27 |
28 | export default instantiateComponent;
29 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/src/performance.weex.js:
--------------------------------------------------------------------------------
1 | module.exports = function(responseEnd) {
2 | let performance = {};
3 | // TODO: current can not get navigationStart time
4 | performance.timing = {
5 | unloadEventStart: 0,
6 | unloadEventEnd: 0,
7 | navigationStart: responseEnd,
8 | redirectStart: 0,
9 | redirectEnd: 0,
10 | fetchStart: responseEnd,
11 | domainLookupStart: responseEnd,
12 | domainLookupEnd: responseEnd,
13 | connectStart: responseEnd,
14 | secureConnectionStart: responseEnd,
15 | connectStart: responseEnd,
16 | requestStart: responseEnd,
17 | responseStart: responseEnd,
18 | responseEnd,
19 | domLoading: 0,
20 | domInteractive: 0,
21 | domComplete: 0,
22 | domContentLoadedEventStart: 0,
23 | domContentLoadedEventEnd: 0,
24 | loadEventStart: 0,
25 | loadEventEnd: 0
26 | };
27 | performance.now = function() {
28 | return Date.now() - performance.timing.navigationStart;
29 | };
30 |
31 | return performance;
32 | };
33 |
--------------------------------------------------------------------------------
/packages/element-loader/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "element-loader",
3 | "version": "0.2.2",
4 | "description": "web component loader.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "dependencies": {
19 | "babel-core": "^6.20.0",
20 | "babel-generator": "^6.20.0",
21 | "babel-loader": "^6.2.10",
22 | "babel-plugin-transform-with": "^1.0.0",
23 | "babel-traverse": "^6.20.0",
24 | "babylon": "^6.14.1",
25 | "consolidate": "^0.14.5",
26 | "domhandler": "^2.3.0",
27 | "htmlparser2": "^3.9.2",
28 | "jsdom": "^9.8.3",
29 | "loader-utils": "^0.2.16",
30 | "lodash": "^4.17.2",
31 | "stylesheet-loader": "^0.2.2",
32 | "uppercamelcase": "^1.1.0"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/rax/src/server/__tests__/escapeText.js:
--------------------------------------------------------------------------------
1 | import escapeText from '../escapeText';
2 |
3 | describe('escapeText', () => {
4 | it('should escape boolean to string', function() {
5 | expect(escapeText(true)).toBe('true');
6 | expect(escapeText(false)).toBe('false');
7 | });
8 |
9 | it('should escape object to string', function() {
10 | let escaped = escapeText({
11 | toString: function() {
12 | return 'ponys';
13 | },
14 | });
15 |
16 | expect(escaped).toBe('ponys');
17 | });
18 |
19 | it('should escape number to string', function() {
20 | expect(escapeText(42)).toBe('42');
21 | });
22 |
23 | it('should escape string', function() {
24 | let escaped = escapeText('');
25 | expect(escaped).not.toContain('<');
26 | expect(escaped).not.toContain('>');
27 | expect(escaped).not.toContain('\'');
28 | expect(escaped).not.toContain('\"');
29 |
30 | escaped = escapeText('&');
31 | expect(escaped).toBe('&');
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/examples/uikit/UIKit.js:
--------------------------------------------------------------------------------
1 | // Based on React Native Elements UI Toolkit https://github.com/react-native-community/react-native-elements
2 | import Button from './Button';
3 | import Card from './Card';
4 | import {ScrollView, View, Text} from 'rax-components';
5 | import {createElement} from 'rax';
6 |
7 | function UIKit() {
8 | return (
9 |
10 |
11 |
14 |
15 | The idea with React Native Elements is more about component structure than actual design.
16 |
17 |
24 |
25 |
26 |
27 | );
28 | }
29 |
30 | export default UIKit;
31 |
--------------------------------------------------------------------------------
/packages/universal-transition/README.md:
--------------------------------------------------------------------------------
1 | # universal-transition [](https://www.npmjs.com/package/universal-transition)
2 |
3 | > Achieve transition animation
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm install universal-transition --save
9 | ```
10 |
11 | ## Usage
12 |
13 | ```js
14 | import transition from 'universal-transition';
15 |
16 | transition(document.querySelector('#box'), {
17 | transform: 'translate(10px, 20px) scale(1.5, 1.5) rotate(90deg)',
18 | opacity: '0.5'
19 | }, {
20 | timingFunction: 'ease',
21 | delay: 0,
22 | duration: 1000
23 | }, function() {
24 | console.log('animation end');
25 | });
26 | ```
27 |
28 | ## APIS
29 |
30 | ### `transition(domNode, styles, options, callback)`
31 |
32 | - domNode: Required, DOMNode
33 | - styles: Required, Object, transition styles
34 | - options: Optional, Object, options attributes:
35 | - timingFunction: default ease,
36 | - delay: default 0,
37 | - duration: default 0,
38 | - callback: Optional, Function, after animation end
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Evan You
2 | Fraser Xu
3 | George Chung
4 | Harry Yu
5 | Mingye Wang
6 | Raincal
7 | Skylar艺璇
8 | Tim Oxley
9 | William Wang(Wei)
10 | azu
11 | boiawang
12 | frankLife
13 | guoyong
14 | liuxiong.lx
15 | mengxue.zmx
16 | noyobo
17 | shangpo.zw
18 | wssgcg1213
19 | wuji.xwt
20 | zhaocai
21 | 亚城
22 | 元彦
23 | 大果
24 | 宝码
25 | 岭伊
26 | 当轩
27 | 慎里
28 | 梧忌
29 | 水澜
30 |
--------------------------------------------------------------------------------
/packages/babel-preset-rax/src/index.js:
--------------------------------------------------------------------------------
1 | import resolvePlugins from './resolvePlugins';
2 |
3 | module.exports = {
4 | plugins: resolvePlugins([
5 | 'transform-react-display-name',
6 | ['transform-react-jsx', {
7 | pragma: 'createElement' // default pragma is React.createElement
8 | }],
9 | 'transform-jsx-stylesheet',
10 | 'transform-flow-strip-types',
11 | 'transform-export-extensions', // stage-1
12 | 'transform-decorators-legacy', // should before transform-class-properties
13 | 'transform-class-properties',
14 | 'transform-object-rest-spread', // stage-3
15 | 'syntax-trailing-function-commas', // stage-3
16 | 'syntax-flow',
17 | 'syntax-jsx',
18 | 'add-module-exports'
19 | ]),
20 | env: {
21 | development: {
22 | plugins: resolvePlugins([
23 | 'transform-react-jsx-source',
24 | ])
25 | },
26 | production: {
27 | plugins: resolvePlugins([
28 | 'transform-react-constant-elements',
29 | 'minify-dead-code-elimination'
30 | ])
31 | },
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/packages/rax/src/testing/renderer.js:
--------------------------------------------------------------------------------
1 | import inject from '../inject';
2 | import instance from '../vdom/instance';
3 | import ServerDriver from '../drivers/server';
4 | import Serializer from '../server/serializer';
5 | import unmountComponentAtNode from '../unmountComponentAtNode';
6 |
7 | // Init
8 | inject({
9 | driver: ServerDriver
10 | });
11 |
12 | export default {
13 | create(element) {
14 | let container = ServerDriver.createBody();
15 | let rootComponent = instance.render(element, container);
16 | let renderedComponent = rootComponent.getRenderedComponent();
17 |
18 | renderedComponent.toJSON = () => {
19 | return new Serializer(container).toJSON();
20 | };
21 |
22 | renderedComponent.getInstance = () => {
23 | return renderedComponent._instance;
24 | };
25 |
26 | renderedComponent.update = (element) => {
27 | instance.render(element, container);
28 | };
29 |
30 | renderedComponent.unmount = () => {
31 | unmountComponentAtNode(container);
32 | };
33 |
34 | return renderedComponent;
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/packages/rax-switch/src/__tests__/Switch.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Switch from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | class SwitchTest extends Component {
12 | state = {
13 | value: true
14 | };
15 | render() {
16 | return {
17 | this.setState({
18 | value: false
19 | });
20 | }} />;
21 | }
22 | }
23 |
24 | describe('Switch in weex', () => {
25 | it('should render a switch', () => {
26 | const component = renderer.create(
27 |
28 | );
29 | let tree = component.toJSON();
30 | expect(tree.tagName).toEqual('SWITCH');
31 | });
32 |
33 | it('should change a value', () => {
34 | const component = renderer.create(
35 |
36 | );
37 | let tree = component.toJSON();
38 |
39 | tree.eventListeners.change(false);
40 | tree = component.toJSON();
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/docs/jsx.md:
--------------------------------------------------------------------------------
1 | ## JSX
2 |
3 | One feature that makes React appealing is that it combines declarative UI elements with code that manipulates them in an elegant way. UI elements are described by component tags that look similar to HTML. For example, the tag **``** may describe a greeting UI component that also takes a name as a parameter. These tags are inserted directly into JavaScript with the help of JSX.
4 |
5 | [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) is a syntax extension to JavaScript; it is pre-processed in the build process to become JavaScript. JSX allows describing UI more elegantly then would be possible with direct code.
6 |
7 | ```html
8 |
9 | Click Me
10 |
11 | ```
12 | compiles into:
13 | ```js
14 | createElement(
15 | MyButton,
16 | {color: 'blue', shadowSize: 2},
17 | 'Click Me'
18 | )
19 | ```
20 | While using JSX is not mandatory, it is recommended for readability. The React website contains [further details on JSX](https://facebook.github.io/react/docs/jsx-in-depth.html).
21 |
--------------------------------------------------------------------------------
/packages/rax-text/src/__tests__/Text.js:
--------------------------------------------------------------------------------
1 | global.callNative = null;
2 | import {createElement} from 'rax';
3 | import renderer from 'rax-test-renderer';
4 | import Text from '../';
5 |
6 | describe('Text', () => {
7 | it('render tag Text', () => {
8 | const component = renderer.create(
9 | Example
10 | );
11 | let tree = component.toJSON();
12 | expect(tree.tagName).toEqual('SPAN');
13 | expect(tree.children[0]).toEqual('Example');
14 | });
15 |
16 | it('style in Text', () => {
17 | const component = renderer.create(
18 | Example
19 | );
20 | let tree = component.toJSON();
21 | expect(tree.style.border).toBe('0 solid black');
22 | expect(tree.style.position).toBe('relative');
23 | expect(tree.style.boxSizing).toBe('border-box');
24 | expect(tree.style.display).toBe('block');
25 | expect(tree.style.flexDirection).toBe('column');
26 | expect(tree.style.alignContent).toBe('flex-start');
27 | expect(tree.style.flexShrink).toBe(0);
28 | expect(tree.style.fontSize).toBe(32);
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/examples/components/VideoDemo.js:
--------------------------------------------------------------------------------
1 |
2 | import {createElement, Component} from 'rax';
3 | import {
4 | View,
5 | Text,
6 | Image,
7 | Link,
8 | TextInput,
9 | Button,
10 | Switch,
11 | Video,
12 | ScrollView,
13 | TouchableWithoutFeedback} from 'rax-components';
14 |
15 | class VideoDemo extends Component {
16 | render() {
17 | return (
18 |
19 |
27 |
28 | );
29 | }
30 | }
31 |
32 | let styles = {
33 | container: {
34 | padding: 20,
35 | borderStyle: 'solid',
36 | borderColor: '#dddddd',
37 | borderWidth: 1,
38 | marginLeft: 20,
39 | marginRight: 20,
40 | marginBottom: 10,
41 | },
42 | box: {
43 | backgroundColor: '#527FE4',
44 | borderColor: '#000033',
45 | borderWidth: 1,
46 | },
47 | };
48 |
49 | export default VideoDemo;
50 |
--------------------------------------------------------------------------------
/packages/rax-image/src/__tests__/Image.weex.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Image from '../';
4 |
5 | jest.mock('universal-env', () => {
6 | return {
7 | isWeex: true
8 | };
9 | });
10 |
11 | describe('Link in weex', () => {
12 | it('should render a image', () => {
13 | const component = renderer.create(
14 |
18 | );
19 | let tree = component.toJSON();
20 | expect(tree.tagName).toEqual('IMAGE');
21 | expect(tree.attributes.src).toEqual('a.png');
22 | });
23 |
24 | it('should render a image with resizeMode', () => {
25 | const component = renderer.create(
26 |
30 | );
31 |
32 | let tree = component.toJSON();
33 | expect(tree.style.resizeMode).toEqual('cover');
34 | expect(tree.attributes.resize).toEqual('cover');
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/packages/rax-button/src/__tests__/__snapshots__/Button.js.snap:
--------------------------------------------------------------------------------
1 | exports[`Button should render a button 1`] = `
2 | Object {
3 | "children": Array [
4 | Object {
5 | "children": Array [
6 | "normal",
7 | ],
8 | "style": Object {
9 | "alignContent": "flex-start",
10 | "border": "0 solid black",
11 | "boxSizing": "border-box",
12 | "color": "#0C42FD",
13 | "display": "block",
14 | "flexDirection": "column",
15 | "flexShrink": 0,
16 | "fontSize": 36,
17 | "padding": 16,
18 | "position": "relative",
19 | "textAlign": "center",
20 | },
21 | "tagName": "SPAN",
22 | },
23 | ],
24 | "eventListeners": Object {
25 | "click": [Function],
26 | },
27 | "style": Object {
28 | "alignContent": "flex-start",
29 | "border": "0 solid black",
30 | "boxSizing": "border-box",
31 | "cursor": "pointer",
32 | "display": "flex",
33 | "flexDirection": "column",
34 | "flexShrink": 0,
35 | "position": "relative",
36 | },
37 | "tagName": "DIV",
38 | }
39 | `;
40 |
--------------------------------------------------------------------------------
/packages/rax/src/__tests__/setNativeProps.js:
--------------------------------------------------------------------------------
1 | /* @jsx createElement */
2 |
3 | import Host from '../vdom/host';
4 | import setNativeProps from '../setNativeProps';
5 |
6 | describe('setNativeProps', () => {
7 | beforeEach(() => {
8 | Host.driver = null;
9 | });
10 |
11 | afterEach(() => {
12 | Host.driver = null;
13 | });
14 |
15 | it('set native props', () => {
16 | let setStyles = jest.fn();
17 | let addEventListener = jest.fn();
18 | let setAttribute = jest.fn();
19 |
20 | Host.driver = {
21 | setStyles,
22 | addEventListener,
23 | setAttribute,
24 | };
25 |
26 | let node = {
27 | nodeType: 1
28 | };
29 |
30 | let style = {
31 | foo: 1
32 | };
33 |
34 | let onPress = () => {};
35 | let id = 'test';
36 |
37 | setNativeProps(node, {
38 | style,
39 | onPress,
40 | id
41 | });
42 |
43 | expect(setStyles).toBeCalledWith(node, style);
44 | expect(addEventListener).toBeCalledWith(node, 'press', onPress);
45 | expect(setAttribute).toBeCalledWith(node, 'id', id);
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/syntax/hello-world.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component, render} from 'rax';
2 |
3 | class Example extends Component {
4 | state = {
5 | title: 'Hello World',
6 | image: '//gw.alicdn.com/tps/i2/TB1DpsmMpXXXXabaXXX20ySQVXX-512-512.png_400x400.jpg'
7 | };
8 |
9 | handleClick = () => {
10 | this.setState({
11 | title: 'Hello Weex',
12 | image: '//gw.alicdn.com/tps/i2/TB1DpsmMpXXXXabaXXX20ySQVXX-512-512.png_400x400.jpg'
13 | });
14 | };
15 |
16 | render() {
17 | return (
18 |
19 |
20 | {this.state.title}
21 |
22 | );
23 | }
24 | }
25 |
26 | const styles = {
27 | container: {
28 | flex: 1,
29 | justifyContent: 'center',
30 | alignItems: 'center',
31 | backgroundColor: 'white'
32 | },
33 | logo: {
34 | width: 200,
35 | height: 200,
36 | marginBottom: 40
37 | },
38 | title: {
39 | fontSize: 48
40 | }
41 | };
42 |
43 | render();
44 |
--------------------------------------------------------------------------------
/packages/stylesheet-loader/src/__tests__/PropTypes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import PropTypes from '../PropTypes';
4 |
5 | describe('PropTypes', () => {
6 | it('should check length type', () => {
7 | expect(PropTypes.length('16rem')).toBeNull();
8 | expect(PropTypes.length('red')).not.toBeNull();
9 | });
10 |
11 | it('should check number type', () => {
12 | expect(PropTypes.number('16.2')).toBeNull();
13 | expect(PropTypes.number('16.5px')).not.toBeNull();
14 | });
15 |
16 | it('should check integer type', () => {
17 | expect(PropTypes.integer('16')).toBeNull();
18 | expect(PropTypes.integer('16px')).not.toBeNull();
19 | });
20 |
21 | it('should check enum type', () => {
22 | const list = ['red', 'blue'];
23 |
24 | expect(PropTypes.oneOf(list)('red')).toBeNull();
25 | expect(PropTypes.oneOf(list)('gray')).not.toBeNull();
26 | });
27 |
28 | it('should check color type', () => {
29 | expect(PropTypes.color('red')).toBeNull();
30 | expect(PropTypes.color('#666')).toBeNull();
31 | expect(PropTypes.color('rgb(255, 0, 0)')).toBeNull();
32 | expect(PropTypes.color('16px')).not.toBeNull();
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/packages/rax/src/findDOMNode.js:
--------------------------------------------------------------------------------
1 | import Host from './vdom/host';
2 |
3 | function findDOMNode(instance) {
4 | if (instance == null) {
5 | return null;
6 | }
7 |
8 | // If a native node, weex may not export ownerDocument property
9 | if (instance.ownerDocument || instance.nodeType) {
10 | return instance;
11 | }
12 |
13 | // Native component
14 | if (instance._nativeNode) {
15 | return instance._nativeNode;
16 | }
17 |
18 | if (typeof instance == 'string') {
19 | return Host.driver.getElementById(instance);
20 | }
21 |
22 | if (typeof instance.render !== 'function') {
23 | throw new Error('Appears to be neither Component nor DOMNode.');
24 | }
25 |
26 | // Composite component
27 | let internal = instance._internal;
28 |
29 | if (internal) {
30 | while (!internal._nativeNode) {
31 | internal = internal._renderedComponent;
32 | // If not mounted
33 | if (internal == null) {
34 | return null;
35 | }
36 | }
37 | return internal._nativeNode;
38 | } else {
39 | throw new Error('findDOMNode was called on an unmounted component.');
40 | }
41 | }
42 |
43 | export default findDOMNode;
44 |
--------------------------------------------------------------------------------
/packages/element-loader/src/__tests__/parserHTML.js:
--------------------------------------------------------------------------------
1 | import parser from '../parserHTML';
2 |
3 | describe('parserHTML', () => {
4 | it('parser template content', () => {
5 | const html = 'hello world
';
6 | const template = parser(html).template;
7 |
8 | expect(template.content).toEqual('hello world
');
9 | });
10 |
11 | it('parser style content', () => {
12 | const html = '';
13 | const style = parser(html).styles;
14 |
15 | expect(style.content).toEqual('.title {color: red;}');
16 | });
17 |
18 | it('parser script content', () => {
19 | const html = '';
20 | const script = parser(html).script;
21 |
22 | expect(script.content).toEqual('const title = "hello world"');
23 | });
24 |
25 | it('parser link content', () => {
26 | const html = `
27 |
28 |
29 | `;
30 | const object = parser(html);
31 |
32 | expect(object.importLinks).toEqual(['index.html']);
33 | expect(object.styleSheetLinks).toEqual(['common.css']);
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/generator/templates/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "YourProjectName",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "start": "./node_modules/.bin/webpack-dev-server --host 0.0.0.0 --no-info",
6 | "build": "rm -rf build && NODE_ENV=production ./node_modules/.bin/webpack",
7 | "lint": "./node_modules/.bin/eslint --ext .js --ext .jsx ./src"
8 | },
9 | "dependencies": {
10 | "rax": "^0.2.2",
11 | "rax-view": "^0.2.2",
12 | "rax-text": "^0.2.2"
13 | },
14 | "devDependencies": {
15 | "babel-core": "^6.18.2",
16 | "babel-eslint": "^7.1.0",
17 | "babel-loader": "^6.2.7",
18 | "babel-preset-es2015": "^6.16.0",
19 | "babel-preset-rax": "^0.2.2",
20 | "case-sensitive-paths-webpack-plugin": "^1.1.4",
21 | "eslint": "^3.10.0",
22 | "eslint-plugin-react": "^6.6.0",
23 | "html-webpack-plugin": "^2.24.1",
24 | "internal-ip": "^1.2.0",
25 | "json-loader": "^0.5.4",
26 | "qrcode-terminal": "^0.11.0",
27 | "rax-webpack-plugin": "^0.2.2",
28 | "stylesheet-loader": "^0.2.2",
29 | "watch-missing-node-modules-webpack-plugin": "0.0.1",
30 | "webpack": "^1.13.3",
31 | "webpack-dev-server": "^1.16.2"
32 | }
33 | }
--------------------------------------------------------------------------------
/packages/universal-toast/src/__tests__/index.web.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import Toast from '../index';
3 |
4 | jest.useFakeTimers();
5 |
6 | describe('default duration', () => {
7 | Toast.show('Hello');
8 |
9 | it('show toast', () => {
10 | expect(setTimeout.mock.calls.length).toBe(1);
11 | expect(setTimeout.mock.calls[0][1]).toBe(Toast.SHORT);
12 | });
13 |
14 | it('hide toast window', () => {
15 | jest.runOnlyPendingTimers();
16 |
17 | expect(setTimeout.mock.calls.length).toBe(3);
18 | expect(setTimeout.mock.calls[1][1]).toBe(0);
19 | });
20 |
21 | it('show next toast in queue', () => {
22 | jest.runOnlyPendingTimers();
23 |
24 | expect(setTimeout.mock.calls.length).toBe(3);
25 | expect(setTimeout.mock.calls[2][1]).toBe(600);
26 | });
27 | });
28 |
29 | it('long duration', () => {
30 | Toast.show('Hello', Toast.LONG);
31 |
32 | expect(setTimeout.mock.calls.length).toBe(4);
33 | expect(setTimeout.mock.calls[3][1]).toBe(Toast.LONG);
34 | });
35 |
36 | it('toast twice', () => {
37 | Toast.show('Hello', Toast.LONG);
38 | Toast.show('Hello', Toast.LONG);
39 |
40 | jest.runAllTimers();
41 |
42 | expect(setTimeout.mock.calls.length).toBe(12);
43 | });
44 |
--------------------------------------------------------------------------------
/packages/rax/src/proptypes.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Current PropTypes only export some api with react, not validate in runtime.
3 | */
4 |
5 | function createChainableTypeChecker(validate) {
6 | function checkType(isRequired, props, propName, componentName, location, propFullName) {
7 | return typeChecker;
8 | }
9 |
10 | let chainedCheckType = checkType.bind(null, false);
11 | chainedCheckType.isRequired = checkType.bind(null, true);
12 |
13 | return chainedCheckType;
14 | }
15 |
16 | function createTypeChecker(expectedType) {
17 | function validate(props, propName, componentName, location, propFullName) {
18 | // Noop
19 | }
20 | return createChainableTypeChecker(validate);
21 | }
22 |
23 | let typeChecker = createTypeChecker();
24 |
25 | export default {
26 | array: typeChecker,
27 | bool: typeChecker,
28 | func: typeChecker,
29 | number: typeChecker,
30 | object: typeChecker,
31 | string: typeChecker,
32 | symbol: typeChecker,
33 | element: typeChecker,
34 | node: typeChecker,
35 | any: typeChecker,
36 | arrayOf: typeChecker,
37 | instanceOf: typeChecker,
38 | objectOf: typeChecker,
39 | oneOf: typeChecker,
40 | oneOfType: typeChecker,
41 | shape: typeChecker,
42 | };
43 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/components/input.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component, render} from 'rax';
2 | import Panel from '../common/Panel';
3 |
4 | class Example extends Component {
5 | state = {
6 | txtInput: '',
7 | txtChange: '',
8 | };
9 | onchange = (event) => {
10 | this.state.txtInput = event.value;
11 | this.setState(this.state);
12 | }
13 | oninput = (event) => {
14 | this.state.txtChange = event.value;
15 | this.setState(this.state);
16 | }
17 | render() {
18 | return (
19 |
20 |
21 |
30 | oninput: {this.state.txtInput}
31 | onchange: {this.state.txtChange}
32 |
33 |
34 | );
35 | }
36 | }
37 |
38 | const styles = {
39 | input: {
40 | fontSize: 60,
41 | height: 80,
42 | width: 400,
43 | }
44 | };
45 |
46 | render();
47 |
--------------------------------------------------------------------------------
/packages/rax/src/testing/__tests__/__snapshots__/snapshot.js.snap:
--------------------------------------------------------------------------------
1 | exports[`test Link changes the class when hovered 1`] = `
2 | Object {
3 | "attributes": Object {
4 | "class": "normal",
5 | "href": "https://example.com",
6 | },
7 | "children": Array [
8 | "Example",
9 | ],
10 | "eventListeners": Object {
11 | "mouseenter": [Function],
12 | "mouseleave": [Function],
13 | },
14 | "tagName": "A",
15 | }
16 | `;
17 |
18 | exports[`test Link changes the class when hovered 2`] = `
19 | Object {
20 | "attributes": Object {
21 | "class": "hovered",
22 | "href": "https://example.com",
23 | },
24 | "children": Array [
25 | "Example",
26 | ],
27 | "eventListeners": Object {
28 | "mouseenter": [Function],
29 | "mouseleave": [Function],
30 | },
31 | "tagName": "A",
32 | }
33 | `;
34 |
35 | exports[`test Link changes the class when hovered 3`] = `
36 | Object {
37 | "attributes": Object {
38 | "class": "normal",
39 | "href": "https://example.com",
40 | },
41 | "children": Array [
42 | "Example",
43 | ],
44 | "eventListeners": Object {
45 | "mouseenter": [Function],
46 | "mouseleave": [Function],
47 | },
48 | "tagName": "A",
49 | }
50 | `;
51 |
--------------------------------------------------------------------------------
/docs/difference-with-react.md:
--------------------------------------------------------------------------------
1 | # Difference with React
2 |
3 | * No `createClass()` method,use ES6 class by `extends Component` class instead of calling createClass.
4 | ```js
5 | // Before
6 | import React from 'react';
7 |
8 | const Hi = React.createClass({
9 | render() {
10 | return (
11 | hi
12 | );
13 | }
14 | });
15 |
16 | export default Hi;
17 | ```
18 |
19 | ```js
20 | // After
21 | import {createElement, Component} from 'rax';
22 |
23 | class Hi extends Component {
24 | render() {
25 | return (
26 | hi
27 | );
28 | }
29 | }
30 |
31 | export default Hi;
32 | ```
33 |
34 | * Render to new container node not clear existed children.
35 | * The `setState()` actions are synchronous, and React `setState` actions are asynchronous.
36 | * The `findDOMNode()` method could accept id which is a string type.
37 | ```js
38 | import {createElement, render, findDOMNode} from 'rax';
39 |
40 | class Hi extends Component {
41 | render() {
42 | return (
43 | hi
44 | );
45 | }
46 | }
47 |
48 | render(, document.body);
49 | const node = findDOMNode('hi');
50 | ```
51 | * The `PropTypes` is only interface React-compatible not really working
52 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/empty.js:
--------------------------------------------------------------------------------
1 | import Host from './host';
2 |
3 | /**
4 | * Empty Component
5 | */
6 | class EmptyComponent {
7 | constructor() {
8 | this._currentElement = null;
9 | }
10 |
11 | mountComponent(parent, context, childMounter) {
12 | this._parent = parent;
13 | this._context = context;
14 |
15 | let instance = {
16 | _internal: this
17 | };
18 |
19 | let nativeNode = this.getNativeNode();
20 | if (childMounter) {
21 | childMounter(nativeNode, parent);
22 | } else {
23 | Host.driver.appendChild(nativeNode, parent);
24 | }
25 |
26 | return instance;
27 | }
28 |
29 | unmountComponent(notRemoveChild) {
30 | if (this._nativeNode && !notRemoveChild) {
31 | Host.driver.removeChild(this._nativeNode, this._parent);
32 | }
33 |
34 | this._nativeNode = null;
35 | this._parent = null;
36 | this._context = null;
37 | }
38 |
39 | updateComponent() {
40 | // Noop
41 | }
42 |
43 | getNativeNode() {
44 | // Weex native node
45 | if (this._nativeNode == null) {
46 | this._nativeNode = Host.driver.createEmpty();
47 | }
48 |
49 | return this._nativeNode;
50 | }
51 | }
52 |
53 | export default EmptyComponent;
54 |
--------------------------------------------------------------------------------
/packages/rax/src/__tests__/unmountComponentAtNode.js:
--------------------------------------------------------------------------------
1 | /* @jsx createElement */
2 |
3 | import {createElement} from '../element';
4 | import Host from '../vdom/host';
5 | import render from '../render';
6 | import unmountComponentAtNode from '../unmountComponentAtNode';
7 |
8 | describe('unmountComponentAtNode', () => {
9 | beforeEach(() => {
10 | Host.driver = null;
11 | });
12 |
13 | afterEach(() => {
14 | Host.driver = null;
15 | });
16 |
17 | it('unmout component', () => {
18 | let appendChildMock = jest.fn();
19 | let removeChildMock = jest.fn();
20 | let body = {tagName: 'BODY'};
21 |
22 | Host.driver = {
23 | createElement() {
24 | return {tagName: 'DIV'};
25 | },
26 | appendChild: appendChildMock,
27 | removeChild: removeChildMock,
28 | removeAllEventListeners() {}
29 | };
30 |
31 | render(, body);
32 | unmountComponentAtNode(body);
33 |
34 | let call = appendChildMock.mock.calls[0];
35 | expect(call[0].tagName).toBe('DIV');
36 | expect(call[1].tagName).toBe('BODY');
37 |
38 | let call2 = removeChildMock.mock.calls[0];
39 | expect(call2[0].tagName).toBe('DIV');
40 | expect(call2[1].tagName).toBe('BODY');
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/packages/rax/src/debug/hook.js:
--------------------------------------------------------------------------------
1 | import instance from '../vdom/instance';
2 | import Host from '../vdom/host';
3 |
4 | export default {
5 | ComponentTree: {
6 | getClosestInstanceFromNode(node) {
7 | return instance.get(node);
8 | },
9 | getNodeFromInstance(inst) {
10 | // inst is an internal instance (but could be a composite)
11 | while (inst._renderedComponent) {
12 | inst = inst._renderedComponent;
13 | }
14 |
15 | if (inst) {
16 | return inst._nativeNode;
17 | } else {
18 | return null;
19 | }
20 | }
21 | },
22 | Mount: {
23 | _instancesByReactRootID: Host.rootComponents,
24 |
25 | // Stub - React DevTools expects to find this method and replace it
26 | // with a wrapper in order to observe new root components being added
27 | _renderNewRootComponent() {}
28 | },
29 | Reconciler: {
30 | // Stubs - React DevTools expects to find these methods and replace them
31 | // with wrappers in order to observe components being mounted, updated and
32 | // unmounted
33 | mountComponent() {},
34 | receiveComponent() {},
35 | unmountComponent() {},
36 | },
37 | // monitor the info of all components
38 | monitor: null
39 | };
40 |
--------------------------------------------------------------------------------
/packages/universal-transition/src/__tests__/index.js:
--------------------------------------------------------------------------------
1 | import transition from '../index';
2 |
3 | jest.mock('universal-env', () => {
4 | return {
5 | isWeb: true
6 | };
7 | });
8 |
9 | describe('transition', () => {
10 | let transitionendEvent;
11 |
12 | beforeEach(() => {
13 | transitionendEvent = document.createEvent('HTMLEvents');
14 | transitionendEvent.initEvent('transitionend', false, true);
15 | });
16 | it('can trigger callback', (done) => {
17 | const mockFn = jest.fn(() => {
18 | done();
19 | });
20 | transition(document.body, {
21 | transform: 'translate(10px, 20px) scale(1.5, 1.5) rotate(90deg)'
22 | }, {
23 | timingFunction: 'ease',
24 | duration: 1000,
25 | delay: 1000
26 | }, mockFn);
27 | document.body.dispatchEvent(transitionendEvent);
28 |
29 | expect(mockFn).toBeCalled();
30 | });
31 |
32 | it('callback as the third parameter when option is function', () => {
33 | const mockFn = jest.fn();
34 | transition(document.body, {
35 | transform: 'translate(10px, 20px) scale(1.5, 1.5) rotate(90deg)'
36 | }, mockFn);
37 | document.body.dispatchEvent(transitionendEvent);
38 |
39 | expect(mockFn).toBeCalled();
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/packages/rax-button/src/index.js:
--------------------------------------------------------------------------------
1 | import {Component, createElement} from 'rax';
2 | import {isWeex} from 'universal-env';
3 | import Text from 'rax-text';
4 | import Touchable from 'rax-touchable';
5 |
6 | class Button extends Component {
7 |
8 | render() {
9 | const props = this.props;
10 | const buttonStyles = [styles.button, props.style];
11 | const textStyles = [styles.text];
12 |
13 | if (props.color) {
14 | textStyles.push({color: props.color});
15 | }
16 |
17 | if (props.disabled) {
18 | buttonStyles.push(styles.buttonDisabled);
19 | textStyles.push(styles.textDisabled);
20 | }
21 |
22 | let content = props.children || props.title;
23 | if (typeof content === 'string') {
24 | content = {content};
25 | }
26 |
27 | return (
28 |
29 | {content}
30 |
31 | );
32 | }
33 | }
34 |
35 | const styles = {
36 | button: {},
37 | text: {
38 | color: '#0C42FD',
39 | textAlign: 'center',
40 | padding: 16,
41 | fontSize: 36,
42 | },
43 | buttonDisabled: {},
44 | textDisabled: {
45 | color: '#cdcdcd',
46 | },
47 | };
48 |
49 | export default Button;
50 |
--------------------------------------------------------------------------------
/packages/rax/src/server/renderToString.js:
--------------------------------------------------------------------------------
1 | import Host from '../vdom/host';
2 | import ServerDriver from '../drivers/server';
3 | import render from '../render';
4 | import Serializer from './serializer';
5 |
6 | const RENDERED_NAME = 'data-rendered';
7 | const CACHE_KEY_NAME = 'data-cache-key';
8 |
9 | /**
10 | * Add renered mark to element
11 | */
12 | function addRenderedMark(element, markedValue) {
13 | if (!element || !element.attributes) {
14 | return element;
15 | }
16 |
17 | element.attributes[RENDERED_NAME] = markedValue;
18 | return element;
19 | }
20 |
21 | export default function renderToString(element) {
22 | // Reset driver iternal state
23 | ServerDriver.nodeMaps = {};
24 |
25 | // Reset host state
26 | Host.rootComponents = {};
27 | Host.rootInstances = {};
28 | Host.mountID = 1;
29 |
30 | let body = ServerDriver.createBody();
31 | render(element, body, {
32 | driver: ServerDriver
33 | });
34 |
35 | // Add rendered mark to root ChildNodes
36 | if (body.childNodes) {
37 | for (let i = 0; i < body.childNodes.length; i ++) {
38 | body.childNodes[i] = addRenderedMark(body.childNodes[i], 'server');
39 | }
40 | }
41 |
42 | let markup = new Serializer(body).serialize() || '';
43 |
44 | return markup;
45 | }
46 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/src/timer.weex.js:
--------------------------------------------------------------------------------
1 | const TIMER_MODULE = '@weex-module/timer';
2 |
3 | module.exports = function(__weex_require__) {
4 | const setTimeout = (handler, time) => {
5 | console.log('setTimeout', handler, time);
6 | const timer = __weex_require__(TIMER_MODULE);
7 | return timer.setTimeout(handler, time);
8 | };
9 |
10 | const setInterval = (handler, time) => {
11 | const timer = __weex_require__(TIMER_MODULE);
12 | return timer.setInterval(handler, time);
13 | };
14 |
15 | const clearTimeout = (n) => {
16 | const timer = __weex_require__(TIMER_MODULE);
17 | timer.clearTimeout(n);
18 | };
19 |
20 | const clearInterval = (n) => {
21 | const timer = __weex_require__(TIMER_MODULE);
22 | timer.clearInterval(n);
23 | };
24 |
25 | const requestAnimationFrame = (callback) => {
26 | const timer = __weex_require__(TIMER_MODULE);
27 | return timer.setTimeout(callback, 16);
28 | };
29 |
30 | const cancelAnimationFrame = (n) => {
31 | const timer = __weex_require__(TIMER_MODULE);
32 | timer.clearTimeout(n);
33 | };
34 |
35 | return {
36 | setTimeout,
37 | clearTimeout,
38 | setInterval,
39 | clearInterval,
40 | requestAnimationFrame,
41 | cancelAnimationFrame
42 | };
43 | };
44 |
--------------------------------------------------------------------------------
/docs/driver-spec.md:
--------------------------------------------------------------------------------
1 | # Driver Spec
2 |
3 | Driver is the key concept that make the application cross-container running.
4 | Rax have been implemented [browser driver](../packages/rax/src/drivers/browser.js), [server driver](../packages/rax/src/drivers/server.js) and [weex driver](../packages/rax/src/drivers/weex.js).
5 | If want Rax works on other container, only need implement the driver specification.
6 | The driver should implement follow method:
7 |
8 | * getElementById(id)
9 | * getChildNodes(node)
10 | * createBody()
11 | * createFragment()
12 | * createComment(content)
13 | * createText(text)
14 | * updateText(node, text)
15 | * createElement(component: {type, props})
16 | * appendChild(node, parent)
17 | * removeChild(node, parent)
18 | * replaceChild(newChild, oldChild, parent)
19 | * insertAfter(node, after, parent)
20 | * insertBefore(node, before, parent)
21 | * addEventListener(node, eventName, eventHandler)
22 | * removeEventListener(node, eventName, eventHandler)
23 | * removeAllEventListeners(node)
24 | * removeAttribute(node, propKey)
25 | * setAttribute(node, propKey, propValue)
26 | * setStyles(node, styles)
27 | * getWindowWidth()
28 | * beforeRender()
29 | * afterRender()
30 |
31 | ```js
32 | const container = driver.createBody();
33 | render(element, container, driver);
34 | ```
35 |
--------------------------------------------------------------------------------
/packages/rax/src/inject.js:
--------------------------------------------------------------------------------
1 | import {isWeb, isWeex} from 'universal-env';
2 | import Host from './vdom/host';
3 | import EmptyComponent from './vdom/empty';
4 | import NativeComponent from './vdom/native';
5 | import TextComponent from './vdom/text';
6 | import CompositeComponent from './vdom/composite';
7 | import FragmentComponent from './vdom/fragment';
8 | import WeexDriver from './drivers/weex';
9 | import BrowserDriver from './drivers/browser';
10 | import Hook from './debug/hook';
11 |
12 | export default function inject({driver, hook, measurer} = {}) {
13 | // Inject component class
14 | Host.EmptyComponent = EmptyComponent;
15 | Host.NativeComponent = NativeComponent;
16 | Host.TextComponent = TextComponent;
17 | Host.FragmentComponent = FragmentComponent;
18 | Host.CompositeComponent = CompositeComponent;
19 | // Inject devtool hook
20 | Host.hook = hook || Hook;
21 |
22 | // Inject performance measurer
23 | Host.measurer = measurer;
24 |
25 | // Inject render driver
26 | if (!Host.driver) {
27 | if (!driver) {
28 | if (isWeex) {
29 | driver = WeexDriver;
30 | } else if (isWeb) {
31 | driver = BrowserDriver;
32 | } else {
33 | throw Error('No builtin driver matched');
34 | }
35 | }
36 |
37 | Host.driver = driver;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, render} from 'rax';
2 | import ExampleList from './common/List';
3 |
4 | const EXAMPLES = [
5 | // common
6 | {name: '/syntax/hello-world', title: 'Hello World'},
7 | {name: '/style/index', title: 'Common Style'},
8 | // component
9 | {name: '/components/text', title: 'Text'},
10 | {name: '/components/image', title: 'Image'},
11 | {name: '/components/input', title: 'Input'},
12 | {name: '/components/scroller', title: 'Scroller'},
13 | {name: '/components/list', title: 'List'},
14 | {name: '/components/slider', title: 'Slider'},
15 | {name: '/components/a', title: 'A'},
16 | {name: '/components/video', title: 'Video'},
17 | {name: '/components/countdown', title: 'Countdown'},
18 | {name: '/components/marquee', title: 'Marquee'},
19 | {name: '/components/web', title: 'Web'},
20 | {name: '/components/navigator', title: 'Navigator'},
21 | {name: '/components/tabbar', title: 'Tabbar'},
22 | // module
23 | {name: '/modules/modal', title: 'Modal'},
24 | {name: '/modules/stream', title: 'Stream'},
25 | {name: '/modules/storage', title: 'Storage'},
26 | {name: '/modules/animation', title: 'Animation'},
27 | // {name: 'module/clipboard', title: 'Clipboard'}, // 0.8 , developing
28 | ];
29 |
30 | render();
31 |
--------------------------------------------------------------------------------
/packages/element-loader/src/__tests__/transformer.js:
--------------------------------------------------------------------------------
1 | import {
2 | transformFor,
3 | transformIf,
4 | transformPair
5 | } from '../transformer';
6 |
7 | describe('transformer', () => {
8 | it('transform for statement', () => {
9 | const beginOutput = transformFor([{
10 | name: ':for',
11 | value: 'item in items'
12 | }], true);
13 | const endOutput = transformFor([{
14 | name: ':for',
15 | value: 'item in items'
16 | }], false);
17 | const errorOutput = transformFor([{
18 | name: ':for',
19 | value: ' in items'
20 | }], false);
21 |
22 | expect(beginOutput).toEqual('{props.items.map((item) => {return (');
23 | expect(endOutput).toEqual(');})}');
24 | expect(errorOutput).toEqual('');
25 | });
26 |
27 | it('transform if statement', () => {
28 | const beginOutput = transformIf([{
29 | name: ':if',
30 | value: '{{items.length !== 0}}'
31 | }], true, 1);
32 | const endOutput = transformIf([{
33 | name: ':if',
34 | value: 'items.length !== 0'
35 | }], false, 1);
36 |
37 | expect(beginOutput).toEqual('{((props.items.length !== 0)) && ');
38 | expect(endOutput).toEqual('}');
39 | });
40 |
41 | it('transform pair statement', () => {
42 | expect(transformPair('items', 1)).toBe('(props.items)');
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/packages/universal-perf/README.md:
--------------------------------------------------------------------------------
1 | # universal-perf [](https://www.npmjs.com/package/universal-perf)
2 |
3 | ## Install
4 |
5 | ```bash
6 | npm install --save universal-perf
7 | ```
8 |
9 | ## Usage
10 |
11 | ```js
12 | import {createElement, Component, render} from 'rax';
13 | import {Text} from 'rax-components';
14 | import Perf from 'universal-perf';
15 |
16 | class PerfTest extends Component {
17 | render() {
18 | return Hello {this.props.name};
19 | }
20 | }
21 |
22 | const styles = {
23 | title: {
24 | color: '#ff4400',
25 | fontSize: 48,
26 | fontWeight: 'bold',
27 | }
28 | };
29 |
30 | Perf.start();
31 | render(, null, {
32 | measurer: Perf.Measurer
33 | });
34 |
35 | Perf.stop();
36 | let measurements = perf.getLastMeasurements();
37 |
38 | Perf.printInclusive(measurements);
39 | Perf.printExclusive(measurements);
40 | ```
41 |
42 | ## API
43 |
44 | ### `perf.printExclusive`
45 |
46 | Prints the render time.
47 |
48 | ### `perf.printInclusive`
49 |
50 | Prints the overall time taken.
51 |
52 | ### `perf.printWasted`
53 |
54 | Print newly inserted dom nodes in list as a waste of time
55 |
56 | ### `perf.printOperations`
57 |
58 | Prints operations, eg. "remove attributes" and "change style"
59 |
--------------------------------------------------------------------------------
/packages/rax-link/src/__tests__/Link.js:
--------------------------------------------------------------------------------
1 | import {createElement} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Link from '../';
4 |
5 | describe('Link', () => {
6 | it('should render a link', () => {
7 | const component = renderer.create(
8 | Example
9 | );
10 | let tree = component.toJSON();
11 | expect(tree.tagName).toEqual('A');
12 | expect(tree.children[0].children[0]).toEqual('Example');
13 | });
14 |
15 | it('should turn onPress to onClick', () => {
16 | const mockPress = jest.fn();
17 | const component = renderer.create(
18 | Example
19 | );
20 | let tree = component.toJSON();
21 | expect(tree.eventListeners.click).toBe(mockPress);
22 | });
23 |
24 | it('is error in a parent link', () => {
25 | const component = renderer.create(
26 |
27 | Example
28 |
29 | );
30 | let tree = component.toJSON();
31 | expect(tree.children).toBe(undefined);
32 | });
33 |
34 | it('should display the font size according to the props', () => {
35 | const component = renderer.create(
36 |
37 | Some link text
38 |
39 | );
40 |
41 | let tree = component.toJSON();
42 | expect(tree.children[0].style.fontSize).toBe('100rem');
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/style/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component, render} from 'rax';
2 | import StyleItem from '../common/StyleItem';
3 | import Panel from '../common/Panel';
4 |
5 | class Example extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | {/* */}
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 | }
30 |
31 | const styles = {
32 | itemBg: {
33 | width: 690,
34 | marginBottom: 10,
35 | }
36 | };
37 |
38 | render();
39 |
--------------------------------------------------------------------------------
/packages/rax-redux/src/components/Provider.js:
--------------------------------------------------------------------------------
1 | import {Component, PropTypes} from 'rax';
2 | import storeShape from '../utils/storeShape';
3 | import warning from '../utils/warning';
4 |
5 | const NODE_ENV = typeof process !== 'undefined' ? process.env.NODE_ENV : 'development';
6 |
7 | let didWarnAboutReceivingStore = false;
8 | function warnAboutReceivingStore() {
9 | if (didWarnAboutReceivingStore) {
10 | return;
11 | }
12 | didWarnAboutReceivingStore = true;
13 |
14 | warning(
15 | ' does not support changing `store` on the fly. '
16 | );
17 | }
18 |
19 | export default class Provider extends Component {
20 | getChildContext() {
21 | return { store: this.store };
22 | }
23 |
24 | constructor(props, context) {
25 | super(props, context);
26 | this.store = props.store;
27 | }
28 |
29 | render() {
30 | return this.props.children;
31 | }
32 | }
33 |
34 | if (NODE_ENV !== 'production') {
35 | Provider.prototype.componentWillReceiveProps = function(nextProps) {
36 | const { store } = this;
37 | const { store: nextStore } = nextProps;
38 |
39 | if (store !== nextStore) {
40 | warnAboutReceivingStore();
41 | }
42 | };
43 | }
44 |
45 |
46 | Provider.propTypes = {
47 | store: storeShape,
48 | children: PropTypes.element.isRequired
49 | };
50 |
51 | Provider.childContextTypes = {
52 | store: storeShape
53 | };
54 |
55 | Provider.displayName = 'Provider';
56 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/build:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Example: ./build -n tnpm -b
4 |
5 | # Reset in case getopts has been used previously in the shell.
6 | OPTIND=1
7 |
8 | # Initialize our own variables:
9 | npm="npm"
10 | install="link"
11 | onlyBuild=0
12 |
13 | while getopts "bin:" opt; do
14 | case "$opt" in
15 | b) onlyBuild=1
16 | ;;
17 | i) install="install"
18 | ;;
19 | n) npm=$OPTARG
20 | ;;
21 | esac
22 | done
23 |
24 | shift $((OPTIND-1))
25 |
26 | [ "$1" = "--" ] && shift
27 |
28 | echo "Make sure you has been build `weex-rax-framework` by `npm run dist` in `rax` project root"
29 |
30 | echo "Creates global weex-rax-framework link:"
31 | $npm link
32 |
33 | if [[ $onlyBuild == 1 ]]; then
34 |
35 | echo "Build without prerequisites:"
36 | cd weex
37 |
38 | else
39 |
40 | echo "Clone the weex repository and install prerequisites:"
41 | git clone https://github.com/alibaba/weex.git --depth=1
42 | cd weex
43 | $npm install
44 |
45 | fi
46 |
47 | echo "Install/Link the weex-rax-framework of your dependency:"
48 | npm $install weex-rax-framework
49 |
50 | echo "Config weex/html5/frameworks/index.js"
51 | echo -e "import * as Weex from './legacy/index'\nimport Rax from 'weex-rax-framework'\nexport default {\n Rax, Weex\n}" > html5/frameworks/index.js
52 |
53 | echo "Build jsfm for native renderer to weex/dist/native.js"
54 | $npm run build:native
55 |
56 | echo "Done"
57 |
--------------------------------------------------------------------------------
/examples/components/SwitchDemo.js:
--------------------------------------------------------------------------------
1 |
2 | import {createElement, Component, setNativeProps, findDOMNode} from 'rax';
3 | import {
4 | View,
5 | Text,
6 | Image,
7 | Link,
8 | TextInput,
9 | Button,
10 | Switch,
11 | Video,
12 | ScrollView,
13 | TouchableHighlight} from 'rax-components';
14 |
15 | class SwitchDemo extends Component {
16 | state = {
17 | eventSwitchIsOn: false,
18 | eventSwitchRegressionIsOn: true,
19 | };
20 | render() {
21 | return (
22 |
23 | {
24 | this.setState({eventSwitchIsOn: value});
25 | }}
26 | style={{marginBottom: 10}}
27 | value={this.state.eventSwitchIsOn} />
28 |
29 | {this.state.eventSwitchIsOn ? 'On' : 'Off'}
30 |
31 | this.setState({eventSwitchRegressionIsOn: value})}
33 | style={{marginBottom: 10}}
34 | value={this.state.eventSwitchRegressionIsOn} />
35 | {this.state.eventSwitchRegressionIsOn ? 'On' : 'Off'}
36 |
37 |
38 | );
39 | }
40 | }
41 |
42 | let styles = {
43 | container: {
44 | padding: 20,
45 | borderStyle: 'solid',
46 | borderColor: '#dddddd',
47 | borderWidth: 1,
48 | marginLeft: 20,
49 | marginRight: 20,
50 | marginBottom: 10,
51 | },
52 | };
53 |
54 | export default SwitchDemo;
55 |
--------------------------------------------------------------------------------
/packages/rax/src/style/__tests__/flexbox.js:
--------------------------------------------------------------------------------
1 | import flexbox from '../flexbox';
2 |
3 | describe('flexbox', () => {
4 | it('convert flex style to polyfill', () => {
5 | expect(flexbox.isFlexProp('flex')).toEqual(true);
6 | expect(flexbox.isFlexProp('display')).toEqual(true);
7 |
8 | expect(Boolean(flexbox.isFlexProp('border'))).toEqual(false);
9 |
10 |
11 | expect(flexbox.display('flex', {})).toEqual({
12 | display: ['-webkit-box', '-webkit-flex', 'flex']
13 | });
14 |
15 | expect(flexbox.flex(1)).toEqual({
16 | flex: 1,
17 | webkitBoxFlex: 1,
18 | webkitFlex: 1,
19 | });
20 |
21 | expect(flexbox.flexWrap('wrap')).toEqual({
22 | flexWrap: 'wrap'
23 | });
24 |
25 | expect(flexbox.alignItems('flex-start')).toEqual({
26 | alignItems: 'flex-start',
27 | webkitAlignItems: 'flex-start',
28 | webkitBoxAlign: 'start',
29 | });
30 |
31 | expect(flexbox.alignSelf('wrap')).toEqual({
32 | webkitAlignSelf: 'wrap',
33 | alignSelf: 'wrap'
34 | });
35 |
36 | expect(flexbox.flexDirection('row')).toEqual({
37 | webkitBoxOrient: 'horizontal',
38 | webkitFlexDirection: 'row',
39 | flexDirection: 'row'
40 | });
41 |
42 | expect(flexbox.justifyContent('flex-start')).toEqual({
43 | justifyContent: 'flex-start',
44 | webkitJustifyContent: 'flex-start',
45 | webkitBoxPack: 'start'
46 | });
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/packages/web-rax-framework/src/index.js:
--------------------------------------------------------------------------------
1 | const global = window;
2 |
3 | // ES
4 | if (!global.Promise) {
5 | global.Promise = require('runtime-shared/dist/promise.module');
6 | }
7 | require('./object');
8 | require('./array');
9 |
10 | // W3C
11 | require('whatwg-fetch');
12 | require('raf/polyfill');
13 |
14 | if (!global.FontFace) {
15 | global.FontFace = require('runtime-shared/dist/fontface.module');
16 | }
17 |
18 | if (!global.matchMedia) {
19 | global.matchMedia = require('runtime-shared/dist/matchMedia.module');
20 | }
21 |
22 | if (!document.fonts) {
23 | document.fonts = {
24 | add: function(fontFace) {
25 | let fontFaceRule = `@font-face {
26 | font-family: ${fontFace.family};
27 | src: ${fontFace.source}
28 | }`;
29 |
30 | let styleElement = document.createElement('style');
31 | styleElement.innerHTML = fontFaceRule;
32 | document.head.appendChild(styleElement);
33 | }
34 | };
35 | }
36 |
37 |
38 | if (!global.URL) {
39 | global.URL = require('runtime-shared/dist/url.module');
40 | }
41 |
42 | if (!global.URLSearchParams) {
43 | global.URLSearchParams = require('runtime-shared/dist/url-search-params.module');
44 | }
45 |
46 | // ModuleJS
47 | require('./require');
48 |
49 | // Polyfills for weex
50 | require('./appear');
51 |
52 | // Default Builtin modules
53 | global.define('rax', function(req, exports, module) {
54 | module.exports = require('rax');
55 | });
56 |
--------------------------------------------------------------------------------
/packages/babel-preset-rax/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "babel-preset-rax",
3 | "version": "0.2.2",
4 | "description": "Babel preset for all Rax plugins.",
5 | "license": "BSD-3-Clause",
6 | "main": "lib/index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/alibaba/rax.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/alibaba/rax/issues"
13 | },
14 | "homepage": "https://github.com/alibaba/rax#readme",
15 | "engines": {
16 | "npm": ">=3.0.0"
17 | },
18 | "dependencies": {
19 | "babel-plugin-add-module-exports": "^0.2.1",
20 | "babel-plugin-minify-dead-code-elimination": "^0.1.1",
21 | "babel-plugin-syntax-flow": "^6.3.13",
22 | "babel-plugin-syntax-jsx": "^6.3.13",
23 | "babel-plugin-syntax-trailing-function-commas": "^6.13.0",
24 | "babel-plugin-transform-class-properties": "^6.16.0",
25 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
26 | "babel-plugin-transform-export-extensions": "^6.8.0",
27 | "babel-plugin-transform-flow-strip-types": "^6.3.13",
28 | "babel-plugin-transform-object-rest-spread": "^6.16.0",
29 | "babel-plugin-transform-react-constant-elements": "^6.9.1",
30 | "babel-plugin-transform-react-display-name": "^6.3.13",
31 | "babel-plugin-transform-react-jsx": "^6.3.13",
32 | "babel-plugin-transform-react-jsx-source": "^6.3.13",
33 | "babel-plugin-transform-jsx-stylesheet": "^0.2.2"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/weex-rax-framework/src/semver.js:
--------------------------------------------------------------------------------
1 | export default {
2 | satisfies(left, right) {
3 | let regex = /(\W+)?([\d|.]+)/;
4 |
5 | if (typeof left + typeof right != 'stringstring')
6 | return false;
7 |
8 | if (right == '*') {
9 | return true;
10 | }
11 |
12 | let arr = right.match(regex);
13 | let a = left.split('.'),
14 | i = 0,
15 | b = arr[2].split('.'),
16 | len = Math.max(a.length, b.length);
17 |
18 | let flag = 0;
19 | for (let i = 0; i < len; i++) {
20 | if (a[i] && !b[i] && parseInt(a[i]) > 0 || parseInt(a[i]) > parseInt(b[i])) {
21 | flag = 1;
22 | break;
23 | } else if (b[i] && !a[i] && parseInt(b[i]) > 0 || parseInt(a[i]) < parseInt(b[i])) {
24 | flag = -1;
25 | break;
26 | }
27 | }
28 |
29 | switch (arr[1]) {
30 | case '<':
31 | if (flag === -1) {
32 | return true;
33 | }
34 | break;
35 | case '<=':
36 | if (flag !== 1) {
37 | return true;
38 | }
39 | break;
40 | case '>':
41 | if (flag === 1) {
42 | return true;
43 | }
44 | break;
45 | case '>=':
46 | if (flag !== -1) {
47 | return true;
48 | }
49 | break;
50 | default:
51 | if (flag === 0) {
52 | return true;
53 | }
54 | break;
55 | }
56 | return false;
57 | }
58 | };
59 |
--------------------------------------------------------------------------------
/packages/weex-rax-examples/common/Tip.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 |
3 | // Inspired by bootstrap http://getbootstrap.com/
4 | class Tip extends Component {
5 | static defaultProps = {
6 | type: 'success',
7 | value: ''
8 | };
9 |
10 | render() {
11 | const {type, value, style} = this.props;
12 |
13 | return (
14 |
15 | {value}
16 |
17 | );
18 | }
19 | }
20 |
21 | const styles = {
22 | tip: {
23 | paddingLeft: 36,
24 | paddingRight: 36,
25 | paddingTop: 36,
26 | paddingBottom: 36,
27 | borderRadius: 10
28 | },
29 | 'tip-txt': {
30 | fontSize: 28
31 | },
32 | 'tip-success': {
33 | backgroundColor: '#dff0d8',
34 | borderColor: '#d6e9c6'
35 | },
36 | 'tip-txt-success': {
37 | color: '#3c763d'
38 | },
39 | 'tip-info': {
40 | backgroundColor: '#d9edf7',
41 | borderColor: '#bce8f1'
42 | },
43 | 'tip-txt-info': {
44 | color: '#31708f'
45 | },
46 | 'tip-warning': {
47 | backgroundColor: '#fcf8e3',
48 | borderColor: '#faebcc'
49 | },
50 | 'tip-txt-warning': {
51 | color: '#8a6d3b'
52 | },
53 | 'tip-danger': {
54 | backgroundColor: '#f2dede',
55 | borderColor: '#ebccd1'
56 | },
57 | 'tip-txt-danger': {
58 | color: '#a94442'
59 | },
60 | };
61 |
62 | export default Tip;
63 |
--------------------------------------------------------------------------------
/packages/rax-cli/src/generator/index.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var chalk = require('chalk');
3 | var spawn = require('cross-spawn');
4 | var easyfile = require('easyfile');
5 | var execSync = require('child_process').execSync;
6 |
7 | function shouldUseYarn() {
8 | try {
9 | execSync('yarnpkg --version', {stdio: 'ignore'});
10 | return true;
11 | } catch (e) {
12 | return false;
13 | }
14 | }
15 |
16 | function install(projectDir, projectName, verbose) {
17 | console.log(chalk.white.bold('Install dependencies:'));
18 |
19 | var pkgManager = shouldUseYarn() ? 'yarnpkg' : 'npm';
20 | var args = ['install'];
21 | if (verbose) {
22 | args.push('--verbose');
23 | }
24 | var proc = spawn(pkgManager, args, {stdio: 'inherit'});
25 |
26 | proc.on('close', function(code) {
27 | if (code !== 0) {
28 | console.error('`' + pkgManager + ' install` failed');
29 | return;
30 | } else {
31 | console.log(chalk.white.bold('To run your app:'));
32 | console.log(chalk.white(' cd ' + projectName));
33 | console.log(chalk.white(' ' + pkgManager + ' run start'));
34 | }
35 | });
36 | }
37 |
38 | module.exports = function(projectDir, projectName, verbose) {
39 | var src = path.join(__dirname, 'templates');
40 |
41 | easyfile.copy(src, projectDir, {
42 | force: true,
43 | backup: true,
44 | });
45 |
46 | process.chdir(projectDir);
47 | install(projectDir, projectName, verbose);
48 | };
49 |
--------------------------------------------------------------------------------
/packages/rax-switch/src/__tests__/Switch.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import Switch from '../';
4 |
5 | class SwitchTest extends Component {
6 | state = {
7 | value: true
8 | };
9 | render() {
10 | return {
11 | this.setState({value: value});
12 | }} />;
13 | }
14 | }
15 |
16 | describe('Switch', () => {
17 | let component;
18 |
19 | beforeEach(() => {
20 | component = renderer.create(
21 |
22 | );
23 | });
24 | it('should render a switch', () => {
25 | let tree = component.toJSON();
26 | expect(tree.tagName).toEqual('SPAN');
27 | expect(tree.children[0].tagName).toEqual('SMALL');
28 | });
29 |
30 | it('should handle click', () => {
31 | let tree = component.toJSON();
32 | expect(tree.style.backgroundColor).toEqual('#00e158');
33 |
34 | tree.eventListeners.click();
35 | tree = component.toJSON();
36 | expect(tree.style.backgroundColor).toEqual('#fff');
37 | });
38 |
39 | it('should change value with disabled', () => {
40 | let component = renderer.create(
41 |
42 | );
43 | let tree = component.toJSON();
44 | expect(tree.style.backgroundColor).toEqual('#fff');
45 | tree.eventListeners.click();
46 | tree = component.toJSON();
47 | expect(tree.style.backgroundColor).toEqual('#fff');
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/packages/rax-link/src/index.js:
--------------------------------------------------------------------------------
1 | import {Component, createElement, PropTypes} from 'rax';
2 | import {isWeex} from 'universal-env';
3 | import Text from 'rax-text';
4 |
5 | class Link extends Component {
6 |
7 | static contextTypes = {
8 | isInAParentLink: PropTypes.bool
9 | };
10 |
11 | static childContextTypes = {
12 | isInAParentLink: PropTypes.bool
13 | };
14 |
15 | getChildContext() {
16 | return {
17 | isInAParentLink: true
18 | };
19 | }
20 |
21 | render() {
22 | // https://www.w3.org/TR/html4/struct/links.html#h-12.2.2
23 | if (this.context.isInAParentLink) {
24 | return console.error('Nested links are illegal');
25 | }
26 |
27 | let props = this.props;
28 | let children = props.children;
29 | let nativeProps = {...props};
30 | let style = {
31 | ...styles.initial,
32 | ...nativeProps.style
33 | };
34 |
35 | if (nativeProps.onPress) {
36 | nativeProps.onClick = nativeProps.onPress;
37 | delete nativeProps.onPress;
38 | }
39 |
40 | let content = children;
41 | if (typeof children === 'string') {
42 | content = {children};
43 | }
44 |
45 | if (isWeex) {
46 | return {content};
47 | } else {
48 | return {content};
49 | }
50 | }
51 | }
52 |
53 | const styles = {
54 | initial: {
55 | textDecoration: 'none'
56 | }
57 | };
58 |
59 | export default Link;
60 |
--------------------------------------------------------------------------------
/packages/rax-listview/src/index.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import {isWeex} from 'universal-env';
3 | import View from 'rax-view';
4 | import RecyclerView from 'rax-recyclerview';
5 |
6 | const SCROLLVIEW_REF = 'scrollview';
7 |
8 | class ListView extends Component {
9 |
10 | static defaultProps = {
11 | renderScrollComponent: props => ,
12 | dataSource: [],
13 | };
14 |
15 | scrollTo = (options) => {
16 | if (this.refs[SCROLLVIEW_REF]) {
17 | this.refs[SCROLLVIEW_REF].scrollTo(options);
18 | }
19 | }
20 |
21 | render() {
22 | let {
23 | renderScrollComponent,
24 | renderHeader,
25 | renderFooter,
26 | renderRow,
27 | dataSource,
28 | onEndReached,
29 | onEndReachedThreshold,
30 | id,
31 | className,
32 | style,
33 | } = this.props;
34 |
35 | let header = typeof renderHeader == 'function' ? renderHeader() : null;
36 | let footer = typeof renderFooter == 'function' ? renderFooter() : null;
37 | let body = dataSource.map((i, index) => {
38 | return renderRow(i, index);
39 | });
40 |
41 | let props = {
42 | id,
43 | className,
44 | ref: SCROLLVIEW_REF,
45 | style,
46 | children: [].concat(header, body, footer),
47 | onEndReached,
48 | onEndReachedThreshold,
49 | _autoWrapCell: true,
50 | };
51 |
52 | return renderScrollComponent(props);
53 | }
54 | }
55 |
56 | export default ListView;
57 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/shallowEqual.js:
--------------------------------------------------------------------------------
1 | const hasOwnProperty = Object.prototype.hasOwnProperty;
2 |
3 | /**
4 | * inlined Object.is polyfill to avoid requiring consumers ship their own
5 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
6 | */
7 | function is(x, y) {
8 | // SameValue algorithm
9 | if (x === y) {
10 | // Steps 1-5, 7-10
11 | // Steps 6.b-6.e: +0 != -0
12 | return x !== 0 || 1 / x === 1 / y;
13 | } else {
14 | // Step 6.a: NaN == NaN
15 | return x !== x && y !== y;
16 | }
17 | }
18 |
19 | /**
20 | * Performs equality by iterating through keys on an object and returning false
21 | * when any key has values which are not strictly equal between the arguments.
22 | * Returns true when the values of all keys are strictly equal.
23 | */
24 | function shallowEqual(objA, objB) {
25 | if (is(objA, objB)) {
26 | return true;
27 | }
28 |
29 | if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
30 | return false;
31 | }
32 |
33 | let keysA = Object.keys(objA);
34 | let keysB = Object.keys(objB);
35 |
36 | if (keysA.length !== keysB.length) {
37 | return false;
38 | }
39 |
40 | // Test for A's keys different from B.
41 | for (let i = 0; i < keysA.length; i++) {
42 | if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
43 | return false;
44 | }
45 | }
46 |
47 | return true;
48 | }
49 |
50 | export default shallowEqual;
51 |
--------------------------------------------------------------------------------
/packages/stylesheet-loader/src/BoxModelPropTypes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import PropTypes from './PropTypes';
4 |
5 | const BoxModelPropTypes = {
6 | width: PropTypes.length,
7 | height: PropTypes.length,
8 | minWidth: PropTypes.length,
9 | minHeight: PropTypes.length,
10 | maxWidth: PropTypes.length,
11 | maxHeight: PropTypes.length,
12 | marginLeft: PropTypes.length,
13 | marginRight: PropTypes.length,
14 | marginTop: PropTypes.length,
15 | marginBottom: PropTypes.length,
16 | paddingLeft: PropTypes.length,
17 | paddingRight: PropTypes.length,
18 | paddingTop: PropTypes.length,
19 | paddingBottom: PropTypes.length,
20 | borderWidth: PropTypes.length,
21 | borderLeftWidth: PropTypes.length,
22 | borderTopWidth: PropTypes.length,
23 | borderRightWidth: PropTypes.length,
24 | borderBottomWidth: PropTypes.length,
25 | borderStyle: PropTypes.oneOf(['dotted', 'dashed', 'solid']),
26 | borderRadius: PropTypes.length,
27 | borderBottomLeftRadius: PropTypes.length,
28 | borderBottomRightRadius: PropTypes.length,
29 | borderTopLeftRadius: PropTypes.length,
30 | borderTopRightRadius: PropTypes.length,
31 | overflow: PropTypes.oneOf(['hidden', 'visible']),
32 | position: PropTypes.oneOf(['relative', 'absolute', 'sticky', 'fixed']),
33 | display: PropTypes.oneOf(['block', 'flex', 'inline-flex', 'inline-block', 'inline']),
34 | top: PropTypes.length,
35 | bottom: PropTypes.length,
36 | left: PropTypes.length,
37 | right: PropTypes.length
38 | };
39 |
40 | export default BoxModelPropTypes;
41 |
--------------------------------------------------------------------------------
/packages/rax-recyclerview/src/__tests__/RecyclerView.js:
--------------------------------------------------------------------------------
1 | import {createElement, Component} from 'rax';
2 | import renderer from 'rax-test-renderer';
3 | import RecyclerView from '../';
4 |
5 | class RecyclerViewTest extends Component {
6 | renderHeader() {
7 | return header;
8 | }
9 | renderFooter() {
10 | return footer;
11 | }
12 | renderBody() {
13 | return [1, 2, 3].map((num) => {
14 | return {num};
15 | });
16 | }
17 | componentDidMount() {
18 | this.refs.recycleview.scrollTo({
19 | x: 0,
20 | y: 0
21 | });
22 | }
23 | render() {
24 | let props = {
25 | ref: 'recycleview',
26 | children: [].concat(this.renderHeader(), this.renderBody(), this.renderFooter())
27 | };
28 | return ;
29 | }
30 | }
31 |
32 | describe('RecyclerView', () => {
33 | let component;
34 |
35 | beforeEach(() => {
36 | component = renderer.create(
37 |
38 | );
39 | });
40 |
41 | it('should render a RecyclerView', () => {
42 | let tree = component.toJSON();
43 | expect(tree.tagName).toEqual('DIV');
44 | expect(tree.children[0].children[0].children[0]).toEqual('header');
45 | expect(tree.children[0].children[1].children[0]).toEqual('1');
46 | expect(tree.children[0].children[2].children[0]).toEqual('2');
47 | expect(tree.children[0].children[3].children[0]).toEqual('3');
48 | expect(tree.children[0].children[4].children[0]).toEqual('footer');
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/__tests__/text.js:
--------------------------------------------------------------------------------
1 | /* @jsx createElement */
2 |
3 | 'use strict';
4 |
5 | import Component from '../../component';
6 | import {createElement} from '../../element';
7 | import Host from '../host';
8 | import render from '../../render';
9 | import ServerDriver from '../../drivers/server';
10 | import findDOMNode from '../../findDOMNode';
11 |
12 | describe('TextComponent', function() {
13 | function createNodeElement(tagName) {
14 | return {
15 | nodeType: 1,
16 | tagName: tagName.toUpperCase(),
17 | attributes: {},
18 | style: {},
19 | childNodes: [],
20 | parentNode: null
21 | };
22 | }
23 |
24 | beforeEach(function() {
25 | Host.driver = ServerDriver;
26 | });
27 |
28 | afterEach(function() {
29 | Host.driver = null;
30 | });
31 |
32 | it('updates a mounted text component in place', function() {
33 | let el = createNodeElement('div');
34 | let inst = render({'foo'}{'bar'}
, el);
35 |
36 | let foo = findDOMNode(inst).childNodes[1];
37 | let bar = findDOMNode(inst).childNodes[2];
38 | expect(foo.data).toBe('foo');
39 | expect(bar.data).toBe('bar');
40 |
41 | inst = render({'baz'}{'qux'}
, el);
42 | // After the update, the text nodes should have stayed in place (as opposed
43 | // to getting unmounted and remounted)
44 | expect(findDOMNode(inst).childNodes[1]).toBe(foo);
45 | expect(findDOMNode(inst).childNodes[2]).toBe(bar);
46 | expect(foo.data).toBe('baz');
47 | expect(bar.data).toBe('qux');
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/packages/rax-view/src/__tests__/View.js:
--------------------------------------------------------------------------------
1 | global.callNative = null;
2 | import {createElement} from 'rax';
3 | import renderer from 'rax-test-renderer';
4 | import View from '../';
5 |
6 | describe('View', () => {
7 | it('render tag view', () => {
8 | const component = renderer.create(
9 | Example
10 | );
11 | let tree = component.toJSON();
12 | expect(tree.tagName).toEqual('DIV');
13 | expect(tree.children[0]).toEqual('Example');
14 | });
15 |
16 | it('turn onPress to onClick', () => {
17 | const mockPress = jest.fn();
18 | const component = renderer.create(
19 | Example
20 | );
21 | let tree = component.toJSON();
22 | expect(tree.eventListeners.click).toBe(mockPress);
23 | });
24 |
25 | it('style in View', () => {
26 | const component = renderer.create(
27 | Example
28 | );
29 | let tree = component.toJSON();
30 | expect(tree.style.border).toBe('0 solid black');
31 | expect(tree.style.position).toBe('relative');
32 | expect(tree.style.boxSizing).toBe('border-box');
33 | expect(tree.style.display).toBe('flex');
34 | expect(tree.style.flexDirection).toBe('column');
35 | expect(tree.style.alignContent).toBe('flex-start');
36 | expect(tree.style.flexShrink).toBe(0);
37 | });
38 |
39 | it('children in View', () => {
40 | const component = renderer.create(
41 |
42 | Example
43 |
44 | );
45 | let tree = component.toJSON();
46 | expect(tree.children[0].children[0]).toBe('Example');
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/packages/element-loader/src/template-loader.js:
--------------------------------------------------------------------------------
1 | import cons from 'consolidate';
2 | import path from 'path';
3 | import loaderUtils from 'loader-utils';
4 | import HTMLtoJSX from './HTMLtoJSX';
5 | import { transform } from 'babel-core';
6 | import getBabelConfig from './getBabelConfig';
7 | const converter = new HTMLtoJSX();
8 |
9 | module.exports = function(source, parseObject) {
10 | this.cacheable && this.cacheable();
11 | const callback = this.async();
12 | const query = loaderUtils.parseQuery(this.query);
13 |
14 | // no engine default: html
15 | if (!cons[query.engine]) {
16 | return callback(null, getConvertText(source, parseObject.importLinks, query));
17 | }
18 |
19 | cons[query.engine].render(source, {
20 | filename: this.resourcePath
21 | }, (error, html) => {
22 | return callback(error, getConvertText(html, parseObject.importLinks, query));
23 | });
24 | };
25 |
26 | const getConvertText = (source, links, query) => {
27 | const convert = converter.convert(source);
28 | const { presets, imports } = query;
29 | const code = `
30 | ${query.banner}
31 | ${getElementsImport(links)}
32 |
33 | module.exports = function(styles) {
34 | const props = this.props;
35 | return ${convert.output};
36 | };
37 | `;
38 |
39 | return transform(code, getBabelConfig(query)).code;
40 | };
41 |
42 | const getElementsImport = (links) => {
43 | let result = '';
44 |
45 | links.forEach((link) => {
46 | const ext = path.extname(link);
47 | const name = path.basename(link, ext);
48 | result += `import ${name} from '${link}';\n`;
49 | });
50 |
51 | return result;
52 | };
53 |
--------------------------------------------------------------------------------
/packages/rax/src/testing/__tests__/snapshot.js:
--------------------------------------------------------------------------------
1 | import {createElement} from '../../element';
2 | import Component from '../../component';
3 | import renderer from '../renderer';
4 |
5 | const STATUS = {
6 | NORMAL: 'normal',
7 | HOVERED: 'hovered',
8 | };
9 |
10 | class Link extends Component {
11 |
12 | constructor() {
13 | super();
14 |
15 | this._onMouseEnter = this._onMouseEnter.bind(this);
16 | this._onMouseLeave = this._onMouseLeave.bind(this);
17 |
18 | this.state = {
19 | class: STATUS.NORMAL,
20 | };
21 | }
22 |
23 | _onMouseEnter() {
24 | this.setState({class: STATUS.HOVERED});
25 | }
26 |
27 | _onMouseLeave() {
28 | this.setState({class: STATUS.NORMAL});
29 | }
30 |
31 | render() {
32 | return (
33 |
38 | {this.props.children}
39 |
40 | );
41 | }
42 | }
43 |
44 | test('Link changes the class when hovered', () => {
45 | const component = renderer.create(
46 | Example
47 | );
48 | let tree = component.toJSON();
49 | expect(tree).toMatchSnapshot();
50 |
51 | // manually trigger the callback
52 | tree.eventListeners.mouseenter();
53 | // re-rendering
54 | tree = component.toJSON();
55 | expect(tree).toMatchSnapshot();
56 |
57 | // manually trigger the callback
58 | tree.eventListeners.mouseleave();
59 | // re-rendering
60 | tree = component.toJSON();
61 | expect(tree).toMatchSnapshot();
62 | });
63 |
--------------------------------------------------------------------------------
/.github/GIT_COMMIT_SPECIFIC.md:
--------------------------------------------------------------------------------
1 | # GIT COMMIT MESSAGE CHEAT SHEET
2 |
3 | **Proposed format of the commit message**
4 |
5 | ```
6 | ():
7 |
8 |
9 | ```
10 |
11 | All lines are wrapped at 100 characters !
12 |
13 |
14 | **Allowed ``**
15 |
16 | - feat (A new feature)
17 | - fix (A bug fix)
18 | - docs (Documentation only changes)
19 | - style (Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc))
20 | - perf (A code change that improves performance)
21 | - refactor (A code change that neither fixes a bug nor adds a feature)
22 | - test (Adding missing tests or correcting existing tests)
23 | - build (Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm))
24 | - ci (Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs))
25 | - chore (Other changes that don't modify src or test files)
26 | - revert (Reverts a previous commit)
27 |
28 | **Allowed ``**
29 | Scope could be anything specifying place of the commit change.
30 |
31 | For example $location, $browser, compiler, scope, ng:href, etc...
32 |
33 |
34 | **Breaking changes**
35 | All breaking changes have to be mentioned in message body, on separated line:
36 | _Breaks removed $browser.setUrl() method (use $browser.url(newUrl))_
37 | _Breaks ng: repeat option is no longer supported on selects (use ng:options)_
38 |
39 |
40 | **Message body**
41 |
42 | - uses the imperative, present tense: “change” not “changed” nor “changes”
43 | - includes motivation for the change and contrasts with previous behavior
44 |
--------------------------------------------------------------------------------
/scripts/mapCoverage.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Because we have a build step, sometimes we can test files from both
3 | * `packages/jest-whatever/build/*` and `packages/jest-whatever/src/*`
4 | *
5 | * If we require file by its relative path like:
6 | * // inside `jest-whatever/src/__tests__/index.js`
7 | * require('../index.js'); // this will require `jest-whatever/src/index.js`
8 | *
9 | * But if we require it by a package name, this will go through node_modules
10 | * and lerna index.js link. So the actual file will be required from `build/`
11 | * // inside another packages
12 | * // this will go through lerna and require `jest-whatever/build/index.js
13 | * require('jest-whatever')
14 | *
15 | * these files are identical (one is preprocessed, another is transformed on
16 | * the fly), but the coverage paths are different.
17 | * This script will map coverage results from both locations to one and
18 | * produce a full coverage report.
19 | */
20 |
21 | const createReporter = require('istanbul-api').createReporter;
22 | const coverage = require('../coverage/coverage-final.json');
23 | const istanbulCoverage = require('istanbul-lib-coverage');
24 |
25 | const map = istanbulCoverage.createCoverageMap();
26 | const reporter = createReporter();
27 |
28 | const mapFileCoverage = fileCoverage => {
29 | fileCoverage.path = fileCoverage.path
30 | .replace(/(.*packages\/.*\/)(lib)(\/.*)/, '$1src$3');
31 | return fileCoverage;
32 | };
33 |
34 | Object.keys(coverage).forEach(
35 | filename => map.addFileCoverage(mapFileCoverage(coverage[filename]))
36 | );
37 |
38 | reporter.addAll(['json', 'lcov', 'text']);
39 | reporter.write(map);
40 |
--------------------------------------------------------------------------------
/packages/rax-test-renderer/README.md:
--------------------------------------------------------------------------------
1 | # rax-test-renderer [](https://www.npmjs.com/package/rax-test-renderer) [](https://david-dm.org/alibaba/rax.svg?path=packages/rax-test-renderer) [](https://snyk.io/test/npm/rax-test-renderer)
2 |
3 | > Rax renderer for snapshot testing.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ npm install --save-dev rax-test-renderer
9 | ```
10 |
11 | ## Usage
12 |
13 | This package provides an renderer that can be used to render Rax components to pure JavaScript objects, without depending on the DOM or a native mobile environment:
14 |
15 | ```jsx
16 | import {createElement} from 'rax';
17 | import renderer from 'rax-test-renderer';
18 |
19 | const tree = renderer.create(
20 | Example
21 | );
22 |
23 | console.log(tree.toJSON());
24 | // { tagName: 'A',
25 | // attributes: { href: 'https://example.com/' },
26 | // children: [ 'Example' ] }
27 | ```
28 |
29 | You can also use Jest's snapshot testing feature to automatically save a copy of the JSON tree to a file and check in your tests that it hasn't changed: http://facebook.github.io/jest/blog/2016/07/27/jest-14.html.
30 |
31 | ```jsx
32 | import {createElement} from 'rax';
33 | import renderer from 'rax-test-renderer';
34 |
35 | test('Link renders correctly', () => {
36 | const tree = renderer.create(
37 | Example
38 | ).toJSON();
39 | expect(tree).toMatchSnapshot();
40 | });
41 | ```
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD License
2 |
3 | Copyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.
4 | Copyright (c) 2013-present, Facebook, Inc. All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification,
7 | are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name Facebook nor the names of its contributors may be used to
17 | endorse or promote products derived from this software without specific
18 | prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/packages/rax-touchable/src/__tests__/Touchable.js:
--------------------------------------------------------------------------------
1 | global.callNative = null;
2 | import {createElement} from 'rax';
3 | import renderer from 'rax-test-renderer';
4 | import Touchable from '../';
5 |
6 | describe('Touchable', () => {
7 | it('render tag Touchable', () => {
8 | const component = renderer.create(
9 | Example
10 | );
11 | let tree = component.toJSON();
12 | expect(tree.tagName).toEqual('DIV');
13 | expect(tree.children[0]).toEqual('Example');
14 | });
15 |
16 | it('turn onPress', () => {
17 | const mockPress = jest.fn();
18 | const component = renderer.create(
19 | Example
20 | );
21 | let tree = component.toJSON();
22 | expect(tree.eventListeners.click).toBe(mockPress);
23 | });
24 |
25 | it('style in Touchable', () => {
26 | const component = renderer.create(
27 | Example
28 | );
29 | let tree = component.toJSON();
30 | expect(tree.style.border).toBe('0 solid black');
31 | expect(tree.style.position).toBe('relative');
32 | expect(tree.style.boxSizing).toBe('border-box');
33 | expect(tree.style.display).toBe('flex');
34 | expect(tree.style.flexDirection).toBe('column');
35 | expect(tree.style.alignContent).toBe('flex-start');
36 | expect(tree.style.cursor).toBe('pointer');
37 | });
38 |
39 | it('children in Touchable', () => {
40 | const component = renderer.create(
41 |
42 | Example
43 |
44 | );
45 | let tree = component.toJSON();
46 | expect(tree.children[0].children[0]).toBe('Example');
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/packages/rax/src/__tests__/component.js:
--------------------------------------------------------------------------------
1 | /* @jsx createElement */
2 |
3 | import Component from '../component';
4 | import {createElement} from '../element';
5 |
6 | describe('Component', () => {
7 | it('preserves the name of the class', () => {
8 | class Foo extends Component { }
9 | expect(Foo.name).toBe('Foo');
10 | });
11 |
12 | it('check a component is class type', () => {
13 | class Foo extends Component { }
14 | let foo = new Foo();
15 | expect(foo.isComponentClass).toBeDefined();
16 | });
17 |
18 | it('create a component with prop', () => {
19 | class Foo extends Component {
20 | render() {
21 | return null;
22 | }
23 | }
24 |
25 | let bar = () => {};
26 | let foo = ;
27 | expect(foo.props.foo).toBe('Foo');
28 | expect(foo.props.bar).toBe(bar);
29 | });
30 |
31 | it('create a component with ignored prop', () => {
32 | class Foo extends Component {
33 | render() {
34 | return null;
35 | }
36 | }
37 |
38 | let foo = ;
39 | expect(foo.props.key).toBe(undefined);
40 | expect(foo.props.ref).toBe(undefined);
41 | });
42 |
43 | it('create a component based on state using initial values in this.props', function() {
44 | class Foo extends Component {
45 | constructor(props) {
46 | super(props);
47 | this.state = {bar: this.props.initialValue};
48 | }
49 | render() {
50 | return null;
51 | }
52 | }
53 |
54 | let foo = ;
55 | let ElementType = foo.type;
56 | let instance = new ElementType(foo.props);
57 | expect(instance.state.bar).toBe('Foo');
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/packages/rax/src/vdom/ref.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Ref manager
3 | */
4 |
5 | export default {
6 | update(prevElement, nextElement, component) {
7 | let prevRef = prevElement != null && prevElement.ref;
8 | let nextRef = nextElement != null && nextElement.ref;
9 |
10 | // Update refs in owner component
11 | if (prevRef !== nextRef) {
12 | // Detach prev RenderedElement's ref
13 | prevRef != null && this.detach(prevElement._owner, prevRef, component);
14 | // Attach next RenderedElement's ref
15 | nextRef != null && this.attach(nextElement._owner, nextRef, component);
16 | }
17 | },
18 | attach(ownerComponent, ref, component) {
19 | if (!ownerComponent) {
20 | throw new Error(
21 | 'You might be adding a ref to a component that was not created inside a component\'s ' +
22 | '`render` method, or you have multiple copies of Rax loaded.'
23 | );
24 | }
25 |
26 | let instance = component.getPublicInstance();
27 | if (typeof ref === 'function') {
28 | ref(instance);
29 | } else {
30 | ownerComponent._instance.refs[ref] = instance;
31 | }
32 | },
33 | detach(ownerComponent, ref, component) {
34 | if (typeof ref === 'function') {
35 | // When the referenced component is unmounted and whenever the ref changes, the old ref will be called with null as an argument.
36 | ref(null);
37 | } else {
38 | // Must match component and ref could detach the ref on owner when A's before ref is B's current ref
39 | let instance = component.getPublicInstance();
40 | if (ownerComponent._instance.refs[ref] === instance) {
41 | delete ownerComponent._instance.refs[ref];
42 | }
43 | }
44 | }
45 | };
46 |
--------------------------------------------------------------------------------
/packages/stylesheet-loader/src/Validation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import BoxModelPropTypes from './BoxModelPropTypes';
4 | import FlexboxPropTypes from './FlexboxPropTypes';
5 | import TextStylePropTypes from './TextStylePropTypes';
6 | import ColorPropTypes from './ColorPropTypes';
7 | import {pushWarnMessage} from './promptMessage';
8 | import particular from './particular';
9 | import chalk from 'chalk';
10 |
11 | class Validation {
12 | static validate(camelCaseProperty, prop, value, selectors = '', position = {}) {
13 | if (allStylePropTypes[camelCaseProperty]) {
14 | let error = allStylePropTypes[camelCaseProperty](value, prop, selectors);
15 |
16 | if (error) {
17 | const message = `line: ${position.start.line}, column: ${position.start.column} - ${error.message}`;
18 | console.warn(chalk.yellow.bold(message));
19 | pushWarnMessage(message);
20 | }
21 | return error;
22 | } else {
23 | if (!particular[camelCaseProperty]) {
24 | const message = `line: ${position.start.line}, column: ${position.start.column} - "${prop}: ${value}" is not valid in "${selectors}" selector`;
25 | console.warn(chalk.yellow.bold(message));
26 | pushWarnMessage(message);
27 | }
28 | }
29 | }
30 |
31 | static addValidStylePropTypes(stylePropTypes) {
32 | for (let prop in stylePropTypes) {
33 | allStylePropTypes[prop] = stylePropTypes[prop];
34 | }
35 | }
36 | }
37 |
38 | let allStylePropTypes = {};
39 |
40 | Validation.addValidStylePropTypes(BoxModelPropTypes);
41 | Validation.addValidStylePropTypes(FlexboxPropTypes);
42 | Validation.addValidStylePropTypes(TextStylePropTypes);
43 | Validation.addValidStylePropTypes(ColorPropTypes);
44 |
45 | export default Validation;
46 |
--------------------------------------------------------------------------------
/packages/rax-textinput/src/__tests__/TextInput.js:
--------------------------------------------------------------------------------
1 | global.callNative = null;
2 | import {createElement} from 'rax';
3 | import renderer from 'rax-test-renderer';
4 | import TextInput from '../';
5 |
6 | describe('TextInput', () => {
7 | it('render tag TextInput', () => {
8 | const component = renderer.create(
9 |
10 | );
11 | let tree = component.toJSON();
12 | expect(tree.tagName).toEqual('INPUT');
13 | });
14 |
15 |
16 | it('style in TextInput', () => {
17 | const component = renderer.create(
18 |
19 | );
20 | let tree = component.toJSON();
21 | expect(tree.style.appearance).toBe('none');
22 | expect(tree.style.backgroundColor).toBe('transparent');
23 | expect(tree.style.borderColor).toBe('#000000');
24 | expect(tree.style.borderWidth).toBe(0);
25 | expect(tree.style.boxSizing).toBe('border-box');
26 | expect(tree.style.color).toBe('#000000');
27 | expect(tree.style.padding).toBe(0);
28 | expect(tree.style.paddingLeft).toBe(24);
29 | expect(tree.style.fontSize).toBe(24);
30 | expect(tree.style.lineHeight).toBe(60);
31 | expect(tree.style.height).toBe(60);
32 | });
33 |
34 | it('onInput & onChange', () => {
35 | const mockFunc = jest.fn();
36 | const component = renderer.create(
37 |
43 | );
44 | let tree = component.toJSON();
45 | expect(typeof tree.eventListeners.input).toBe('function');
46 | expect(typeof tree.eventListeners.change).toBe('function');
47 | expect(typeof tree.eventListeners.blur).toBe('function');
48 | expect(typeof tree.eventListeners.focus).toBe('function');
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/packages/universal-transition/src/index.js:
--------------------------------------------------------------------------------
1 | import {isWeex, isWeb} from 'universal-env';
2 |
3 | export default function transition(node, styles, options, callback) {
4 | if (typeof options == 'function' || options == null) {
5 | callback = options;
6 | options = {
7 | timingFunction: 'ease',
8 | duration: 0,
9 | delay: 0,
10 | };
11 | }
12 |
13 | if (isWeex) {
14 | const animation = require('@weex-module/animation');
15 | animation.transition(node.ref, {
16 | styles,
17 | timingFunction: options.timingFunction,
18 | delay: options.delay,
19 | duration: options.duration,
20 | }, callback || function() {});
21 | } else if (isWeb) {
22 | const duration = options.duration; // ms
23 | const timingFunction = options.timingFunction;
24 | const delay = options.delay; // ms
25 | const transitionValue = 'all ' + duration + 'ms '
26 | + timingFunction + ' ' + delay + 'ms';
27 |
28 | node.style.transition = transitionValue;
29 | node.style.webkitTransition = transitionValue;
30 |
31 | if (callback) {
32 | const transitionEndHandler = function(e) {
33 | e.stopPropagation();
34 | node.removeEventListener('webkitTransitionEnd', transitionEndHandler);
35 | node.removeEventListener('transitionend', transitionEndHandler);
36 | node.style.transition = '';
37 | node.style.webkitTransition = '';
38 | callback();
39 | };
40 | node.addEventListener('webkitTransitionEnd', transitionEndHandler);
41 | node.addEventListener('transitionend', transitionEndHandler);
42 | }
43 |
44 | for (const key in styles) {
45 | // TODO add vendor prefix
46 | let value = styles[key];
47 | node.style[key] = value;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------