├── .gitignore ├── LICENSE ├── README.md ├── config └── config.exs ├── lib ├── react_phoenix.ex └── react_phoenix │ ├── engine.ex │ ├── js_context.ex │ ├── renderer.ex │ └── utils.ex ├── mix.exs ├── mix.lock ├── priv └── react-0.14.0-beta3.min.js └── test ├── engine_test.exs ├── fixtures └── templates │ └── my_app │ └── page │ ├── application.html.eex │ ├── layout.html.eex │ ├── new.html.js │ ├── sub.html.eex │ ├── template.html.jade │ ├── util-prerender.html.eex │ └── util.html.eex ├── js_context_test.exs ├── test_helper.exs └── utils_test.exs /.gitignore: -------------------------------------------------------------------------------- 1 | /_build 2 | /deps 3 | erl_crash.dump 4 | *.ez 5 | .DS_Store 6 | Guardfile 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Increments inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Phoenix Template Engine for React 2 | 3 | Server side react rendering on Phoenix. 4 | 5 | Inspired by [reactjs/react-rails](https://github.com/reactjs/react-rails "reactjs/react-rails") 6 | 7 | ## Usage 8 | 9 | 1. Add `{:react_phoenix, github: "increments/react_phoenix"}` to your deps in `mix.exs`. 10 | 2. Import `ReactPhoenix.Utils` and call `react_component` 11 | 12 | page_view.ex 13 | 14 | ```elixir 15 | defmodule YourApp.PageView do 16 | use HelloPhoenix.Web, :view 17 | import ReactPhoenix.Utils 18 | end 19 | ``` 20 | 21 | page.eex 22 | 23 | ```elixir 24 | <%= react_component("HelloComponent", %{propA: 1, propB: 2}) %> 25 | # =>
26 | ``` 27 | 28 | ## Prerender 29 | 30 | if react_compoent's option, `prerender: true`, ReactPhoenix compiles react component in server side. 31 | 32 | ```elixir 33 | # Eval javascript at application boot 34 | ReactPhoenix.JSContext.load_javascript """ 35 | var Hello = React.createClass({render: function(){return React.createElement('div', {}, "hello")}}) 36 | """ 37 | 38 | # or load_file 39 | 40 | ReactPhoenix.JSContext.load_file "components.js" # expect precompiled javascripts 41 | 42 | ... 43 | 44 | ```elixir 45 | <%= react_component("Hello", %{}, prerender: true) %> 46 | # =>
hello
47 | ``` 48 | 49 | ## Optional: Client Side Rendering with react-ssr-mounter 50 | 51 | ``` 52 | npm install @mizchi/react-ssr-mounter --save 53 | ``` 54 | 55 | ```js 56 | let {initComponents} = require('@mizchi/react-ssr-mounter'); 57 | 58 | // register save reference name with server side resolver. 59 | window.Hello = React.createClass({ 60 | render(){return

hello

;} 61 | }); 62 | 63 | window.addEventListener("load", () => { 64 | var components = initComponents(); 65 | }); 66 | ``` 67 | 68 | You can take over server side state if it can. 69 | 70 | ## TODO 71 | 72 | - [x] react_compoent prerender: false 73 | - [x] react_compoent prerender: true 74 | - [ ] Add an example 75 | - [ ] Use v8 context pool 76 | - [ ] .js renderer 77 | - [ ] .jsx renderer 78 | - [ ] .jade renderer for react-jade 79 | - [ ] Cache by filename 80 | - [ ] Reload renderer when template files change 81 | 82 | ## Special Thanks 83 | 84 | [Chris McCord](https://github.com/chrismccord) and his [phoenix_haml](https://github.com/chrismccord/phoenix_haml) project for bootstraping the react_phoenix project. 85 | -------------------------------------------------------------------------------- /config/config.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | config :phoenix, :template_engines, 3 | js: ReactPhoenix.Engine 4 | -------------------------------------------------------------------------------- /lib/react_phoenix.ex: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenix do 2 | use Application 3 | def start(_type, _args) do 4 | IO.puts "ReactPhoenix started!" 5 | import Supervisor.Spec, warn: false 6 | 7 | Supervisor.start_link([ 8 | worker(ReactPhoenix.JSContext, []) 9 | ], [ 10 | strategy: :one_for_one, 11 | name: ReactPhoenix.Supervisor 12 | ]) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/react_phoenix/engine.ex: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenix.Engine do 2 | @behaviour Phoenix.Template.Engine 3 | 4 | def compile(path, _name) do 5 | {:ok, html} = 6 | path 7 | |> read! 8 | |> ReactPhoenix.JSContext.eval 9 | html |> EEx.compile_string(engine: Phoenix.HTML.Engine, file: path, line: 1) 10 | end 11 | 12 | defp read!(file_path) do 13 | file_path |> File.read! 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/react_phoenix/js_context.ex: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenix.JSContext do 2 | use GenServer 3 | 4 | def load_javascript(code) do 5 | eval code 6 | nil 7 | end 8 | 9 | def load_file(filename) do 10 | eval File.read! filename 11 | nil 12 | end 13 | 14 | # Internal APIs 15 | def eval(code) do 16 | GenServer.call(:v8context, {:eval, code}) 17 | end 18 | 19 | def call(f, args) do 20 | GenServer.call(:v8context, {:call, f, args}) 21 | end 22 | 23 | def start_link do 24 | source = 25 | """ 26 | var global = global || this; 27 | var self = self || this; 28 | var window = window || this; 29 | """ 30 | <> File.read!("priv/react-0.14.0-beta3.min.js") 31 | 32 | {:ok, vm} = :erlang_v8.start_vm 33 | :erlang_v8.eval vm, source 34 | GenServer.start_link(__MODULE__, vm, name: :v8context) 35 | end 36 | 37 | def handle_call({:eval, code}, _from, vm) do 38 | result = :erlang_v8.eval vm, code 39 | {:reply, result, vm} 40 | end 41 | 42 | def handle_call({:call, f, args}, _from, vm) do 43 | result = :erlang_v8.call vm, args 44 | {:reply, result, vm} 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/react_phoenix/renderer.ex: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenix.Renderer do 2 | def render_component(name, props) do 3 | {:ok, strProps} = JSX.encode props 4 | {:ok, result} = ReactPhoenix.JSContext.eval """ 5 | React.renderToString(React.createElement(#{name}), #{strProps}) 6 | """ 7 | result 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/react_phoenix/utils.ex: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenix.Utils do 2 | def react_component(name, props) do 3 | react_component(name, props, prerender: false) 4 | end 5 | 6 | def react_component(name, props, opts) do 7 | {:ok, strProps} = JSX.encode props 8 | embeddedAttrs = "data-react-class=\'#{name}\' data-react-props=\'#{strProps}\'" 9 | 10 | if opts[:prerender] do 11 | html = ReactPhoenix.Renderer.render_component(name, props) 12 | {:safe, Regex.replace(~r/^(\<(\w+)\s)/, html, "\\0#{embeddedAttrs} ")} 13 | else 14 | {:safe, "
"} 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenix.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :react_phoenix, 7 | version: "0.0.1", 8 | elixir: "~> 1.0.1 or ~> 1.1", 9 | deps: deps, 10 | package: [ 11 | contributors: ["Koutaro Chikuba"], 12 | licenses: ["MIT"], 13 | links: %{github: "https://github.com/mizchi/react_phoenix"} 14 | ], 15 | description: """ 16 | Phoenix Template Engine for ReactJSX (WIP) 17 | """ 18 | ] 19 | end 20 | 21 | def application do 22 | [ 23 | applications: [:phoenix, :exjsx, :erlang_v8], 24 | mod: {ReactPhoenix, []} 25 | ] 26 | end 27 | 28 | defp deps do 29 | [ 30 | {:phoenix, "~> 1.0"}, 31 | {:phoenix_html, "~> 2.1"}, 32 | {:exjsx, "~> 3.2.0"}, 33 | {:erlang_v8, github: "babie/erlang-v8", branch: "fix_make_error", compile: "make"}, 34 | {:cowboy, "~> 1.0.0", only: [:dev, :test]} 35 | ] 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{"cowboy": {:hex, :cowboy, "1.0.2"}, 2 | "cowlib": {:hex, :cowlib, "1.0.1"}, 3 | "erlang_v8": {:git, "git://github.com/babie/erlang-v8.git", "9fe0724411c6ffdc21c81f98581a3d5ab028322a", [branch: "fix_make_error"]}, 4 | "exjsx": {:hex, :exjsx, "3.2.0"}, 5 | "jsx": {:hex, :jsx, "2.6.2"}, 6 | "phoenix": {:hex, :phoenix, "0.17.1"}, 7 | "phoenix_html": {:hex, :phoenix_html, "2.1.2"}, 8 | "plug": {:hex, :plug, "1.0.0"}, 9 | "poison": {:hex, :poison, "1.5.0"}, 10 | "ranch": {:hex, :ranch, "1.1.0"}} 11 | -------------------------------------------------------------------------------- /priv/react-0.14.0-beta3.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * React v0.14.0-beta3 3 | * 4 | * Copyright 2013-2015, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | * 11 | */ 12 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.React=e()}}(function(){return function e(t,n,r){function o(i,u){if(!n[i]){if(!t[i]){var s="function"==typeof require&&require;if(!u&&s)return s(i,!0);if(a)return a(i,!0);var l=new Error("Cannot find module '"+i+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[i]={exports:{}};t[i][0].call(c.exports,function(e){var n=t[i][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;i8&&11>=x),M=32,N=String.fromCharCode(M),w=f.topLevelTypes,I={beforeInput:{phasedRegistrationNames:{bubbled:C({onBeforeInput:null}),captured:C({onBeforeInputCapture:null})},dependencies:[w.topCompositionEnd,w.topKeyPress,w.topTextInput,w.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:C({onCompositionEnd:null}),captured:C({onCompositionEndCapture:null})},dependencies:[w.topBlur,w.topCompositionEnd,w.topKeyDown,w.topKeyPress,w.topKeyUp,w.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:C({onCompositionStart:null}),captured:C({onCompositionStartCapture:null})},dependencies:[w.topBlur,w.topCompositionStart,w.topKeyDown,w.topKeyPress,w.topKeyUp,w.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:C({onCompositionUpdate:null}),captured:C({onCompositionUpdateCapture:null})},dependencies:[w.topBlur,w.topCompositionUpdate,w.topKeyDown,w.topKeyPress,w.topKeyUp,w.topMouseDown]}},R=!1,S=null,T={eventTypes:I,extractEvents:function(e,t,n,r,o){return[l(e,t,n,r,o),d(e,t,n,r,o)]}};t.exports=T},{125:125,143:143,15:15,19:19,20:20,86:86,90:90}],4:[function(e,t,n){"use strict";function r(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var o={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0},a=["Webkit","ms","Moz","O"];Object.keys(o).forEach(function(e){a.forEach(function(t){o[r(t,e)]=o[e]})});var i={background:{backgroundImage:!0,backgroundPosition:!0,backgroundRepeat:!0,backgroundColor:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0,fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0}},u={isUnitlessNumber:o,shorthandPropertyExpansions:i};t.exports=u},{}],5:[function(e,t,n){"use strict";var r=e(4),o=e(125),a=(e(127),e(100)),i=e(138),u=e(115),s=(e(147),u(function(e){return i(e)})),l="cssFloat";o.canUseDOM&&void 0===document.documentElement.style.cssFloat&&(l="styleFloat");var c={createMarkupForStyles:function(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];null!=r&&(t+=s(n)+":",t+=a(n,r)+";")}return t||null},setValueForStyles:function(e,t){var n=e.style;for(var o in t)if(t.hasOwnProperty(o)){var i=a(o,t[o]);if("float"===o&&(o=l),i)n[o]=i;else{var u=r.shorthandPropertyExpansions[o];if(u)for(var s in u)n[s]="";else n[o]=""}}}};t.exports=c},{100:100,115:115,125:125,127:127,138:138,147:147,4:4}],6:[function(e,t,n){"use strict";function r(){this._callbacks=null,this._contexts=null}var o=e(24),a=e(23),i=e(139);a(r.prototype,{enqueue:function(e,t){this._callbacks=this._callbacks||[],this._contexts=this._contexts||[],this._callbacks.push(e),this._contexts.push(t)},notifyAll:function(){var e=this._callbacks,t=this._contexts;if(e){e.length!==t.length?i(!1):void 0,this._callbacks=null,this._contexts=null;for(var n=0;n8));var O=!1;E.canUseDOM&&(O=D("input")&&(!("documentMode"in document)||document.documentMode>9));var A={get:function(){return T.get.call(this)},set:function(e){S=""+e,T.set.call(this,e)}},L={eventTypes:w,extractEvents:function(e,t,n,o,a){var i,u;if(r(t)?k?i=s:u=l:P(t)?O?i=f:(i=v,u=h):m(t)&&(i=g),i){var c=i(e,t,n);if(c){var p=x.getPooled(w.change,c,o,a);return p.type="change",b.accumulateTwoPhaseDispatches(p),p}}u&&u(e,t,n)}};t.exports=L},{113:113,114:114,125:125,143:143,15:15,16:16,19:19,80:80,88:88}],8:[function(e,t,n){"use strict";var r=0,o={createReactRootIndex:function(){return r++}};t.exports=o},{}],9:[function(e,t,n){"use strict";function r(e,t,n){var r=n>=e.childNodes.length?null:e.childNodes.item(n);e.insertBefore(t,r)}var o=e(12),a=e(64),i=e(119),u=e(120),s=e(139),l={dangerouslyReplaceNodeWithMarkup:o.dangerouslyReplaceNodeWithMarkup,updateTextContent:u,processUpdates:function(e,t){for(var n,l=null,c=null,p=0;pt||e.hasOverloadedBooleanValue&&t===!1}var a=e(10),i=e(117),u=(e(147),/^[a-zA-Z_][a-zA-Z_\.\-\d]*$/),s={},l={},c={createMarkupForID:function(e){return a.ID_ATTRIBUTE_NAME+"="+i(e)},createMarkupForProperty:function(e,t){var n=a.properties.hasOwnProperty(e)?a.properties[e]:null;if(n){if(o(n,t))return"";var r=n.attributeName;return n.hasBooleanValue||n.hasOverloadedBooleanValue&&t===!0?r+'=""':r+"="+i(t)}return a.isCustomAttribute(e)?null==t?"":e+"="+i(t):null},createMarkupForCustomAttribute:function(e,t){return r(e)&&null!=t?e+"="+i(t):""},setValueForProperty:function(e,t,n){var r=a.properties.hasOwnProperty(t)?a.properties[t]:null;if(r){var i=r.mutationMethod;if(i)i(e,n);else if(o(r,n))this.deleteValueForProperty(e,t);else if(r.mustUseAttribute){var u=r.attributeName,s=r.attributeNamespace;s?e.setAttributeNS(s,u,""+n):e.setAttribute(u,""+n)}else{var l=r.propertyName;r.hasSideEffects&&""+e[l]==""+n||(e[l]=n)}}else a.isCustomAttribute(t)&&c.setValueForAttribute(e,t,n)},setValueForAttribute:function(e,t,n){r(t)&&(null==n?e.removeAttribute(t):e.setAttribute(t,""+n))},deleteValueForProperty:function(e,t){var n=a.properties.hasOwnProperty(t)?a.properties[t]:null;if(n){var r=n.mutationMethod;if(r)r(e,void 0);else if(n.mustUseAttribute)e.removeAttribute(n.attributeName);else{var o=n.propertyName,i=a.getDefaultValueForProperty(e.nodeName,o);n.hasSideEffects&&""+e[o]===i||(e[o]=i)}}else a.isCustomAttribute(t)&&e.removeAttribute(t)}};t.exports=c},{10:10,117:117,147:147}],12:[function(e,t,n){"use strict";function r(e){return e.substring(1,e.indexOf(" "))}var o=e(125),a=e(130),i=e(131),u=e(135),s=e(139),l=/^(<[^ \/>]+)/,c="data-danger-index",p={dangerouslyRenderMarkup:function(e){o.canUseDOM?void 0:s(!1);for(var t,n={},p=0;p-1?void 0:i(!1),!l.plugins[n]){t.extractEvents?void 0:i(!1),l.plugins[n]=t;var r=t.eventTypes;for(var a in r)o(r[a],t,a)?void 0:i(!1)}}}function o(e,t,n){l.eventNameDispatchConfigs.hasOwnProperty(n)?i(!1):void 0,l.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var o in r)if(r.hasOwnProperty(o)){var u=r[o];a(u,t,n)}return!0}return e.registrationName?(a(e.registrationName,t,n),!0):!1}function a(e,t,n){l.registrationNameModules[e]?i(!1):void 0,l.registrationNameModules[e]=t,l.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var i=e(139),u=null,s={},l={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(e){u?i(!1):void 0,u=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var t=!1;for(var n in e)if(e.hasOwnProperty(n)){var o=e[n];s.hasOwnProperty(n)&&s[n]===o||(s[n]?i(!1):void 0,s[n]=o,t=!0)}t&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return l.registrationNameModules[t.registrationName]||null;for(var n in t.phasedRegistrationNames)if(t.phasedRegistrationNames.hasOwnProperty(n)){var r=l.registrationNameModules[t.phasedRegistrationNames[n]];if(r)return r}return null},_resetEventPlugins:function(){u=null;for(var e in s)s.hasOwnProperty(e)&&delete s[e];l.plugins.length=0;var t=l.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=l.registrationNameModules;for(var o in r)r.hasOwnProperty(o)&&delete r[o]}};t.exports=l},{139:139}],18:[function(e,t,n){"use strict";function r(e){return e===m.topMouseUp||e===m.topTouchEnd||e===m.topTouchCancel}function o(e){return e===m.topMouseMove||e===m.topTouchMove}function a(e){return e===m.topMouseDown||e===m.topTouchStart}function i(e,t){var n=e._dispatchListeners,r=e._dispatchIDs;if(Array.isArray(n))for(var o=0;oe&&n[e]===o[e];e++);var i=r-e;for(t=1;i>=t&&n[r-t]===o[a-t];t++);var u=t>1?1-t:void 0;return this._fallbackText=o.slice(e,u),this._fallbackText}}),o.addPoolingTo(r),t.exports=r},{111:111,23:23,24:24}],21:[function(e,t,n){"use strict";var r,o=e(10),a=e(125),i=o.injection.MUST_USE_ATTRIBUTE,u=o.injection.MUST_USE_PROPERTY,s=o.injection.HAS_BOOLEAN_VALUE,l=o.injection.HAS_SIDE_EFFECTS,c=o.injection.HAS_NUMERIC_VALUE,p=o.injection.HAS_POSITIVE_NUMERIC_VALUE,d=o.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(a.canUseDOM){var f=document.implementation;r=f&&f.hasFeature&&f.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var h={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:i|s,allowTransparency:i,alt:null,async:s,autoComplete:null,autoPlay:s,capture:i|s,cellPadding:null,cellSpacing:null,charSet:i,challenge:i,checked:u|s,classID:i,className:r?i:u,cols:i|p,colSpan:null,content:null,contentEditable:null,contextMenu:i,controls:u|s,coords:null,crossOrigin:null,data:null,dateTime:i,defer:s,dir:null,disabled:i|s,download:d,draggable:null,encType:null,form:i,formAction:i,formEncType:i,formMethod:i,formNoValidate:s,formTarget:i,frameBorder:i,headers:null,height:i,hidden:i|s,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:u,inputMode:i,is:i,keyParams:i,keyType:i,label:null,lang:null,list:i,loop:u|s,low:null,manifest:i,marginHeight:null,marginWidth:null,max:null,maxLength:i,media:i,mediaGroup:null,method:null,min:null,minLength:i,multiple:u|s,muted:u|s,name:null,noValidate:s,open:s,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:u|s,rel:null,required:s,role:i,rows:i|p,rowSpan:null,sandbox:null,scope:null,scoped:s,scrolling:null,seamless:i|s,selected:u|s,shape:null,size:i|p,sizes:i,span:p,spellCheck:null,src:null,srcDoc:u,srcSet:i,start:c,step:null,style:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:u|l,width:i,wmode:i,wrap:null,autoCapitalize:null,autoCorrect:null,itemProp:i,itemScope:i|s,itemType:i,itemID:i,itemRef:i,property:null,security:i,unselectable:i},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoCorrect:"autocorrect",autoFocus:"autofocus",autoPlay:"autoplay",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};t.exports=h},{10:10,125:125}],22:[function(e,t,n){"use strict";function r(e){null!=e.checkedLink&&null!=e.valueLink?l(!1):void 0}function o(e){r(e),null!=e.value||null!=e.onChange?l(!1):void 0}function a(e){r(e),null!=e.checked||null!=e.onChange?l(!1):void 0}function i(e){if(e){var t=e.getName();if(t)return" Check the render method of `"+t+"`."}return""}var u=e(71),s=e(70),l=e(139),c=(e(147),{button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0}),p={value:function(e,t,n){return!e[t]||c[e.type]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t,n){return!e[t]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")},onChange:u.func},d={},f={checkPropTypes:function(e,t,n){for(var r in p){if(p.hasOwnProperty(r))var o=p[r](t,r,e,s.prop);o instanceof Error&&!(o.message in d)&&(d[o.message]=!0,i(n))}},getValue:function(e){return e.valueLink?(o(e),e.valueLink.value):e.value},getChecked:function(e){return e.checkedLink?(a(e),e.checkedLink.value):e.checked},executeOnChange:function(e,t){return e.valueLink?(o(e),e.valueLink.requestChange(t.target.value)):e.checkedLink?(a(e),e.checkedLink.requestChange(t.target.checked)):e.onChange?e.onChange.call(void 0,t):void 0}};t.exports=f},{139:139,147:147,70:70,71:71}],23:[function(e,t,n){"use strict";function r(e,t){if(null==e)throw new TypeError("Object.assign target cannot be null or undefined");for(var n=Object(e),r=Object.prototype.hasOwnProperty,o=1;o=0||null!=t.is}function m(e){f(e),this._tag=e.toLowerCase(),this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._rootNodeID=null,this._wrapperState=null,this._topLevelWrapper=null,this._nodeWithLegacyProperties=null}var g=e(2),y=e(5),C=e(10),b=e(11),E=e(15),_=e(26),x=e(31),D=e(36),P=e(40),M=e(41),N=e(42),w=e(46),I=e(62),R=e(63),S=e(68),T=e(79),k=e(23),O=e(101),A=e(139),L=(e(113),e(143)),U=(e(145),e(123),e(147),_.deleteListener),B=_.listenTo,F=_.registrationNameModules,j={string:!0,number:!0},V=L({style:null}),W=1,K=!1;try{Object.defineProperty({},"test",{get:function(){}}),K=!0}catch(H){}var q=null,z={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},Y={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},G={listing:!0,pre:!0,textarea:!0},X=(k({menuitem:!0},Y),/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/),Q={},$={}.hasOwnProperty;m.displayName="ReactDOMComponent",m.Mixin={construct:function(e){this._currentElement=e},mountComponent:function(e,t,n){this._rootNodeID=e;var r=this._currentElement.props;switch(this._tag){case"iframe":case"img":case"form":case"video":case"audio":this._wrapperState={listeners:null},t.getReactMountReady().enqueue(p,this);break;case"button":r=D.getNativeProps(this,r,n);break;case"input":P.mountWrapper(this,r,n),r=P.getNativeProps(this,r,n);break;case"option":M.mountWrapper(this,r,n),r=M.getNativeProps(this,r,n);break;case"select":N.mountWrapper(this,r,n),r=N.getNativeProps(this,r,n),n=N.processChildContext(this,r,n);break;case"textarea":w.mountWrapper(this,r,n),r=w.getNativeProps(this,r,n)}s(this,r);var o=this._createOpenTagMarkupAndPutListeners(t,r),a=this._createContentMarkup(t,r,n);switch(this._tag){case"button":case"input":case"select":case"textarea":r.autoFocus&&t.getReactMountReady().enqueue(g.focusDOMComponent,this)}return!a&&Y[this._tag]?o+"/>":o+">"+a+""},_createOpenTagMarkupAndPutListeners:function(e,t){var n="<"+this._currentElement.type;for(var r in t)if(t.hasOwnProperty(r)){var o=t[r];if(null!=o)if(F.hasOwnProperty(r))l(this._rootNodeID,r,o,e);else{r===V&&(o&&(o=this._previousStyleCopy=k({},t.style)),o=y.createMarkupForStyles(o));var a=null;a=null!=this._tag&&v(this._tag,t)?b.createMarkupForCustomAttribute(r,o):b.createMarkupForProperty(r,o),a&&(n+=" "+a)}}if(e.renderToStaticMarkup)return n;var i=b.createMarkupForID(this._rootNodeID);return n+" "+i},_createContentMarkup:function(e,t,n){var r="",o=t.dangerouslySetInnerHTML;if(null!=o)null!=o.__html&&(r=o.__html);else{var a=j[typeof t.children]?t.children:null,i=null!=a?null:t.children;if(null!=a)r=O(a);else if(null!=i){var u=this.mountChildren(i,e,h(n,this));r=u.join("")}}return G[this._tag]&&"\n"===r.charAt(0)?"\n"+r:r},receiveComponent:function(e,t,n){var r=this._currentElement;this._currentElement=e,this.updateComponent(t,r,e,n)},updateComponent:function(e,t,n,r){var o=t.props,a=this._currentElement.props;switch(this._tag){case"button":o=D.getNativeProps(this,o),a=D.getNativeProps(this,a);break;case"input":P.updateWrapper(this),o=P.getNativeProps(this,o),a=P.getNativeProps(this,a);break;case"option":o=M.getNativeProps(this,o),a=M.getNativeProps(this,a);break;case"select":o=N.getNativeProps(this,o),a=N.getNativeProps(this,a);break;case"textarea":w.updateWrapper(this),o=w.getNativeProps(this,o),a=w.getNativeProps(this,a)}s(this,a),this._updateDOMProperties(o,a,e),this._updateDOMChildren(o,a,e,h(r,this)),!K&&this._nodeWithLegacyProperties&&(this._nodeWithLegacyProperties.props=a),"select"===this._tag&&e.getReactMountReady().enqueue(d,this)},_updateDOMProperties:function(e,t,n){var r,o,a;for(r in e)if(!t.hasOwnProperty(r)&&e.hasOwnProperty(r))if(r===V){var i=this._previousStyleCopy;for(o in i)i.hasOwnProperty(o)&&(a=a||{},a[o]="");this._previousStyleCopy=null}else F.hasOwnProperty(r)?e[r]&&U(this._rootNodeID,r):(C.properties[r]||C.isCustomAttribute(r))&&q.deletePropertyByID(this._rootNodeID,r);for(r in t){var u=t[r],s=r===V?this._previousStyleCopy:e[r];if(t.hasOwnProperty(r)&&u!==s)if(r===V)if(u?u=this._previousStyleCopy=k({},u):this._previousStyleCopy=null,s){for(o in s)!s.hasOwnProperty(o)||u&&u.hasOwnProperty(o)||(a=a||{},a[o]="");for(o in u)u.hasOwnProperty(o)&&s[o]!==u[o]&&(a=a||{},a[o]=u[o])}else a=u;else F.hasOwnProperty(r)?u?l(this._rootNodeID,r,u,n):s&&U(this._rootNodeID,r):v(this._tag,t)?q.updateAttributeByID(this._rootNodeID,r,u):(C.properties[r]||C.isCustomAttribute(r))&&q.updatePropertyByID(this._rootNodeID,r,u)}a&&q.updateStylesByID(this._rootNodeID,a)},_updateDOMChildren:function(e,t,n,r){var o=j[typeof e.children]?e.children:null,a=j[typeof t.children]?t.children:null,i=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,u=t.dangerouslySetInnerHTML&&t.dangerouslySetInnerHTML.__html,s=null!=o?null:e.children,l=null!=a?null:t.children,c=null!=o||null!=i,p=null!=a||null!=u;null!=s&&null==l?this.updateChildren(null,n,r):c&&!p&&this.updateTextContent(""),null!=a?o!==a&&this.updateTextContent(""+a):null!=u?i!==u&&this.updateMarkup(""+u):null!=l&&this.updateChildren(l,n,r)},unmountComponent:function(){switch(this._tag){case"iframe":case"img":case"form":case"video":case"audio":var e=this._wrapperState.listeners;if(e)for(var t=0;tt.end?(n=t.end,r=t.start):(n=t.start,r=t.end),o.moveToElementText(e),o.moveStart("character",n),o.setEndPoint("EndToStart",o),o.moveEnd("character",r-n),o.select()}function u(e,t){if(window.getSelection){var n=window.getSelection(),r=e[c()].length,o=Math.min(t.start,r),a="undefined"==typeof t.end?o:Math.min(t.end,r);if(!n.extend&&o>a){var i=a;a=o,o=i}var u=l(e,o),s=l(e,a);if(u&&s){var p=document.createRange();p.setStart(u.node,u.offset),n.removeAllRanges(),o>a?(n.addRange(p),n.extend(s.node,s.offset)):(p.setEnd(s.node,s.offset),n.addRange(p))}}}var s=e(125),l=e(110),c=e(111),p=s.canUseDOM&&"selection"in document&&!("getSelection"in window),d={getOffsets:p?o:a,setOffsets:p?i:u};t.exports=d},{110:110,111:111,125:125}],44:[function(e,t,n){"use strict";var r=e(48),o=e(77);r.inject();var a={renderToString:o.renderToString,renderToStaticMarkup:o.renderToStaticMarkup};t.exports=a},{48:48,77:77}],45:[function(e,t,n){"use strict";var r=e(11),o=e(31),a=e(37),i=e(23),u=e(101),s=(e(123),function(e){});i(s.prototype,{construct:function(e){this._currentElement=e,this._stringText=""+e,this._rootNodeID=null,this._mountIndex=0},mountComponent:function(e,t,n){this._rootNodeID=e;var o=u(this._stringText);return t.renderToStaticMarkup?o:""+o+""},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;n!==this._stringText&&(this._stringText=n,a.BackendIDOperations.updateTextContentByID(this._rootNodeID,n))}},unmountComponent:function(){o.unmountIDFromEnvironment(this._rootNodeID)}}),t.exports=s},{101:101,11:11,123:123,23:23,31:31,37:37}],46:[function(e,t,n){ 14 | "use strict";function r(){this._rootNodeID&&c.updateWrapper(this)}function o(e){var t=this._currentElement.props,n=a.executeOnChange(t,e);return u.asap(r,this),n}var a=e(22),i=e(39),u=e(80),s=e(23),l=e(139),c=(e(147),{getNativeProps:function(e,t,n){null!=t.dangerouslySetInnerHTML?l(!1):void 0;var r=s({},t,{defaultValue:void 0,value:void 0,children:e._wrapperState.initialValue,onChange:e._wrapperState.onChange});return r},mountWrapper:function(e,t){a.checkPropTypes("textarea",t,e._currentElement._owner);var n=t.defaultValue,r=t.children;null!=r&&(null!=n?l(!1):void 0,Array.isArray(r)&&(r.length<=1?void 0:l(!1),r=r[0]),n=""+r),null==n&&(n="");var i=a.getValue(t);e._wrapperState={initialValue:""+(null!=i?i:n),onChange:o.bind(e)}},updateWrapper:function(e){var t=e._currentElement.props,n=a.getValue(t);null!=n&&i.updatePropertyByID(e._rootNodeID,"value",""+n)}});t.exports=c},{139:139,147:147,22:22,23:23,39:39,80:80}],47:[function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var o=e(80),a=e(96),i=e(23),u=e(131),s={initialize:u,close:function(){d.isBatchingUpdates=!1}},l={initialize:u,close:o.flushBatchedUpdates.bind(o)},c=[l,s];i(r.prototype,a.Mixin,{getTransactionWrappers:function(){return c}});var p=new r,d={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,o,a){var i=d.isBatchingUpdates;d.isBatchingUpdates=!0,i?e(t,n,r,o,a):p.perform(e,null,t,n,r,o,a)}};t.exports=d},{131:131,23:23,80:80,96:96}],48:[function(e,t,n){"use strict";function r(){M||(M=!0,y.EventEmitter.injectReactEventListener(g),y.EventPluginHub.injectEventPluginOrder(u),y.EventPluginHub.injectInstanceHandle(C),y.EventPluginHub.injectMount(b),y.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:D,EnterLeaveEventPlugin:s,ChangeEventPlugin:a,SelectEventPlugin:_,BeforeInputEventPlugin:o}),y.NativeComponent.injectGenericComponentClass(h),y.NativeComponent.injectTextComponentClass(m),y.Class.injectMixin(p),y.DOMProperty.injectDOMPropertyConfig(c),y.DOMProperty.injectDOMPropertyConfig(P),y.EmptyComponent.injectEmptyComponent("noscript"),y.Updates.injectReconcileTransaction(E),y.Updates.injectBatchingStrategy(f),y.RootIndex.injectCreateReactRootIndex(l.canUseDOM?i.createReactRootIndex:x.createReactRootIndex),y.Component.injectEnvironment(d),y.DOMComponent.injectIDOperations(v))}var o=e(3),a=e(7),i=e(8),u=e(13),s=e(14),l=e(125),c=e(21),p=e(25),d=e(31),f=e(47),h=e(37),v=e(39),m=e(45),g=e(54),y=e(56),C=e(58),b=e(62),E=e(72),_=e(82),x=e(83),D=e(84),P=e(81),M=!1;t.exports={inject:r}},{125:125,13:13,14:14,21:21,25:25,3:3,31:31,37:37,39:39,45:45,47:47,54:54,56:56,58:58,62:62,7:7,72:72,8:8,81:81,82:82,83:83,84:84}],49:[function(e,t,n){"use strict";var r=e(34),o=e(23),a={key:!0,ref:!0},i=function(e,t,n,r,o){this.type=e,this.key=t,this.ref=n,this._owner=r,this.props=o};i.prototype={_isReactElement:!0},i.createElement=function(e,t,n){var o,u={},s=null,l=null;if(null!=t){l=void 0===t.ref?null:t.ref,s=void 0===t.key?null:""+t.key;for(o in t)t.hasOwnProperty(o)&&!a.hasOwnProperty(o)&&(u[o]=t[o])}var c=arguments.length-2;if(1===c)u.children=n;else if(c>1){for(var p=Array(c),d=0;c>d;d++)p[d]=arguments[d+2];u.children=p}if(e&&e.defaultProps){var f=e.defaultProps;for(o in f)"undefined"==typeof u[o]&&(u[o]=f[o])}return new i(e,s,l,r.current,u)},i.createFactory=function(e){var t=i.createElement.bind(null,e);return t.type=e,t},i.cloneAndReplaceProps=function(e,t){var n=new i(e.type,e.key,e.ref,e._owner,t);return n},i.cloneElement=function(e,t,n){var u,s=o({},e.props),l=e.key,c=e.ref,p=e._owner;if(null!=t){void 0!==t.ref&&(c=t.ref,p=r.current),void 0!==t.key&&(l=""+t.key);for(u in t)t.hasOwnProperty(u)&&!a.hasOwnProperty(u)&&(s[u]=t[u])}var d=arguments.length-2;if(1===d)s.children=n;else if(d>1){for(var f=Array(d),h=0;d>h;h++)f[h]=arguments[h+2];s.children=f}return new i(e.type,l,c,p,s)},i.isValidElement=function(e){var t=!(!e||!e._isReactElement);return t},t.exports=i},{23:23,34:34}],50:[function(e,t,n){"use strict";function r(){if(v.current){var e=v.current.getName();if(e)return" Check the render method of `"+e+"`."}return""}function o(e){var t=e&&e.getPublicInstance();if(!t)return void 0;var n=t.constructor;return n?n.displayName||n.name||void 0:void 0}function a(){var e=v.current;return e&&o(e)||void 0}function i(e,t){e._store.validated||null!=e.key||(e._store.validated=!0,s("uniqueKey",e,t))}function u(e,t,n){b.test(e)&&s("numericKeys",t,n)}function s(e,t,n){var r=a(),i="string"==typeof n?n:n.displayName||n.name,u=r||i,s=y[e]||(y[e]={});if(s[u])return null;s[u]=!0;var l={parentOrOwner:r?" Check the render method of "+r+".":i?" Check the React.render call using <"+i+">.":null,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return t&&t._owner&&t._owner!==v.current&&(l.childOwner=" It was passed a child from "+o(t._owner)+"."),l}function l(e,t){if(Array.isArray(e))for(var n=0;n1?u(e):i(e)}function i(e){for(var t=f.getFirstReactDOM(m(e.nativeEvent))||window,n=t;n;)e.ancestors.push(n),n=r(n);for(var o=0;o=i;i++)if(o(e,i)&&o(t,i))r=i;else if(e.charAt(i)!==t.charAt(i))break;var u=e.substr(0,r);return a(u)?void 0:d(!1),u}function c(e,t,n,r,o,a){e=e||"",t=t||"",e===t?d(!1):void 0;var l=i(t,e);l||i(e,t)?void 0:d(!1);for(var c=0,p=l?u:s,f=e;;f=p(f,t)){var h;if(o&&f===e||a&&f===t||(h=n(f,l,r)),h===!1||f===t)break;c++1){var t=e.indexOf(f,1);return t>-1?e.substr(0,t):e}return null},traverseEnterLeave:function(e,t,n,r,o){var a=l(e,t);a!==e&&c(e,a,n,r,!1,!0),a!==t&&c(a,t,n,o,!0,!1)},traverseTwoPhase:function(e,t,n){e&&(c("",e,t,n,!0,!1),c(e,"",t,n,!1,!0))},traverseTwoPhaseSkipTarget:function(e,t,n){e&&(c("",e,t,n,!0,!0),c(e,"",t,n,!0,!0))},traverseAncestors:function(e,t,n){c("",e,t,n,!0,!1)},getFirstCommonAncestorID:l,_getNextDescendantID:s,isAncestorIDOf:i,SEPARATOR:f};t.exports=m},{139:139,75:75}],59:[function(e,t,n){"use strict";var r={remove:function(e){e._reactInternalInstance=void 0},get:function(e){return e._reactInternalInstance},has:function(e){return void 0!==e._reactInternalInstance},set:function(e,t){e._reactInternalInstance=t}};t.exports=r},{}],60:[function(e,t,n){"use strict";var r=e(28),o=e(30),a=e(29),i=e(38),u=e(49),s=(e(50),e(71)),l=e(23),c=e(116),p=u.createElement,d=u.createFactory,f=u.cloneElement,h={Children:{map:r.map,forEach:r.forEach,count:r.count,only:c},Component:o,createElement:p,cloneElement:f,isValidElement:u.isValidElement,PropTypes:s,createClass:a.createClass,createFactory:d,createMixin:function(e){return e},DOM:i,__spread:l};t.exports=h},{116:116,23:23,28:28,29:29,30:30,38:38,49:49,50:50,71:71}],61:[function(e,t,n){"use strict";var r=e(99),o=/\/?>/,a={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return e.replace(o," "+a.CHECKSUM_ATTR_NAME+'="'+t+'"$&')},canReuseMarkup:function(e,t){var n=t.getAttribute(a.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var o=r(e);return o===n}};t.exports=a},{99:99}],62:[function(e,t,n){"use strict";function r(e,t){for(var n=Math.min(e.length,t.length),r=0;n>r;r++)if(e.charAt(r)!==t.charAt(r))return r;return e.length===t.length?-1:n}function o(e){return e?e.nodeType===F?e.documentElement:e.firstChild:null}function a(e){var t=o(e);return t&&z.getID(t)}function i(e){var t=u(e);if(t)if(U.hasOwnProperty(t)){var n=U[t];n!==e&&(p(n,t)?T(!1):void 0,U[t]=e)}else U[t]=e;return t}function u(e){return e&&e.getAttribute&&e.getAttribute(L)||""}function s(e,t){var n=u(e);n!==t&&delete U[n],e.setAttribute(L,t),U[t]=e}function l(e){return U.hasOwnProperty(e)&&p(U[e],e)||(U[e]=z.findReactNodeByID(e)),U[e]}function c(e){var t=x.get(e)._rootNodeID;return E.isNullComponentID(t)?null:(U.hasOwnProperty(t)&&p(U[t],t)||(U[t]=z.findReactNodeByID(t)),U[t])}function p(e,t){if(e){u(e)!==t?T(!1):void 0;var n=z.findReactContainerForID(t);if(n&&R(n,e))return!0}return!1}function d(e){delete U[e]}function f(e){var t=U[e];return t&&p(t,e)?void(H=t):!1}function h(e){H=null,_.traverseAncestors(e,f);var t=H;return H=null,t}function v(e,t,n,r,o,a){var i=M.mountComponent(e,t,r,a);e._renderedComponent._topLevelWrapper=e,z._mountImageIntoNode(i,n,o)}function m(e,t,n,r,o){var a=w.ReactReconcileTransaction.getPooled();a.perform(v,null,e,t,n,a,r,o),w.ReactReconcileTransaction.release(a)}function g(e,t){for(M.unmountComponent(e),t.nodeType===F&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)}var y=e(10),C=e(26),b=(e(34),e(49)),E=e(51),_=e(58),x=e(59),D=e(61),P=e(68),M=e(73),N=e(79),w=e(80),I=e(132),R=e(128),S=e(112),T=e(139),k=e(119),O=e(121),A=(e(123),e(147),_.SEPARATOR),L=y.ID_ATTRIBUTE_NAME,U={},B=1,F=9,j=11,V={},W={},K=[],H=null,q=function(){};q.prototype.render=function(){return this.props};var z={_instancesByReactRootID:V,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,t,n,r){return z.scrollMonitor(n,function(){N.enqueueElementInternal(e,t),r&&N.enqueueCallbackInternal(e,r)}),e},_registerComponent:function(e,t){!t||t.nodeType!==B&&t.nodeType!==F&&t.nodeType!==j?T(!1):void 0,C.ensureScrollValueMonitoring();var n=z.registerContainer(t);return V[n]=e,n},_renderNewRootComponent:function(e,t,n,r){var o=S(e,null),a=z._registerComponent(o,t);return w.batchedUpdates(m,o,a,t,n,r),o},renderSubtreeIntoContainer:function(e,t,n,r){return null==e||null==e._reactInternalInstance?T(!1):void 0,z._renderSubtreeIntoContainer(e,t,n,r)},_renderSubtreeIntoContainer:function(e,t,n,r){b.isValidElement(t)?void 0:T(!1);var i=new b(q,null,null,null,t),u=V[a(n)];if(u){var s=u._currentElement,l=s.props;if(O(l,t))return z._updateRootComponent(u,i,n,r)._renderedComponent.getPublicInstance();z.unmountComponentAtNode(n)}var c=o(n),p=c&&z.isRenderedByReact(c),d=p&&!u,f=z._renderNewRootComponent(i,n,d,null!=e?e._reactInternalInstance._processChildContext(e._reactInternalInstance._context):I)._renderedComponent.getPublicInstance();return r&&r.call(f),f},render:function(e,t,n){return z._renderSubtreeIntoContainer(null,e,t,n)},registerContainer:function(e){var t=a(e);return t&&(t=_.getReactRootIDFromNodeID(t)),t||(t=_.createReactRootID()),W[t]=e,t},unmountComponentAtNode:function(e){!e||e.nodeType!==B&&e.nodeType!==F&&e.nodeType!==j?T(!1):void 0;var t=a(e),n=V[t];return n?(w.batchedUpdates(g,n,e),delete V[t],delete W[t],!0):!1},findReactContainerForID:function(e){var t=_.getReactRootIDFromNodeID(e),n=W[t];return n},findReactNodeByID:function(e){var t=z.findReactContainerForID(e);return z.findComponentRoot(t,e)},isRenderedByReact:function(e){if(1!==e.nodeType)return!1;var t=z.getID(e);return t?t.charAt(0)===A:!1},getFirstReactDOM:function(e){for(var t=e;t&&t.parentNode!==t;){if(z.isRenderedByReact(t))return t;t=t.parentNode}return null},findComponentRoot:function(e,t){var n=K,r=0,o=h(t)||e;for(n[0]=o.firstChild,n.length=1;r>",x={array:o("array"),bool:o("boolean"),func:o("function"),number:o("number"),object:o("object"),string:o("string"),any:a(),arrayOf:i,element:u(),instanceOf:s,node:d(),objectOf:c,oneOf:l,oneOfType:p,shape:f};t.exports=x},{109:109,131:131,49:49,55:55,69:69}],72:[function(e,t,n){"use strict";function r(){this.reinitializeTransaction(),this.renderToStaticMarkup=!1,this.reactMountReady=o.getPooled(null)}var o=e(6),a=e(24),i=e(26),u=e(57),s=e(96),l=e(23),c={initialize:u.getSelectionInformation,close:u.restoreSelection},p={initialize:function(){var e=i.isEnabled();return i.setEnabled(!1),e},close:function(e){i.setEnabled(e)}},d={initialize:function(){this.reactMountReady.reset()},close:function(){this.reactMountReady.notifyAll()}},f=[c,p,d],h={getTransactionWrappers:function(){return f},getReactMountReady:function(){return this.reactMountReady},destructor:function(){o.release(this.reactMountReady),this.reactMountReady=null}};l(r.prototype,s.Mixin,h),a.addPoolingTo(r),t.exports=r},{23:23,24:24,26:26,57:57,6:6,96:96}],73:[function(e,t,n){"use strict";function r(){o.attachRefs(this,this._currentElement)}var o=e(74),a={mountComponent:function(e,t,n,o){var a=e.mountComponent(t,n,o);return null!=e._currentElement.ref&&n.getReactMountReady().enqueue(r,e),a},unmountComponent:function(e){o.detachRefs(e,e._currentElement),e.unmountComponent()},receiveComponent:function(e,t,n,a){var i=e._currentElement;if(t!==i||null==t._owner){var u=o.shouldUpdateRefs(i,t);u&&o.detachRefs(e,i),e.receiveComponent(t,n,a),u&&n.getReactMountReady().enqueue(r,e)}},performUpdateIfNecessary:function(e,t){e.performUpdateIfNecessary(t)}};t.exports=a},{74:74}],74:[function(e,t,n){"use strict";function r(e,t,n){"function"==typeof e?e(t.getPublicInstance()):a.addComponentAsRefTo(t,e,n)}function o(e,t,n){"function"==typeof e?e(null):a.removeComponentAsRefFrom(t,e,n)}var a=e(67),i={};i.attachRefs=function(e,t){var n=t.ref;null!=n&&r(n,e,t._owner)},i.shouldUpdateRefs=function(e,t){return t._owner!==e._owner||t.ref!==e.ref},i.detachRefs=function(e,t){var n=t.ref;null!=n&&o(n,e,t._owner)},t.exports=i},{67:67}],75:[function(e,t,n){"use strict";var r={injectCreateReactRootIndex:function(e){o.createReactRootIndex=e}},o={createReactRootIndex:null,injection:r};t.exports=o},{}],76:[function(e,t,n){"use strict";var r={isBatchingUpdates:!1,batchedUpdates:function(e){}};t.exports=r},{}],77:[function(e,t,n){"use strict";function r(e){i.isValidElement(e)?void 0:h(!1);var t;try{p.injection.injectBatchingStrategy(l);var n=u.createReactRootID();return t=c.getPooled(!1),t.perform(function(){var r=f(e,null),o=r.mountComponent(n,t,d);return s.addChecksumToMarkup(o)},null)}finally{c.release(t),p.injection.injectBatchingStrategy(a)}}function o(e){i.isValidElement(e)?void 0:h(!1);var t;try{p.injection.injectBatchingStrategy(l);var n=u.createReactRootID();return t=c.getPooled(!0),t.perform(function(){var r=f(e,null);return r.mountComponent(n,t,d)},null)}finally{c.release(t),p.injection.injectBatchingStrategy(a)}}var a=e(47),i=e(49),u=e(58),s=e(61),l=e(76),c=e(78),p=e(80),d=e(132),f=e(112),h=e(139);t.exports={renderToString:r,renderToStaticMarkup:o}},{112:112,132:132,139:139,47:47,49:49,58:58,61:61,76:76,78:78,80:80}],78:[function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e,this.reactMountReady=a.getPooled(null)}var o=e(24),a=e(6),i=e(96),u=e(23),s=e(131),l={initialize:function(){this.reactMountReady.reset()},close:s},c=[l],p={getTransactionWrappers:function(){return c},getReactMountReady:function(){return this.reactMountReady},destructor:function(){a.release(this.reactMountReady),this.reactMountReady=null}};u(r.prototype,i.Mixin,p),o.addPoolingTo(r),t.exports=r},{131:131,23:23,24:24,6:6,96:96}],79:[function(e,t,n){"use strict";function r(e){u.enqueueUpdate(e)}function o(e,t){var n=i.get(e);return n?n:null}var a=(e(34),e(49)),i=e(59),u=e(80),s=e(23),l=e(139),c=(e(147),{isMounted:function(e){var t=i.get(e);return t?!!t._renderedComponent:!1},enqueueCallback:function(e,t){"function"!=typeof t?l(!1):void 0;var n=o(e);return n?(n._pendingCallbacks?n._pendingCallbacks.push(t):n._pendingCallbacks=[t],void r(n)):null},enqueueCallbackInternal:function(e,t){"function"!=typeof t?l(!1):void 0,e._pendingCallbacks?e._pendingCallbacks.push(t):e._pendingCallbacks=[t],r(e)},enqueueForceUpdate:function(e){var t=o(e,"forceUpdate");t&&(t._pendingForceUpdate=!0,r(t))},enqueueReplaceState:function(e,t){var n=o(e,"replaceState");n&&(n._pendingStateQueue=[t],n._pendingReplaceState=!0,r(n))},enqueueSetState:function(e,t){var n=o(e,"setState");if(n){var a=n._pendingStateQueue||(n._pendingStateQueue=[]);a.push(t),r(n)}},enqueueSetProps:function(e,t){var n=o(e,"setProps");n&&c.enqueueSetPropsInternal(n,t)},enqueueSetPropsInternal:function(e,t){var n=e._topLevelWrapper;n?void 0:l(!1);var o=n._pendingElement||n._currentElement,i=o.props,u=s({},i.props,t);n._pendingElement=a.cloneAndReplaceProps(o,a.cloneAndReplaceProps(i,u)),r(n)},enqueueReplaceProps:function(e,t){var n=o(e,"replaceProps");n&&c.enqueueReplacePropsInternal(n,t)},enqueueReplacePropsInternal:function(e,t){var n=e._topLevelWrapper;n?void 0:l(!1);var o=n._pendingElement||n._currentElement,i=o.props;n._pendingElement=a.cloneAndReplaceProps(o,a.cloneAndReplaceProps(i,t)),r(n)},enqueueElementInternal:function(e,t){e._pendingElement=t,r(e)}});t.exports=c},{139:139,147:147,23:23,34:34,49:49,59:59,80:80}],80:[function(e,t,n){"use strict";function r(){M.ReactReconcileTransaction&&b?void 0:m(!1)}function o(){this.reinitializeTransaction(), 15 | this.dirtyComponentsLength=null,this.callbackQueue=c.getPooled(),this.reconcileTransaction=M.ReactReconcileTransaction.getPooled()}function a(e,t,n,o,a,i){r(),b.batchedUpdates(e,t,n,o,a,i)}function i(e,t){return e._mountOrder-t._mountOrder}function u(e){var t=e.dirtyComponentsLength;t!==g.length?m(!1):void 0,g.sort(i);for(var n=0;t>n;n++){var r=g[n],o=r._pendingCallbacks;if(r._pendingCallbacks=null,f.performUpdateIfNecessary(r,e.reconcileTransaction),o)for(var a=0;ar;){for(;rr;r++)n+=t+=e.charCodeAt(r);return t%=o,n%=o,t|n<<16}var o=65521;t.exports=r},{}],100:[function(e,t,n){"use strict";function r(e,t){var n=null==t||"boolean"==typeof t||""===t;if(n)return"";var r=isNaN(t);return r||0===t||a.hasOwnProperty(e)&&a[e]?""+t:("string"==typeof t&&(t=t.trim()),t+"px")}var o=e(4),a=o.isUnitlessNumber;t.exports=r},{4:4}],101:[function(e,t,n){"use strict";function r(e){return a[e]}function o(e){return(""+e).replace(i,r)}var a={"&":"&",">":">","<":"<",'"':""","'":"'"},i=/[&><"']/g;t.exports=o},{}],102:[function(e,t,n){"use strict";function r(e){return null==e?null:1===e.nodeType?e:o.has(e)?a.getNodeFromInstance(e):(null!=e.render&&"function"==typeof e.render?i(!1):void 0,void i(!1))}var o=(e(34),e(59)),a=e(62),i=e(139);e(147);t.exports=r},{139:139,147:147,34:34,59:59,62:62}],103:[function(e,t,n){"use strict";function r(e,t,n){var r=e,o=void 0===r[n];o&&null!=t&&(r[n]=t)}function o(e){if(null==e)return e;var t={};return a(e,r,t),t}var a=e(122);e(147);t.exports=o},{122:122,147:147}],104:[function(e,t,n){"use strict";var r=function(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)};t.exports=r},{}],105:[function(e,t,n){"use strict";function r(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}t.exports=r},{}],106:[function(e,t,n){"use strict";function r(e){if(e.key){var t=a[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=o(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?i[e.keyCode]||"Unidentified":""}var o=e(105),a={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},i={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};t.exports=r},{105:105}],107:[function(e,t,n){"use strict";function r(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=a[e];return r?!!n[r]:!1}function o(e){return r}var a={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};t.exports=o},{}],108:[function(e,t,n){"use strict";function r(e){var t=e.target||e.srcElement||window;return 3===t.nodeType?t.parentNode:t}t.exports=r},{}],109:[function(e,t,n){"use strict";function r(e){var t=e&&(o&&e[o]||e[a]);return"function"==typeof t?t:void 0}var o="function"==typeof Symbol&&Symbol.iterator,a="@@iterator";t.exports=r},{}],110:[function(e,t,n){"use strict";function r(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function o(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function a(e,t){for(var n=r(e),a=0,i=0;n;){if(3===n.nodeType){if(i=a+n.textContent.length,t>=a&&i>=t)return{node:n,offset:t-a};a=i}n=r(o(n))}}t.exports=a},{}],111:[function(e,t,n){"use strict";function r(){return!a&&o.canUseDOM&&(a="textContent"in document.documentElement?"textContent":"innerText"),a}var o=e(125),a=null;t.exports=r},{125:125}],112:[function(e,t,n){"use strict";function r(e){return"function"==typeof e&&"undefined"!=typeof e.prototype&&"function"==typeof e.prototype.mountComponent&&"function"==typeof e.prototype.receiveComponent}function o(e){var t;if((null===e||e===!1)&&(e=i.emptyElement),"object"==typeof e){var n=e;!n||"function"!=typeof n.type&&"string"!=typeof n.type?l(!1):void 0,t="string"==typeof n.type?u.createInternalComponent(n):r(n.type)?new n.type(n):new c}else"string"==typeof e||"number"==typeof e?t=u.createInstanceForText(e):l(!1);return t.construct(e),t._mountIndex=0,t._mountImage=null,t}var a=e(33),i=e(51),u=e(65),s=e(23),l=e(139),c=(e(147),function(){});s(c.prototype,a.Mixin,{_instantiateReactComponent:o}),t.exports=o},{139:139,147:147,23:23,33:33,51:51,65:65}],113:[function(e,t,n){"use strict";function r(e,t){if(!a.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var i=document.createElement("div");i.setAttribute(n,"return;"),r="function"==typeof i[n]}return!r&&o&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var o,a=e(125);a.canUseDOM&&(o=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),t.exports=r},{125:125}],114:[function(e,t,n){"use strict";function r(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&o[e.type]||"textarea"===t)}var o={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};t.exports=r},{}],115:[function(e,t,n){"use strict";function r(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}t.exports=r},{}],116:[function(e,t,n){"use strict";function r(e){return o.isValidElement(e)?void 0:a(!1),e}var o=e(49),a=e(139);t.exports=r},{139:139,49:49}],117:[function(e,t,n){"use strict";function r(e){return'"'+o(e)+'"'}var o=e(101);t.exports=r},{101:101}],118:[function(e,t,n){"use strict";var r=e(62);t.exports=r.renderSubtreeIntoContainer},{62:62}],119:[function(e,t,n){"use strict";var r=e(125),o=/^[ \r\n\t\f]/,a=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(e,t){e.innerHTML=t};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(e,t){MSApp.execUnsafeLocalFunction(function(){e.innerHTML=t})}),r.canUseDOM){var u=document.createElement("div");u.innerHTML=" ",""===u.innerHTML&&(i=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),o.test(t)||"<"===t[0]&&a.test(t)){e.innerHTML=String.fromCharCode(65279)+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t})}t.exports=i},{125:125}],120:[function(e,t,n){"use strict";var r=e(125),o=e(101),a=e(119),i=function(e,t){e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(i=function(e,t){a(e,o(t))})),t.exports=i},{101:101,119:119,125:125}],121:[function(e,t,n){"use strict";function r(e,t){if(null!=e&&null!=t){var n=typeof e,r=typeof t;return"string"===n||"number"===n?"string"===r||"number"===r:"object"===r&&e.type===t.type&&e.key===t.key}return!1}t.exports=r},{}],122:[function(e,t,n){"use strict";function r(e){return m[e]}function o(e,t){return e&&null!=e.key?i(e.key):t.toString(36)}function a(e){return(""+e).replace(g,r)}function i(e){return"$"+a(e)}function u(e,t,n,r){var a=typeof e;if(("undefined"===a||"boolean"===a)&&(e=null),null===e||"string"===a||"number"===a||l.isValidElement(e))return n(r,e,""===t?h+o(e,0):t),1;var s,p,m=0,g=""!==t?t+v:h;if(Array.isArray(e))for(var y=0;y":i.innerHTML="<"+e+">",u[e]=!i.firstChild),u[e]?d[e]:null}var o=e(125),a=e(139),i=o.canUseDOM?document.createElement("div"):null,u={},s=[1,'"],l=[1,"","
"],c=[3,"","
"],p=[1,'',""],d={"*":[1,"?
","
"],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"], 16 | param:[1,"",""],tr:[2,"","
"],optgroup:s,option:s,caption:l,colgroup:l,tbody:l,tfoot:l,thead:l,td:c,th:c},f=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];f.forEach(function(e){d[e]=p,u[e]=!0}),t.exports=r},{125:125,139:139}],136:[function(e,t,n){"use strict";function r(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}t.exports=r},{}],137:[function(e,t,n){"use strict";function r(e){return e.replace(o,"-$1").toLowerCase()}var o=/([A-Z])/g;t.exports=r},{}],138:[function(e,t,n){"use strict";function r(e){return o(e).replace(a,"-ms-")}var o=e(137),a=/^ms-/;t.exports=r},{137:137}],139:[function(e,t,n){"use strict";var r=function(e,t,n,r,o,a,i,u){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,a,i,u],c=0;s=new Error("Invariant Violation: "+t.replace(/%s/g,function(){return l[c++]}))}throw s.framesToPop=1,s}};t.exports=r},{}],140:[function(e,t,n){"use strict";function r(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}t.exports=r},{}],141:[function(e,t,n){"use strict";function r(e){return o(e)&&3==e.nodeType}var o=e(140);t.exports=r},{140:140}],142:[function(e,t,n){"use strict";var r=e(139),o=function(e){var t,n={};e instanceof Object&&!Array.isArray(e)?void 0:r(!1);for(t in e)e.hasOwnProperty(t)&&(n[t]=t);return n};t.exports=o},{139:139}],143:[function(e,t,n){"use strict";var r=function(e){var t;for(t in e)if(e.hasOwnProperty(t))return t;return null};t.exports=r},{}],144:[function(e,t,n){"use strict";function r(e,t,n){if(!e)return null;var r={};for(var a in e)o.call(e,a)&&(r[a]=t.call(n,e[a],a,e));return r}var o=Object.prototype.hasOwnProperty;t.exports=r},{}],145:[function(e,t,n){"use strict";function r(e,t){if(e===t)return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(var a=o.bind(t),i=0;ia;a++)r[a]=e[a];return r}var o=e(139);t.exports=r},{139:139}],147:[function(e,t,n){"use strict";var r=e(131),o=r;t.exports=o},{131:131}]},{},[1])(1)}); -------------------------------------------------------------------------------- /test/engine_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenixTest do 2 | # Engine 3 | use ExUnit.Case 4 | alias Phoenix.View 5 | 6 | defmodule MyApp.PageView do 7 | use Phoenix.View, root: "test/fixtures/templates" 8 | use Phoenix.HTML 9 | import ReactPhoenix.Utils 10 | end 11 | 12 | test "render a js template without layout" do 13 | {:safe, html} = View.render(MyApp.PageView, "new.html", []) 14 | assert (to_string html) == "
foo
" 15 | end 16 | 17 | test "render a js template with layout" do 18 | {:safe, data} = View.render(MyApp.PageView, "new.html", 19 | layout: {MyApp.PageView, "application.html"} 20 | ) 21 | assert (to_string data) == "\n
foo
\n\n" 22 | end 23 | 24 | test "render as prerender: false" do 25 | {:safe, data} = View.render(MyApp.PageView, "util.html", 26 | layout: {MyApp.PageView, "application.html"} 27 | ) 28 | assert (to_string data) == "\n
\n
\n
\n\n\n" 29 | end 30 | 31 | test "render as prerender: true" do 32 | ReactPhoenix.JSContext.load_javascript """ 33 | var Hello = React.createClass({render: function(){return React.createElement('div', {}, "hello")}}) 34 | """ 35 | 36 | {:safe, data} = View.render(MyApp.PageView, "util-prerender.html", 37 | layout: {MyApp.PageView, "application.html"} 38 | ) 39 | assert (to_string data) != "\n
\n
\n
\n\n\n" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /test/fixtures/templates/my_app/page/application.html.eex: -------------------------------------------------------------------------------- 1 | 2 | <%= @inner %> 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/templates/my_app/page/layout.html.eex: -------------------------------------------------------------------------------- 1 |
<%= @inner %>
2 | -------------------------------------------------------------------------------- /test/fixtures/templates/my_app/page/new.html.js: -------------------------------------------------------------------------------- 1 | React.renderToStaticMarkup(React.createElement('div', {}, 'foo')) 2 | -------------------------------------------------------------------------------- /test/fixtures/templates/my_app/page/sub.html.eex: -------------------------------------------------------------------------------- 1 |
sub
2 | -------------------------------------------------------------------------------- /test/fixtures/templates/my_app/page/template.html.jade: -------------------------------------------------------------------------------- 1 | .container 2 | h1 This is react-jade template 3 | -------------------------------------------------------------------------------- /test/fixtures/templates/my_app/page/util-prerender.html.eex: -------------------------------------------------------------------------------- 1 |
2 | <%= react_component "Hello", %{a: 1}, prerender: true %> 3 |
4 | -------------------------------------------------------------------------------- /test/fixtures/templates/my_app/page/util.html.eex: -------------------------------------------------------------------------------- 1 |
2 | <%= react_component "Hello", %{a: 1}, prerender: false %> 3 |
4 | -------------------------------------------------------------------------------- /test/js_context_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenixTest.Renderer do 2 | use ExUnit.Case 3 | test "Renderer returns result" do 4 | {:ok, result} = ReactPhoenix.JSContext.eval "React.renderToStaticMarkup(React.createElement('div', {}, 'foo'))" 5 | assert result == "
foo
" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /test/utils_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ReactPhoenixTest.Utils do 2 | use ExUnit.Case 3 | import ReactPhoenix.Utils 4 | # defmodule MyApp.PageView do 5 | # use Phoenix.View, root: "test/fixtures/templates" 6 | # use Phoenix.HTML 7 | # import ReactPhoenix.Utils 8 | # end 9 | 10 | test "react_component should render wrapper with prerender: false" do 11 | {:safe, html} = react_component "Hello", %{a: 1}, prerender: false 12 | assert (to_string html) == "
" 13 | end 14 | 15 | test "react_component should render content with prerender: true" do 16 | ReactPhoenix.JSContext.load_javascript """ 17 | var Hello = React.createClass({render: function(){return React.createElement('div', {}, "hello")}}) 18 | """ 19 | 20 | {:safe, html} = react_component "Hello", %{a: 1}, prerender: true 21 | assert (to_string html) != "
" 22 | end 23 | end 24 | --------------------------------------------------------------------------------