UNPKG

@haiku/player

Version:

Haiku Player is a JavaScript library for building user interfaces

252 lines 10.6 kB
"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