@haiku/player
Version:
Haiku Player is a JavaScript library for building user interfaces
252 lines • 10.6 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var ReactDOM = require("react-dom");
var EventsDict_1 = require("./EventsDict");
var DEFAULT_HOST_ELEMENT_TAG_NAME = 'div';
var HAIKU_FORWARDED_PROPS = {
haikuOptions: 'options',
haikuStates: 'states',
haikuInitialStates: 'states',
haikuEventHandlers: 'eventHandlers',
haikuTimelines: 'timelines',
haikuVanities: 'vanities',
};
var VALID_PROPS = {
tagName: 'string',
id: 'string',
className: 'string',
style: 'object',
width: 'string',
height: 'string',
onComponentWillMount: 'func',
onComponentWillUnmount: 'func',
onComponentDidMount: 'func',
onHaikuComponentWillInitialize: 'func',
onHaikuComponentDidMount: 'func',
onHaikuComponentDidInitialize: 'func',
onHaikuComponentWillUnmount: 'func',
haikuAdapter: 'func',
haikuCode: 'object',
};
var REACT_ELEMENT_PROPS_TO_OMIT = {
onComponentWillMount: true,
onComponentWillUnmount: true,
onComponentDidMount: true,
onHaikuComponentWillInitialize: true,
onHaikuComponentDidMount: true,
onHaikuComponentDidInitialize: true,
onHaikuComponentWillUnmount: true,
haikuAdapter: true,
haikuCode: true,
};
for (var eventKey in EventsDict_1.default) {
VALID_PROPS[eventKey] = EventsDict_1.default[eventKey];
}
for (var fwdPropKey in HAIKU_FORWARDED_PROPS) {
VALID_PROPS[fwdPropKey] = 'object';
}
function HaikuReactDOMAdapter(haikuComponentFactory, optionalRawBytecode) {
var HaikuReactComponentInternal = (function (_super) {
__extends(HaikuReactComponentInternal, _super);
function HaikuReactComponentInternal(props) {
var _this = _super.call(this, props) || this;
_this.state = {
randomId: 'haiku-reactroot-' + randomString(24),
};
return _this;
}
HaikuReactComponentInternal.prototype.componentWillReceiveProps = function (nextPropsRaw) {
if (this.haiku) {
var haikuConfig = this.buildHaikuCompatibleConfigFromRawProps(nextPropsRaw);
this.haiku.assignConfig(haikuConfig);
}
};
HaikuReactComponentInternal.prototype.componentWillMount = function () {
if (this.props.onComponentWillMount) {
this.props.onComponentWillMount(this);
}
};
HaikuReactComponentInternal.prototype.componentWillUnmount = function () {
if (this.props.onComponentWillUnmount) {
this.props.onComponentWillUnmount(this);
}
if (this.haiku) {
this.haiku.callUnmount();
}
};
HaikuReactComponentInternal.prototype.componentDidMount = function () {
this.attemptMount();
};
HaikuReactComponentInternal.prototype.attemptMount = function () {
if (this.mount) {
this.createContext(this.props);
if (this.props.onComponentDidMount) {
this.props.onComponentDidMount(this, this.mount);
}
}
};
HaikuReactComponentInternal.prototype.buildHaikuCompatibleConfigFromRawProps = function (rawProps) {
var haikuConfig = {
ref: this.mount,
vanities: {
'controlFlow.placeholder': function _controlFlowPlaceholderReactVanity(element, surrogate, value, context, component) {
visit(this.mount, function (node) {
var flexId = flexIdIfSame(element, node);
if (flexId) {
if (!component._didElementRenderSurrogate(element, surrogate)) {
if (typeof surrogate.type === 'string' ||
(typeof surrogate.type === 'function' && surrogate.type.isHaikuAdapter)) {
var div = document.createElement('div');
node.parentNode.replaceChild(div, node);
node = div;
element.elementName = 'div';
}
node.style.visibility = 'hidden';
ReactDOM.render(surrogate, node);
window.requestAnimationFrame(function () {
component._markElementSurrogateAsRendered(element, surrogate);
node.style.visibility = 'visible';
});
component._markHorizonElement(element);
component._markForFullFlush();
}
}
});
}.bind(this),
},
};
if (rawProps) {
for (var verboseKeyName in rawProps) {
var haikuConfigFinalKey = HAIKU_FORWARDED_PROPS[verboseKeyName];
if (haikuConfigFinalKey) {
haikuConfig[haikuConfigFinalKey] = rawProps[verboseKeyName];
}
else {
haikuConfig[verboseKeyName] = rawProps[verboseKeyName];
}
}
}
return haikuConfig;
};
HaikuReactComponentInternal.prototype.createContext = function (rawProps) {
var haikuConfig = this.buildHaikuCompatibleConfigFromRawProps(rawProps);
var haikuAdapter;
if (rawProps.haikuAdapter) {
if (rawProps.haikuCode) {
haikuAdapter = rawProps.haikuAdapter(rawProps.haikuCode);
}
else if (optionalRawBytecode) {
haikuAdapter = rawProps.haikuAdapter(optionalRawBytecode);
}
else {
throw new Error('A Haiku code object is required if you supply a Haiku adapter');
}
}
else {
haikuAdapter = haikuComponentFactory;
}
if (!haikuAdapter) {
throw new Error('A Haiku adapter is required');
}
if (!this.haiku) {
this.haiku = haikuAdapter(this.mount, haikuConfig);
}
else {
this.haiku.callRemount(haikuConfig);
}
};
HaikuReactComponentInternal.prototype.createEventPropWrapper = function (eventListener) {
return function _eventPropWrapper(proxy, event) {
return eventListener.call(this, proxy, event, this.haiku);
}.bind(this);
};
HaikuReactComponentInternal.prototype.buildHostElementPropsFromRawProps = function (rawProps) {
var propsForHostElement = {};
for (var key in rawProps) {
if (VALID_PROPS[key]) {
if (EventsDict_1.default[key]) {
propsForHostElement[key] = this.createEventPropWrapper(rawProps[key]);
}
else if (!HAIKU_FORWARDED_PROPS[key]) {
if (!REACT_ELEMENT_PROPS_TO_OMIT[key]) {
propsForHostElement[key] = rawProps[key];
}
}
}
}
var stylesForHostElement = propsForHostElement.style || {};
delete propsForHostElement.style;
return __assign({ id: this.state.randomId, style: __assign({ position: 'relative', margin: 0, padding: 0, border: 0, width: '100%', height: '100%', transform: 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)' }, stylesForHostElement) }, propsForHostElement);
};
HaikuReactComponentInternal.prototype.assignMountFromRef = function (element) {
this.mount = element;
};
HaikuReactComponentInternal.prototype.render = function () {
var _this = this;
var hostElementProps = this.buildHostElementPropsFromRawProps(this.props);
hostElementProps.ref = function (element) {
_this.assignMountFromRef(element);
};
return React.createElement(hostElementProps.tagName || DEFAULT_HOST_ELEMENT_TAG_NAME, hostElementProps);
};
HaikuReactComponentInternal.React = React;
HaikuReactComponentInternal.ReactDOM = ReactDOM;
HaikuReactComponentInternal.isHaikuAdapter = true;
return HaikuReactComponentInternal;
}(React.Component));
return HaikuReactComponentInternal;
}
exports.default = HaikuReactDOMAdapter;
var ALPHABET = 'abcdefghijklmnopqrstuvwxyz';
function randomString(len) {
var str = '';
while (str.length < len) {
str += ALPHABET[Math.floor(Math.random() * ALPHABET.length)];
}
return str;
}
function visit(el, visitor) {
if (el) {
visitor(el);
if (el.children) {
for (var i = 0; i < el.children.length; i++) {
visit(el.children[i], visitor);
}
}
}
}
function flexIdIfSame(virtual, dom) {
if (virtual.attributes) {
if (virtual.attributes['haiku-id']) {
if (dom.getAttribute('haiku-id') === virtual.attributes['haiku-id']) {
return virtual.attributes['haiku-id'];
}
}
if (virtual.attributes.id) {
if (dom.getAttribute('id') === virtual.attributes.id) {
return virtual.attributes.id;
}
}
}
return null;
}
//# sourceMappingURL=HaikuReactDOMAdapter.js.map