Advertisement
Guest User

Untitled

a guest
May 21st, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 102.02 KB | None | 0 0
  1. module SomeThing = {
  2. #1 SomeThing
  3.  
  4. let x = 30;
  5. let z = 10;
  6.  
  7. };
  8.  
  9. module OtherThing = {
  10. #1 OtherThing
  11. let y = SomeThing.x;
  12.  
  13. };
  14.  
  15. module ReactEventRe = {
  16. #1 ReactEventRe
  17. type synthetic('a);
  18.  
  19. module MakeSyntheticWrapper = (Type: {type t;}) => {
  20. [@bs.get] external bubbles : Type.t => bool = "";
  21. [@bs.get] external cancelable : Type.t => bool = "";
  22. [@bs.get] external currentTarget : Type.t => Dom.element = ""; /* Should return Dom.evetTarget */
  23. [@bs.get] external defaultPrevented : Type.t => bool = "";
  24. [@bs.get] external eventPhase : Type.t => int = "";
  25. [@bs.get] external isTrusted : Type.t => bool = "";
  26. [@bs.get] external nativeEvent : Type.t => Js.t({..}) = ""; /* Should return Dom.event */
  27. [@bs.send.pipe: Type.t] external preventDefault : unit = "";
  28. [@bs.send.pipe: Type.t] external isDefaultPrevented : bool = "";
  29. [@bs.send.pipe: Type.t] external stopPropagation : unit = "";
  30. [@bs.send.pipe: Type.t] external isPropagationStopped : bool = "";
  31. [@bs.get] external target : Type.t => Dom.element = ""; /* Should return Dom.evetTarget */
  32. [@bs.get] external timeStamp : Type.t => float = "";
  33. [@bs.get] external _type : Type.t => string = "type";
  34. [@bs.send.pipe: Type.t] external persist : unit = "";
  35. };
  36.  
  37. module Synthetic = {
  38. type tag;
  39. type t = synthetic(tag);
  40. [@bs.get] external bubbles : synthetic('a) => bool = "";
  41. [@bs.get] external cancelable : synthetic('a) => bool = "";
  42. [@bs.get] external currentTarget : synthetic('a) => Dom.element = ""; /* Should return Dom.evetTarget */
  43. [@bs.get] external defaultPrevented : synthetic('a) => bool = "";
  44. [@bs.get] external eventPhase : synthetic('a) => int = "";
  45. [@bs.get] external isTrusted : synthetic('a) => bool = "";
  46. [@bs.get] external nativeEvent : synthetic('a) => Js.t({..}) = ""; /* Should return Dom.event */
  47. [@bs.send.pipe: synthetic('a)] external preventDefault : unit = "";
  48. [@bs.send.pipe: synthetic('a)] external isDefaultPrevented : bool = "";
  49. [@bs.send.pipe: synthetic('a)] external stopPropagation : unit = "";
  50. [@bs.send.pipe: synthetic('a)] external isPropagationStopped : bool = "";
  51. [@bs.get] external target : synthetic('a) => Dom.element = ""; /* Should return Dom.evetTarget */
  52. [@bs.get] external timeStamp : synthetic('a) => float = "";
  53. [@bs.get] external _type : synthetic('a) => string = "type";
  54. [@bs.send.pipe: synthetic('a)] external persist : unit = "";
  55. };
  56.  
  57. /* Cast any event type to the general synthetic type. This is safe, since synthetic is more general */
  58. external toSyntheticEvent : synthetic('a) => Synthetic.t = "%identity";
  59.  
  60. module Clipboard = {
  61. type tag;
  62. type t = synthetic(tag);
  63. include
  64. MakeSyntheticWrapper(
  65. {
  66. type nonrec t = t;
  67. },
  68. );
  69. [@bs.get] external clipboardData : t => Js.t({..}) = ""; /* Should return Dom.dataTransfer */
  70. };
  71.  
  72. module Composition = {
  73. type tag;
  74. type t = synthetic(tag);
  75. include
  76. MakeSyntheticWrapper(
  77. {
  78. type nonrec t = t;
  79. },
  80. );
  81. [@bs.get] external data : t => string = "";
  82. };
  83.  
  84. module Keyboard = {
  85. type tag;
  86. type t = synthetic(tag);
  87. include
  88. MakeSyntheticWrapper(
  89. {
  90. type nonrec t = t;
  91. },
  92. );
  93. [@bs.get] external altKey : t => bool = "";
  94. [@bs.get] external charCode : t => int = "";
  95. [@bs.get] external ctrlKey : t => bool = "";
  96. [@bs.send.pipe: t] external getModifierState : string => bool = "";
  97. [@bs.get] external key : t => string = "";
  98. [@bs.get] external keyCode : t => int = "";
  99. [@bs.get] external locale : t => string = "";
  100. [@bs.get] external location : t => int = "";
  101. [@bs.get] external metaKey : t => bool = "";
  102. [@bs.get] external repeat : t => bool = "";
  103. [@bs.get] external shiftKey : t => bool = "";
  104. [@bs.get] external which : t => int = "";
  105. };
  106.  
  107. module Focus = {
  108. type tag;
  109. type t = synthetic(tag);
  110. include
  111. MakeSyntheticWrapper(
  112. {
  113. type nonrec t = t;
  114. },
  115. );
  116. [@bs.get] external relatedTarget : t => Dom.element = ""; /* Should return Dom.eventTarget */
  117. };
  118.  
  119. module Form = {
  120. type tag;
  121. type t = synthetic(tag);
  122. include
  123. MakeSyntheticWrapper(
  124. {
  125. type nonrec t = t;
  126. },
  127. );
  128. };
  129.  
  130. module Mouse = {
  131. type tag;
  132. type t = synthetic(tag);
  133. include
  134. MakeSyntheticWrapper(
  135. {
  136. type nonrec t = t;
  137. },
  138. );
  139. [@bs.get] external altKey : t => bool = "";
  140. [@bs.get] external button : t => int = "";
  141. [@bs.get] external buttons : t => int = "";
  142. [@bs.get] external clientX : t => int = "";
  143. [@bs.get] external clientY : t => int = "";
  144. [@bs.get] external ctrlKey : t => bool = "";
  145. [@bs.send.pipe: t] external getModifierState : string => bool = "";
  146. [@bs.get] external metaKey : t => bool = "";
  147. [@bs.get] external pageX : t => int = "";
  148. [@bs.get] external pageY : t => int = "";
  149. [@bs.get] external relatedTarget : t => Dom.element = ""; /* Should return Dom.eventTarget */
  150. [@bs.get] external screenX : t => int = "";
  151. [@bs.get] external screenY : t => int = "";
  152. [@bs.get] external shiftKey : t => bool = "";
  153. };
  154.  
  155. module Selection = {
  156. type tag;
  157. type t = synthetic(tag);
  158. include
  159. MakeSyntheticWrapper(
  160. {
  161. type nonrec t = t;
  162. },
  163. );
  164. };
  165.  
  166. module Touch = {
  167. type tag;
  168. type t = synthetic(tag);
  169. include
  170. MakeSyntheticWrapper(
  171. {
  172. type nonrec t = t;
  173. },
  174. );
  175. [@bs.get] external altKey : t => bool = "";
  176. [@bs.get] external changedTouches : t => Js.t({..}) = ""; /* Should return Dom.touchList */
  177. [@bs.get] external ctrlKey : t => bool = "";
  178. [@bs.send.pipe: t] external getModifierState : string => bool = "";
  179. [@bs.get] external metaKey : t => bool = "";
  180. [@bs.get] external shiftKey : t => bool = "";
  181. [@bs.get] external targetTouches : t => Js.t({..}) = ""; /* Should return Dom.touchList */
  182. [@bs.get] external touches : t => Js.t({..}) = ""; /* Should return Dom.touchList */
  183. };
  184.  
  185. module UI = {
  186. type tag;
  187. type t = synthetic(tag);
  188. include
  189. MakeSyntheticWrapper(
  190. {
  191. type nonrec t = t;
  192. },
  193. );
  194. [@bs.get] external detail : t => int = "";
  195. [@bs.get] external view : t => Dom.window = ""; /* Should return DOMAbstractView/WindowProxy */
  196. };
  197.  
  198. module Wheel = {
  199. type tag;
  200. type t = synthetic(tag);
  201. include
  202. MakeSyntheticWrapper(
  203. {
  204. type nonrec t = t;
  205. },
  206. );
  207. [@bs.get] external deltaMode : t => int = "";
  208. [@bs.get] external deltaX : t => float = "";
  209. [@bs.get] external deltaY : t => float = "";
  210. [@bs.get] external deltaZ : t => float = "";
  211. };
  212.  
  213. module Media = {
  214. type tag;
  215. type t = synthetic(tag);
  216. include
  217. MakeSyntheticWrapper(
  218. {
  219. type nonrec t = t;
  220. },
  221. );
  222. };
  223.  
  224. module Image = {
  225. type tag;
  226. type t = synthetic(tag);
  227. include
  228. MakeSyntheticWrapper(
  229. {
  230. type nonrec t = t;
  231. },
  232. );
  233. };
  234.  
  235. module Animation = {
  236. type tag;
  237. type t = synthetic(tag);
  238. include
  239. MakeSyntheticWrapper(
  240. {
  241. type nonrec t = t;
  242. },
  243. );
  244. [@bs.get] external animationName : t => string = "";
  245. [@bs.get] external pseudoElement : t => string = "";
  246. [@bs.get] external elapsedTime : t => float = "";
  247. };
  248.  
  249. module Transition = {
  250. type tag;
  251. type t = synthetic(tag);
  252. include
  253. MakeSyntheticWrapper(
  254. {
  255. type nonrec t = t;
  256. },
  257. );
  258. [@bs.get] external propertyName : t => string = "";
  259. [@bs.get] external pseudoElement : t => string = "";
  260. [@bs.get] external elapsedTime : t => float = "";
  261. };
  262.  
  263. };
  264.  
  265. module ReasonReactOptimizedCreateClass = {
  266. #1 ReasonReactOptimizedCreateClass
  267. let _assign = Js.Obj.assign;
  268.  
  269. let emptyObject = Js.Obj.empty();
  270.  
  271. [%%bs.raw
  272. {|
  273. /**
  274. * Copyright 2013-present, Facebook, Inc.
  275. * All rights reserved.
  276. *
  277. * This source code is licensed under the BSD-style license found in the
  278. * LICENSE file in the root directory of this source tree. An additional grant
  279. * of patent rights can be found in the PATENTS file in the same directory.
  280. *
  281. */
  282.  
  283. // 'use strict';
  284.  
  285. // var _assign = require('object-assign');
  286.  
  287. // var emptyObject = require('emptyObject');
  288. // var _invariant = require('invariant');
  289.  
  290. // if (process.env.NODE_ENV !== 'production') {
  291. // var warning = require('fbjs/lib/warning');
  292. // }
  293.  
  294. var MIXINS_KEY = 'mixins';
  295.  
  296. // Helper function to allow the creation of anonymous functions which do not
  297. // have .name set to the name of the variable being assigned to.
  298. function identity(fn) {
  299. return fn;
  300. }
  301.  
  302. var ReactPropTypeLocationNames;
  303. // if (process.env.NODE_ENV !== 'production') {
  304. // ReactPropTypeLocationNames = {
  305. // prop: 'prop',
  306. // context: 'context',
  307. // childContext: 'child context'
  308. // };
  309. // } else {
  310. ReactPropTypeLocationNames = {};
  311. // }
  312. |}
  313. ];
  314.  
  315. let factory = [%bs.raw
  316. {|
  317. function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
  318. /**
  319. * Policies that describe methods in `ReactClassInterface`.
  320. */
  321.  
  322. var injectedMixins = [];
  323.  
  324. /**
  325. * Composite components are higher-level components that compose other composite
  326. * or host components.
  327. *
  328. * To create a new type of `ReactClass`, pass a specification of
  329. * your new class to `React.createClass`. The only requirement of your class
  330. * specification is that you implement a `render` method.
  331. *
  332. * var MyComponent = React.createClass({
  333. * render: function() {
  334. * return <div>Hello World</div>;
  335. * }
  336. * });
  337. *
  338. * The class specification supports a specific protocol of methods that have
  339. * special meaning (e.g. `render`). See `ReactClassInterface` for
  340. * more the comprehensive protocol. Any other properties and methods in the
  341. * class specification will be available on the prototype.
  342. *
  343. * @interface ReactClassInterface
  344. * @internal
  345. */
  346. var ReactClassInterface = {
  347. /**
  348. * An array of Mixin objects to include when defining your component.
  349. *
  350. * @type {array}
  351. * @optional
  352. */
  353. mixins: 'DEFINE_MANY',
  354.  
  355. /**
  356. * An object containing properties and methods that should be defined on
  357. * the component's constructor instead of its prototype (static methods).
  358. *
  359. * @type {object}
  360. * @optional
  361. */
  362. statics: 'DEFINE_MANY',
  363.  
  364. /**
  365. * Definition of prop types for this component.
  366. *
  367. * @type {object}
  368. * @optional
  369. */
  370. propTypes: 'DEFINE_MANY',
  371.  
  372. /**
  373. * Definition of context types for this component.
  374. *
  375. * @type {object}
  376. * @optional
  377. */
  378. contextTypes: 'DEFINE_MANY',
  379.  
  380. /**
  381. * Definition of context types this component sets for its children.
  382. *
  383. * @type {object}
  384. * @optional
  385. */
  386. childContextTypes: 'DEFINE_MANY',
  387.  
  388. // ==== Definition methods ====
  389.  
  390. /**
  391. * Invoked when the component is mounted. Values in the mapping will be set on
  392. * `this.props` if that prop is not specified (i.e. using an `in` check).
  393. *
  394. * This method is invoked before `getInitialState` and therefore cannot rely
  395. * on `this.state` or use `this.setState`.
  396. *
  397. * @return {object}
  398. * @optional
  399. */
  400. getDefaultProps: 'DEFINE_MANY_MERGED',
  401.  
  402. /**
  403. * Invoked once before the component is mounted. The return value will be used
  404. * as the initial value of `this.state`.
  405. *
  406. * getInitialState: function() {
  407. * return {
  408. * isOn: false,
  409. * fooBaz: new BazFoo()
  410. * }
  411. * }
  412. *
  413. * @return {object}
  414. * @optional
  415. */
  416. getInitialState: 'DEFINE_MANY_MERGED',
  417.  
  418. /**
  419. * @return {object}
  420. * @optional
  421. */
  422. getChildContext: 'DEFINE_MANY_MERGED',
  423.  
  424. /**
  425. * Uses props from `this.props` and state from `this.state` to render the
  426. * structure of the component.
  427. *
  428. * No guarantees are made about when or how often this method is invoked, so
  429. * it must not have side effects.
  430. *
  431. * render: function() {
  432. * var name = this.props.name;
  433. * return <div>Hello, {name}!</div>;
  434. * }
  435. *
  436. * @return {ReactComponent}
  437. * @required
  438. */
  439. render: 'DEFINE_ONCE',
  440.  
  441. // ==== Delegate methods ====
  442.  
  443. /**
  444. * Invoked when the component is initially created and about to be mounted.
  445. * This may have side effects, but any external subscriptions or data created
  446. * by this method must be cleaned up in `componentWillUnmount`.
  447. *
  448. * @optional
  449. */
  450. componentWillMount: 'DEFINE_MANY',
  451.  
  452. /**
  453. * Invoked when the component has been mounted and has a DOM representation.
  454. * However, there is no guarantee that the DOM node is in the document.
  455. *
  456. * Use this as an opportunity to operate on the DOM when the component has
  457. * been mounted (initialized and rendered) for the first time.
  458. *
  459. * @param {DOMElement} rootNode DOM element representing the component.
  460. * @optional
  461. */
  462. componentDidMount: 'DEFINE_MANY',
  463.  
  464. /**
  465. * Invoked before the component receives new props.
  466. *
  467. * Use this as an opportunity to react to a prop transition by updating the
  468. * state using `this.setState`. Current props are accessed via `this.props`.
  469. *
  470. * componentWillReceiveProps: function(nextProps, nextContext) {
  471. * this.setState({
  472. * likesIncreasing: nextProps.likeCount > this.props.likeCount
  473. * });
  474. * }
  475. *
  476. * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
  477. * transition may cause a state change, but the opposite is not true. If you
  478. * need it, you are probably looking for `componentWillUpdate`.
  479. *
  480. * @param {object} nextProps
  481. * @optional
  482. */
  483. componentWillReceiveProps: 'DEFINE_MANY',
  484.  
  485. /**
  486. * Invoked while deciding if the component should be updated as a result of
  487. * receiving new props, state and/or context.
  488. *
  489. * Use this as an opportunity to `return false` when you're certain that the
  490. * transition to the new props/state/context will not require a component
  491. * update.
  492. *
  493. * shouldComponentUpdate: function(nextProps, nextState, nextContext) {
  494. * return !equal(nextProps, this.props) ||
  495. * !equal(nextState, this.state) ||
  496. * !equal(nextContext, this.context);
  497. * }
  498. *
  499. * @param {object} nextProps
  500. * @param {?object} nextState
  501. * @param {?object} nextContext
  502. * @return {boolean} True if the component should update.
  503. * @optional
  504. */
  505. shouldComponentUpdate: 'DEFINE_ONCE',
  506.  
  507. /**
  508. * Invoked when the component is about to update due to a transition from
  509. * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
  510. * and `nextContext`.
  511. *
  512. * Use this as an opportunity to perform preparation before an update occurs.
  513. *
  514. * NOTE: You **cannot** use `this.setState()` in this method.
  515. *
  516. * @param {object} nextProps
  517. * @param {?object} nextState
  518. * @param {?object} nextContext
  519. * @param {ReactReconcileTransaction} transaction
  520. * @optional
  521. */
  522. componentWillUpdate: 'DEFINE_MANY',
  523.  
  524. /**
  525. * Invoked when the component's DOM representation has been updated.
  526. *
  527. * Use this as an opportunity to operate on the DOM when the component has
  528. * been updated.
  529. *
  530. * @param {object} prevProps
  531. * @param {?object} prevState
  532. * @param {?object} prevContext
  533. * @param {DOMElement} rootNode DOM element representing the component.
  534. * @optional
  535. */
  536. componentDidUpdate: 'DEFINE_MANY',
  537.  
  538. /**
  539. * Invoked when the component is about to be removed from its parent and have
  540. * its DOM representation destroyed.
  541. *
  542. * Use this as an opportunity to deallocate any external resources.
  543. *
  544. * NOTE: There is no `componentDidUnmount` since your component will have been
  545. * destroyed by that point.
  546. *
  547. * @optional
  548. */
  549. componentWillUnmount: 'DEFINE_MANY',
  550.  
  551. // ==== Advanced methods ====
  552.  
  553. /**
  554. * Updates the component's currently mounted DOM representation.
  555. *
  556. * By default, this implements React's rendering and reconciliation algorithm.
  557. * Sophisticated clients may wish to override this.
  558. *
  559. * @param {ReactReconcileTransaction} transaction
  560. * @internal
  561. * @overridable
  562. */
  563. updateComponent: 'OVERRIDE_BASE'
  564. };
  565.  
  566. /**
  567. * Mapping from class specification keys to special processing functions.
  568. *
  569. * Although these are declared like instance properties in the specification
  570. * when defining classes using `React.createClass`, they are actually static
  571. * and are accessible on the constructor instead of the prototype. Despite
  572. * being static, they must be defined outside of the "statics" key under
  573. * which all other static methods are defined.
  574. */
  575. var RESERVED_SPEC_KEYS = {
  576. displayName: function(Constructor, displayName) {
  577. Constructor.displayName = displayName;
  578. },
  579. mixins: function(Constructor, mixins) {
  580. if (mixins) {
  581. for (var i = 0; i < mixins.length; i++) {
  582. mixSpecIntoComponent(Constructor, mixins[i]);
  583. }
  584. }
  585. },
  586. childContextTypes: function(Constructor, childContextTypes) {
  587. // if (process.env.NODE_ENV !== 'production') {
  588. // validateTypeDef(Constructor, childContextTypes, 'childContext');
  589. // }
  590. Constructor.childContextTypes = _assign(
  591. {},
  592. Constructor.childContextTypes,
  593. childContextTypes
  594. );
  595. },
  596. contextTypes: function(Constructor, contextTypes) {
  597. // if (process.env.NODE_ENV !== 'production') {
  598. // validateTypeDef(Constructor, contextTypes, 'context');
  599. // }
  600. Constructor.contextTypes = _assign(
  601. {},
  602. Constructor.contextTypes,
  603. contextTypes
  604. );
  605. },
  606. /**
  607. * Special case getDefaultProps which should move into statics but requires
  608. * automatic merging.
  609. */
  610. getDefaultProps: function(Constructor, getDefaultProps) {
  611. if (Constructor.getDefaultProps) {
  612. Constructor.getDefaultProps = createMergedResultFunction(
  613. Constructor.getDefaultProps,
  614. getDefaultProps
  615. );
  616. } else {
  617. Constructor.getDefaultProps = getDefaultProps;
  618. }
  619. },
  620. propTypes: function(Constructor, propTypes) {
  621. // if (process.env.NODE_ENV !== 'production') {
  622. // validateTypeDef(Constructor, propTypes, 'prop');
  623. // }
  624. Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes);
  625. },
  626. statics: function(Constructor, statics) {
  627. mixStaticSpecIntoComponent(Constructor, statics);
  628. },
  629. autobind: function() {}
  630. };
  631.  
  632. function validateTypeDef(Constructor, typeDef, location) {
  633. for (var propName in typeDef) {
  634. // if (typeDef.hasOwnProperty(propName)) {
  635. // // use a warning instead of an _invariant so components
  636. // // don't show up in prod but only in __DEV__
  637. // // if (process.env.NODE_ENV !== 'production') {
  638. // // warning(
  639. // // typeof typeDef[propName] === 'function',
  640. // // '%s: %s type `%s` is invalid; it must be a function, usually from ' +
  641. // // 'React.PropTypes.',
  642. // // Constructor.displayName || 'ReactClass',
  643. // // ReactPropTypeLocationNames[location],
  644. // // propName
  645. // // );
  646. // // }
  647. // }
  648. }
  649. }
  650.  
  651. function validateMethodOverride(isAlreadyDefined, name) {
  652. var specPolicy = ReactClassInterface.hasOwnProperty(name)
  653. ? ReactClassInterface[name]
  654. : null;
  655.  
  656. // Disallow overriding of base class methods unless explicitly allowed.
  657. if (ReactClassMixin.hasOwnProperty(name)) {
  658. // _invariant(
  659. // specPolicy === 'OVERRIDE_BASE',
  660. // 'ReactClassInterface: You are attempting to override ' +
  661. // '`%s` from your class specification. Ensure that your method names ' +
  662. // 'do not overlap with React methods.',
  663. // name
  664. // );
  665. }
  666.  
  667. // Disallow defining methods more than once unless explicitly allowed.
  668. if (isAlreadyDefined) {
  669. // _invariant(
  670. // specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED',
  671. // 'ReactClassInterface: You are attempting to define ' +
  672. // '`%s` on your component more than once. This conflict may be due ' +
  673. // 'to a mixin.',
  674. // name
  675. // );
  676. }
  677. }
  678.  
  679. /**
  680. * Mixin helper which handles policy validation and reserved
  681. * specification keys when building React classes.
  682. */
  683. function mixSpecIntoComponent(Constructor, spec) {
  684. if (!spec) {
  685. // if (process.env.NODE_ENV !== 'production') {
  686. // var typeofSpec = typeof spec;
  687. // var isMixinValid = typeofSpec === 'object' && spec !== null;
  688. //
  689. // if (process.env.NODE_ENV !== 'production') {
  690. // warning(
  691. // isMixinValid,
  692. // "%s: You're attempting to include a mixin that is either null " +
  693. // 'or not an object. Check the mixins included by the component, ' +
  694. // 'as well as any mixins they include themselves. ' +
  695. // 'Expected object but got %s.',
  696. // Constructor.displayName || 'ReactClass',
  697. // spec === null ? null : typeofSpec
  698. // );
  699. // }
  700. // }
  701.  
  702. return;
  703. }
  704.  
  705. // _invariant(
  706. // typeof spec !== 'function',
  707. // "ReactClass: You're attempting to " +
  708. // 'use a component class or function as a mixin. Instead, just use a ' +
  709. // 'regular object.'
  710. // );
  711. // _invariant(
  712. // !isValidElement(spec),
  713. // "ReactClass: You're attempting to " +
  714. // 'use a component as a mixin. Instead, just use a regular object.'
  715. // );
  716.  
  717. var proto = Constructor.prototype;
  718. var autoBindPairs = proto.__reactAutoBindPairs;
  719.  
  720. // By handling mixins before any other properties, we ensure the same
  721. // chaining order is applied to methods with DEFINE_MANY policy, whether
  722. // mixins are listed before or after these methods in the spec.
  723. if (spec.hasOwnProperty(MIXINS_KEY)) {
  724. RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
  725. }
  726.  
  727. for (var name in spec) {
  728. if (!spec.hasOwnProperty(name)) {
  729. continue;
  730. }
  731.  
  732. if (name === MIXINS_KEY) {
  733. // We have already handled mixins in a special case above.
  734. continue;
  735. }
  736.  
  737. var property = spec[name];
  738. var isAlreadyDefined = proto.hasOwnProperty(name);
  739. validateMethodOverride(isAlreadyDefined, name);
  740.  
  741. if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
  742. RESERVED_SPEC_KEYS[name](Constructor, property);
  743. } else {
  744. // Setup methods on prototype:
  745. // The following member methods should not be automatically bound:
  746. // 1. Expected ReactClass methods (in the "interface").
  747. // 2. Overridden methods (that were mixed in).
  748. var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);
  749. var isFunction = typeof property === 'function';
  750. var shouldAutoBind =
  751. isFunction &&
  752. !isReactClassMethod &&
  753. !isAlreadyDefined &&
  754. spec.autobind !== false;
  755.  
  756. if (shouldAutoBind) {
  757. autoBindPairs.push(name, property);
  758. proto[name] = property;
  759. } else {
  760. if (isAlreadyDefined) {
  761. var specPolicy = ReactClassInterface[name];
  762.  
  763. // These cases should already be caught by validateMethodOverride.
  764. // _invariant(
  765. // isReactClassMethod &&
  766. // (specPolicy === 'DEFINE_MANY_MERGED' ||
  767. // specPolicy === 'DEFINE_MANY'),
  768. // 'ReactClass: Unexpected spec policy %s for key %s ' +
  769. // 'when mixing in component specs.',
  770. // specPolicy,
  771. // name
  772. // );
  773.  
  774. // For methods which are defined more than once, call the existing
  775. // methods before calling the new property, merging if appropriate.
  776. if (specPolicy === 'DEFINE_MANY_MERGED') {
  777. proto[name] = createMergedResultFunction(proto[name], property);
  778. } else if (specPolicy === 'DEFINE_MANY') {
  779. proto[name] = createChainedFunction(proto[name], property);
  780. }
  781. } else {
  782. proto[name] = property;
  783. // if (process.env.NODE_ENV !== 'production') {
  784. // // Add verbose displayName to the function, which helps when looking
  785. // // at profiling tools.
  786. // if (typeof property === 'function' && spec.displayName) {
  787. // proto[name].displayName = spec.displayName + '_' + name;
  788. // }
  789. // }
  790. }
  791. }
  792. }
  793. }
  794. }
  795.  
  796. function mixStaticSpecIntoComponent(Constructor, statics) {
  797. if (!statics) {
  798. return;
  799. }
  800. for (var name in statics) {
  801. var property = statics[name];
  802. if (!statics.hasOwnProperty(name)) {
  803. continue;
  804. }
  805.  
  806. var isReserved = name in RESERVED_SPEC_KEYS;
  807. // _invariant(
  808. // !isReserved,
  809. // 'ReactClass: You are attempting to define a reserved ' +
  810. // 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' +
  811. // 'as an instance property instead; it will still be accessible on the ' +
  812. // 'constructor.',
  813. // name
  814. // );
  815.  
  816. var isInherited = name in Constructor;
  817. // _invariant(
  818. // !isInherited,
  819. // 'ReactClass: You are attempting to define ' +
  820. // '`%s` on your component more than once. This conflict may be ' +
  821. // 'due to a mixin.',
  822. // name
  823. // );
  824. Constructor[name] = property;
  825. }
  826. }
  827.  
  828. /**
  829. * Merge two objects, but throw if both contain the same key.
  830. *
  831. * @param {object} one The first object, which is mutated.
  832. * @param {object} two The second object
  833. * @return {object} one after it has been mutated to contain everything in two.
  834. */
  835. function mergeIntoWithNoDuplicateKeys(one, two) {
  836. // _invariant(
  837. // one && two && typeof one === 'object' && typeof two === 'object',
  838. // 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.'
  839. // );
  840.  
  841. for (var key in two) {
  842. if (two.hasOwnProperty(key)) {
  843. // _invariant(
  844. // one[key] === undefined,
  845. // 'mergeIntoWithNoDuplicateKeys(): ' +
  846. // 'Tried to merge two objects with the same key: `%s`. This conflict ' +
  847. // 'may be due to a mixin; in particular, this may be caused by two ' +
  848. // 'getInitialState() or getDefaultProps() methods returning objects ' +
  849. // 'with clashing keys.',
  850. // key
  851. // );
  852. one[key] = two[key];
  853. }
  854. }
  855. return one;
  856. }
  857.  
  858. /**
  859. * Creates a function that invokes two functions and merges their return values.
  860. *
  861. * @param {function} one Function to invoke first.
  862. * @param {function} two Function to invoke second.
  863. * @return {function} Function that invokes the two argument functions.
  864. * @private
  865. */
  866. function createMergedResultFunction(one, two) {
  867. return function mergedResult() {
  868. var a = one.apply(this, arguments);
  869. var b = two.apply(this, arguments);
  870. if (a == null) {
  871. return b;
  872. } else if (b == null) {
  873. return a;
  874. }
  875. var c = {};
  876. mergeIntoWithNoDuplicateKeys(c, a);
  877. mergeIntoWithNoDuplicateKeys(c, b);
  878. return c;
  879. };
  880. }
  881.  
  882. /**
  883. * Creates a function that invokes two functions and ignores their return vales.
  884. *
  885. * @param {function} one Function to invoke first.
  886. * @param {function} two Function to invoke second.
  887. * @return {function} Function that invokes the two argument functions.
  888. * @private
  889. */
  890. function createChainedFunction(one, two) {
  891. return function chainedFunction() {
  892. one.apply(this, arguments);
  893. two.apply(this, arguments);
  894. };
  895. }
  896.  
  897. /**
  898. * Binds a method to the component.
  899. *
  900. * @param {object} component Component whose method is going to be bound.
  901. * @param {function} method Method to be bound.
  902. * @return {function} The bound method.
  903. */
  904. function bindAutoBindMethod(component, method) {
  905. var boundMethod = method.bind(component);
  906. // if (process.env.NODE_ENV !== 'production') {
  907. // boundMethod.__reactBoundContext = component;
  908. // boundMethod.__reactBoundMethod = method;
  909. // boundMethod.__reactBoundArguments = null;
  910. // var componentName = component.constructor.displayName;
  911. // var _bind = boundMethod.bind;
  912. // boundMethod.bind = function(newThis) {
  913. // for (
  914. // var _len = arguments.length,
  915. // args = Array(_len > 1 ? _len - 1 : 0),
  916. // _key = 1;
  917. // _key < _len;
  918. // _key++
  919. // ) {
  920. // args[_key - 1] = arguments[_key];
  921. // }
  922. //
  923. // // User is trying to bind() an autobound method; we effectively will
  924. // // ignore the value of "this" that the user is trying to use, so
  925. // // let's warn.
  926. // if (newThis !== component && newThis !== null) {
  927. // if (process.env.NODE_ENV !== 'production') {
  928. // warning(
  929. // false,
  930. // 'bind(): React component methods may only be bound to the ' +
  931. // 'component instance. See %s',
  932. // componentName
  933. // );
  934. // }
  935. // } else if (!args.length) {
  936. // if (process.env.NODE_ENV !== 'production') {
  937. // warning(
  938. // false,
  939. // 'bind(): You are binding a component method to the component. ' +
  940. // 'React does this for you automatically in a high-performance ' +
  941. // 'way, so you can safely remove this call. See %s',
  942. // componentName
  943. // );
  944. // }
  945. // return boundMethod;
  946. // }
  947. // var reboundMethod = _bind.apply(boundMethod, arguments);
  948. // reboundMethod.__reactBoundContext = component;
  949. // reboundMethod.__reactBoundMethod = method;
  950. // reboundMethod.__reactBoundArguments = args;
  951. // return reboundMethod;
  952. // };
  953. // }
  954. return boundMethod;
  955. }
  956.  
  957. /**
  958. * Binds all auto-bound methods in a component.
  959. *
  960. * @param {object} component Component whose method is going to be bound.
  961. */
  962. function bindAutoBindMethods(component) {
  963. var pairs = component.__reactAutoBindPairs;
  964. for (var i = 0; i < pairs.length; i += 2) {
  965. var autoBindKey = pairs[i];
  966. var method = pairs[i + 1];
  967. component[autoBindKey] = bindAutoBindMethod(component, method);
  968. }
  969. }
  970.  
  971. var IsMountedPreMixin = {
  972. componentDidMount: function() {
  973. this.__isMounted = true;
  974. }
  975. };
  976.  
  977. var IsMountedPostMixin = {
  978. componentWillUnmount: function() {
  979. this.__isMounted = false;
  980. }
  981. };
  982.  
  983. /**
  984. * Add more to the ReactClass base class. These are all legacy features and
  985. * therefore not already part of the modern ReactComponent.
  986. */
  987. var ReactClassMixin = {
  988. /**
  989. * TODO: This will be deprecated because state should always keep a consistent
  990. * type signature and the only use case for this, is to avoid that.
  991. */
  992. replaceState: function(newState, callback) {
  993. this.updater.enqueueReplaceState(this, newState, callback);
  994. },
  995.  
  996. /**
  997. * Checks whether or not this composite component is mounted.
  998. * @return {boolean} True if mounted, false otherwise.
  999. * @protected
  1000. * @final
  1001. */
  1002. isMounted: function() {
  1003. // if (process.env.NODE_ENV !== 'production') {
  1004. // warning(
  1005. // this.__didWarnIsMounted,
  1006. // '%s: isMounted is deprecated. Instead, make sure to clean up ' +
  1007. // 'subscriptions and pending requests in componentWillUnmount to ' +
  1008. // 'prevent memory leaks.',
  1009. // (this.constructor && this.constructor.displayName) ||
  1010. // this.name ||
  1011. // 'Component'
  1012. // );
  1013. // this.__didWarnIsMounted = true;
  1014. // }
  1015. return !!this.__isMounted;
  1016. }
  1017. };
  1018.  
  1019. var ReactClassComponent = function() {};
  1020. _assign(
  1021. ReactClassComponent.prototype,
  1022. ReactComponent.prototype,
  1023. ReactClassMixin
  1024. );
  1025.  
  1026. /**
  1027. * Creates a composite component class given a class specification.
  1028. * See https://facebook.github.io/react/docs/top-level-api.html#react.createclass
  1029. *
  1030. * @param {object} spec Class specification (which must define `render`).
  1031. * @return {function} Component constructor function.
  1032. * @public
  1033. */
  1034. function createClass(spec) {
  1035. // To keep our warnings more understandable, we'll use a little hack here to
  1036. // ensure that Constructor.name !== 'Constructor'. This makes sure we don't
  1037. // unnecessarily identify a class without displayName as 'Constructor'.
  1038. var Constructor = identity(function(props, context, updater) {
  1039. // This constructor gets overridden by mocks. The argument is used
  1040. // by mocks to assert on what gets mounted.
  1041.  
  1042. // if (process.env.NODE_ENV !== 'production') {
  1043. // warning(
  1044. // this instanceof Constructor,
  1045. // 'Something is calling a React component directly. Use a factory or ' +
  1046. // 'JSX instead. See: https://fb.me/react-legacyfactory'
  1047. // );
  1048. // }
  1049.  
  1050. // Wire up auto-binding
  1051. if (this.__reactAutoBindPairs.length) {
  1052. bindAutoBindMethods(this);
  1053. }
  1054.  
  1055. this.props = props;
  1056. this.context = context;
  1057. this.refs = emptyObject;
  1058. this.updater = updater || ReactNoopUpdateQueue;
  1059.  
  1060. this.state = null;
  1061.  
  1062. // ReactClasses doesn't have constructors. Instead, they use the
  1063. // getInitialState and componentWillMount methods for initialization.
  1064.  
  1065. var initialState = this.getInitialState ? this.getInitialState() : null;
  1066. // if (process.env.NODE_ENV !== 'production') {
  1067. // // We allow auto-mocks to proceed as if they're returning null.
  1068. // if (
  1069. // initialState === undefined &&
  1070. // this.getInitialState._isMockFunction
  1071. // ) {
  1072. // // This is probably bad practice. Consider warning here and
  1073. // // deprecating this convenience.
  1074. // initialState = null;
  1075. // }
  1076. // }
  1077. // _invariant(
  1078. // typeof initialState === 'object' && !Array.isArray(initialState),
  1079. // '%s.getInitialState(): must return an object or null',
  1080. // Constructor.displayName || 'ReactCompositeComponent'
  1081. // );
  1082.  
  1083. this.state = initialState;
  1084. });
  1085. Constructor.prototype = new ReactClassComponent();
  1086. Constructor.prototype.constructor = Constructor;
  1087. Constructor.prototype.__reactAutoBindPairs = [];
  1088.  
  1089. injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));
  1090.  
  1091. mixSpecIntoComponent(Constructor, IsMountedPreMixin);
  1092. mixSpecIntoComponent(Constructor, spec);
  1093. mixSpecIntoComponent(Constructor, IsMountedPostMixin);
  1094.  
  1095. // Initialize the defaultProps property after all mixins have been merged.
  1096. if (Constructor.getDefaultProps) {
  1097. Constructor.defaultProps = Constructor.getDefaultProps();
  1098. }
  1099.  
  1100. // if (process.env.NODE_ENV !== 'production') {
  1101. // // This is a tag to indicate that the use of these method names is ok,
  1102. // // since it's used with createClass. If it's not, then it's likely a
  1103. // // mistake so we'll warn you to use the static property, property
  1104. // // initializer or constructor respectively.
  1105. // if (Constructor.getDefaultProps) {
  1106. // Constructor.getDefaultProps.isReactClassApproved = {};
  1107. // }
  1108. // if (Constructor.prototype.getInitialState) {
  1109. // Constructor.prototype.getInitialState.isReactClassApproved = {};
  1110. // }
  1111. // }
  1112.  
  1113. // _invariant(
  1114. // Constructor.prototype.render,
  1115. // 'createClass(...): Class specification must implement a `render` method.'
  1116. // );
  1117.  
  1118. // if (process.env.NODE_ENV !== 'production') {
  1119. // warning(
  1120. // !Constructor.prototype.componentShouldUpdate,
  1121. // '%s has a method called ' +
  1122. // 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
  1123. // 'The name is phrased as a question because the function is ' +
  1124. // 'expected to return a value.',
  1125. // spec.displayName || 'A component'
  1126. // );
  1127. // warning(
  1128. // !Constructor.prototype.componentWillRecieveProps,
  1129. // '%s has a method called ' +
  1130. // 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
  1131. // spec.displayName || 'A component'
  1132. // );
  1133. // }
  1134.  
  1135. // Reduce time spent doing lookups by setting these on the prototype.
  1136. for (var methodName in ReactClassInterface) {
  1137. if (!Constructor.prototype[methodName]) {
  1138. Constructor.prototype[methodName] = null;
  1139. }
  1140. }
  1141.  
  1142. return Constructor;
  1143. }
  1144.  
  1145. return createClass;
  1146. }
  1147. |}
  1148. ];
  1149.  
  1150. [@bs.module "react"] external reactComponent : 'a = "Component";
  1151.  
  1152. [@bs.module "react"] external reactIsValidElement : bool = "isValidElement";
  1153.  
  1154. [@bs.module "react"] [@bs.new] external newReactComponent : unit => {. "updater": 'a} =
  1155. "Component";
  1156.  
  1157. let reactNoopUpdateQueue = newReactComponent()##updater;
  1158.  
  1159. let createClass = [@bs] factory(reactComponent, reactIsValidElement, reactNoopUpdateQueue);
  1160.  
  1161. };
  1162.  
  1163. module ReasonReact = {
  1164. #1 ReasonReact
  1165. type reactClass;
  1166.  
  1167. type jsProps;
  1168.  
  1169. type reactElement;
  1170.  
  1171. type reactRef;
  1172.  
  1173. [@deprecated "Please use ReasonReact.null instead"] [@bs.val]
  1174. external nullElement : reactElement = "null";
  1175.  
  1176. [@deprecated "Please use ReasonReact.string instead"]
  1177. external stringToElement : string => reactElement = "%identity";
  1178.  
  1179. [@deprecated "Please use ReasonReact.array instead"]
  1180. external arrayToElement : array(reactElement) => reactElement = "%identity";
  1181.  
  1182. [@bs.val] external null : reactElement = "null";
  1183.  
  1184. external string : string => reactElement = "%identity";
  1185.  
  1186. external array : array(reactElement) => reactElement = "%identity";
  1187.  
  1188. external refToJsObj : reactRef => Js.t({..}) = "%identity";
  1189.  
  1190. [@bs.splice] [@bs.val] [@bs.module "react"]
  1191. external createElement :
  1192. (reactClass, ~props: Js.t({..})=?, array(reactElement)) => reactElement =
  1193. "createElement";
  1194.  
  1195. [@bs.splice] [@bs.module "react"]
  1196. external cloneElement :
  1197. (reactElement, ~props: Js.t({..})=?, array(reactElement)) => reactElement =
  1198. "cloneElement";
  1199.  
  1200. [@bs.val] [@bs.module "react"]
  1201. external createElementVerbatim : 'a = "createElement";
  1202.  
  1203. let createDomElement = (s, ~props, children) => {
  1204. let vararg =
  1205. [|Obj.magic(s), Obj.magic(props)|] |> Js.Array.concat(children);
  1206. /* Use varargs to avoid warnings on duplicate keys in children */
  1207. Obj.magic(createElementVerbatim)##apply(Js.Nullable.null, vararg);
  1208. };
  1209.  
  1210. [@bs.val] external magicNull : 'a = "null";
  1211.  
  1212. type reactClassInternal = reactClass;
  1213.  
  1214. type renderNotImplemented =
  1215. | RenderNotImplemented;
  1216.  
  1217. type stateless = unit;
  1218.  
  1219. type noRetainedProps = unit;
  1220.  
  1221. type actionless = unit;
  1222.  
  1223. type subscription =
  1224. | Sub(unit => 'token, 'token => unit): subscription;
  1225.  
  1226.  
  1227. /***
  1228. * Elements are what JSX blocks become. They represent the *potential* for a
  1229. * component instance and state to be created / updated. They are not yet
  1230. * instances.
  1231. */
  1232. type element =
  1233. | Element(component('state, 'retainedProps, 'action)): element
  1234. and jsPropsToReason('jsProps, 'state, 'retainedProps, 'action) =
  1235. 'jsProps => component('state, 'retainedProps, 'action)
  1236. /***
  1237. * Type of hidden field for Reason components that use JS components
  1238. */
  1239. and jsElementWrapped =
  1240. option(
  1241. (
  1242. ~key: Js.nullable(string),
  1243. ~ref: Js.nullable(Js.nullable(reactRef) => unit)
  1244. ) =>
  1245. reactElement,
  1246. )
  1247. and update('state, 'retainedProps, 'action) =
  1248. | NoUpdate
  1249. | Update('state)
  1250. | SideEffects(self('state, 'retainedProps, 'action) => unit)
  1251. | UpdateWithSideEffects(
  1252. 'state,
  1253. self('state, 'retainedProps, 'action) => unit,
  1254. )
  1255. /***
  1256. * Granularly types state, and initial state as being independent, so that we
  1257. * may include a template that all instances extend from.
  1258. */
  1259. and componentSpec(
  1260. 'state,
  1261. 'initialState,
  1262. 'retainedProps,
  1263. 'initialRetainedProps,
  1264. 'action,
  1265. ) = {
  1266. debugName: string,
  1267. reactClassInternal,
  1268. /* Keep here as a way to prove that the API may be implemented soundly */
  1269. mutable handedOffState: ref(option('state)),
  1270. willReceiveProps: self('state, 'retainedProps, 'action) => 'state,
  1271. didMount: self('state, 'retainedProps, 'action) => unit,
  1272. didUpdate: oldNewSelf('state, 'retainedProps, 'action) => unit,
  1273. willUnmount: self('state, 'retainedProps, 'action) => unit,
  1274. willUpdate: oldNewSelf('state, 'retainedProps, 'action) => unit,
  1275. shouldUpdate: oldNewSelf('state, 'retainedProps, 'action) => bool,
  1276. render: self('state, 'retainedProps, 'action) => reactElement,
  1277. initialState: unit => 'initialState,
  1278. retainedProps: 'initialRetainedProps,
  1279. reducer: ('action, 'state) => update('state, 'retainedProps, 'action),
  1280. subscriptions: self('state, 'retainedProps, 'action) => list(subscription),
  1281. jsElementWrapped,
  1282. }
  1283. and component('state, 'retainedProps, 'action) =
  1284. componentSpec('state, 'state, 'retainedProps, 'retainedProps, 'action)
  1285. and self('state, 'retainedProps, 'action) = {
  1286. handle:
  1287. 'payload .
  1288. (('payload, self('state, 'retainedProps, 'action)) => unit, 'payload) =>
  1289. unit,
  1290. state: 'state,
  1291. retainedProps: 'retainedProps,
  1292. send: 'action => unit,
  1293. onUnmount: (unit => unit) => unit,
  1294. }
  1295. and oldNewSelf('state, 'retainedProps, 'action) = {
  1296. oldSelf: self('state, 'retainedProps, 'action),
  1297. newSelf: self('state, 'retainedProps, 'action),
  1298. };
  1299.  
  1300. type jsComponentThis('state, 'props, 'retainedProps, 'action) = {
  1301. .
  1302. "state": totalState('state, 'retainedProps, 'action),
  1303. "props": {. "reasonProps": 'props},
  1304. "setState":
  1305. [@bs.meth] (
  1306. (
  1307. (totalState('state, 'retainedProps, 'action), 'props) =>
  1308. totalState('state, 'retainedProps, 'action),
  1309. Js.nullable(unit => unit)
  1310. ) =>
  1311. unit
  1312. ),
  1313. "jsPropsToReason":
  1314. option(jsPropsToReason('props, 'state, 'retainedProps, 'action)),
  1315. }
  1316. /***
  1317. * `totalState` tracks all of the internal reason API bookkeeping.
  1318. *
  1319. * Since we will mutate `totalState` in `shouldComponentUpdate`, and since
  1320. * there's no guarantee that returning true from `shouldComponentUpdate`
  1321. * guarantees that a component's update *actually* takes place (it could get
  1322. * rolled back by Fiber etc), then we should put all properties that we
  1323. * mutate directly on the totalState, so that when Fiber makes backup shallow
  1324. * backup copies of `totalState`, our changes can be rolled back correctly
  1325. * even when we mutate them.
  1326. */
  1327. and totalState('state, 'retainedProps, 'action) = {. "reasonState": 'state};
  1328.  
  1329. let anyToUnit = (_) => ();
  1330.  
  1331. let anyToTrue = (_) => true;
  1332.  
  1333. let willReceivePropsDefault = ({state}) => state;
  1334.  
  1335. let renderDefault = _self => string("RenderNotImplemented");
  1336.  
  1337. let initialStateDefault = () => ();
  1338.  
  1339. let reducerDefault:
  1340. ('action, 'state) => update('state, 'retainedProps, 'action) =
  1341. (_action, _state) => NoUpdate;
  1342.  
  1343. let subscriptionsDefault = _self => [];
  1344.  
  1345. let convertPropsIfTheyreFromJs = (props, jsPropsToReason, debugName) => {
  1346. let props = Obj.magic(props);
  1347. switch (Js.Nullable.toOption(props##reasonProps), jsPropsToReason) {
  1348. | (Some(props), _) => props
  1349. /* TODO: annotate with BS to avoid curry overhead */
  1350. | (None, Some(toReasonProps)) => Element(toReasonProps(props))
  1351. | (None, None) =>
  1352. raise(
  1353. Invalid_argument(
  1354. "A JS component called the Reason component "
  1355. ++ debugName
  1356. ++ " which didn't implement the JS->Reason React props conversion.",
  1357. ),
  1358. )
  1359. };
  1360. };
  1361.  
  1362. /* This prepares us to remove our dependency on List, which shrinks
  1363. ReasonReact dramatically and makes it adoptible on some codebases with tightly enforced size constraints */
  1364. let arrayOfList = l => {
  1365. let rec arrayOfList = (l, acc) =>
  1366. switch (l) {
  1367. | [] => Js.Array.reverseInPlace(acc)
  1368. | [head, ...rest] =>
  1369. ignore(Js.Array.push(head, acc));
  1370. arrayOfList(rest, acc);
  1371. };
  1372. arrayOfList(l, [||]);
  1373. };
  1374.  
  1375. let createClass =
  1376. (type reasonState, type retainedProps, type action, debugName)
  1377. : reactClass =>
  1378. ReasonReactOptimizedCreateClass.createClass(.
  1379. [@bs]
  1380. {
  1381. val displayName = debugName;
  1382. val mutable subscriptions = Js.null;
  1383. /***
  1384. * TODO: Avoid allocating this every time we need it. Should be doable.
  1385. */
  1386. pub self = (state, retainedProps) => {
  1387. handle: Obj.magic(this##handleMethod),
  1388. send: Obj.magic(this##sendMethod),
  1389. state,
  1390. retainedProps,
  1391. onUnmount: Obj.magic(this##onUnmountMethod),
  1392. };
  1393. /***
  1394. * TODO: Null out fields that aren't overridden beyond defaults in
  1395. * `component`. React optimizes components that don't implement
  1396. * lifecycles!
  1397. */
  1398. pub transitionNextTotalState = (curTotalState, reasonStateUpdate) =>
  1399. switch (reasonStateUpdate) {
  1400. | NoUpdate => (None, curTotalState)
  1401. | Update(nextReasonState) => (
  1402. None,
  1403. {"reasonState": nextReasonState},
  1404. )
  1405. | SideEffects(performSideEffects) => (
  1406. Some(performSideEffects),
  1407. curTotalState,
  1408. )
  1409. | UpdateWithSideEffects(nextReasonState, performSideEffects) => (
  1410. Some(performSideEffects),
  1411. {"reasonState": nextReasonState},
  1412. )
  1413. };
  1414. pub getInitialState = () : totalState('state, 'retainedProps, 'action) => {
  1415. let thisJs:
  1416. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1417. "this"
  1418. ];
  1419. let convertedReasonProps =
  1420. convertPropsIfTheyreFromJs(
  1421. thisJs##props,
  1422. thisJs##jsPropsToReason,
  1423. debugName,
  1424. );
  1425. let Element(component) = convertedReasonProps;
  1426. let initialReasonState = component.initialState();
  1427. {"reasonState": Obj.magic(initialReasonState)};
  1428. };
  1429. pub componentDidMount = () => {
  1430. let thisJs:
  1431. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1432. "this"
  1433. ];
  1434. let convertedReasonProps =
  1435. convertPropsIfTheyreFromJs(
  1436. thisJs##props,
  1437. thisJs##jsPropsToReason,
  1438. debugName,
  1439. );
  1440. let Element(component) = convertedReasonProps;
  1441. let curTotalState = thisJs##state;
  1442. let curReasonState = curTotalState##reasonState;
  1443. let self =
  1444. this##self(curReasonState, Obj.magic(component.retainedProps));
  1445. let self = Obj.magic(self);
  1446. if (component.subscriptions !== subscriptionsDefault) {
  1447. let subscriptions =
  1448. component.subscriptions(self)
  1449. |> arrayOfList
  1450. |> Js.Array.map((Sub(subscribe, unsubscribe)) => {
  1451. let token = subscribe();
  1452. () => unsubscribe(token);
  1453. });
  1454. this##subscriptions#=(Js.Null.return(subscriptions));
  1455. };
  1456. if (component.didMount !== anyToUnit) {
  1457. component.didMount(self);
  1458. };
  1459. };
  1460. pub componentDidUpdate = (prevProps, prevState) => {
  1461. let thisJs:
  1462. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1463. "this"
  1464. ];
  1465. let curState = thisJs##state;
  1466. let curReasonState = curState##reasonState;
  1467. let newJsProps = thisJs##props;
  1468. let newConvertedReasonProps =
  1469. convertPropsIfTheyreFromJs(
  1470. newJsProps,
  1471. thisJs##jsPropsToReason,
  1472. debugName,
  1473. );
  1474. let Element(newComponent) = newConvertedReasonProps;
  1475. if (newComponent.didUpdate !== anyToUnit) {
  1476. let oldConvertedReasonProps =
  1477. prevProps === newJsProps ?
  1478. newConvertedReasonProps :
  1479. convertPropsIfTheyreFromJs(
  1480. prevProps,
  1481. thisJs##jsPropsToReason,
  1482. debugName,
  1483. );
  1484. let Element(oldComponent) = oldConvertedReasonProps;
  1485. let prevReasonState = prevState##reasonState;
  1486. let prevReasonState = Obj.magic(prevReasonState);
  1487. let newSelf =
  1488. this##self(
  1489. curReasonState,
  1490. Obj.magic(newComponent.retainedProps),
  1491. );
  1492. let newSelf = Obj.magic(newSelf);
  1493. /* bypass this##self call for small perf boost */
  1494. let oldSelf =
  1495. Obj.magic({
  1496. ...newSelf,
  1497. state: prevReasonState,
  1498. retainedProps: oldComponent.retainedProps,
  1499. });
  1500. newComponent.didUpdate({oldSelf, newSelf});
  1501. };
  1502. };
  1503. /* pub componentWillMount .. TODO (or not?) */
  1504. pub componentWillUnmount = () => {
  1505. let thisJs:
  1506. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1507. "this"
  1508. ];
  1509. let convertedReasonProps =
  1510. convertPropsIfTheyreFromJs(
  1511. thisJs##props,
  1512. thisJs##jsPropsToReason,
  1513. debugName,
  1514. );
  1515. let Element(component) = convertedReasonProps;
  1516. let curState = thisJs##state;
  1517. let curReasonState = curState##reasonState;
  1518. if (component.willUnmount !== anyToUnit) {
  1519. let self =
  1520. this##self(curReasonState, Obj.magic(component.retainedProps));
  1521. let self = Obj.magic(self);
  1522. component.willUnmount(self);
  1523. };
  1524. switch (Js.Null.toOption(this##subscriptions)) {
  1525. | None => ()
  1526. | Some(subs) => Js.Array.forEach(unsubscribe => unsubscribe(), subs)
  1527. };
  1528. };
  1529. /***
  1530. * If we are even getting this far, we've already done all the logic for
  1531. * detecting unnecessary updates in shouldComponentUpdate. We know at
  1532. * this point that we need to rerender, and we've even *precomputed* the
  1533. * render result (subelements)!
  1534. */
  1535. pub componentWillUpdate = (nextProps, nextState: totalState(_)) => {
  1536. let thisJs:
  1537. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1538. "this"
  1539. ];
  1540. let newConvertedReasonProps =
  1541. convertPropsIfTheyreFromJs(
  1542. nextProps,
  1543. thisJs##jsPropsToReason,
  1544. debugName,
  1545. );
  1546. let Element(newComponent) = newConvertedReasonProps;
  1547. if (newComponent.willUpdate !== anyToUnit) {
  1548. let oldJsProps = thisJs##props;
  1549. /* Avoid converting again the props that are just the same as curProps. */
  1550. let oldConvertedReasonProps =
  1551. nextProps === oldJsProps ?
  1552. newConvertedReasonProps :
  1553. convertPropsIfTheyreFromJs(
  1554. oldJsProps,
  1555. thisJs##jsPropsToReason,
  1556. debugName,
  1557. );
  1558. let Element(oldComponent) = oldConvertedReasonProps;
  1559. let curState = thisJs##state;
  1560. let curReasonState = curState##reasonState;
  1561. let curReasonState = Obj.magic(curReasonState);
  1562. let nextReasonState = nextState##reasonState;
  1563. let newSelf =
  1564. this##self(
  1565. nextReasonState,
  1566. Obj.magic(newComponent.retainedProps),
  1567. );
  1568. let newSelf = Obj.magic(newSelf);
  1569. /* bypass this##self call for small perf boost */
  1570. let oldSelf =
  1571. Obj.magic({
  1572. ...newSelf,
  1573. state: curReasonState,
  1574. retainedProps: oldComponent.retainedProps,
  1575. });
  1576. newComponent.willUpdate({oldSelf, newSelf});
  1577. };
  1578. };
  1579. /***
  1580. * One interesting part of the new Reason React API. There isn't a need
  1581. * for a separate `willReceiveProps` function. The primary `create` API
  1582. * is *always* receiving props.
  1583. */
  1584. pub componentWillReceiveProps = nextProps => {
  1585. let thisJs:
  1586. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1587. "this"
  1588. ];
  1589. let newConvertedReasonProps =
  1590. convertPropsIfTheyreFromJs(
  1591. nextProps,
  1592. thisJs##jsPropsToReason,
  1593. debugName,
  1594. );
  1595. let Element(newComponent) = Obj.magic(newConvertedReasonProps);
  1596. if (newComponent.willReceiveProps !== willReceivePropsDefault) {
  1597. let oldJsProps = thisJs##props;
  1598. /* Avoid converting again the props that are just the same as curProps. */
  1599. let oldConvertedReasonProps =
  1600. nextProps === oldJsProps ?
  1601. newConvertedReasonProps :
  1602. convertPropsIfTheyreFromJs(
  1603. oldJsProps,
  1604. thisJs##jsPropsToReason,
  1605. debugName,
  1606. );
  1607. let Element(oldComponent) = oldConvertedReasonProps;
  1608. thisJs##setState(
  1609. (curTotalState, _) => {
  1610. let curReasonState = Obj.magic(curTotalState##reasonState);
  1611. let oldSelf =
  1612. Obj.magic(
  1613. this##self(
  1614. curReasonState,
  1615. Obj.magic(oldComponent.retainedProps),
  1616. ),
  1617. );
  1618. let nextReasonState =
  1619. Obj.magic(newComponent.willReceiveProps(oldSelf));
  1620. if (nextReasonState !== curTotalState) {
  1621. let nextTotalState: totalState(_) = {
  1622. "reasonState": nextReasonState,
  1623. };
  1624. let nextTotalState = Obj.magic(nextTotalState);
  1625. nextTotalState;
  1626. } else {
  1627. curTotalState;
  1628. };
  1629. },
  1630. Js.Nullable.null,
  1631. );
  1632. };
  1633. };
  1634. /***
  1635. * shouldComponentUpdate is invoked any time props change, or new state
  1636. * updates occur.
  1637. *
  1638. * The easiest way to think about this method, is:
  1639. * - "Should component have its componentWillUpdate method called,
  1640. * followed by its render() method?",
  1641. *
  1642. * Therefore the component.shouldUpdate becomes a hook solely to perform
  1643. * performance optimizations through.
  1644. */
  1645. pub shouldComponentUpdate = (nextJsProps, nextState, _) => {
  1646. let thisJs:
  1647. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1648. "this"
  1649. ];
  1650. let curJsProps = thisJs##props;
  1651.  
  1652. /***
  1653. * Now, we inspect the next state that we are supposed to render, and ensure that
  1654. * - We have enough information to answer "should update?"
  1655. * - We have enough information to render() in the event that the answer is "true".
  1656. *
  1657. * If we can detect that props have changed update has occured,
  1658. * we ask the component's shouldUpdate if it would like to update - defaulting to true.
  1659. */
  1660. let oldConvertedReasonProps =
  1661. convertPropsIfTheyreFromJs(
  1662. thisJs##props,
  1663. thisJs##jsPropsToReason,
  1664. debugName,
  1665. );
  1666. /* Avoid converting again the props that are just the same as curProps. */
  1667. let newConvertedReasonProps =
  1668. nextJsProps === curJsProps ?
  1669. oldConvertedReasonProps :
  1670. convertPropsIfTheyreFromJs(
  1671. nextJsProps,
  1672. thisJs##jsPropsToReason,
  1673. debugName,
  1674. );
  1675. let Element(oldComponent) = oldConvertedReasonProps;
  1676. let Element(newComponent) = newConvertedReasonProps;
  1677. let nextReasonState = nextState##reasonState;
  1678. let newSelf =
  1679. this##self(nextReasonState, Obj.magic(newComponent.retainedProps));
  1680. if (newComponent.shouldUpdate !== anyToTrue) {
  1681. let curState = thisJs##state;
  1682. let curReasonState = curState##reasonState;
  1683. let curReasonState = Obj.magic(curReasonState);
  1684. let newSelf = Obj.magic(newSelf);
  1685. /* bypass this##self call for small perf boost */
  1686. let oldSelf =
  1687. Obj.magic({
  1688. ...newSelf,
  1689. state: curReasonState,
  1690. retainedProps: oldComponent.retainedProps,
  1691. });
  1692. newComponent.shouldUpdate({oldSelf, newSelf});
  1693. } else {
  1694. true;
  1695. };
  1696. };
  1697. pub onUnmountMethod = subscription =>
  1698. switch (Js.Null.toOption(this##subscriptions)) {
  1699. | None => this##subscriptions#=(Js.Null.return([|subscription|]))
  1700. | Some(subs) => ignore(Js.Array.push(subscription, subs))
  1701. };
  1702. pub handleMethod = callback => {
  1703. let thisJs:
  1704. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1705. "this"
  1706. ];
  1707. callbackPayload => {
  1708. let curState = thisJs##state;
  1709. let curReasonState = curState##reasonState;
  1710. let convertedReasonProps =
  1711. convertPropsIfTheyreFromJs(
  1712. thisJs##props,
  1713. thisJs##jsPropsToReason,
  1714. debugName,
  1715. );
  1716. let Element(component) = convertedReasonProps;
  1717. callback(
  1718. callbackPayload,
  1719. Obj.magic(
  1720. this##self(curReasonState, Obj.magic(component.retainedProps)),
  1721. ),
  1722. );
  1723. };
  1724. };
  1725. pub sendMethod = (action: 'action) => {
  1726. let thisJs:
  1727. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1728. "this"
  1729. ];
  1730. let convertedReasonProps =
  1731. convertPropsIfTheyreFromJs(
  1732. thisJs##props,
  1733. thisJs##jsPropsToReason,
  1734. debugName,
  1735. );
  1736. let Element(component) = convertedReasonProps;
  1737. if (component.reducer !== reducerDefault) {
  1738. let sideEffects = ref(ignore);
  1739. /* allow side-effects to be executed here */
  1740. let partialStateApplication = component.reducer(Obj.magic(action));
  1741. thisJs##setState(
  1742. (curTotalState, _) => {
  1743. let curReasonState = curTotalState##reasonState;
  1744. let reasonStateUpdate =
  1745. partialStateApplication(Obj.magic(curReasonState));
  1746. if (reasonStateUpdate === NoUpdate) {
  1747. magicNull;
  1748. } else {
  1749. let reasonStateUpdate = Obj.magic(reasonStateUpdate);
  1750. let (performSideEffects, nextTotalState) =
  1751. this##transitionNextTotalState(
  1752. curTotalState,
  1753. reasonStateUpdate,
  1754. );
  1755. switch (performSideEffects) {
  1756. | Some(performSideEffects) =>
  1757. sideEffects.contents = performSideEffects
  1758. | None => ()
  1759. };
  1760. if (nextTotalState !== curTotalState) {
  1761. nextTotalState;
  1762. } else {
  1763. magicNull;
  1764. };
  1765. };
  1766. },
  1767. Js.Nullable.return(
  1768. this##handleMethod(((), self) => sideEffects.contents(self)),
  1769. ),
  1770. );
  1771. };
  1772. };
  1773. /***
  1774. * In order to ensure we always operate on freshest props / state, and to
  1775. * support the API that "reduces" the next state along with the next
  1776. * rendering, with full acccess to named argument props in the closure,
  1777. * we always *pre* compute the render result.
  1778. */
  1779. pub render = () => {
  1780. let thisJs:
  1781. jsComponentThis(reasonState, element, retainedProps, action) = [%bs.raw
  1782. "this"
  1783. ];
  1784. let convertedReasonProps =
  1785. convertPropsIfTheyreFromJs(
  1786. thisJs##props,
  1787. thisJs##jsPropsToReason,
  1788. debugName,
  1789. );
  1790. let Element(created) = Obj.magic(convertedReasonProps);
  1791. let component = created;
  1792. let curState = thisJs##state;
  1793. let curReasonState = Obj.magic(curState##reasonState);
  1794. let self =
  1795. Obj.magic(
  1796. this##self(curReasonState, Obj.magic(component.retainedProps)),
  1797. );
  1798. component.render(self);
  1799. }
  1800. },
  1801. );
  1802.  
  1803. let basicComponent = debugName => {
  1804. let componentTemplate = {
  1805. reactClassInternal: createClass(debugName),
  1806. debugName,
  1807. /* Keep here as a way to prove that the API may be implemented soundly */
  1808. handedOffState: {
  1809. contents: None,
  1810. },
  1811. didMount: anyToUnit,
  1812. willReceiveProps: willReceivePropsDefault,
  1813. didUpdate: anyToUnit,
  1814. willUnmount: anyToUnit,
  1815. willUpdate: anyToUnit,
  1816. /***
  1817. * Called when component will certainly mount at some point - and may be
  1818. * called on the sever for server side React rendering.
  1819. */
  1820. shouldUpdate: anyToTrue,
  1821. render: renderDefault,
  1822. initialState: initialStateDefault,
  1823. reducer: reducerDefault,
  1824. jsElementWrapped: None,
  1825. retainedProps: (),
  1826. subscriptions: subscriptionsDefault,
  1827. };
  1828. componentTemplate;
  1829. };
  1830.  
  1831. let statelessComponent =
  1832. debugName
  1833. : component(stateless, noRetainedProps, actionless) =>
  1834. basicComponent(debugName);
  1835.  
  1836. let statelessComponentWithRetainedProps =
  1837. debugName
  1838. : componentSpec(
  1839. stateless,
  1840. stateless,
  1841. 'retainedProps,
  1842. noRetainedProps,
  1843. actionless,
  1844. ) =>
  1845. basicComponent(debugName);
  1846.  
  1847. let reducerComponent =
  1848. debugName
  1849. : componentSpec(
  1850. 'state,
  1851. stateless,
  1852. noRetainedProps,
  1853. noRetainedProps,
  1854. 'action,
  1855. ) =>
  1856. basicComponent(debugName);
  1857.  
  1858. let reducerComponentWithRetainedProps =
  1859. debugName
  1860. : componentSpec(
  1861. 'state,
  1862. stateless,
  1863. 'retainedProps,
  1864. noRetainedProps,
  1865. 'action,
  1866. ) =>
  1867. basicComponent(debugName);
  1868.  
  1869.  
  1870. /***
  1871. * Convenience for creating React elements before we have a better JSX transform. Hopefully this makes it
  1872. * usable to build some components while waiting to migrate the JSX transform to the next API.
  1873. *
  1874. * Constrain the component here instead of relying on the Element constructor which would lead to confusing
  1875. * error messages.
  1876. */
  1877. let element =
  1878. (
  1879. ~key: string=Obj.magic(Js.Nullable.undefined),
  1880. ~ref: Js.nullable(reactRef) => unit=Obj.magic(Js.Nullable.undefined),
  1881. component: component('state, 'retainedProps, 'action),
  1882. ) => {
  1883. let element = Element(component);
  1884. switch (component.jsElementWrapped) {
  1885. | Some(jsElementWrapped) =>
  1886. jsElementWrapped(
  1887. ~key=Js.Nullable.return(key),
  1888. ~ref=Js.Nullable.return(ref),
  1889. )
  1890. | None =>
  1891. createElement(
  1892. component.reactClassInternal,
  1893. ~props={"key": key, "ref": ref, "reasonProps": element},
  1894. [||],
  1895. )
  1896. };
  1897. };
  1898.  
  1899. let wrapReasonForJs =
  1900. (
  1901. ~component,
  1902. jsPropsToReason:
  1903. jsPropsToReason('jsProps, 'state, 'retainedProps, 'action),
  1904. ) => {
  1905. let jsPropsToReason:
  1906. jsPropsToReason(jsProps, 'state, 'retainedProps, 'action) =
  1907. Obj.magic(jsPropsToReason) /* cast 'jsProps to jsProps */;
  1908. Obj.magic(component.reactClassInternal)##prototype##jsPropsToReason#=(
  1909. Some(
  1910. jsPropsToReason,
  1911. )
  1912. );
  1913. component.reactClassInternal;
  1914. };
  1915.  
  1916. module WrapProps = {
  1917. /* We wrap the props for reason->reason components, as a marker that "these props were passed from another
  1918. reason component" */
  1919. let wrapProps =
  1920. (
  1921. ~reactClass,
  1922. ~props,
  1923. children,
  1924. ~key: Js.nullable(string),
  1925. ~ref: Js.nullable(Js.nullable(reactRef) => unit),
  1926. ) => {
  1927. let props =
  1928. Js.Obj.assign(
  1929. Js.Obj.assign(Js.Obj.empty(), Obj.magic(props)),
  1930. {"ref": ref, "key": key},
  1931. );
  1932. let varargs =
  1933. [|Obj.magic(reactClass), Obj.magic(props)|]
  1934. |> Js.Array.concat(Obj.magic(children));
  1935. /* Use varargs under the hood */
  1936. Obj.magic(createElementVerbatim)##apply(Js.Nullable.null, varargs);
  1937. };
  1938. let dummyInteropComponent = basicComponent("interop");
  1939. let wrapJsForReason =
  1940. (~reactClass, ~props, children)
  1941. : component(stateless, noRetainedProps, _) => {
  1942. let jsElementWrapped = Some(wrapProps(~reactClass, ~props, children));
  1943. {...dummyInteropComponent, jsElementWrapped};
  1944. };
  1945. };
  1946.  
  1947. let wrapJsForReason = WrapProps.wrapJsForReason;
  1948.  
  1949. module Router = {
  1950. [@bs.get] external location : Dom.window => Dom.location = "";
  1951.  
  1952. [@bs.send]
  1953. /* actually the cb is Dom.event => unit, but let's restrict the access for now */
  1954. external addEventListener : (Dom.window, string, unit => unit) => unit = "";
  1955.  
  1956. [@bs.send]
  1957. external removeEventListener : (Dom.window, string, unit => unit) => unit =
  1958. "";
  1959.  
  1960. [@bs.send] external dispatchEvent : (Dom.window, Dom.event) => unit = "";
  1961.  
  1962. [@bs.get] external pathname : Dom.location => string = "";
  1963.  
  1964. [@bs.get] external hash : Dom.location => string = "";
  1965.  
  1966. [@bs.get] external search : Dom.location => string = "";
  1967.  
  1968. [@bs.send]
  1969. external pushState :
  1970. (Dom.history, [@bs.as {json|null|json}] _, [@bs.as ""] _, ~href: string) =>
  1971. unit =
  1972. "";
  1973.  
  1974. [@bs.val] external event : 'a = "Event";
  1975.  
  1976. [@bs.new] external makeEventIE11Compatible : string => Dom.event = "Event";
  1977.  
  1978. [@bs.val] [@bs.scope "document"]
  1979.  
  1980. external createEventNonIEBrowsers : string => Dom.event = "createEvent";
  1981.  
  1982. [@bs.send]
  1983. external initEventNonIEBrowsers : (Dom.event, string, bool, bool) => unit =
  1984. "initEvent";
  1985.  
  1986. let safeMakeEvent = eventName =>
  1987. if (Js.typeof(event) == "function") {
  1988. makeEventIE11Compatible(eventName);
  1989. } else {
  1990. let event = createEventNonIEBrowsers("Event");
  1991. initEventNonIEBrowsers(event, eventName, true, true);
  1992. event;
  1993. };
  1994.  
  1995. /* This is copied from array.ml. We want to cut dependencies for ReasonReact so
  1996. that it's friendlier to use in size-constrained codebases */
  1997. let arrayToList = a => {
  1998. let rec tolist = (i, res) =>
  1999. if (i < 0) {
  2000. res;
  2001. } else {
  2002. tolist(i - 1, [Array.unsafe_get(a, i), ...res]);
  2003. };
  2004. tolist(Array.length(a) - 1, []);
  2005. };
  2006. /* if we ever roll our own parser in the future, make sure you test all url combinations
  2007. e.g. foo.com/?#bar
  2008. */
  2009. /* sigh URLSearchParams doesn't work on IE11, edge16, etc. */
  2010. /* actually you know what, not gonna provide search for now. It's a mess.
  2011. We'll let users roll their own solution/data structure for now */
  2012. let path = () =>
  2013. switch ([%external window]) {
  2014. | None => []
  2015. | Some((window: Dom.window)) =>
  2016. switch (window |> location |> pathname) {
  2017. | ""
  2018. | "/" => []
  2019. | raw =>
  2020. /* remove the preceeding /, which every pathname seems to have */
  2021. let raw = Js.String.sliceToEnd(~from=1, raw);
  2022. /* remove the trailing /, which some pathnames might have. Ugh */
  2023. let raw =
  2024. switch (Js.String.get(raw, Js.String.length(raw) - 1)) {
  2025. | "/" => Js.String.slice(~from=0, ~to_=-1, raw)
  2026. | _ => raw
  2027. };
  2028. raw |> Js.String.split("/") |> arrayToList;
  2029. }
  2030. };
  2031. let hash = () =>
  2032. switch ([%external window]) {
  2033. | None => ""
  2034. | Some((window: Dom.window)) =>
  2035. switch (window |> location |> hash) {
  2036. | ""
  2037. | "#" => ""
  2038. | raw =>
  2039. /* remove the preceeding #, which every hash seems to have.
  2040. Why is this even included in location.hash?? */
  2041. raw |> Js.String.sliceToEnd(~from=1)
  2042. }
  2043. };
  2044. let search = () =>
  2045. switch ([%external window]) {
  2046. | None => ""
  2047. | Some((window: Dom.window)) =>
  2048. switch (window |> location |> search) {
  2049. | ""
  2050. | "?" => ""
  2051. | raw =>
  2052. /* remove the preceeding ?, which every search seems to have. */
  2053. raw |> Js.String.sliceToEnd(~from=1)
  2054. }
  2055. };
  2056. let push = path =>
  2057. switch ([%external history], [%external window]) {
  2058. | (None, _)
  2059. | (_, None) => ()
  2060. | (Some((history: Dom.history)), Some((window: Dom.window))) =>
  2061. pushState(history, ~href=path);
  2062. dispatchEvent(window, safeMakeEvent("popstate"));
  2063. };
  2064. type url = {
  2065. path: list(string),
  2066. hash: string,
  2067. search: string,
  2068. };
  2069. type watcherID = unit => unit;
  2070. let url = () => {path: path(), hash: hash(), search: search()};
  2071. /* alias exposed publicly */
  2072. let dangerouslyGetInitialUrl = url;
  2073. let watchUrl = callback =>
  2074. switch ([%external window]) {
  2075. | None => (() => ())
  2076. | Some((window: Dom.window)) =>
  2077. let watcherID = () => callback(url());
  2078. addEventListener(window, "popstate", watcherID);
  2079. watcherID;
  2080. };
  2081. let unwatchUrl = watcherID =>
  2082. switch ([%external window]) {
  2083. | None => ()
  2084. | Some((window: Dom.window)) =>
  2085. removeEventListener(window, "popstate", watcherID)
  2086. };
  2087. };
  2088.  
  2089. module Callback = {
  2090. type t('payload) = 'payload => unit;
  2091. let default = _event => ();
  2092. let chain = (handlerOne, handlerTwo, payload) => {
  2093. handlerOne(payload);
  2094. handlerTwo(payload);
  2095. };
  2096. };
  2097.  
  2098. };
  2099.  
  2100. module ReactDOMRe = {
  2101. #1 ReactDOMRe
  2102. /* First time reading an OCaml/Reason/BuckleScript file? */
  2103. /* `external` is the foreign function call in OCaml. */
  2104. /* here we're saying `I guarantee that on the JS side, we have a `render` function in the module "react-dom"
  2105. that takes in a reactElement, a dom element, and returns unit (nothing) */
  2106. /* It's like `let`, except you're pointing the implementation to the JS side. The compiler will inline these
  2107. calls and add the appropriate `require("react-dom")` in the file calling this `render` */
  2108. [@bs.val] [@bs.module "react-dom"]
  2109. external render : (ReasonReact.reactElement, Dom.element) => unit = "render";
  2110.  
  2111. [@bs.val]
  2112. external _getElementsByClassName : string => array(Dom.element) =
  2113. "document.getElementsByClassName";
  2114.  
  2115. [@bs.val] [@bs.return nullable]
  2116. external _getElementById : string => option(Dom.element) =
  2117. "document.getElementById";
  2118.  
  2119. let renderToElementWithClassName = (reactElement, className) =>
  2120. switch (_getElementsByClassName(className)) {
  2121. | [||] =>
  2122. raise(
  2123. Invalid_argument(
  2124. "ReactDOMRe.renderToElementWithClassName: no element of class "
  2125. ++ className
  2126. ++ " found in the HTML.",
  2127. ),
  2128. )
  2129. | elements => render(reactElement, Array.unsafe_get(elements, 0))
  2130. };
  2131.  
  2132. let renderToElementWithId = (reactElement, id) =>
  2133. switch (_getElementById(id)) {
  2134. | None =>
  2135. raise(
  2136. Invalid_argument(
  2137. "ReactDOMRe.renderToElementWithId : no element of id "
  2138. ++ id
  2139. ++ " found in the HTML.",
  2140. ),
  2141. )
  2142. | Some(element) => render(reactElement, element)
  2143. };
  2144.  
  2145. [@bs.val] [@bs.module "react-dom"]
  2146. external hydrate : (ReasonReact.reactElement, Dom.element) => unit = "hydrate";
  2147.  
  2148. let hydrateToElementWithClassName = (reactElement, className) =>
  2149. switch (_getElementsByClassName(className)) {
  2150. | [||] =>
  2151. raise(
  2152. Invalid_argument(
  2153. "ReactDOMRe.hydrateToElementWithClassName: no element of class "
  2154. ++ className
  2155. ++ " found in the HTML.",
  2156. ),
  2157. )
  2158. | elements => hydrate(reactElement, Array.unsafe_get(elements, 0))
  2159. };
  2160.  
  2161. let hydrateToElementWithId = (reactElement, id) =>
  2162. switch (_getElementById(id)) {
  2163. | None =>
  2164. raise(
  2165. Invalid_argument(
  2166. "ReactDOMRe.hydrateToElementWithId : no element of id "
  2167. ++ id
  2168. ++ " found in the HTML.",
  2169. ),
  2170. )
  2171. | Some(element) => hydrate(reactElement, element)
  2172. };
  2173.  
  2174. [@bs.val] [@bs.module "react-dom"]
  2175. external createPortal :
  2176. (ReasonReact.reactElement, Dom.element) => ReasonReact.reactElement =
  2177. "createPortal";
  2178.  
  2179. [@bs.val] [@bs.module "react-dom"]
  2180. external unmountComponentAtNode : Dom.element => unit =
  2181. "unmountComponentAtNode";
  2182.  
  2183. [@bs.val] [@bs.module "react-dom"]
  2184. external findDOMNode : ReasonReact.reactRef => Dom.element = "findDOMNode";
  2185.  
  2186. external domElementToObj : Dom.element => Js.t({..}) = "%identity";
  2187.  
  2188. type reactDOMProps;
  2189.  
  2190. external objToDOMProps : Js.t({..}) => reactDOMProps = "%identity";
  2191.  
  2192. type style;
  2193.  
  2194. /* This list isn't exhaustive. We'll add more as we go. */
  2195. [@bs.obj]
  2196. external props :
  2197. (
  2198. ~key: string=?,
  2199. ~ref: Js.nullable(Dom.element) => unit=?,
  2200. /* react textarea/input */
  2201. ~defaultChecked: bool=?,
  2202. ~defaultValue: string=?,
  2203. /* global html attributes */
  2204. ~accessKey: string=?,
  2205. ~className: string=?, /* substitute for "class" */
  2206. ~contentEditable: bool=?,
  2207. ~contextMenu: string=?,
  2208. ~dir: string=?, /* "ltr", "rtl" or "auto" */
  2209. ~draggable: bool=?,
  2210. ~hidden: bool=?,
  2211. ~id: string=?,
  2212. ~lang: string=?,
  2213. ~role: string=?, /* ARIA role */
  2214. ~style: style=?,
  2215. ~spellCheck: bool=?,
  2216. ~tabIndex: int=?,
  2217. ~title: string=?,
  2218. /* html5 microdata */
  2219. ~itemID: string=?,
  2220. ~itemProp: string=?,
  2221. ~itemRef: string=?,
  2222. ~itemScope: bool=?,
  2223. ~itemType: string=?, /* uri */
  2224. /* tag-specific html attributes */
  2225. ~accept: string=?,
  2226. ~acceptCharset: string=?,
  2227. ~action: string=?, /* uri */
  2228. ~allowFullScreen: bool=?,
  2229. ~alt: string=?,
  2230. ~async: bool=?,
  2231. ~autoComplete: string=?, /* has a fixed, but large-ish, set of possible values */
  2232. ~autoFocus: bool=?,
  2233. ~autoPlay: bool=?,
  2234. ~challenge: string=?,
  2235. ~charSet: string=?,
  2236. ~checked: bool=?,
  2237. ~cite: string=?, /* uri */
  2238. ~crossorigin: bool=?,
  2239. ~cols: int=?,
  2240. ~colSpan: int=?,
  2241. ~content: string=?,
  2242. ~controls: bool=?,
  2243. ~coords: string=?, /* set of values specifying the coordinates of a region */
  2244. ~data: string=?, /* uri */
  2245. ~dateTime: string=?, /* "valid date string with optional time" */
  2246. ~default: bool=?,
  2247. ~defer: bool=?,
  2248. ~disabled: bool=?,
  2249. ~download: string=?, /* should really be either a boolean, signifying presence, or a string */
  2250. ~encType: string=?, /* "application/x-www-form-urlencoded", "multipart/form-data" or "text/plain" */
  2251. ~form: string=?,
  2252. ~formAction: string=?, /* uri */
  2253. ~formTarget: string=?, /* "_blank", "_self", etc. */
  2254. ~formMethod: string=?, /* "post", "get", "put" */
  2255. ~headers: string=?,
  2256. ~height: string=?, /* in html5 this can only be a number, but in html4 it can ba a percentage as well */
  2257. ~high: int=?,
  2258. ~href: string=?, /* uri */
  2259. ~hrefLang: string=?,
  2260. ~htmlFor: string=?, /* substitute for "for" */
  2261. ~httpEquiv: string=?, /* has a fixed set of possible values */
  2262. ~icon: string=?, /* uri? */
  2263. ~inputMode: string=?, /* "verbatim", "latin", "numeric", etc. */
  2264. ~integrity: string=?,
  2265. ~keyType: string=?,
  2266. ~kind: string=?, /* has a fixed set of possible values */
  2267. ~label: string=?,
  2268. ~list: string=?,
  2269. ~loop: bool=?,
  2270. ~low: int=?,
  2271. ~manifest: string=?, /* uri */
  2272. ~max: string=?, /* should be int or Js.Date.t */
  2273. ~maxLength: int=?,
  2274. ~media: string=?, /* a valid media query */
  2275. ~mediaGroup: string=?,
  2276. ~method: string=?, /* "post" or "get" */
  2277. ~min: int=?,
  2278. ~minLength: int=?,
  2279. ~multiple: bool=?,
  2280. ~muted: bool=?,
  2281. ~name: string=?,
  2282. ~nonce: string=?,
  2283. ~noValidate: bool=?,
  2284. ~_open: bool=?,
  2285. ~optimum: int=?,
  2286. ~pattern: string=?, /* valid Js RegExp */
  2287. ~placeholder: string=?,
  2288. ~poster: string=?, /* uri */
  2289. ~preload: string=?, /* "none", "metadata" or "auto" (and "" as a synonym for "auto") */
  2290. ~radioGroup: string=?,
  2291. ~readOnly: bool=?,
  2292. ~rel: string=?, /* a space- or comma-separated (depending on the element) list of a fixed set of "link types" */
  2293. ~required: bool=?,
  2294. ~reversed: bool=?,
  2295. ~rows: int=?,
  2296. ~rowSpan: int=?,
  2297. ~sandbox: string=?, /* has a fixed set of possible values */
  2298. ~scope: string=?, /* has a fixed set of possible values */
  2299. ~scoped: bool=?,
  2300. ~scrolling: string=?, /* html4 only, "auto", "yes" or "no" */
  2301. /* seamless - supported by React, but removed from the html5 spec */
  2302. ~selected: bool=?,
  2303. ~shape: string=?,
  2304. ~size: int=?,
  2305. ~sizes: string=?,
  2306. ~span: int=?,
  2307. ~src: string=?, /* uri */
  2308. ~srcDoc: string=?,
  2309. ~srcLang: string=?,
  2310. ~srcSet: string=?,
  2311. ~start: int=?,
  2312. ~step: float=?,
  2313. ~summary: string=?, /* deprecated */
  2314. ~target: string=?,
  2315. ~_type: string=?, /* has a fixed but large-ish set of possible values */
  2316. ~useMap: string=?,
  2317. ~value: string=?,
  2318. ~width: string=?, /* in html5 this can only be a number, but in html4 it can ba a percentage as well */
  2319. ~wrap: string=?, /* "hard" or "soft" */
  2320. /* Clipboard events */
  2321. ~onCopy: ReactEventRe.Clipboard.t => unit=?,
  2322. ~onCut: ReactEventRe.Clipboard.t => unit=?,
  2323. ~onPaste: ReactEventRe.Clipboard.t => unit=?,
  2324. /* Composition events */
  2325. ~onCompositionEnd: ReactEventRe.Composition.t => unit=?,
  2326. ~onCompositionStart: ReactEventRe.Composition.t => unit=?,
  2327. ~onCompositionUpdate: ReactEventRe.Composition.t => unit=?,
  2328. /* Keyboard events */
  2329. ~onKeyDown: ReactEventRe.Keyboard.t => unit=?,
  2330. ~onKeyPress: ReactEventRe.Keyboard.t => unit=?,
  2331. ~onKeyUp: ReactEventRe.Keyboard.t => unit=?,
  2332. /* Focus events */
  2333. ~onFocus: ReactEventRe.Focus.t => unit=?,
  2334. ~onBlur: ReactEventRe.Focus.t => unit=?,
  2335. /* Form events */
  2336. ~onChange: ReactEventRe.Form.t => unit=?,
  2337. ~onInput: ReactEventRe.Form.t => unit=?,
  2338. ~onSubmit: ReactEventRe.Form.t => unit=?,
  2339. /* Mouse events */
  2340. ~onClick: ReactEventRe.Mouse.t => unit=?,
  2341. ~onContextMenu: ReactEventRe.Mouse.t => unit=?,
  2342. ~onDoubleClick: ReactEventRe.Mouse.t => unit=?,
  2343. ~onDrag: ReactEventRe.Mouse.t => unit=?,
  2344. ~onDragEnd: ReactEventRe.Mouse.t => unit=?,
  2345. ~onDragEnter: ReactEventRe.Mouse.t => unit=?,
  2346. ~onDragExit: ReactEventRe.Mouse.t => unit=?,
  2347. ~onDragLeave: ReactEventRe.Mouse.t => unit=?,
  2348. ~onDragOver: ReactEventRe.Mouse.t => unit=?,
  2349. ~onDragStart: ReactEventRe.Mouse.t => unit=?,
  2350. ~onDrop: ReactEventRe.Mouse.t => unit=?,
  2351. ~onMouseDown: ReactEventRe.Mouse.t => unit=?,
  2352. ~onMouseEnter: ReactEventRe.Mouse.t => unit=?,
  2353. ~onMouseLeave: ReactEventRe.Mouse.t => unit=?,
  2354. ~onMouseMove: ReactEventRe.Mouse.t => unit=?,
  2355. ~onMouseOut: ReactEventRe.Mouse.t => unit=?,
  2356. ~onMouseOver: ReactEventRe.Mouse.t => unit=?,
  2357. ~onMouseUp: ReactEventRe.Mouse.t => unit=?,
  2358. /* Selection events */
  2359. ~onSelect: ReactEventRe.Selection.t => unit=?,
  2360. /* Touch events */
  2361. ~onTouchCancel: ReactEventRe.Touch.t => unit=?,
  2362. ~onTouchEnd: ReactEventRe.Touch.t => unit=?,
  2363. ~onTouchMove: ReactEventRe.Touch.t => unit=?,
  2364. ~onTouchStart: ReactEventRe.Touch.t => unit=?,
  2365. /* UI events */
  2366. ~onScroll: ReactEventRe.UI.t => unit=?,
  2367. /* Wheel events */
  2368. ~onWheel: ReactEventRe.Wheel.t => unit=?,
  2369. /* Media events */
  2370. ~onAbort: ReactEventRe.Media.t => unit=?,
  2371. ~onCanPlay: ReactEventRe.Media.t => unit=?,
  2372. ~onCanPlayThrough: ReactEventRe.Media.t => unit=?,
  2373. ~onDurationChange: ReactEventRe.Media.t => unit=?,
  2374. ~onEmptied: ReactEventRe.Media.t => unit=?,
  2375. ~onEncrypetd: ReactEventRe.Media.t => unit=?,
  2376. ~onEnded: ReactEventRe.Media.t => unit=?,
  2377. ~onError: ReactEventRe.Media.t => unit=?,
  2378. ~onLoadedData: ReactEventRe.Media.t => unit=?,
  2379. ~onLoadedMetadata: ReactEventRe.Media.t => unit=?,
  2380. ~onLoadStart: ReactEventRe.Media.t => unit=?,
  2381. ~onPause: ReactEventRe.Media.t => unit=?,
  2382. ~onPlay: ReactEventRe.Media.t => unit=?,
  2383. ~onPlaying: ReactEventRe.Media.t => unit=?,
  2384. ~onProgress: ReactEventRe.Media.t => unit=?,
  2385. ~onRateChange: ReactEventRe.Media.t => unit=?,
  2386. ~onSeeked: ReactEventRe.Media.t => unit=?,
  2387. ~onSeeking: ReactEventRe.Media.t => unit=?,
  2388. ~onStalled: ReactEventRe.Media.t => unit=?,
  2389. ~onSuspend: ReactEventRe.Media.t => unit=?,
  2390. ~onTimeUpdate: ReactEventRe.Media.t => unit=?,
  2391. ~onVolumeChange: ReactEventRe.Media.t => unit=?,
  2392. ~onWaiting: ReactEventRe.Media.t => unit=?,
  2393. /* Image events */
  2394. ~onLoad: ReactEventRe.Image.t => unit=? /* duplicate */, /*~onError: ReactEventRe.Image.t => unit=?,*/
  2395. /* Animation events */
  2396. ~onAnimationStart: ReactEventRe.Animation.t => unit=?,
  2397. ~onAnimationEnd: ReactEventRe.Animation.t => unit=?,
  2398. ~onAnimationIteration: ReactEventRe.Animation.t => unit=?,
  2399. /* Transition events */
  2400. ~onTransitionEnd: ReactEventRe.Transition.t => unit=?,
  2401. /* svg */
  2402. ~accentHeight: string=?,
  2403. ~accumulate: string=?,
  2404. ~additive: string=?,
  2405. ~alignmentBaseline: string=?,
  2406. ~allowReorder: string=?,
  2407. ~alphabetic: string=?,
  2408. ~amplitude: string=?,
  2409. ~arabicForm: string=?,
  2410. ~ascent: string=?,
  2411. ~attributeName: string=?,
  2412. ~attributeType: string=?,
  2413. ~autoReverse: string=?,
  2414. ~azimuth: string=?,
  2415. ~baseFrequency: string=?,
  2416. ~baseProfile: string=?,
  2417. ~baselineShift: string=?,
  2418. ~bbox: string=?,
  2419. ~_begin: string=?,
  2420. ~bias: string=?,
  2421. ~by: string=?,
  2422. ~calcMode: string=?,
  2423. ~capHeight: string=?,
  2424. ~clip: string=?,
  2425. ~clipPath: string=?,
  2426. ~clipPathUnits: string=?,
  2427. ~clipRule: string=?,
  2428. ~colorInterpolation: string=?,
  2429. ~colorInterpolationFilters: string=?,
  2430. ~colorProfile: string=?,
  2431. ~colorRendering: string=?,
  2432. ~contentScriptType: string=?,
  2433. ~contentStyleType: string=?,
  2434. ~cursor: string=?,
  2435. ~cx: string=?,
  2436. ~cy: string=?,
  2437. ~d: string=?,
  2438. ~decelerate: string=?,
  2439. ~descent: string=?,
  2440. ~diffuseConstant: string=?,
  2441. ~direction: string=?,
  2442. ~display: string=?,
  2443. ~divisor: string=?,
  2444. ~dominantBaseline: string=?,
  2445. ~dur: string=?,
  2446. ~dx: string=?,
  2447. ~dy: string=?,
  2448. ~edgeMode: string=?,
  2449. ~elevation: string=?,
  2450. ~enableBackground: string=?,
  2451. ~_end: string=?,
  2452. ~exponent: string=?,
  2453. ~externalResourcesRequired: string=?,
  2454. ~fill: string=?,
  2455. ~fillOpacity: string=?,
  2456. ~fillRule: string=?,
  2457. ~filter: string=?,
  2458. ~filterRes: string=?,
  2459. ~filterUnits: string=?,
  2460. ~floodColor: string=?,
  2461. ~floodOpacity: string=?,
  2462. ~focusable: string=?,
  2463. ~fontFamily: string=?,
  2464. ~fontSize: string=?,
  2465. ~fontSizeAdjust: string=?,
  2466. ~fontStretch: string=?,
  2467. ~fontStyle: string=?,
  2468. ~fontVariant: string=?,
  2469. ~fontWeight: string=?,
  2470. ~fomat: string=?,
  2471. ~from: string=?,
  2472. ~fx: string=?,
  2473. ~fy: string=?,
  2474. ~g1: string=?,
  2475. ~g2: string=?,
  2476. ~glyphName: string=?,
  2477. ~glyphOrientationHorizontal: string=?,
  2478. ~glyphOrientationVertical: string=?,
  2479. ~glyphRef: string=?,
  2480. ~gradientTransform: string=?,
  2481. ~gradientUnits: string=?,
  2482. ~hanging: string=?,
  2483. ~horizAdvX: string=?,
  2484. ~horizOriginX: string=?,
  2485. ~ideographic: string=?,
  2486. ~imageRendering: string=?,
  2487. ~_in: string=?,
  2488. ~in2: string=?,
  2489. ~intercept: string=?,
  2490. ~k: string=?,
  2491. ~k1: string=?,
  2492. ~k2: string=?,
  2493. ~k3: string=?,
  2494. ~k4: string=?,
  2495. ~kernelMatrix: string=?,
  2496. ~kernelUnitLength: string=?,
  2497. ~kerning: string=?,
  2498. ~keyPoints: string=?,
  2499. ~keySplines: string=?,
  2500. ~keyTimes: string=?,
  2501. ~lengthAdjust: string=?,
  2502. ~letterSpacing: string=?,
  2503. ~lightingColor: string=?,
  2504. ~limitingConeAngle: string=?,
  2505. ~local: string=?,
  2506. ~markerEnd: string=?,
  2507. ~markerHeight: string=?,
  2508. ~markerMid: string=?,
  2509. ~markerStart: string=?,
  2510. ~markerUnits: string=?,
  2511. ~markerWidth: string=?,
  2512. ~mask: string=?,
  2513. ~maskContentUnits: string=?,
  2514. ~maskUnits: string=?,
  2515. ~mathematical: string=?,
  2516. ~mode: string=?,
  2517. ~numOctaves: string=?,
  2518. ~offset: string=?,
  2519. ~opacity: string=?,
  2520. ~operator: string=?,
  2521. ~order: string=?,
  2522. ~orient: string=?,
  2523. ~orientation: string=?,
  2524. ~origin: string=?,
  2525. ~overflow: string=?,
  2526. ~overflowX: string=?,
  2527. ~overflowY: string=?,
  2528. ~overlinePosition: string=?,
  2529. ~overlineThickness: string=?,
  2530. ~paintOrder: string=?,
  2531. ~panose1: string=?,
  2532. ~pathLength: string=?,
  2533. ~patternContentUnits: string=?,
  2534. ~patternTransform: string=?,
  2535. ~patternUnits: string=?,
  2536. ~pointerEvents: string=?,
  2537. ~points: string=?,
  2538. ~pointsAtX: string=?,
  2539. ~pointsAtY: string=?,
  2540. ~pointsAtZ: string=?,
  2541. ~preserveAlpha: string=?,
  2542. ~preserveAspectRatio: string=?,
  2543. ~primitiveUnits: string=?,
  2544. ~r: string=?,
  2545. ~radius: string=?,
  2546. ~refX: string=?,
  2547. ~refY: string=?,
  2548. ~renderingIntent: string=?,
  2549. ~repeatCount: string=?,
  2550. ~repeatDur: string=?,
  2551. ~requiredExtensions: string=?,
  2552. ~requiredFeatures: string=?,
  2553. ~restart: string=?,
  2554. ~result: string=?,
  2555. ~rotate: string=?,
  2556. ~rx: string=?,
  2557. ~ry: string=?,
  2558. ~scale: string=?,
  2559. ~seed: string=?,
  2560. ~shapeRendering: string=?,
  2561. ~slope: string=?,
  2562. ~spacing: string=?,
  2563. ~specularConstant: string=?,
  2564. ~specularExponent: string=?,
  2565. ~speed: string=?,
  2566. ~spreadMethod: string=?,
  2567. ~startOffset: string=?,
  2568. ~stdDeviation: string=?,
  2569. ~stemh: string=?,
  2570. ~stemv: string=?,
  2571. ~stitchTiles: string=?,
  2572. ~stopColor: string=?,
  2573. ~stopOpacity: string=?,
  2574. ~strikethroughPosition: string=?,
  2575. ~strikethroughThickness: string=?,
  2576. ~string: string=?,
  2577. ~stroke: string=?,
  2578. ~strokeDasharray: string=?,
  2579. ~strokeDashoffset: string=?,
  2580. ~strokeLinecap: string=?,
  2581. ~strokeLinejoin: string=?,
  2582. ~strokeMiterlimit: string=?,
  2583. ~strokeOpacity: string=?,
  2584. ~strokeWidth: string=?,
  2585. ~surfaceScale: string=?,
  2586. ~systemLanguage: string=?,
  2587. ~tableValues: string=?,
  2588. ~targetX: string=?,
  2589. ~targetY: string=?,
  2590. ~textAnchor: string=?,
  2591. ~textDecoration: string=?,
  2592. ~textLength: string=?,
  2593. ~textRendering: string=?,
  2594. ~_to: string=?,
  2595. ~transform: string=?,
  2596. ~u1: string=?,
  2597. ~u2: string=?,
  2598. ~underlinePosition: string=?,
  2599. ~underlineThickness: string=?,
  2600. ~unicode: string=?,
  2601. ~unicodeBidi: string=?,
  2602. ~unicodeRange: string=?,
  2603. ~unitsPerEm: string=?,
  2604. ~vAlphabetic: string=?,
  2605. ~vHanging: string=?,
  2606. ~vIdeographic: string=?,
  2607. ~vMathematical: string=?,
  2608. ~values: string=?,
  2609. ~vectorEffect: string=?,
  2610. ~version: string=?,
  2611. ~vertAdvX: string=?,
  2612. ~vertAdvY: string=?,
  2613. ~vertOriginX: string=?,
  2614. ~vertOriginY: string=?,
  2615. ~viewBox: string=?,
  2616. ~viewTarget: string=?,
  2617. ~visibility: string=?,
  2618. /*width::string? =>*/
  2619. ~widths: string=?,
  2620. ~wordSpacing: string=?,
  2621. ~writingMode: string=?,
  2622. ~x: string=?,
  2623. ~x1: string=?,
  2624. ~x2: string=?,
  2625. ~xChannelSelector: string=?,
  2626. ~xHeight: string=?,
  2627. ~xlinkActuate: string=?,
  2628. ~xlinkArcrole: string=?,
  2629. ~xlinkHref: string=?,
  2630. ~xlinkRole: string=?,
  2631. ~xlinkShow: string=?,
  2632. ~xlinkTitle: string=?,
  2633. ~xlinkType: string=?,
  2634. ~xmlns: string=?,
  2635. ~xmlnsXlink: string=?,
  2636. ~xmlBase: string=?,
  2637. ~xmlLang: string=?,
  2638. ~xmlSpace: string=?,
  2639. ~y: string=?,
  2640. ~y1: string=?,
  2641. ~y2: string=?,
  2642. ~yChannelSelector: string=?,
  2643. ~z: string=?,
  2644. ~zoomAndPan: string=?,
  2645. /* RDFa */
  2646. ~about: string=?,
  2647. ~datatype: string=?,
  2648. ~inlist: string=?,
  2649. ~prefix: string=?,
  2650. ~property: string=?,
  2651. ~resource: string=?,
  2652. ~typeof: string=?,
  2653. ~vocab: string=?,
  2654. /* react-specific */
  2655. ~dangerouslySetInnerHTML: {. "__html": string}=?,
  2656. ~suppressContentEditableWarning: bool=?,
  2657. unit
  2658. ) =>
  2659. reactDOMProps =
  2660. "";
  2661.  
  2662. [@bs.splice] [@bs.val] [@bs.module "react"]
  2663. external createElement :
  2664. (string, ~props: reactDOMProps=?, array(ReasonReact.reactElement)) =>
  2665. ReasonReact.reactElement =
  2666. "createElement";
  2667.  
  2668. module Style = {
  2669. type t = style;
  2670. [@bs.obj]
  2671. external make :
  2672. (
  2673. ~azimuth: string=?,
  2674. ~background: string=?,
  2675. ~backgroundAttachment: string=?,
  2676. ~backgroundColor: string=?,
  2677. ~backgroundImage: string=?,
  2678. ~backgroundPosition: string=?,
  2679. ~backgroundRepeat: string=?,
  2680. ~border: string=?,
  2681. ~borderCollapse: string=?,
  2682. ~borderColor: string=?,
  2683. ~borderSpacing: string=?,
  2684. ~borderStyle: string=?,
  2685. ~borderTop: string=?,
  2686. ~borderRight: string=?,
  2687. ~borderBottom: string=?,
  2688. ~borderLeft: string=?,
  2689. ~borderTopColor: string=?,
  2690. ~borderRightColor: string=?,
  2691. ~borderBottomColor: string=?,
  2692. ~borderLeftColor: string=?,
  2693. ~borderTopStyle: string=?,
  2694. ~borderRightStyle: string=?,
  2695. ~borderBottomStyle: string=?,
  2696. ~borderLeftStyle: string=?,
  2697. ~borderTopWidth: string=?,
  2698. ~borderRightWidth: string=?,
  2699. ~borderBottomWidth: string=?,
  2700. ~borderLeftWidth: string=?,
  2701. ~borderWidth: string=?,
  2702. ~bottom: string=?,
  2703. ~captionSide: string=?,
  2704. ~clear: string=?,
  2705. ~clip: string=?,
  2706. ~color: string=?,
  2707. ~content: string=?,
  2708. ~counterIncrement: string=?,
  2709. ~counterReset: string=?,
  2710. ~cue: string=?,
  2711. ~cueAfter: string=?,
  2712. ~cueBefore: string=?,
  2713. ~cursor: string=?,
  2714. ~direction: string=?,
  2715. ~display: string=?,
  2716. ~elevation: string=?,
  2717. ~emptyCells: string=?,
  2718. ~float: string=?,
  2719. ~font: string=?,
  2720. ~fontFamily: string=?,
  2721. ~fontSize: string=?,
  2722. ~fontSizeAdjust: string=?,
  2723. ~fontStretch: string=?,
  2724. ~fontStyle: string=?,
  2725. ~fontVariant: string=?,
  2726. ~fontWeight: string=?,
  2727. ~height: string=?,
  2728. ~left: string=?,
  2729. ~letterSpacing: string=?,
  2730. ~lineHeight: string=?,
  2731. ~listStyle: string=?,
  2732. ~listStyleImage: string=?,
  2733. ~listStylePosition: string=?,
  2734. ~listStyleType: string=?,
  2735. ~margin: string=?,
  2736. ~marginTop: string=?,
  2737. ~marginRight: string=?,
  2738. ~marginBottom: string=?,
  2739. ~marginLeft: string=?,
  2740. ~markerOffset: string=?,
  2741. ~marks: string=?,
  2742. ~maxHeight: string=?,
  2743. ~maxWidth: string=?,
  2744. ~minHeight: string=?,
  2745. ~minWidth: string=?,
  2746. ~orphans: string=?,
  2747. ~outline: string=?,
  2748. ~outlineColor: string=?,
  2749. ~outlineStyle: string=?,
  2750. ~outlineWidth: string=?,
  2751. ~overflow: string=?,
  2752. ~overflowX: string=?,
  2753. ~overflowY: string=?,
  2754. ~padding: string=?,
  2755. ~paddingTop: string=?,
  2756. ~paddingRight: string=?,
  2757. ~paddingBottom: string=?,
  2758. ~paddingLeft: string=?,
  2759. ~page: string=?,
  2760. ~pageBreakAfter: string=?,
  2761. ~pageBreakBefore: string=?,
  2762. ~pageBreakInside: string=?,
  2763. ~pause: string=?,
  2764. ~pauseAfter: string=?,
  2765. ~pauseBefore: string=?,
  2766. ~pitch: string=?,
  2767. ~pitchRange: string=?,
  2768. ~playDuring: string=?,
  2769. ~position: string=?,
  2770. ~quotes: string=?,
  2771. ~richness: string=?,
  2772. ~right: string=?,
  2773. ~size: string=?,
  2774. ~speak: string=?,
  2775. ~speakHeader: string=?,
  2776. ~speakNumeral: string=?,
  2777. ~speakPunctuation: string=?,
  2778. ~speechRate: string=?,
  2779. ~stress: string=?,
  2780. ~tableLayout: string=?,
  2781. ~textAlign: string=?,
  2782. ~textDecoration: string=?,
  2783. ~textIndent: string=?,
  2784. ~textShadow: string=?,
  2785. ~textTransform: string=?,
  2786. ~top: string=?,
  2787. ~unicodeBidi: string=?,
  2788. ~verticalAlign: string=?,
  2789. ~visibility: string=?,
  2790. ~voiceFamily: string=?,
  2791. ~volume: string=?,
  2792. ~whiteSpace: string=?,
  2793. ~widows: string=?,
  2794. ~width: string=?,
  2795. ~wordSpacing: string=?,
  2796. ~zIndex: string=?,
  2797. /* Below properties based on https://www.w3.org/Style/CSS/all-properties */
  2798. /* Color Level 3 - REC */
  2799. ~opacity: string=?,
  2800. /* Backgrounds and Borders Level 3 - CR */
  2801. /* backgroundRepeat - already defined by CSS2Properties */
  2802. /* backgroundAttachment - already defined by CSS2Properties */
  2803. ~backgroundOrigin: string=?,
  2804. ~backgroundSize: string=?,
  2805. ~backgroundClip: string=?,
  2806. ~borderRadius: string=?,
  2807. ~borderTopLeftRadius: string=?,
  2808. ~borderTopRightRadius: string=?,
  2809. ~borderBottomLeftRadius: string=?,
  2810. ~borderBottomRightRadius: string=?,
  2811. ~borderImage: string=?,
  2812. ~borderImageSource: string=?,
  2813. ~borderImageSlice: string=?,
  2814. ~borderImageWidth: string=?,
  2815. ~borderImageOutset: string=?,
  2816. ~borderImageRepeat: string=?,
  2817. ~boxShadow: string=?,
  2818. /* Multi-column Layout - CR */
  2819. ~columns: string=?,
  2820. ~columnCount: string=?,
  2821. ~columnFill: string=?,
  2822. ~columnGap: string=?,
  2823. ~columnRule: string=?,
  2824. ~columnRuleColor: string=?,
  2825. ~columnRuleStyle: string=?,
  2826. ~columnRuleWidth: string=?,
  2827. ~columnSpan: string=?,
  2828. ~columnWidth: string=?,
  2829. ~breakAfter: string=?,
  2830. ~breakBefore: string=?,
  2831. ~breakInside: string=?,
  2832. /* Speech - CR */
  2833. ~rest: string=?,
  2834. ~restAfter: string=?,
  2835. ~restBefore: string=?,
  2836. ~speakAs: string=?,
  2837. ~voiceBalance: string=?,
  2838. ~voiceDuration: string=?,
  2839. ~voicePitch: string=?,
  2840. ~voiceRange: string=?,
  2841. ~voiceRate: string=?,
  2842. ~voiceStress: string=?,
  2843. ~voiceVolume: string=?,
  2844. /* Image Values and Replaced Content Level 3 - CR */
  2845. ~objectFit: string=?,
  2846. ~objectPosition: string=?,
  2847. ~imageResolution: string=?,
  2848. ~imageOrientation: string=?,
  2849. /* Flexible Box Layout - CR */
  2850. ~alignContent: string=?,
  2851. ~alignItems: string=?,
  2852. ~alignSelf: string=?,
  2853. ~flex: string=?,
  2854. ~flexBasis: string=?,
  2855. ~flexDirection: string=?,
  2856. ~flexFlow: string=?,
  2857. ~flexGrow: string=?,
  2858. ~flexShrink: string=?,
  2859. ~flexWrap: string=?,
  2860. ~justifyContent: string=?,
  2861. ~order: string=?,
  2862. /* Text Decoration Level 3 - CR */
  2863. /* textDecoration - already defined by CSS2Properties */
  2864. ~textDecorationColor: string=?,
  2865. ~textDecorationLine: string=?,
  2866. ~textDecorationSkip: string=?,
  2867. ~textDecorationStyle: string=?,
  2868. ~textEmphasis: string=?,
  2869. ~textEmphasisColor: string=?,
  2870. ~textEmphasisPosition: string=?,
  2871. ~textEmphasisStyle: string=?,
  2872. /* textShadow - already defined by CSS2Properties */
  2873. ~textUnderlinePosition: string=?,
  2874. /* Fonts Level 3 - CR */
  2875. ~fontFeatureSettings: string=?,
  2876. ~fontKerning: string=?,
  2877. ~fontLanguageOverride: string=?,
  2878. /* fontSizeAdjust - already defined by CSS2Properties */
  2879. /* fontStretch - already defined by CSS2Properties */
  2880. ~fontSynthesis: string=?,
  2881. ~forntVariantAlternates: string=?,
  2882. ~fontVariantCaps: string=?,
  2883. ~fontVariantEastAsian: string=?,
  2884. ~fontVariantLigatures: string=?,
  2885. ~fontVariantNumeric: string=?,
  2886. ~fontVariantPosition: string=?,
  2887. /* Cascading and Inheritance Level 3 - CR */
  2888. ~all: string=?,
  2889. /* Writing Modes Level 3 - CR */
  2890. ~glyphOrientationVertical: string=?,
  2891. ~textCombineUpright: string=?,
  2892. ~textOrientation: string=?,
  2893. ~writingMode: string=?,
  2894. /* Shapes Level 1 - CR */
  2895. ~shapeImageThreshold: string=?,
  2896. ~shapeMargin: string=?,
  2897. ~shapeOutside: string=?,
  2898. /* Masking Level 1 - CR */
  2899. ~clipPath: string=?,
  2900. ~clipRule: string=?,
  2901. ~mask: string=?,
  2902. ~maskBorder: string=?,
  2903. ~maskBorderMode: string=?,
  2904. ~maskBorderOutset: string=?,
  2905. ~maskBorderRepeat: string=?,
  2906. ~maskBorderSlice: string=?,
  2907. ~maskBorderSource: string=?,
  2908. ~maskBorderWidth: string=?,
  2909. ~maskClip: string=?,
  2910. ~maskComposite: string=?,
  2911. ~maskImage: string=?,
  2912. ~maskMode: string=?,
  2913. ~maskOrigin: string=?,
  2914. ~maskPosition: string=?,
  2915. ~maskRepeat: string=?,
  2916. ~maskSize: string=?,
  2917. ~maskType: string=?,
  2918. /* Compositing and Blending Level 1 - CR */
  2919. ~backgroundBlendMode: string=?,
  2920. ~isolation: string=?,
  2921. ~mixBlendMode: string=?,
  2922. /* Fragmentation Level 3 - CR */
  2923. ~boxDecorationBreak: string=?,
  2924. /* breakAfter - already defined by Multi-column Layout */
  2925. /* breakBefore - already defined by Multi-column Layout */
  2926. /* breakInside - already defined by Multi-column Layout */
  2927. /* Basic User Interface Level 3 - CR */
  2928. ~boxSizing: string=?,
  2929. ~caretColor: string=?,
  2930. ~navDown: string=?,
  2931. ~navLeft: string=?,
  2932. ~navRight: string=?,
  2933. ~navUp: string=?,
  2934. ~outlineOffset: string=?,
  2935. ~resize: string=?,
  2936. ~textOverflow: string=?,
  2937. /* Grid Layout Level 1 - CR */
  2938. ~grid: string=?,
  2939. ~gridArea: string=?,
  2940. ~gridAutoColumns: string=?,
  2941. ~gridAutoFlow: string=?,
  2942. ~gridAutoRows: string=?,
  2943. ~gridColumn: string=?,
  2944. ~gridColumnEnd: string=?,
  2945. ~gridColumnGap: string=?,
  2946. ~gridColumnStart: string=?,
  2947. ~gridGap: string=?,
  2948. ~gridRow: string=?,
  2949. ~gridRowEnd: string=?,
  2950. ~gridRowGap: string=?,
  2951. ~gridRowStart: string=?,
  2952. ~gridTemplate: string=?,
  2953. ~gridTemplateAreas: string=?,
  2954. ~gridTemplateColumns: string=?,
  2955. ~gridTemplateRows: string=?,
  2956. /* Will Change Level 1 - CR */
  2957. ~willChange: string=?,
  2958. /* Text Level 3 - LC */
  2959. ~hangingPunctuation: string=?,
  2960. ~hyphens: string=?,
  2961. /* letterSpacing - already defined by CSS2Properties */
  2962. ~lineBreak: string=?,
  2963. ~overflowWrap: string=?,
  2964. ~tabSize: string=?,
  2965. /* textAlign - already defined by CSS2Properties */
  2966. ~textAlignLast: string=?,
  2967. ~textJustify: string=?,
  2968. ~wordBreak: string=?,
  2969. ~wordWrap: string=?,
  2970. /* Animations - WD */
  2971. ~animation: string=?,
  2972. ~animationDelay: string=?,
  2973. ~animationDirection: string=?,
  2974. ~animationDuration: string=?,
  2975. ~animationFillMode: string=?,
  2976. ~animationIterationCount: string=?,
  2977. ~animationName: string=?,
  2978. ~animationPlayState: string=?,
  2979. ~animationTimingFunction: string=?,
  2980. /* Transitions - WD */
  2981. ~transition: string=?,
  2982. ~transitionDelay: string=?,
  2983. ~transitionDuration: string=?,
  2984. ~transitionProperty: string=?,
  2985. ~transitionTimingFunction: string=?,
  2986. /* Transforms Level 1 - WD */
  2987. ~backfaceVisibility: string=?,
  2988. ~perspective: string=?,
  2989. ~perspectiveOrigin: string=?,
  2990. ~transform: string=?,
  2991. ~transformOrigin: string=?,
  2992. ~transformStyle: string=?,
  2993. /* Box Alignment Level 3 - WD */
  2994. /* alignContent - already defined by Flexible Box Layout */
  2995. /* alignItems - already defined by Flexible Box Layout */
  2996. ~justifyItems: string=?,
  2997. ~justifySelf: string=?,
  2998. ~placeContent: string=?,
  2999. ~placeItems: string=?,
  3000. ~placeSelf: string=?,
  3001. /* Basic User Interface Level 4 - FPWD */
  3002. ~appearance: string=?,
  3003. ~caret: string=?,
  3004. ~caretAnimation: string=?,
  3005. ~caretShape: string=?,
  3006. ~userSelect: string=?,
  3007. /* Overflow Level 3 - WD */
  3008. ~maxLines: string=?,
  3009. /* Basix Box Model - WD */
  3010. ~marqueeDirection: string=?,
  3011. ~marqueeLoop: string=?,
  3012. ~marqueeSpeed: string=?,
  3013. ~marqueeStyle: string=?,
  3014. ~overflowStyle: string=?,
  3015. ~rotation: string=?,
  3016. ~rotationPoint: string=?,
  3017. /* SVG 1.1 - REC */
  3018. ~alignmentBaseline: string=?,
  3019. ~baselineShift: string=?,
  3020. ~clip: string=?,
  3021. ~clipPath: string=?,
  3022. ~clipRule: string=?,
  3023. ~colorInterpolation: string=?,
  3024. ~colorInterpolationFilters: string=?,
  3025. ~colorProfile: string=?,
  3026. ~colorRendering: string=?,
  3027. ~cursor: string=?,
  3028. ~dominantBaseline: string=?,
  3029. ~fill: string=?,
  3030. ~fillOpacity: string=?,
  3031. ~fillRule: string=?,
  3032. ~filter: string=?,
  3033. ~floodColor: string=?,
  3034. ~floodOpacity: string=?,
  3035. ~glyphOrientationHorizontal: string=?,
  3036. ~glyphOrientationVertical: string=?,
  3037. ~imageRendering: string=?,
  3038. ~kerning: string=?,
  3039. ~lightingColor: string=?,
  3040. ~markerEnd: string=?,
  3041. ~markerMid: string=?,
  3042. ~markerStart: string=?,
  3043. ~pointerEvents: string=?,
  3044. ~shapeRendering: string=?,
  3045. ~stopColor: string=?,
  3046. ~stopOpacity: string=?,
  3047. ~stroke: string=?,
  3048. ~strokeDasharray: string=?,
  3049. ~strokeDashoffset: string=?,
  3050. ~strokeLinecap: string=?,
  3051. ~strokeLinejoin: string=?,
  3052. ~strokeMiterlimit: string=?,
  3053. ~strokeOpacity: string=?,
  3054. ~strokeWidth: string=?,
  3055. ~textAnchor: string=?,
  3056. ~textRendering: string=?,
  3057. /* Ruby Layout Level 1 - WD */
  3058. ~rubyAlign: string=?,
  3059. ~rubyMerge: string=?,
  3060. ~rubyPosition: string=?,
  3061. /* Lists and Counters Level 3 - WD */
  3062. /* listStyle - already defined by CSS2Properties */
  3063. /* listStyleImage - already defined by CSS2Properties */
  3064. /* listStylePosition - already defined by CSS2Properties */
  3065. /* listStyleType - already defined by CSS2Properties */
  3066. /* counterIncrement - already defined by CSS2Properties */
  3067. /* counterReset - already defined by CSS2Properties */
  3068. /* Not added yet
  3069. * -------------
  3070. * Generated Content for Paged Media - WD
  3071. * Generated Content Level 3 - WD
  3072. * Line Grid Level 1 - WD
  3073. * Regions - WD
  3074. * Inline Layout Level 3 - WD
  3075. * Round Display Level 1 - WD
  3076. * Image Values and Replaced Content Level 4 - WD
  3077. * Positioned Layout Level 3 - WD
  3078. * Filter Effects Level 1 - -WD
  3079. * Exclusions Level 1 - WD
  3080. * Text Level 4 - FPWD
  3081. * SVG Markers - FPWD
  3082. * Motion Path Level 1 - FPWD
  3083. * Color Level 4 - FPWD
  3084. * SVG Strokes - FPWD
  3085. * Table Level 3 - FPWD
  3086. */
  3087. unit
  3088. ) =>
  3089. style =
  3090. "";
  3091. /* CSS2Properties: https://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties */
  3092. let combine: (style, style) => style =
  3093. (a, b) => {
  3094. let a: Js.t({..}) = Obj.magic(a);
  3095. let b: Js.t({..}) = Obj.magic(b);
  3096. Js.Obj.assign(Js.Obj.assign(Js.Obj.empty(), a), b) |> Obj.magic;
  3097. };
  3098. let unsafeAddProp: (style, string, string) => style =
  3099. (style, property, value) => {
  3100. let propStyle: style = {
  3101. let dict = Js.Dict.empty();
  3102. Js.Dict.set(dict, property, value);
  3103. Obj.magic(dict);
  3104. };
  3105. combine(style, propStyle);
  3106. };
  3107. };
  3108.  
  3109. };
  3110.  
  3111. module Index = {
  3112. #1 Index
  3113.  
  3114. let str = ReasonReact.stringToElement;
  3115.  
  3116. module CustomComponent = {
  3117. let component = ReasonReact.statelessComponent("CustomComponent");
  3118. let z = string_of_int(SomeThing.x + OtherThing.y * 2);
  3119.  
  3120. let make = (~name, _children) => {
  3121. ...component,
  3122. render: _self => <div>(str("Hello Wrld!" ++ z))</div> ,
  3123. }
  3124. };
  3125.  
  3126.  
  3127. let root = <CustomComponent name="Folks" />;
  3128.  
  3129. ReactDOMRe.renderToElementWithId(root, "root");
  3130. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement