@es-react/react
Version:
Hippy react framework
156 lines (135 loc) • 4.25 kB
text/typescript
/*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2017-2019 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { FunctionComponent, ComponentClass } from 'react';
import Document from './dom/document-node';
import renderer from './renderer';
import * as Native from './native';
import { setRootContainer } from './utils/node';
import { trace, warn, setSilent, setBubbles, isDev } from './utils';
const {
createContainer,
updateContainer,
getPublicRootInstance,
injectIntoDevTools,
} = renderer;
interface HippyReactConfig {
/**
* Hippy app name, it's will register to `__GLOBAL__.appRegister` object,
* waiting the native load instance event for start the app.
*/
appName: string;
/**
* Entry component of Hippy app.
*/
entryPage: string | FunctionComponent<any> | ComponentClass<any, any>;
/**
* Disable trace output
*/
silent?: boolean;
/**
* enable global bubbles
*/
bubbles?: boolean;
/**
* The callback after rendering.
*/
callback?: () => void | undefined | null;
}
interface SuperProps {
__instanceId__: number;
}
const componentName = ['%c[Hippy-React process.env.HIPPY_REACT_VERSION]%c', 'color: #61dafb', 'color: auto'];
interface HippyReact {
config: HippyReactConfig;
rootContainer: any;
// Keep forward compatible.
regist: () => void;
}
class HippyReact implements HippyReact {
// version
public static version = process.env.HIPPY_REACT_VERSION as string;
// Native methods
public static get Native() {
warn('HippyReact.Native interface is not stable yet. DO NOT USE IT');
return Native;
}
/**
* Create new Hippy instance
*
* @param {Object} config - Hippy config.
* @param {string} config.appName - The name of Hippy app.
* @param {HippyReactConfig.entryPage} config.entryPage - The Entry page of Hippy app.
* @param {function} config.callback - The callback after rendering.
*/
public constructor(config: HippyReactConfig) {
if (!config.appName || !config.entryPage) {
throw new TypeError('Invalid arguments');
}
this.config = config;
this.regist = this.start; // Forward compatible alias
this.render = this.render.bind(this);
// Start Render
const rootDocument = new Document();
this.rootContainer = createContainer(rootDocument, 0, false, null);
}
/**
* Start hippy app execution.
*/
public start() {
Native.HippyRegister.regist(this.config.appName, this.render);
}
/**
* Native rendering callback
* @param {Object} superProps - The props passed by native start the app.
*/
private render(superProps: SuperProps) {
const {
appName,
entryPage,
silent = false,
bubbles = false,
callback = () => {},
} = this.config;
const { __instanceId__: rootViewId } = superProps;
trace(...componentName, 'Start', appName, 'with rootViewId', rootViewId, superProps);
if (isDev()) {
injectIntoDevTools({
bundleType: 1,
version: React.version,
rendererPackageName: 'hippy-react',
});
}
// Update nodeId for container
this.rootContainer.containerInfo.nodeId = rootViewId;
if (silent) {
setSilent(silent);
}
if (bubbles) {
setBubbles(bubbles);
}
// Save the root container
setRootContainer(rootViewId, this.rootContainer);
// Render to screen.
const rootElement = React.createElement(entryPage, superProps);
updateContainer(rootElement, this.rootContainer, null, callback);
return getPublicRootInstance(this.rootContainer);
}
}
export default HippyReact;