egreact
Version:
A react render for egret 一个为 egret 而生的 react 渲染器
1,537 lines (1,493 loc) • 77.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var reactContextBridge = require('react-context-bridge');
var constants = require('react-reconciler/constants');
var Reconciler = require('react-reconciler');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var Reconciler__default = /*#__PURE__*/_interopDefaultLegacy(Reconciler);
exports.CONSTANTS = void 0;
(function (CONSTANTS) {
CONSTANTS.PROP_MOUNT = '__PROP_MOUNT';
CONSTANTS.DEFAULT = '__default';
CONSTANTS.DEFAULT_REMOVE = `${CONSTANTS.DEFAULT}_remove`;
CONSTANTS.CUSTOM_DIFF_PREFIX = '__diff_';
CONSTANTS.INFO_KEY = '__renderInfo';
CONSTANTS.STATE_NODE_KEY = '__stateNode';
CONSTANTS.TARGET_KEY = '__target';
CONSTANTS.FIBER_KEY = '__fiber';
CONSTANTS.POOL_DEFAULT_SIZE = 300;
})(exports.CONSTANTS || (exports.CONSTANTS = {}));
const isProduction = process.env.NODE_ENV === 'production';
const isBrowser = typeof navigator !== 'undefined' &&
(navigator.product === 'ReactNative' || navigator.product === 'NativeScript' || navigator.product === 'NS')
? false
: typeof window !== 'undefined' && typeof document !== 'undefined';
const isBrowserDev = !isProduction && isBrowser;
class Config {
static ins = new Config();
constructor() {
return Config.ins;
}
errorHandler;
registerErrorHandler(errorHandler) {
this.errorHandler = errorHandler;
}
}
const config = Config.ins;
exports.EventProp = void 0;
(function (EventProp) {
EventProp.eventSetterWithType = () => {
const eventHandler = (props) => {
const { newValue, targetKey, eInfo } = props;
const instance = props.instance;
const memorizedListeners = instance.memorizedListeners || (instance.memorizedListeners = {});
const actualInstance = getActualInstance(instance);
const { type, once, capture, priority, keys } = eInfo;
const isMountEvent = !(targetKey in memorizedListeners);
const canDefaultTouchEnabled = keys.includes('Touch') &&
!('touchEnabled' in instance[exports.CONSTANTS.INFO_KEY].memoizedProps) &&
'touchEnabled' in actualInstance;
if (isMountEvent) {
if (canDefaultTouchEnabled) {
actualInstance.touchEnabled = true;
}
const innerListener = function (...args) {
memorizedListeners[targetKey][1].apply(this, args);
};
memorizedListeners[targetKey] = [innerListener, newValue];
actualInstance[once ? 'once' : 'addEventListener'](type, innerListener, actualInstance, capture, priority);
}
else {
memorizedListeners[targetKey][1] = newValue;
}
return (isRemove) => {
if (isRemove) {
if (canDefaultTouchEnabled) {
actualInstance.touchEnabled = false;
}
const innerListener = memorizedListeners[targetKey][0];
actualInstance.removeEventListener(type, innerListener, instance, capture);
delete memorizedListeners[targetKey];
}
};
};
return eventHandler;
};
EventProp.eventSetter = EventProp.eventSetterWithType();
EventProp.touchEventSetter = EventProp.eventSetterWithType();
EventProp.uiEventSetter = EventProp.eventSetterWithType();
EventProp.focusEventSetter = EventProp.eventSetterWithType();
EventProp.uiEventSetters = {
onUiResize: EventProp.uiEventSetter,
onUiResizeOnce: EventProp.uiEventSetter,
onUiMove: EventProp.uiEventSetter,
onUiMoveOnce: EventProp.uiEventSetter,
onUiCreationComplete: EventProp.uiEventSetter,
onUiCreationCompleteOnce: EventProp.uiEventSetter,
};
})(exports.EventProp || (exports.EventProp = {}));
exports.NormalProp = void 0;
(function (NormalProp) {
NormalProp.boo = ({ newValue, target, targetKey }) => ((target[targetKey] = newValue === 'false' ? false : Boolean(newValue)), void 0);
NormalProp.num = ({ newValue, target, targetKey }) => ((target[targetKey] = Number(newValue)), void 0);
NormalProp.str = ({ newValue, target, targetKey }) => ((target[targetKey] = String(newValue)), void 0);
NormalProp.pass = ({ newValue, target, targetKey }) => (!is.empty(target) && (target[targetKey] = newValue), void 0);
NormalProp.instance = (constructor) => ({ newValue, target, targetKey }) => {
if (newValue instanceof constructor) {
target[targetKey] = newValue;
}
else {
target[targetKey] = new constructor(...(is.arr(newValue) ? newValue : [newValue]));
}
};
NormalProp.flatArrDiffWithLevel = (level = Infinity) => {
const flatArr = (np, op) => {
if (np === op)
return true;
if (is.arr(np) && is.arr(op)) {
np = np.flat(level);
op = op.flat(level);
if (np.length !== op.length)
return false;
for (let i = 0; i < np.length; i++) {
if (np[i] !== op[i])
return false;
}
return true;
}
else
return false;
};
return flatArr;
};
})(exports.NormalProp || (exports.NormalProp = {}));
exports.Graphics = void 0;
(function (Graphics) {
Graphics.setter = ({ newValue, instance }) => {
if (is.arr(newValue)) {
for (const action of newValue) {
instance.graphics[action[0]](...action.slice(1));
}
return () => instance.graphics.clear();
}
else if (is.fun(newValue)) {
return newValue(instance.graphics, instance);
}
};
Graphics.diff = exports.NormalProp.flatArrDiffWithLevel(1);
})(exports.Graphics || (exports.Graphics = {}));
const graphicsProp = {
__Class: Object,
__setter: exports.Graphics.setter,
__diff: exports.Graphics.diff,
};
exports.Point = void 0;
(function (Point) {
Point.setter = exports.NormalProp.instance(egret.Point);
Point.diff = exports.NormalProp.flatArrDiffWithLevel();
})(exports.Point || (exports.Point = {}));
const pointProp = {
__Class: egret.Point,
__setter: exports.Point.setter,
__diff: exports.Point.diff,
x: exports.NormalProp.num,
y: exports.NormalProp.num,
};
exports.Rectangle = void 0;
(function (Rectangle) {
Rectangle.setter = exports.NormalProp.instance(egret.Rectangle);
Rectangle.diff = exports.NormalProp.flatArrDiffWithLevel();
})(exports.Rectangle || (exports.Rectangle = {}));
const rectangleProp = {
__Class: egret.Rectangle,
__setter: exports.Rectangle.setter,
__diff: exports.Rectangle.diff,
height: exports.NormalProp.num,
width: exports.NormalProp.num,
left: exports.NormalProp.num,
right: exports.NormalProp.num,
top: exports.NormalProp.num,
bottom: exports.NormalProp.num,
x: exports.NormalProp.num,
y: exports.NormalProp.num,
bottomRight: pointProp,
topLeft: pointProp,
};
exports.Mask = void 0;
(function (Mask) {
const rectSetter = exports.NormalProp.instance(egret.Rectangle);
Mask.setter = (props) => {
const { newValue } = props;
if (newValue instanceof egret.DisplayObject)
return exports.NormalProp.pass(props);
else
return rectSetter(props);
};
Mask.diff = exports.NormalProp.flatArrDiffWithLevel();
})(exports.Mask || (exports.Mask = {}));
const maskProp = {
...rectangleProp,
__setter: exports.Mask.setter,
__diff: exports.Mask.diff,
};
exports.Texture = void 0;
(function (Texture) {
Texture.setter = exports.NormalProp.instance(egret.Texture);
Texture.diff = exports.NormalProp.flatArrDiffWithLevel();
})(exports.Texture || (exports.Texture = {}));
const textureProp = {
__Class: egret.Texture,
__setter: exports.Texture.setter,
__diff: exports.Texture.diff,
bitmapData: (exports.NormalProp.pass),
disposeBitmapData: exports.NormalProp.boo,
};
const layoutBaseProp = {
__Class: eui.LayoutBase,
__setter: ({ newValue, target, targetKey }) => {
let value;
if (newValue === 'basic') {
value = new eui.BasicLayout();
}
else if (newValue === 'tile') {
value = new eui.TileLayout();
}
else if (newValue === 'horizontal') {
value = new eui.HorizontalLayout();
}
else if (newValue === 'vertical') {
value = new eui.VerticalLayout();
}
else if (newValue instanceof eui.LayoutBase) {
value = newValue;
}
else {
value = new eui.BasicLayout();
DevThrow(`The value of prop \`LayoutBase \` must be "basic" | "tile" | "horizontal" | "vertical" | eui.LayoutBase`);
}
target[targetKey] = value;
},
__diff: (a, b) => a === b,
horizontalAlign: exports.NormalProp.str,
verticalAlign: exports.NormalProp.str,
paddingBottom: exports.NormalProp.num,
paddingLeft: exports.NormalProp.num,
paddingRight: exports.NormalProp.num,
paddingTop: exports.NormalProp.num,
columnAlign: exports.NormalProp.str,
columnCount: exports.NormalProp.num,
columnWidth: exports.NormalProp.num,
horizontalGap: exports.NormalProp.num,
orientation: exports.NormalProp.str,
requestedColumnCount: exports.NormalProp.num,
requestedRowCount: exports.NormalProp.num,
rowAlign: exports.NormalProp.str,
rowCount: exports.NormalProp.num,
rowHeight: exports.NormalProp.num,
verticalGap: exports.NormalProp.num,
gap: exports.NormalProp.num,
useVirtualLayout: exports.NormalProp.boo,
};
const euiBaseLayoutProp = {
bottom: exports.NormalProp.num,
left: exports.NormalProp.num,
right: exports.NormalProp.num,
top: exports.NormalProp.num,
explicitHeight: exports.NormalProp.num,
explicitWidth: exports.NormalProp.num,
horizontalCenter: exports.NormalProp.str,
verticalCenter: exports.NormalProp.str,
includeInLayout: exports.NormalProp.boo,
maxHeight: exports.NormalProp.num,
maxWidth: exports.NormalProp.num,
minHeight: exports.NormalProp.num,
minWidth: exports.NormalProp.num,
percentHeight: exports.NormalProp.num,
percentWidth: exports.NormalProp.num,
...exports.EventProp.uiEventSetters,
};
var Mixin;
(function (Mixin) {
Mixin.mixin = (target, obj, ...key) => {
const entries = [];
const collectTranslateKey = (obj, prefixKey) => {
for (const [key, value] of Object.entries(obj)) {
if ('__setter' in value) {
collectTranslateKey(value, [...prefixKey, key]);
}
else {
entries.push([[...prefixKey, key], value]);
}
}
};
collectTranslateKey(obj, key);
const flattenObj = entries.reduce((obj, [keys, value]) => {
if (keys[keys.length - 1] === '__setter') {
keys.pop();
obj[keys.join('-')] = value;
}
else if (keys[keys.length - 1] === '__diff') {
keys.pop();
obj[exports.CONSTANTS.CUSTOM_DIFF_PREFIX + keys.join('-')] = value;
}
else {
obj[keys.join('-')] = value;
}
return obj;
}, {});
return { ...target, ...flattenObj };
};
})(Mixin || (Mixin = {}));
const mixinHelper = {
store: {},
set(target) {
return {
...this,
store: target,
};
},
mixin(obj, ...name) {
return {
...this,
store: Mixin.mixin(this.store, obj, name[0]),
};
},
get() {
return this.store;
},
};
const proxyHelper = (config) => {
let { constructor, targetKey = '__target', excludeKeys = ['__renderInfo'], setCallback = () => void 0, configs = {}, } = config;
excludeKeys = [...excludeKeys, '__renderInfo'];
const keys = targetKey.split('.');
targetKey = keys.pop();
const name = 'Proxy' + constructor.name;
let proxyConstructor = {
[name]: function (...args) {
const instance = new constructor(...args);
instance['$name'] = name;
return new Proxy(instance, {
set(target, p, value) {
if (p in target || excludeKeys.includes(p)) {
const oldValue = target[p];
target[p] = value;
setCallback.call(target, {
instance: target,
target: target,
propName: p,
value,
oldValue,
});
}
else {
const _target = target;
target = keys.reduce((t, p) => t[p], target);
const oldValue = target[targetKey][p];
target[targetKey][p] = value;
setCallback.call(_target, {
instance: _target,
target: target[targetKey],
propName: p,
value,
oldValue,
});
}
return true;
},
get(target, p) {
if (p in target)
return target[p];
else {
target = keys.reduce((t, p) => t[p], target);
return target[targetKey][p];
}
},
getPrototypeOf() {
return proxyConstructor.prototype;
},
...configs,
});
},
}[name];
return proxyConstructor;
};
function proxyGetPropsHandlers(target, key, receiver) {
if (key in target)
return Reflect.get(target, key, receiver);
else if (typeof key === 'symbol' || key.startsWith('__'))
return undefined;
else if (isEvent(key))
return exports.EventProp.eventSetter;
else
return exports.NormalProp.pass;
}
const normalEventType = [
'onChange',
'onChanging',
'onComplete',
'onAdded',
'onAddedToStage',
'onRemoved',
'onRemovedFromStage',
'onEnterFrame',
'onRender',
'onAddedOnce',
'onAddedToStageOnce',
'onRemovedOnce',
'onRemovedFromStageOnce',
'onEnterFrameOnce',
'onRenderOnce',
];
const touchEventType = ['onTouchMove', 'onTouchBegin', 'onTouchEnd', 'onTouchTap', 'onTouchReleaseOutside'];
const normalEventTypeSets = normalEventType.reduce((acc, key) => ((acc[key] = exports.EventProp.eventSetter), acc), {});
const touchEventTypeSets = touchEventType.reduce((acc, key) => ((acc[key] = exports.EventProp.touchEventSetter), acc), {});
const displayObjectPropsHandlers = mixinHelper
.set({
...touchEventTypeSets,
...normalEventTypeSets,
...{},
__Class: egret.DisplayObject,
width: ({ newValue, instance }) => {
const isPercent = typeof newValue === 'string' && newValue[newValue.length - 1] === '%';
if (isPercent)
instance.percentWidth = Number(newValue.replace('%', ''));
else
instance.width = Number(newValue);
return () => isPercent && (instance.percentWidth = null);
},
height: ({ newValue, instance }) => {
const isPercent = typeof newValue === 'string' && newValue[newValue.length - 1] === '%';
if (isPercent)
instance.percentHeight = Number(newValue.replace('%', ''));
else
instance.height = Number(newValue);
return () => isPercent && (instance.percentHeight = null);
},
x: exports.NormalProp.num,
y: exports.NormalProp.num,
zIndex: exports.NormalProp.num,
scaleX: exports.NormalProp.num,
scaleY: exports.NormalProp.num,
skewX: exports.NormalProp.num,
skewY: exports.NormalProp.num,
anchorOffsetX: exports.NormalProp.num,
anchorOffsetY: exports.NormalProp.num,
rotation: exports.NormalProp.num,
alpha: exports.NormalProp.num,
tint: exports.NormalProp.num,
visible: exports.NormalProp.boo,
touchEnabled: exports.NormalProp.boo,
sortableChildren: exports.NormalProp.boo,
cacheAsBitmap: exports.NormalProp.boo,
blendMode: exports.NormalProp.str,
name: exports.NormalProp.str,
matrix: (exports.NormalProp.pass),
filters: (exports.NormalProp.pass),
})
.mixin(maskProp, 'mask')
.mixin(rectangleProp, 'scrollRect')
.get();
const displayObjectContainerPropsHandlers = {
...displayObjectPropsHandlers,
__Class: egret.DisplayObjectContainer,
childrenSortMode: ({ newValue, instance }) => (instance.setChildrenSortMode?.(newValue),
(isRemove) => isRemove && instance.setChildrenSortMode?.('DEFAULT')),
};
const shapePropsHandlers = mixinHelper
.set({
...displayObjectPropsHandlers,
__Class: egret.Sprite,
})
.mixin(graphicsProp, 'graphics')
.get();
const spritePropsHandlers = mixinHelper
.set({
...displayObjectContainerPropsHandlers,
__Class: egret.Sprite
})
.mixin(graphicsProp, "graphics")
.get();
const bitmapPropsHandlers = mixinHelper
.set({
...displayObjectPropsHandlers,
...{},
__Class: egret.Bitmap,
pixelHitTest: exports.NormalProp.boo,
smoothing: exports.NormalProp.boo,
fillMode: exports.NormalProp.str,
})
.mixin(textureProp, 'texture')
.mixin(rectangleProp, 'scale9Grid')
.get();
const bitmapTextHandlers = {
...displayObjectPropsHandlers,
__Class: egret.BitmapText,
font: (exports.NormalProp.pass),
letterSpacing: exports.NormalProp.num,
lineSpacing: exports.NormalProp.num,
smoothing: exports.NormalProp.boo,
text: exports.NormalProp.str,
textAlign: exports.NormalProp.str,
verticalAlign: exports.NormalProp.str,
};
const TextContainerMap = new Map();
class TextNode {
_text;
container = { text: '' };
constructor(_text) {
this._text = _text;
}
setContainer(container) {
this.container = container;
if (container) {
if (!TextContainerMap.has(container))
TextContainerMap.set(container, []);
const children = TextContainerMap.get(container);
children.push(this);
this.updateContainerText();
}
}
removeContainer() {
const textNodes = TextContainerMap.get(this.container);
textNodes.splice(textNodes.indexOf(this), 1);
this.updateContainerText();
}
updateContainerText() {
const children = TextContainerMap.get(this.container);
this.container.text = children.reduce((s, c) => s + c.text, '');
}
set text(value) {
this._text = value;
this.updateContainerText();
}
get text() {
return this._text;
}
}
const detachTextContainer = (container) => {
if (TextContainerMap.has(container))
TextContainerMap.delete(container);
};
const focusEventTypeSetters = {
onFocusIn: exports.EventProp.focusEventSetter,
onFocusInOnce: exports.EventProp.focusEventSetter,
onFocusOut: exports.EventProp.focusEventSetter,
onFocusOutOnce: exports.EventProp.focusEventSetter,
};
const textFieldHandlers = {
...displayObjectPropsHandlers,
__Class: egret.TextField,
__detach: detachTextContainer,
background: exports.NormalProp.boo,
bold: exports.NormalProp.boo,
border: exports.NormalProp.boo,
italic: exports.NormalProp.boo,
displayAsPassword: exports.NormalProp.boo,
multiline: exports.NormalProp.boo,
wordWrap: exports.NormalProp.boo,
backgroundColor: exports.NormalProp.num,
borderColor: exports.NormalProp.num,
lineSpacing: exports.NormalProp.num,
maxChars: exports.NormalProp.num,
scrollV: exports.NormalProp.num,
maxScrollV: exports.NormalProp.num,
numLines: exports.NormalProp.num,
size: exports.NormalProp.num,
stroke: exports.NormalProp.num,
strokeColor: exports.NormalProp.num,
textColor: exports.NormalProp.num,
textHeight: exports.NormalProp.num,
textWidth: exports.NormalProp.num,
fontFamily: exports.NormalProp.str,
inputType: exports.NormalProp.str,
restrict: exports.NormalProp.str,
text: exports.NormalProp.str,
textAlign: exports.NormalProp.str,
verticalAlign: exports.NormalProp.str,
type: exports.NormalProp.str,
textFlow: (exports.NormalProp.pass),
...focusEventTypeSetters,
};
var egretProps = {
displayObject: displayObjectPropsHandlers,
displayObjectContainer: displayObjectContainerPropsHandlers,
shape: shapePropsHandlers,
sprite: spritePropsHandlers,
bitmap: bitmapPropsHandlers,
bitmapText: bitmapTextHandlers,
textField: textFieldHandlers,
};
const componentHandlers = {
...displayObjectContainerPropsHandlers,
...euiBaseLayoutProp,
__Class: eui.Component,
skinName: (exports.NormalProp.pass),
currentState: exports.NormalProp.str,
hostComponentKey: exports.NormalProp.str,
enabled: exports.NormalProp.boo,
skin: (exports.NormalProp.pass),
onComplete: exports.EventProp.eventSetter,
};
const uiComponentHandlers = {
...displayObjectPropsHandlers,
...euiBaseLayoutProp
};
const iViewport = {
...uiComponentHandlers,
contentHeight: exports.NormalProp.num,
contentWidth: exports.NormalProp.num,
scrollEnabled: exports.NormalProp.boo,
scrollH: exports.NormalProp.num,
scrollV: exports.NormalProp.num
};
const groupHandlers = mixinHelper
.set({
...iViewport,
__detach: (instance) => ((instance.scrollH = 0), (instance.scrollV = 0)),
__Class: eui.Group,
numElements: exports.NormalProp.num,
hasState: (exports.NormalProp.pass),
touchThrough: exports.NormalProp.boo,
})
.mixin(layoutBaseProp, 'layout')
.get();
const image = {
...bitmapPropsHandlers,
...euiBaseLayoutProp,
__Class: eui.Image,
source: (exports.NormalProp.pass),
onComplete: exports.EventProp.eventSetter,
};
const label = {
...textFieldHandlers,
...euiBaseLayoutProp,
__Class: eui.Label,
style: exports.NormalProp.str
};
const rect = mixinHelper
.set({
...componentHandlers,
__Class: eui.Rect,
ellipseHeight: exports.NormalProp.num,
ellipseWidth: exports.NormalProp.num,
fillAlpha: exports.NormalProp.num,
fillColor: exports.NormalProp.num,
strokeAlpha: exports.NormalProp.num,
strokeColor: exports.NormalProp.num,
strokeWeight: exports.NormalProp.num
})
.mixin(graphicsProp, "graphics")
.get();
const scrollerUiEventTypeSets = {
onUiChangeStart: exports.EventProp.uiEventSetter,
onUiChangeEnd: exports.EventProp.uiEventSetter,
};
const scrollerHandlers = {
...componentHandlers,
...scrollerUiEventTypeSets,
__Class: eui.Scroller,
bounces: exports.NormalProp.boo,
scrollPolicyH: exports.NormalProp.str,
scrollPolicyV: exports.NormalProp.str,
scrollThreshold: exports.NormalProp.num,
throwSpeed: exports.NormalProp.num,
viewport: (exports.NormalProp.pass),
horizontalScrollBar: (exports.NormalProp.pass),
verticalScrollBar: (exports.NormalProp.pass),
};
const bitmapLabel = {
...displayObjectPropsHandlers,
...euiBaseLayoutProp,
__Class: eui.BitmapLabel,
font: exports.NormalProp.pass,
letterSpacing: exports.NormalProp.num,
lineSpacing: exports.NormalProp.num,
smoothing: exports.NormalProp.boo,
text: exports.NormalProp.str,
textAlign: exports.NormalProp.str,
textHeight: exports.NormalProp.num,
textWidth: exports.NormalProp.num,
verticalAlign: exports.NormalProp.str
};
const buttonHandlers = {
...componentHandlers,
__Class: eui.Button,
label: exports.NormalProp.str,
icon: (exports.NormalProp.pass),
iconDisplay: (exports.NormalProp.pass),
labelDisplay: (exports.NormalProp.pass),
};
const editableTextHandlers = {
...textFieldHandlers,
...euiBaseLayoutProp,
__Class: eui.EditableText,
prompt: exports.NormalProp.str,
promptColor: exports.NormalProp.num,
};
const dataGroupHandlers = {
...groupHandlers,
__Class: eui.DataGroup,
dataProvider: (exports.NormalProp.pass),
itemRenderer: (exports.NormalProp.pass),
itemRendererFunction: (exports.NormalProp.pass),
itemRendererSkinName: (exports.NormalProp.pass),
};
const listHandlers = {
...dataGroupHandlers,
__Class: eui.List,
requireSelection: exports.NormalProp.boo,
allowMultipleSelection: exports.NormalProp.boo,
onItemTap: exports.EventProp.eventSetter,
};
class ItemRenderer {
constructor(...args) {
const props = args[args.length - 1];
const { object } = props;
if (object)
return object;
}
}
const itemRenderer = {
...componentHandlers,
__Class: ItemRenderer,
object() { },
};
var euiProps = {
component: componentHandlers,
group: groupHandlers,
image,
bitmapLabel,
label,
rect,
scroller: scrollerHandlers,
button: buttonHandlers,
editableText: editableTextHandlers,
dataGroup: dataGroupHandlers,
list: listHandlers,
itemRenderer,
};
class ArrayContainer {
__target = [];
addChild(child) {
this.__target.push(child);
}
removeChild(child) {
this.__target.splice(this.__target.indexOf(child), 1);
}
addChildAt(child, index) {
this.__target.splice(index, 0, child);
}
getChildIndex(child) {
return this.__target.indexOf(child);
}
reAttach() {
const _this = this;
if (_this[exports.CONSTANTS.INFO_KEY]?.targetInfo) {
this.__target = [...this.__target];
const [target, targetKey] = _this[exports.CONSTANTS.INFO_KEY].targetInfo;
target[targetKey] = this.__target;
}
}
}
const ArrayContainerProxy = proxyHelper({ constructor: ArrayContainer });
const arrayContainer = {
__Class: ArrayContainerProxy,
};
class ObjectContainer {
__target = {};
addChild() {
DevThrow(`\`objectContainer\` can't add child directly. Please add \`attach\` prop to child`);
}
reAttach() {
if (this[exports.CONSTANTS.INFO_KEY].targetInfo) {
this.__target = { ...this.__target };
const [target, targetKey] = this[exports.CONSTANTS.INFO_KEY].targetInfo;
target[targetKey] = this.__target;
}
}
}
const ObjectContainerProxy = proxyHelper({
constructor: ObjectContainer,
});
const objectContainer = {
__Class: ObjectContainerProxy,
};
const objectContainerProxy = new Proxy(objectContainer, {
get: proxyGetPropsHandlers,
});
const docLink = 'https://xingxinglieo.github.io/egreact/components/custom#primitive';
class Primitive$1 {
__target;
__isPrimitive = true;
constructor(...args) {
const props = args[args.length - 1];
const { object, constructor } = props;
if (object !== undefined && object !== null) {
this.__target = object;
}
else if (props.hasOwnProperty('constructor') && typeof constructor === 'function') {
this.__target = new constructor(...args.slice(0, -1));
}
else {
DevThrow(`\`primitive\` must have an \`object\` or a \`constructor\` prop`, {
from: 'primitive',
link: docLink,
});
}
}
get object() {
return this.__target;
}
addChild(child, childInstance) {
if (is.fun(this.__target.addChild)) {
this.__target.addChild(child, childInstance);
}
else {
DevThrow(`Please promise addChild method to ${this.__target.constructor.name}`, {
from: 'primitive',
});
}
}
removeChild(child, childInstance) {
if (is.fun(this.__target.removeChild)) {
this.__target.removeChild(child, childInstance);
}
else {
DevThrow(`Please promise removeChild method to ${this.__target.constructor.name}`, {
from: 'primitive',
});
}
}
addChildAt(child, index, childInstance) {
if (is.fun(this.__target.addChildAt)) {
this.__target.addChildAt(child, index, childInstance);
}
else {
DevThrow(`Please promise addChildAt method to ${this.__target.constructor.name}`, {
from: 'primitive',
});
}
}
getChildIndex(child, childInstance) {
if (is.fun(this.__target.getChildIndex)) {
return this.__target.getChildIndex(child, childInstance);
}
else {
DevThrow(`Please promise getChildIndex method to ${this.__target.constructor.name}`, {
from: 'primitive',
});
return 0;
}
}
}
const objectDiffKey = `${exports.CONSTANTS.CUSTOM_DIFF_PREFIX}object`;
const primitive = {
__Class: proxyHelper({
constructor: Primitive$1,
}),
object: ({}) => {
return (isRemove) => {
if (!isRemove) {
DevThrow(`Please use key to refresh object in primitive`, {
from: 'primitive',
link: docLink,
});
}
};
},
constructor: ({}) => {
return (isRemove) => {
if (!isRemove) {
DevThrow(`Please use key to refresh constructor in primitive`, {
from: 'primitive',
link: docLink,
});
}
};
},
[objectDiffKey]: (n, o) => n === o,
};
const primitiveProxy = new Proxy(primitive, {
get: proxyGetPropsHandlers,
});
class Font {
text = '';
style = {};
}
const font = {
__Class: proxyHelper({
constructor: Font,
excludeKeys: ['text'],
targetKey: 'style',
setCallback() {
const parent = this.__renderInfo.parent;
const caller = parent?.__isPrimitive ? getActualInstance(parent) : parent;
parent?.reAttach?.apply(caller);
},
}),
textColor: exports.NormalProp.num,
strokeColor: exports.NormalProp.num,
size: exports.NormalProp.num,
stroke: exports.NormalProp.num,
bold: exports.NormalProp.boo,
italic: exports.NormalProp.boo,
fontFamily: exports.NormalProp.str,
href: exports.NormalProp.str,
target: exports.NormalProp.str,
underline: exports.NormalProp.boo,
text: exports.NormalProp.str,
};
class Anchor extends eui.Label {
}
const aTag = {
...label,
__Class: eui.Label,
href: () => void 0,
onClick: ({ newValue, instance }) => {
const value = (e) => {
e.button = 0;
newValue(e);
};
instance.addEventListener(egret.TouchEvent.TOUCH_TAP, value, instance);
instance.touchEnabled = true;
return () => {
instance.removeEventListener(egret.TouchEvent.TOUCH_TAP, value, instance);
};
},
};
var customProps = {
objectContainer: objectContainerProxy,
arrayContainer,
primitive: primitiveProxy,
font,
a: aTag,
};
exports.catalogueMap = {};
const extend = (newCatalogue) => {
return (exports.catalogueMap = { ...exports.catalogueMap, ...newCatalogue });
};
const EVENT_CATEGORY_MAP = {
Touch: {
category: egret.TouchEvent,
withPrefix: true,
},
Item: {
category: eui.ItemTapEvent,
withPrefix: true,
},
Ui: {
category: eui.UIEvent,
withPrefix: false,
},
Focus: {
category: egret.FocusEvent,
withPrefix: true,
},
};
extend({
...Object.entries({ ...egretProps, ...customProps }).reduce((acc, [key, val]) => {
acc[key] = val;
return acc;
}, {}),
...Object.keys(euiProps).reduce((acc, key) => {
acc[`eui-${key}`] = euiProps[key];
return acc;
}, {}),
});
function findTargetByPosition(displayObject, stageX, stageY) {
if (!displayObject.visible) {
return null;
}
const matrix = displayObject.$getInvertedConcatenatedMatrix();
const x = matrix.a * stageX + matrix.c * stageY + matrix.tx;
const y = matrix.b * stageX + matrix.d * stageY + matrix.ty;
const rect = displayObject.$scrollRect ? displayObject.$scrollRect : displayObject.$maskRect;
if (rect && !rect.contains(x, y)) {
return null;
}
if (this?.$mask && !displayObject.$mask.$hitTest(stageX, stageY)) {
return null;
}
const children = displayObject.$children;
let notTouchThrough = false;
var target = null;
if (children) {
for (let index = children.length - 1; index >= 0; index--) {
const child = children[index];
if (child.$maskedObject) {
continue;
}
target = findTargetByPosition(child, stageX, stageY);
if (target && target.ispTouchThrough !== true) {
notTouchThrough = true;
break;
}
}
}
if (target) {
return target;
}
if (notTouchThrough) {
return displayObject;
}
return displayObject.$hitTest(stageX, stageY);
}
function getEventPriority(domEventName) {
switch (domEventName) {
case 'cancel':
case 'click':
case 'close':
case 'contextmenu':
case 'copy':
case 'cut':
case 'auxclick':
case 'dblclick':
case 'dragend':
case 'dragstart':
case 'drop':
case 'focusin':
case 'focusout':
case 'input':
case 'invalid':
case 'keydown':
case 'keypress':
case 'keyup':
case 'mousedown':
case 'mouseup':
case 'paste':
case 'pause':
case 'play':
case 'pointercancel':
case 'pointerdown':
case 'pointerup':
case 'ratechange':
case 'reset':
case 'resize':
case 'seeked':
case 'submit':
case 'touchcancel':
case 'touchend':
case 'touchstart':
case 'volumechange':
case 'change':
case 'selectionchange':
case 'textInput':
case 'compositionstart':
case 'compositionend':
case 'compositionupdate':
case 'beforeblur':
case 'afterblur':
case 'beforeinput':
case 'blur':
case 'fullscreenchange':
case 'focus':
case 'hashchange':
case 'popstate':
case 'select':
case 'selectstart':
return constants.DiscreteEventPriority;
case 'drag':
case 'dragenter':
case 'dragexit':
case 'dragleave':
case 'dragover':
case 'mousemove':
case 'mouseout':
case 'mouseover':
case 'pointermove':
case 'pointerout':
case 'pointerover':
case 'scroll':
case 'toggle':
case 'touchmove':
case 'wheel':
case 'mouseenter':
case 'mouseleave':
case 'pointerenter':
case 'pointerleave':
return constants.ContinuousEventPriority;
default:
return constants.DefaultEventPriority;
}
}
const defaultOnRecoverableError = typeof reportError === 'function'
?
reportError
: (error) => {
console['error'](error);
};
function throttle(func, wait) {
let previous = 0;
let res;
return function (...args) {
let now = +new Date();
let remain = wait - (now - previous);
if (remain < 0) {
previous = now;
return (res = func.apply(this, args));
}
else
return res;
};
}
const hyphenateRE = /\B([A-Z])/g;
function hyphenate(str) {
return str.replace(hyphenateRE, '-$1').toLowerCase();
}
const isEvent = (key) => /^on(([A-Z]|-)[a-z]+)+\d*$/.test(key);
const isMountProp = (value) => value === exports.CONSTANTS.PROP_MOUNT;
const DevThrow = (e, options = {}) => {
const { from, link, toThrow = false } = options;
const prefix = `Egreact${from ? `(from \`${from}\`)` : ''}:`;
const suffix = link && !isProduction ? `,\nsee ${link}` : '';
if (e instanceof Error)
e.message = prefix + e.message + suffix;
else
e = prefix + e + suffix;
if (is.fun(config.errorHandler)) {
config.errorHandler(e);
}
else if (!isProduction) {
throw e;
}
if (toThrow) {
throw e;
}
};
function getActualInstance(instance) {
return instance.__target ?? instance;
}
function getCanvas() {
return document.querySelector('.egret-player > canvas');
}
const is = {
obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== 'function',
fun: (a) => typeof a === 'function',
str: (a) => typeof a === 'string',
num: (a) => typeof a === 'number',
boo: (a) => typeof a === 'boolean',
und: (a) => a === void 0,
arr: (a) => Array.isArray(a),
empty: (a) => a === undefined || a === null,
equ(a, b, { arrays = 'shallow', objects = 'reference', strict = true } = {}) {
if (typeof a !== typeof b || !!a !== !!b)
return false;
if (is.str(a) || is.num(a) || is.fun(a))
return a === b;
const isObj = is.obj(a);
if (isObj && objects === 'reference')
return a === b;
const isArr = is.arr(a);
if (isArr && arrays === 'reference')
return a === b;
if ((isArr || isObj) && a === b)
return true;
let i;
for (i in a)
if (!(i in b))
return false;
for (i in strict ? b : a)
if (a[i] !== b[i])
return false;
if (is.und(i)) {
if (isArr && a.length === 0 && b.length === 0)
return true;
if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0)
return true;
return a === b;
}
return true;
},
};
function findEgretAncestor(o) {
while (!(getActualInstance(o) instanceof egret.DisplayObject)) {
let fiber = o[exports.CONSTANTS.INFO_KEY].fiber.return;
while (fiber && fiber.stateNode === null) {
fiber = fiber.return;
}
if (fiber)
o = fiber.stateNode;
}
return getActualInstance(o);
}
function reduceKeysToTarget(target, key, separator = '-') {
const prefixKeys = key.split(separator);
const targetKey = prefixKeys.pop();
try {
target = prefixKeys.reduce((target, key) => target[key], target);
if (target instanceof Object) {
return [target, targetKey, prefixKeys];
}
}
catch (e) { }
return [null, targetKey, prefixKeys];
}
const DEFAULT_EVENT_CATEGORY = egret.Event;
const eventReg = /((([A-Z]|-)[a-z]+)|([0-9]+))/g;
function splitEventKeyToInfo(key) {
const words = [];
const info = {
type: '',
name: '',
once: false,
capture: false,
priority: 0,
keys: [],
};
key.replace(eventReg, (match) => (words.push(match.replace('-', '')), ''));
info.keys = [...words];
const endIndex = Math.max(words.length - 3, 0);
for (let i = words.length - 1; i >= endIndex; i--) {
let word = words[i];
if (/^\d+$/.test(word)) {
info.priority = parseInt(word);
words.pop();
word = words[--i];
}
if (word === 'Capture') {
info.capture = true;
words.pop();
word = words[--i];
}
if (word === 'Once') {
info.once = true;
words.pop();
word = words[--i];
}
}
info.name = `on${words.join('')}`;
let category;
if (Object.keys(EVENT_CATEGORY_MAP).includes(words[0]) && EVENT_CATEGORY_MAP[words[0]]) {
const categoryInfo = EVENT_CATEGORY_MAP[words[0]];
if (!categoryInfo.withPrefix)
words.shift();
category = categoryInfo.category;
}
else {
category = DEFAULT_EVENT_CATEGORY;
}
info.type = category[words.join('_').toUpperCase()] ?? words.join('');
return info;
}
function collectContextsFromDom(dom) {
if (!(dom instanceof HTMLElement)) {
console.error(`prop is not a HTMLElement`);
return [];
}
const fiberKey = Object.keys(dom).find((key) => key.startsWith('__react') && dom[key]?.stateNode === dom);
if (!fiberKey) {
console.error(`dom must be created by react-dom`);
return [];
}
let fiber = dom[fiberKey];
const contexts = [];
while (fiber) {
if (fiber.type?._context) {
contexts.push(fiber.type._context);
}
fiber = fiber.return;
}
return contexts;
}
var name = "egreact";
var version = "1.4.0";
var description = "A react render for egret 一个为 egret 而生的 react 渲染器";
var keywords = [
"react",
"reactjs",
"egret",
"egreact"
];
var author = "xingyu.hu(https://github.com/xingxinglieo)";
var repository = "https://github.com/xingxinglieo/egreact";
var bugs = "https://github.com/xingxinglieo/egreact/issues";
var homepage = "https://xingxinglieo.github.io/egreact";
var module$1 = "dist/index.esm.js";
var main = "dist/index.cjs.js";
var types = "dist/src/index.d.ts";
var files = [
"dist",
"src"
];
var scripts = {
test: "jest --silent --detect-open-handles",
build: "rollup -c",
dev: "rollup -c -w"
};
var license = "ISC";
var publishConfig = {
access: "public"
};
var dependencies = {
"@types/react": "^18.0.19",
react: ">=18.0",
"react-context-bridge": "^0.0.5",
"react-reconciler": "^0.27.0",
typescript: "^4.7.3"
};
var peerDependenciesMeta = {
};
var devDependencies = {
"@babel/core": "^7.18.2",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-typescript": "^8.3.4",
"@types/node": "^17.0.42",
"@types/sinon": "^10.0.11",
concurrently: "^7.2.2",
jest: "^29.0.3",
rollup: "^2.75.6",
sinon: "^14.0.0",
"ts-jest": "^29.0.0",
tslib: "^2.4.0"
};
var sideEffects = false;
var packageJson = {
name: name,
version: version,
description: description,
keywords: keywords,
author: author,
repository: repository,
bugs: bugs,
homepage: homepage,
module: module$1,
main: main,
types: types,
files: files,
scripts: scripts,
license: license,
publishConfig: publishConfig,
dependencies: dependencies,
peerDependenciesMeta: peerDependenciesMeta,
devDependencies: devDependencies,
sideEffects: sideEffects
};
function calculateScale() {
const canvas = getCanvas();
const rect = canvas.getBoundingClientRect();
return rect.width / egret.lifecycle.stage.stageWidth;
}
const [storeOriginComputedStyle, getOriginComputedStyle] = (function () {
var getComputedStyle;
return [() => getComputedStyle || (getComputedStyle = window.getComputedStyle), () => getComputedStyle];
})();
const getEmptyCSSStyleSheet = (function () {
var emptyCSSStyleSheet;
return () => emptyCSSStyleSheet ||
(emptyCSSStyleSheet = {
...getOriginComputedStyle()(document.createElement('div')),
borderLeftWidth: '0',
borderRightWidth: '0',
borderTopWidth: '0',
borderBottomWidth: '0',
marginLeft: '0',
marginRight: '0',
marginTop: '0',
marginBottom: '0',
paddingLeft: '0',
paddingRight: '0',
paddingTop: '0',
paddingBottom: '0',
});
})();
let latestEgretRect = { w: 0, h: 0, x: 0, y: 0 };
function getBoundingClientRect(instance) {
const egretInstance = findEgretAncestor(instance);
const canvasRect = getCanvas().getBoundingClientRect();
if (!egretInstance)
return canvasRect;
const point = egretInstance.localToGlobal(0, 0);
const scale = calculateScale();
const x = point.x * scale + canvasRect.left;
const y = point.y * scale + canvasRect.top;
const width = egretInstance.width * scale;
const height = egretInstance.height * scale;
latestEgretRect = { w: instance.width, h: instance.height, x: instance.x, y: instance.y };
return { x, y, width, height, left: x, top: y };
}
let isSelectedEgret = false;
function proxyGetComputedStyle() {
storeOriginComputedStyle();
window.getComputedStyle = function (el, pseudo) {
if (Object.entries(exports.catalogueMap).some(([n, catalogue]) => catalogue.__Class && el instanceof catalogue.__Class)) {
isSelectedEgret = true;
return getEmptyCSSStyleSheet();
}
else {
isSelectedEgret = false;
return getOriginComputedStyle().call(this, el, pseudo);
}
};
}
function unProxyGetComputedStyle() {
window.getComputedStyle = getOriginComputedStyle();
}
const [storeOriginListeners, getOriginListeners] = (function () {
var listeners;
return [
() => listeners ||
(listeners = { addEventListener: window.addEventListener, removeEventListener: window.removeEventListener }),
() => listeners,
];
})();
const eventInfoCollection = [];
function findMatchEventIndex([type1, handler1, options1], collection = eventInfoCollection) {
return collection.findIndex(([type2, handler2, options2]) => {
const capture1 = typeof options1 === 'boolean' ? options1 : options1?.capture ?? false;
const capture2 = typeof options2 === 'boolean' ? options2 : options2?.capture ?? false;
if (type1 === type2 && handler1 === handler2 && capture1 === capture2) {
return true;
}
return false;
});
}
function extraMatchEvent(info) {
const index = findMatchEventIndex(info);
if (index > -1) {
return eventInfoCollection.splice(index, 1)[0];
}
else
return null;
}
let rafId = null;
function specifiedShadowInfoForEgret() {
const shadows = document.querySelectorAll('div[style^="z-index: 10000000;"]');
for (let i = 0; i < shadows.length; i++) {
const shadow = shadows[i];
if (i === 0) {
shadow.style.display = 'block';
const rectSpan = shadow.firstChild?.lastChild;
if (isSelectedEgret && rectSpan)
rectSpan.textContent = `w:${latestEgretRect.w} h:${latestEgretRect.h} x:${latestEgretRect.x} y:${latestEgretRect.y} (in egret)`;
}
else
shadow.style.display = 'none';
}
rafId = requestAnimationFrame(specifiedShadowInfoForEgret);
}
function proxyListener() {
if (!rafId) {
rafId = requestAnimationFrame(specifiedShadowInfoForEgret);
}
storeOriginListeners();
window.addEventListener = function (type, listener, options) {
if (is.fun(listener) &&
['click', 'mousedown', 'mouseover', 'mouseup', 'pointerdown', 'pointerover', 'pointerup'].includes(type)) {
const proxyHandler = function (e) {
const { pageX: x, pageY: y } = e;
const r = getCanvas().getBoundingClientRect();
r.x += window.scrollX;
r.y += window.scrollY;
let target = null;
if (x > r.x && x < r.x + r.width && y > r.y && y < r.y + r.height) {
const scale = calculateScale();
target = findTargetByPosition(egret.lifecycle.stage, (x - r.x) / scale, (y - r.y) / scale);
if (target) {
e = {
...e,
preventDefault: e.preventDefault.bind(e),
stopPropagation: e.stopPropagation.bind(e),
target: target,
};
}
}
listener.call(this, e);
};
if (findMatchEventIndex([type, listener, options]) === -1) {
getOriginListeners().addEventListener.call(window, type, proxyHandler, options);
const info = [type, listener, options, proxyHandler];
if (type === 'pointerover') {
const throttlerProxyHandler = throttle(proxyHandler, 150);
const canvas = getCanvas();
canvas.addEventListener('pointermove', throttlerProxyHandler, options);
info.push(throttlerProxyHandler);
}
eventInfoCollection.push(info);
}
}
else {
getOriginListeners().addEventListener.call(window, type, listener, options);
}
};
window.removeEventListener = function (type, listener, options = false) {
if (is.fun(listener)) {
const info = extraMatchEvent([type, listener, options]);
if (info) {
getOriginListeners().removeEventListener.call(window, type, info[3], options);
if (type === 'pointerover' && info[4]) {
getCanvas().removeEventListener('pointermove', info[4], options);
}
}
else {
getOriginListeners().removeEventListener.call(window, type, listener, options);
}
}
else {
getOriginListeners().removeEventListener.call(window, type, listener, options);
}
};
}
function unProxyListener() {
if (rafId) {