reactive-ruby 0.7.28 → 0.7.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +6 -0
- data/Gemfile.lock +4 -1
- data/README.md +132 -68
- data/Rakefile +5 -2
- data/example/examples/Gemfile +0 -2
- data/example/rails-tutorial/Gemfile +3 -2
- data/lib/generators/reactive_ruby/test_app/templates/application.rb +11 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/application.rb +2 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +3 -0
- data/lib/generators/reactive_ruby/test_app/templates/boot.rb +6 -0
- data/lib/generators/reactive_ruby/test_app/templates/script/rails +5 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
- data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +105 -0
- data/lib/rails-helpers/top_level_rails_component.rb +9 -16
- data/lib/{reactive-ruby → react}/api.rb +8 -65
- data/lib/{reactive-ruby → react}/callbacks.rb +0 -0
- data/lib/react/component.rb +266 -0
- data/lib/react/component/api.rb +48 -0
- data/lib/react/component/class_methods.rb +183 -0
- data/lib/{reactive-ruby → react}/element.rb +10 -11
- data/lib/{reactive-ruby → react}/event.rb +0 -0
- data/lib/{reactive-ruby → react}/ext/hash.rb +0 -0
- data/lib/{reactive-ruby → react}/ext/string.rb +0 -0
- data/lib/react/native_library.rb +57 -0
- data/lib/{reactive-ruby → react}/observable.rb +0 -4
- data/lib/{reactive-ruby → react}/rendering_context.rb +0 -6
- data/lib/{reactive-ruby → react}/state.rb +3 -6
- data/lib/{reactive-ruby → react}/top_level.rb +2 -3
- data/lib/react/validator.rb +127 -0
- data/lib/reactive-ruby.rb +20 -20
- data/lib/reactive-ruby/version.rb +1 -1
- data/{opal-spec/reactjs → spec}/index.html.erb +1 -1
- data/{opal-spec → spec/react}/callbacks_spec.rb +8 -9
- data/{opal-spec → spec/react}/component_spec.rb +170 -120
- data/spec/react/dsl_spec.rb +16 -0
- data/{opal-spec → spec/react}/element_spec.rb +7 -20
- data/{opal-spec → spec/react}/event_spec.rb +3 -1
- data/spec/react/native_library_spec.rb +10 -0
- data/spec/react/param_declaration_spec.rb +18 -0
- data/{opal-spec → spec/react}/react_spec.rb +3 -2
- data/spec/react/react_state_spec.rb +22 -0
- data/spec/react/top_level_component_spec.rb +68 -0
- data/{opal-spec → spec/react}/tutorial/tutorial_spec.rb +11 -13
- data/{opal-spec → spec/react}/validator_spec.rb +50 -4
- data/spec/reactive-ruby/isomorphic_helpers_spec.rb +22 -4
- data/spec/spec_helper.rb +51 -0
- data/spec/support/react/spec_helpers.rb +57 -0
- data/spec/vendor/es5-shim.min.js +6 -0
- metadata +56 -24
- data/lib/reactive-ruby/component.rb +0 -502
- data/lib/reactive-ruby/validator.rb +0 -99
- data/old-readme +0 -220
- data/opal-spec/spec_helper.rb +0 -29
@@ -0,0 +1,57 @@
|
|
1
|
+
module React
|
2
|
+
module SpecHelpers
|
3
|
+
`var ReactTestUtils = React.addons.TestUtils`
|
4
|
+
|
5
|
+
def renderToDocument(type, options = {})
|
6
|
+
element = React.create_element(type, options)
|
7
|
+
return renderElementToDocument(element)
|
8
|
+
end
|
9
|
+
|
10
|
+
def renderElementToDocument(element)
|
11
|
+
instance = Native(`ReactTestUtils.renderIntoDocument(#{element.to_n})`)
|
12
|
+
instance.class.include(React::Component::API)
|
13
|
+
return instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def simulateEvent(event, element, params = {})
|
17
|
+
simulator = Native(`ReactTestUtils.Simulate`)
|
18
|
+
simulator[event.to_s].call(`#{element.to_n}.getDOMNode()`, params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def isElementOfType(element, type)
|
22
|
+
`React.addons.TestUtils.isElementOfType(#{element.to_n}, #{type.cached_component_class})`
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_element(type, options)
|
26
|
+
component = React.create_element(type, options)
|
27
|
+
element = `ReactTestUtils.renderIntoDocument(#{component.to_n})`
|
28
|
+
if `typeof React.findDOMNode === 'undefined'`
|
29
|
+
`$(element.getDOMNode())` # v0.12
|
30
|
+
else
|
31
|
+
`$(React.findDOMNode(element))` # v0.13
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def expect_component_to_eventually(component_class, opts = {}, &block)
|
36
|
+
# Calls block after each update of a component until it returns true.
|
37
|
+
# When it does set the expectation to true. Uses the after_update
|
38
|
+
# callback of the component_class, then instantiates an element of that
|
39
|
+
# class The call back is only called on updates, so the call back is
|
40
|
+
# manually called right after the element is created. Because React.rb
|
41
|
+
# runs the callback inside the components context, we have to setup a
|
42
|
+
# lambda to get back to correct context before executing run_async.
|
43
|
+
# Because run_async can only be run once it is protected by clearing
|
44
|
+
# element once the test passes.
|
45
|
+
element = nil
|
46
|
+
check_block = lambda do
|
47
|
+
context = block.arity > 0 ? self : element
|
48
|
+
run_async do
|
49
|
+
element = nil; expect(true).to be(true)
|
50
|
+
end if element and context.instance_exec(element, &block)
|
51
|
+
end
|
52
|
+
component_class.after_update { check_block.call }
|
53
|
+
element = build_element component_class, opts
|
54
|
+
check_block.call
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
/*!
|
2
|
+
* https://github.com/es-shims/es5-shim
|
3
|
+
* @license es5-shim Copyright 2009-2014 by contributors, MIT License
|
4
|
+
* see https://github.com/es-shims/es5-shim/blob/v4.1.0/LICENSE
|
5
|
+
*/
|
6
|
+
(function(t,e){"use strict";if(typeof define==="function"&&define.amd){define(e)}else if(typeof exports==="object"){module.exports=e()}else{t.returnExports=e()}})(this,function(){var t=Array.prototype;var e=Object.prototype;var r=Function.prototype;var n=String.prototype;var i=Number.prototype;var a=t.slice;var o=t.splice;var u=t.push;var l=t.unshift;var f=r.call;var s=e.toString;var c=Array.isArray||function ye(t){return s.call(t)==="[object Array]"};var p=typeof Symbol==="function"&&typeof Symbol.toStringTag==="symbol";var h;var v=Function.prototype.toString,g=function de(t){try{v.call(t);return true}catch(e){return false}},y="[object Function]",d="[object GeneratorFunction]";h=function me(t){if(typeof t!=="function"){return false}if(p){return g(t)}var e=s.call(t);return e===y||e===d};var m;var b=RegExp.prototype.exec,w=function be(t){try{b.call(t);return true}catch(e){return false}},T="[object RegExp]";m=function we(t){if(typeof t!=="object"){return false}return p?w(t):s.call(t)===T};var x;var O=String.prototype.valueOf,j=function Te(t){try{O.call(t);return true}catch(e){return false}},S="[object String]";x=function xe(t){if(typeof t==="string"){return true}if(typeof t!=="object"){return false}return p?j(t):s.call(t)===S};var E=function Oe(t){var e=s.call(t);var r=e==="[object Arguments]";if(!r){r=!c(t)&&t!==null&&typeof t==="object"&&typeof t.length==="number"&&t.length>=0&&h(t.callee)}return r};var N=function(t){var e=Object.defineProperty&&function(){try{Object.defineProperty({},"x",{});return true}catch(t){return false}}();var r;if(e){r=function(t,e,r,n){if(!n&&e in t){return}Object.defineProperty(t,e,{configurable:true,enumerable:false,writable:true,value:r})}}else{r=function(t,e,r,n){if(!n&&e in t){return}t[e]=r}}return function n(e,i,a){for(var o in i){if(t.call(i,o)){r(e,o,i[o],a)}}}}(e.hasOwnProperty);function I(t){var e=typeof t;return t===null||e==="undefined"||e==="boolean"||e==="number"||e==="string"}var D={ToInteger:function je(t){var e=+t;if(e!==e){e=0}else if(e!==0&&e!==1/0&&e!==-(1/0)){e=(e>0||-1)*Math.floor(Math.abs(e))}return e},ToPrimitive:function Se(t){var e,r,n;if(I(t)){return t}r=t.valueOf;if(h(r)){e=r.call(t);if(I(e)){return e}}n=t.toString;if(h(n)){e=n.call(t);if(I(e)){return e}}throw new TypeError},ToObject:function(t){if(t==null){throw new TypeError("can't convert "+t+" to object")}return Object(t)},ToUint32:function Ee(t){return t>>>0}};var M=function Ne(){};N(r,{bind:function Ie(t){var e=this;if(!h(e)){throw new TypeError("Function.prototype.bind called on incompatible "+e)}var r=a.call(arguments,1);var n;var i=function(){if(this instanceof n){var i=e.apply(this,r.concat(a.call(arguments)));if(Object(i)===i){return i}return this}else{return e.apply(t,r.concat(a.call(arguments)))}};var o=Math.max(0,e.length-r.length);var u=[];for(var l=0;l<o;l++){u.push("$"+l)}n=Function("binder","return function ("+u.join(",")+"){ return binder.apply(this, arguments); }")(i);if(e.prototype){M.prototype=e.prototype;n.prototype=new M;M.prototype=null}return n}});var F=f.bind(e.hasOwnProperty);var R=function(){var t=[1,2];var e=t.splice();return t.length===2&&c(e)&&e.length===0}();N(t,{splice:function De(t,e){if(arguments.length===0){return[]}else{return o.apply(this,arguments)}}},!R);var U=function(){var e={};t.splice.call(e,0,0,1);return e.length===1}();N(t,{splice:function Me(t,e){if(arguments.length===0){return[]}var r=arguments;this.length=Math.max(D.ToInteger(this.length),0);if(arguments.length>0&&typeof e!=="number"){r=a.call(arguments);if(r.length<2){r.push(this.length-t)}else{r[1]=D.ToInteger(e)}}return o.apply(this,r)}},!U);var k=[].unshift(0)!==1;N(t,{unshift:function(){l.apply(this,arguments);return this.length}},k);N(Array,{isArray:c});var A=Object("a");var C=A[0]!=="a"||!(0 in A);var P=function Fe(t){var e=true;var r=true;if(t){t.call("foo",function(t,r,n){if(typeof n!=="object"){e=false}});t.call([1],function(){"use strict";r=typeof this==="string"},"x")}return!!t&&e&&r};N(t,{forEach:function Re(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=arguments[1],i=-1,a=r.length>>>0;if(!h(t)){throw new TypeError}while(++i<a){if(i in r){t.call(n,r[i],i,e)}}}},!P(t.forEach));N(t,{map:function Ue(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=r.length>>>0,i=Array(n),a=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var o=0;o<n;o++){if(o in r){i[o]=t.call(a,r[o],o,e)}}return i}},!P(t.map));N(t,{filter:function ke(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=r.length>>>0,i=[],a,o=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var u=0;u<n;u++){if(u in r){a=r[u];if(t.call(o,a,u,e)){i.push(a)}}}return i}},!P(t.filter));N(t,{every:function Ae(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=r.length>>>0,i=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var a=0;a<n;a++){if(a in r&&!t.call(i,r[a],a,e)){return false}}return true}},!P(t.every));N(t,{some:function Ce(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=r.length>>>0,i=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var a=0;a<n;a++){if(a in r&&t.call(i,r[a],a,e)){return true}}return false}},!P(t.some));var Z=false;if(t.reduce){Z=typeof t.reduce.call("es5",function(t,e,r,n){return n})==="object"}N(t,{reduce:function Pe(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=r.length>>>0;if(!h(t)){throw new TypeError(t+" is not a function")}if(!n&&arguments.length===1){throw new TypeError("reduce of empty array with no initial value")}var i=0;var a;if(arguments.length>=2){a=arguments[1]}else{do{if(i in r){a=r[i++];break}if(++i>=n){throw new TypeError("reduce of empty array with no initial value")}}while(true)}for(;i<n;i++){if(i in r){a=t.call(void 0,a,r[i],i,e)}}return a}},!Z);var J=false;if(t.reduceRight){J=typeof t.reduceRight.call("es5",function(t,e,r,n){return n})==="object"}N(t,{reduceRight:function Ze(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=r.length>>>0;if(!h(t)){throw new TypeError(t+" is not a function")}if(!n&&arguments.length===1){throw new TypeError("reduceRight of empty array with no initial value")}var i,a=n-1;if(arguments.length>=2){i=arguments[1]}else{do{if(a in r){i=r[a--];break}if(--a<0){throw new TypeError("reduceRight of empty array with no initial value")}}while(true)}if(a<0){return i}do{if(a in r){i=t.call(void 0,i,r[a],a,e)}}while(a--);return i}},!J);var z=Array.prototype.indexOf&&[0,1].indexOf(1,2)!==-1;N(t,{indexOf:function Je(t){var e=C&&x(this)?this.split(""):D.ToObject(this),r=e.length>>>0;if(!r){return-1}var n=0;if(arguments.length>1){n=D.ToInteger(arguments[1])}n=n>=0?n:Math.max(0,r+n);for(;n<r;n++){if(n in e&&e[n]===t){return n}}return-1}},z);var $=Array.prototype.lastIndexOf&&[0,1].lastIndexOf(0,-3)!==-1;N(t,{lastIndexOf:function ze(t){var e=C&&x(this)?this.split(""):D.ToObject(this),r=e.length>>>0;if(!r){return-1}var n=r-1;if(arguments.length>1){n=Math.min(n,D.ToInteger(arguments[1]))}n=n>=0?n:r-Math.abs(n);for(;n>=0;n--){if(n in e&&t===e[n]){return n}}return-1}},$);var B=!{toString:null}.propertyIsEnumerable("toString"),G=function(){}.propertyIsEnumerable("prototype"),H=!F("x","0"),L=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],X=L.length;N(Object,{keys:function $e(t){var e=h(t),r=E(t),n=t!==null&&typeof t==="object",i=n&&x(t);if(!n&&!e&&!r){throw new TypeError("Object.keys called on a non-object")}var a=[];var o=G&&e;if(i&&H||r){for(var u=0;u<t.length;++u){a.push(String(u))}}if(!r){for(var l in t){if(!(o&&l==="prototype")&&F(t,l)){a.push(String(l))}}}if(B){var f=t.constructor,s=f&&f.prototype===t;for(var c=0;c<X;c++){var p=L[c];if(!(s&&p==="constructor")&&F(t,p)){a.push(p)}}}return a}});var Y=Object.keys&&function(){return Object.keys(arguments).length===2}(1,2);var q=Object.keys;N(Object,{keys:function Be(e){if(E(e)){return q(t.slice.call(e))}else{return q(e)}}},!Y);var K=-621987552e5;var Q="-000001";var V=Date.prototype.toISOString&&new Date(K).toISOString().indexOf(Q)===-1;N(Date.prototype,{toISOString:function Ge(){var t,e,r,n,i;if(!isFinite(this)){throw new RangeError("Date.prototype.toISOString called on non-finite value.")}n=this.getUTCFullYear();i=this.getUTCMonth();n+=Math.floor(i/12);i=(i%12+12)%12;t=[i+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()];n=(n<0?"-":n>9999?"+":"")+("00000"+Math.abs(n)).slice(0<=n&&n<=9999?-4:-6);e=t.length;while(e--){r=t[e];if(r<10){t[e]="0"+r}}return n+"-"+t.slice(0,2).join("-")+"T"+t.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"}},V);var W=false;try{W=Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(K).toJSON().indexOf(Q)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(_){}if(!W){Date.prototype.toJSON=function He(t){var e=Object(this),r=D.ToPrimitive(e),n;if(typeof r==="number"&&!isFinite(r)){return null}n=e.toISOString;if(typeof n!=="function"){throw new TypeError("toISOString property is not callable")}return n.call(e)}}var te=Date.parse("+033658-09-27T01:46:40.000Z")===1e15;var ee=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"));var re=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));if(!Date.parse||re||ee||!te){Date=function(t){function e(r,n,i,a,o,u,l){var f=arguments.length;if(this instanceof t){var s=f===1&&String(r)===r?new t(e.parse(r)):f>=7?new t(r,n,i,a,o,u,l):f>=6?new t(r,n,i,a,o,u):f>=5?new t(r,n,i,a,o):f>=4?new t(r,n,i,a):f>=3?new t(r,n,i):f>=2?new t(r,n):f>=1?new t(r):new t;s.constructor=e;return s}return t.apply(this,arguments)}var r=new RegExp("^"+"(\\d{4}|[+-]\\d{6})"+"(?:-(\\d{2})"+"(?:-(\\d{2})"+"(?:"+"T(\\d{2})"+":(\\d{2})"+"(?:"+":(\\d{2})"+"(?:(\\.\\d{1,}))?"+")?"+"("+"Z|"+"(?:"+"([-+])"+"(\\d{2})"+":(\\d{2})"+")"+")?)?)?)?"+"$");var n=[0,31,59,90,120,151,181,212,243,273,304,334,365];function i(t,e){var r=e>1?1:0;return n[e]+Math.floor((t-1969+r)/4)-Math.floor((t-1901+r)/100)+Math.floor((t-1601+r)/400)+365*(t-1970)}function a(e){return Number(new t(1970,0,1,0,0,0,e))}for(var o in t){e[o]=t[o]}e.now=t.now;e.UTC=t.UTC;e.prototype=t.prototype;e.prototype.constructor=e;e.parse=function u(e){var n=r.exec(e);if(n){var o=Number(n[1]),u=Number(n[2]||1)-1,l=Number(n[3]||1)-1,f=Number(n[4]||0),s=Number(n[5]||0),c=Number(n[6]||0),p=Math.floor(Number(n[7]||0)*1e3),h=Boolean(n[4]&&!n[8]),v=n[9]==="-"?1:-1,g=Number(n[10]||0),y=Number(n[11]||0),d;if(f<(s>0||c>0||p>0?24:25)&&s<60&&c<60&&p<1e3&&u>-1&&u<12&&g<24&&y<60&&l>-1&&l<i(o,u+1)-i(o,u)){d=((i(o,u)+l)*24+f+g*v)*60;d=((d+s+y*v)*60+c)*1e3+p;if(h){d=a(d)}if(-864e13<=d&&d<=864e13){return d}}return NaN}return t.parse.apply(this,arguments)};return e}(Date)}if(!Date.now){Date.now=function Le(){return(new Date).getTime()}}var ne=i.toFixed&&(8e-5.toFixed(3)!=="0.000"||.9.toFixed(0)!=="1"||1.255.toFixed(2)!=="1.25"||0xde0b6b3a7640080.toFixed(0)!=="1000000000000000128");var ie={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function Xe(t,e){var r=-1;while(++r<ie.size){e+=t*ie.data[r];ie.data[r]=e%ie.base;e=Math.floor(e/ie.base)}},divide:function Ye(t){var e=ie.size,r=0;while(--e>=0){r+=ie.data[e];ie.data[e]=Math.floor(r/t);r=r%t*ie.base}},numToString:function qe(){var t=ie.size;var e="";while(--t>=0){if(e!==""||t===0||ie.data[t]!==0){var r=String(ie.data[t]);if(e===""){e=r}else{e+="0000000".slice(0,7-r.length)+r}}}return e},pow:function Ke(t,e,r){return e===0?r:e%2===1?Ke(t,e-1,r*t):Ke(t*t,e/2,r)},log:function Qe(t){var e=0;while(t>=4096){e+=12;t/=4096}while(t>=2){e+=1;t/=2}return e}};N(i,{toFixed:function Ve(t){var e,r,n,i,a,o,u,l;e=Number(t);e=e!==e?0:Math.floor(e);if(e<0||e>20){throw new RangeError("Number.toFixed called with invalid number of decimals")}r=Number(this);if(r!==r){return"NaN"}if(r<=-1e21||r>=1e21){return String(r)}n="";if(r<0){n="-";r=-r}i="0";if(r>1e-21){a=ie.log(r*ie.pow(2,69,1))-69;o=a<0?r*ie.pow(2,-a,1):r/ie.pow(2,a,1);o*=4503599627370496;a=52-a;if(a>0){ie.multiply(0,o);u=e;while(u>=7){ie.multiply(1e7,0);u-=7}ie.multiply(ie.pow(10,u,1),0);u=a-1;while(u>=23){ie.divide(1<<23);u-=23}ie.divide(1<<u);ie.multiply(1,1);ie.divide(2);i=ie.numToString()}else{ie.multiply(0,o);ie.multiply(1<<-a,0);i=ie.numToString()+"0.00000000000000000000".slice(2,2+e)}}if(e>0){l=i.length;if(l<=e){i=n+"0.0000000000000000000".slice(0,e-l+2)+i}else{i=n+i.slice(0,l-e)+"."+i.slice(l-e)}}else{i=n+i}return i}},ne);var ae=n.split;if("ab".split(/(?:ab)*/).length!==2||".".split(/(.?)(.?)/).length!==4||"tesst".split(/(s)*/)[1]==="t"||"test".split(/(?:)/,-1).length!==4||"".split(/.?/).length||".".split(/()()/).length>1){(function(){var t=typeof/()??/.exec("")[1]==="undefined";n.split=function(e,r){var n=this;if(typeof e==="undefined"&&r===0){return[]}if(!m(e)){return ae.call(this,e,r)}var i=[],a=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":""),o=0,l,f,s,c;e=new RegExp(e.source,a+"g");n+="";if(!t){l=new RegExp("^"+e.source+"$(?!\\s)",a)}r=typeof r==="undefined"?-1>>>0:D.ToUint32(r);f=e.exec(n);while(f){s=f.index+f[0].length;if(s>o){i.push(n.slice(o,f.index));if(!t&&f.length>1){f[0].replace(l,function(){for(var t=1;t<arguments.length-2;t++){if(typeof arguments[t]==="undefined"){f[t]=void 0}}})}if(f.length>1&&f.index<n.length){u.apply(i,f.slice(1))}c=f[0].length;o=s;if(i.length>=r){break}}if(e.lastIndex===f.index){e.lastIndex++}f=e.exec(n)}if(o===n.length){if(c||!e.test("")){i.push("")}}else{i.push(n.slice(o))}return i.length>r?i.slice(0,r):i}})()}else if("0".split(void 0,0).length){n.split=function We(t,e){if(typeof t==="undefined"&&e===0){return[]}return ae.call(this,t,e)}}var oe=n.replace;var ue=function(){var t=[];"x".replace(/x(.)?/g,function(e,r){t.push(r)});return t.length===1&&typeof t[0]==="undefined"}();if(!ue){n.replace=function _e(t,e){var r=h(e);var n=m(t)&&/\)[*?]/.test(t.source);if(!r||!n){return oe.call(this,t,e)}else{var i=function(r){var n=arguments.length;var i=t.lastIndex;t.lastIndex=0;var a=t.exec(r)||[];t.lastIndex=i;a.push(arguments[n-2],arguments[n-1]);return e.apply(this,a)};return oe.call(this,t,i)}}}var le=n.substr;var fe="".substr&&"0b".substr(-1)!=="b";N(n,{substr:function tr(t,e){return le.call(this,t<0?(t=this.length+t)<0?0:t:t,e)}},fe);var se=" \n\f\r \xa0\u1680\u180e\u2000\u2001\u2002\u2003"+"\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028"+"\u2029\ufeff";var ce="\u200b";var pe="["+se+"]";var he=new RegExp("^"+pe+pe+"*");var ve=new RegExp(pe+pe+"*$");var ge=n.trim&&(se.trim()||!ce.trim());N(n,{trim:function er(){if(typeof this==="undefined"||this===null){throw new TypeError("can't convert "+this+" to object")}return String(this).replace(he,"").replace(ve,"")}},ge);if(parseInt(se+"08")!==8||parseInt(se+"0x16")!==22){parseInt=function(t){var e=/^0[xX]/;return function r(n,i){n=String(n).trim();if(!Number(i)){i=e.test(n)?16:10}return t(n,i)}}(parseInt)}});
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reactive-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.29
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opal
|
@@ -143,6 +143,7 @@ executables: []
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
+
- ".codeclimate.yml"
|
146
147
|
- ".gitignore"
|
147
148
|
- ".travis.yml"
|
148
149
|
- Gemfile
|
@@ -248,51 +249,67 @@ files:
|
|
248
249
|
- example/todos/vendor/base.css
|
249
250
|
- example/todos/vendor/bg.png
|
250
251
|
- example/todos/vendor/jquery.js
|
252
|
+
- lib/generators/reactive_ruby/test_app/templates/application.rb
|
253
|
+
- lib/generators/reactive_ruby/test_app/templates/assets/javascripts/application.rb
|
254
|
+
- lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb
|
255
|
+
- lib/generators/reactive_ruby/test_app/templates/boot.rb
|
256
|
+
- lib/generators/reactive_ruby/test_app/templates/script/rails
|
257
|
+
- lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb
|
258
|
+
- lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb
|
259
|
+
- lib/generators/reactive_ruby/test_app/test_app_generator.rb
|
251
260
|
- lib/rails-helpers/top_level_rails_component.rb
|
261
|
+
- lib/react/api.rb
|
262
|
+
- lib/react/callbacks.rb
|
263
|
+
- lib/react/component.rb
|
264
|
+
- lib/react/component/api.rb
|
265
|
+
- lib/react/component/class_methods.rb
|
266
|
+
- lib/react/element.rb
|
267
|
+
- lib/react/event.rb
|
268
|
+
- lib/react/ext/hash.rb
|
269
|
+
- lib/react/ext/string.rb
|
270
|
+
- lib/react/native_library.rb
|
271
|
+
- lib/react/observable.rb
|
272
|
+
- lib/react/rendering_context.rb
|
273
|
+
- lib/react/state.rb
|
274
|
+
- lib/react/top_level.rb
|
275
|
+
- lib/react/validator.rb
|
252
276
|
- lib/reactive-ruby.rb
|
253
|
-
- lib/reactive-ruby/api.rb
|
254
|
-
- lib/reactive-ruby/callbacks.rb
|
255
|
-
- lib/reactive-ruby/component.rb
|
256
277
|
- lib/reactive-ruby/component_loader.rb
|
257
|
-
- lib/reactive-ruby/element.rb
|
258
|
-
- lib/reactive-ruby/event.rb
|
259
|
-
- lib/reactive-ruby/ext/hash.rb
|
260
|
-
- lib/reactive-ruby/ext/string.rb
|
261
278
|
- lib/reactive-ruby/isomorphic_helpers.rb
|
262
|
-
- lib/reactive-ruby/observable.rb
|
263
279
|
- lib/reactive-ruby/rails.rb
|
264
280
|
- lib/reactive-ruby/rails/component_mount.rb
|
265
281
|
- lib/reactive-ruby/rails/controller_helper.rb
|
266
282
|
- lib/reactive-ruby/rails/railtie.rb
|
267
|
-
- lib/reactive-ruby/rendering_context.rb
|
268
283
|
- lib/reactive-ruby/serializers.rb
|
269
284
|
- lib/reactive-ruby/server_rendering/contextual_renderer.rb
|
270
|
-
- lib/reactive-ruby/state.rb
|
271
|
-
- lib/reactive-ruby/top_level.rb
|
272
|
-
- lib/reactive-ruby/validator.rb
|
273
285
|
- lib/reactive-ruby/version.rb
|
274
286
|
- lib/sources/react.js
|
275
287
|
- lib/sources/react.js-v12
|
276
288
|
- logo1.png
|
277
289
|
- logo2.png
|
278
290
|
- logo3.png
|
279
|
-
- old-readme
|
280
|
-
- opal-spec/callbacks_spec.rb
|
281
|
-
- opal-spec/component_spec.rb
|
282
|
-
- opal-spec/element_spec.rb
|
283
|
-
- opal-spec/event_spec.rb
|
284
|
-
- opal-spec/react_spec.rb
|
285
|
-
- opal-spec/reactjs/index.html.erb
|
286
|
-
- opal-spec/spec_helper.rb
|
287
|
-
- opal-spec/tutorial/tutorial_spec.rb
|
288
|
-
- opal-spec/validator_spec.rb
|
289
291
|
- reactive-ruby.gemspec
|
290
292
|
- spec/controller_helper_spec.rb
|
293
|
+
- spec/index.html.erb
|
294
|
+
- spec/react/callbacks_spec.rb
|
295
|
+
- spec/react/component_spec.rb
|
296
|
+
- spec/react/dsl_spec.rb
|
297
|
+
- spec/react/element_spec.rb
|
298
|
+
- spec/react/event_spec.rb
|
299
|
+
- spec/react/native_library_spec.rb
|
300
|
+
- spec/react/param_declaration_spec.rb
|
301
|
+
- spec/react/react_spec.rb
|
302
|
+
- spec/react/react_state_spec.rb
|
303
|
+
- spec/react/top_level_component_spec.rb
|
304
|
+
- spec/react/tutorial/tutorial_spec.rb
|
305
|
+
- spec/react/validator_spec.rb
|
291
306
|
- spec/reactive-ruby/component_loader_spec.rb
|
292
307
|
- spec/reactive-ruby/isomorphic_helpers_spec.rb
|
293
308
|
- spec/reactive-ruby/rails/component_mount_spec.rb
|
294
309
|
- spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb
|
295
310
|
- spec/spec_helper.rb
|
311
|
+
- spec/support/react/spec_helpers.rb
|
312
|
+
- spec/vendor/es5-shim.min.js
|
296
313
|
homepage: https://github.com/zetachang/react.rb
|
297
314
|
licenses:
|
298
315
|
- MIT
|
@@ -319,8 +336,23 @@ specification_version: 4
|
|
319
336
|
summary: Opal Ruby wrapper of React.js library.
|
320
337
|
test_files:
|
321
338
|
- spec/controller_helper_spec.rb
|
339
|
+
- spec/index.html.erb
|
340
|
+
- spec/react/callbacks_spec.rb
|
341
|
+
- spec/react/component_spec.rb
|
342
|
+
- spec/react/dsl_spec.rb
|
343
|
+
- spec/react/element_spec.rb
|
344
|
+
- spec/react/event_spec.rb
|
345
|
+
- spec/react/native_library_spec.rb
|
346
|
+
- spec/react/param_declaration_spec.rb
|
347
|
+
- spec/react/react_spec.rb
|
348
|
+
- spec/react/react_state_spec.rb
|
349
|
+
- spec/react/top_level_component_spec.rb
|
350
|
+
- spec/react/tutorial/tutorial_spec.rb
|
351
|
+
- spec/react/validator_spec.rb
|
322
352
|
- spec/reactive-ruby/component_loader_spec.rb
|
323
353
|
- spec/reactive-ruby/isomorphic_helpers_spec.rb
|
324
354
|
- spec/reactive-ruby/rails/component_mount_spec.rb
|
325
355
|
- spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb
|
326
356
|
- spec/spec_helper.rb
|
357
|
+
- spec/support/react/spec_helpers.rb
|
358
|
+
- spec/vendor/es5-shim.min.js
|
@@ -1,502 +0,0 @@
|
|
1
|
-
require "reactive-ruby/ext/string"
|
2
|
-
require 'active_support/core_ext/class/attribute'
|
3
|
-
require 'reactive-ruby/callbacks'
|
4
|
-
require "reactive-ruby/ext/hash"
|
5
|
-
require "reactive-ruby/rendering_context"
|
6
|
-
require "reactive-ruby/observable"
|
7
|
-
require "reactive-ruby/state"
|
8
|
-
|
9
|
-
require 'native'
|
10
|
-
|
11
|
-
module React
|
12
|
-
module Component
|
13
|
-
|
14
|
-
def self.included(base)
|
15
|
-
base.include(API)
|
16
|
-
base.include(React::Callbacks)
|
17
|
-
base.class_eval do
|
18
|
-
class_attribute :initial_state
|
19
|
-
define_callback :before_mount
|
20
|
-
define_callback :after_mount
|
21
|
-
define_callback :before_receive_props
|
22
|
-
define_callback :before_update
|
23
|
-
define_callback :after_update
|
24
|
-
define_callback :before_unmount
|
25
|
-
|
26
|
-
def render
|
27
|
-
raise "no render defined"
|
28
|
-
end unless method_defined? :render
|
29
|
-
|
30
|
-
def children
|
31
|
-
nodes = [`#{@native}.props.children`].flatten
|
32
|
-
class << nodes
|
33
|
-
include Enumerable
|
34
|
-
|
35
|
-
def to_n
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
def each(&block)
|
40
|
-
if block_given?
|
41
|
-
%x{
|
42
|
-
React.Children.forEach(#{self.to_n}, function(context){
|
43
|
-
#{block.call(React::Element.new(`context`))}
|
44
|
-
})
|
45
|
-
}
|
46
|
-
nil
|
47
|
-
else
|
48
|
-
Enumerator.new(`React.Children.count(#{self.to_n})`) do |y|
|
49
|
-
%x{
|
50
|
-
React.Children.forEach(#{self.to_n}, function(context){
|
51
|
-
#{y << React::Element.new(`context`)}
|
52
|
-
})
|
53
|
-
}
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
nodes
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
base.extend(ClassMethods)
|
64
|
-
|
65
|
-
if base.name
|
66
|
-
parent = base.name.split("::").inject([Module]) { |nesting, next_const| nesting + [nesting.last.const_get(next_const)] }[-2]
|
67
|
-
|
68
|
-
class << parent
|
69
|
-
|
70
|
-
def method_missing(n, *args, &block)
|
71
|
-
name = n
|
72
|
-
if name =~ /_as_node$/
|
73
|
-
node_only = true
|
74
|
-
name = name.gsub(/_as_node$/, "")
|
75
|
-
end
|
76
|
-
begin
|
77
|
-
name = const_get(name)
|
78
|
-
rescue Exception
|
79
|
-
name = nil
|
80
|
-
end
|
81
|
-
unless name and name.method_defined? :render
|
82
|
-
return super
|
83
|
-
end
|
84
|
-
if node_only
|
85
|
-
React::RenderingContext.build { React::RenderingContext.render(name, *args, &block) }.to_n
|
86
|
-
else
|
87
|
-
React::RenderingContext.render(name, *args, &block)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def initialize(native_element)
|
96
|
-
@native = native_element
|
97
|
-
end
|
98
|
-
|
99
|
-
def params
|
100
|
-
Hash.new(`#{@native}.props`)
|
101
|
-
end
|
102
|
-
|
103
|
-
def refs
|
104
|
-
Hash.new(`#{@native}.refs`)
|
105
|
-
end
|
106
|
-
|
107
|
-
def state
|
108
|
-
raise "No native ReactComponent associated" unless @native
|
109
|
-
Hash.new(`#{@native}.state`)
|
110
|
-
end
|
111
|
-
|
112
|
-
def update_react_js_state(object, name, value)
|
113
|
-
set_state({"***_state_updated_at-***" => Time.now.to_f, "#{object.class.to_s+'.' unless object == self}#{name}" => value}) rescue nil
|
114
|
-
end
|
115
|
-
|
116
|
-
def emit(event_name, *args)
|
117
|
-
self.params["_on#{event_name.to_s.event_camelize}"].call(*args)
|
118
|
-
end
|
119
|
-
|
120
|
-
def component_will_mount
|
121
|
-
IsomorphicHelpers.load_context(true) if IsomorphicHelpers.on_opal_client?
|
122
|
-
@processed_params = {}
|
123
|
-
React::State.initialize_states(self, initial_state)
|
124
|
-
React::State.set_state_context_to(self) { self.run_callback(:before_mount) }
|
125
|
-
rescue Exception => e
|
126
|
-
self.class.process_exception(e, self)
|
127
|
-
end
|
128
|
-
|
129
|
-
def component_did_mount
|
130
|
-
React::State.set_state_context_to(self) do
|
131
|
-
self.run_callback(:after_mount)
|
132
|
-
React::State.update_states_to_observe
|
133
|
-
end
|
134
|
-
rescue Exception => e
|
135
|
-
self.class.process_exception(e, self)
|
136
|
-
end
|
137
|
-
|
138
|
-
def component_will_receive_props(next_props)
|
139
|
-
# need to rethink how this works in opal-react, or if its actually that useful within the react.rb environment
|
140
|
-
# for now we are just using it to clear processed_params
|
141
|
-
React::State.set_state_context_to(self) { self.run_callback(:before_receive_props, Hash.new(next_props)) }
|
142
|
-
@processed_params = {}
|
143
|
-
rescue Exception => e
|
144
|
-
self.class.process_exception(e, self)
|
145
|
-
end
|
146
|
-
|
147
|
-
def props_changed?(next_props)
|
148
|
-
return true unless params.keys.sort == next_props.keys.sort
|
149
|
-
params.detect { |k, v| `#{next_props[k]} != #{params[k]}`}
|
150
|
-
end
|
151
|
-
|
152
|
-
def should_component_update?(next_props, next_state)
|
153
|
-
React::State.set_state_context_to(self) do
|
154
|
-
next_props = Hash.new(next_props)
|
155
|
-
if self.respond_to?(:needs_update?)
|
156
|
-
!!self.needs_update?(next_props, Hash.new(next_state))
|
157
|
-
elsif false # switch to true to force updates per standard react
|
158
|
-
true
|
159
|
-
elsif props_changed? next_props
|
160
|
-
true
|
161
|
-
elsif `!next_state != !#{@native}.state`
|
162
|
-
true
|
163
|
-
elsif `!next_state && !#{@native}.state`
|
164
|
-
false
|
165
|
-
elsif `next_state["***_state_updated_at-***"] != #{@native}.state["***_state_updated_at-***"]`
|
166
|
-
true
|
167
|
-
else
|
168
|
-
false
|
169
|
-
end.to_n
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def component_will_update(next_props, next_state)
|
174
|
-
React::State.set_state_context_to(self) { self.run_callback(:before_update, Hash.new(next_props), Hash.new(next_state)) }
|
175
|
-
rescue Exception => e
|
176
|
-
self.class.process_exception(e, self)
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
def component_did_update(prev_props, prev_state)
|
181
|
-
React::State.set_state_context_to(self) do
|
182
|
-
self.run_callback(:after_update, Hash.new(prev_props), Hash.new(prev_state))
|
183
|
-
React::State.update_states_to_observe
|
184
|
-
end
|
185
|
-
rescue Exception => e
|
186
|
-
self.class.process_exception(e, self)
|
187
|
-
end
|
188
|
-
|
189
|
-
def component_will_unmount
|
190
|
-
React::State.set_state_context_to(self) do
|
191
|
-
self.run_callback(:before_unmount)
|
192
|
-
React::State.remove
|
193
|
-
end
|
194
|
-
rescue Exception => e
|
195
|
-
self.class.process_exception(e, self)
|
196
|
-
end
|
197
|
-
|
198
|
-
def p(*args, &block)
|
199
|
-
if block || args.count == 0 || (args.count == 1 && args.first.is_a?(Hash))
|
200
|
-
_p_tag(*args, &block)
|
201
|
-
else
|
202
|
-
Kernel.p(*args)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
def component?(name)
|
207
|
-
name_list = name.split("::")
|
208
|
-
scope_list = self.class.name.split("::").inject([Module]) { |nesting, next_const| nesting + [nesting.last.const_get(next_const)] }.reverse
|
209
|
-
scope_list.each do |scope|
|
210
|
-
component = name_list.inject(scope) do |scope, class_name|
|
211
|
-
scope.const_get(class_name)
|
212
|
-
end rescue nil
|
213
|
-
return component if component and component.method_defined? :render
|
214
|
-
end
|
215
|
-
nil
|
216
|
-
end
|
217
|
-
|
218
|
-
def method_missing(n, *args, &block)
|
219
|
-
return params[n] if params.key? n
|
220
|
-
name = n
|
221
|
-
if name =~ /_as_node$/
|
222
|
-
node_only = true
|
223
|
-
name = name.gsub(/_as_node$/, "")
|
224
|
-
end
|
225
|
-
unless (React::HTML_TAGS.include?(name) || name == 'present' || name == '_p_tag' || (name = component?(name, self)))
|
226
|
-
return super
|
227
|
-
end
|
228
|
-
|
229
|
-
if name == "present"
|
230
|
-
name = args.shift
|
231
|
-
end
|
232
|
-
|
233
|
-
if name == "_p_tag"
|
234
|
-
name = "p"
|
235
|
-
end
|
236
|
-
|
237
|
-
if node_only
|
238
|
-
React::RenderingContext.build { React::RenderingContext.render(name, *args, &block) }.to_n
|
239
|
-
else
|
240
|
-
React::RenderingContext.render(name, *args, &block)
|
241
|
-
end
|
242
|
-
|
243
|
-
end
|
244
|
-
|
245
|
-
def watch(value, &on_change)
|
246
|
-
React::Observable.new(value, on_change)
|
247
|
-
end
|
248
|
-
|
249
|
-
def define_state(*args, &block)
|
250
|
-
React::State.initialize_states(self, self.class.define_state(*args, &block))
|
251
|
-
end
|
252
|
-
|
253
|
-
attr_reader :waiting_on_resources
|
254
|
-
|
255
|
-
def _render_wrapper
|
256
|
-
React::State.set_state_context_to(self) do
|
257
|
-
RenderingContext.render(nil) {render || ""}.tap { |element| @waiting_on_resources = element.waiting_on_resources if element.respond_to? :waiting_on_resources }
|
258
|
-
end
|
259
|
-
rescue Exception => e
|
260
|
-
self.class.process_exception(e, self)
|
261
|
-
end
|
262
|
-
|
263
|
-
module ClassMethods
|
264
|
-
|
265
|
-
def backtrace(*args)
|
266
|
-
@backtrace_off = (args[0] == :off)
|
267
|
-
end
|
268
|
-
|
269
|
-
def process_exception(e, component, reraise = nil)
|
270
|
-
message = ["Exception raised while rendering #{component}"]
|
271
|
-
if !@backtrace_off
|
272
|
-
message << " #{e.backtrace[0]}"
|
273
|
-
message += e.backtrace[1..-1].collect { |line| line }
|
274
|
-
else
|
275
|
-
message[0] += ": #{e.message}"
|
276
|
-
end
|
277
|
-
message = message.join("\n")
|
278
|
-
`console.error(message)`
|
279
|
-
raise e if reraise
|
280
|
-
end
|
281
|
-
|
282
|
-
def validator
|
283
|
-
@validator ||= React::Validator.new
|
284
|
-
end
|
285
|
-
|
286
|
-
def prop_types
|
287
|
-
if self.validator
|
288
|
-
{
|
289
|
-
_componentValidator: %x{
|
290
|
-
function(props, propName, componentName) {
|
291
|
-
var errors = #{validator.validate(Hash.new(`props`))};
|
292
|
-
var error = new Error(#{"In component `" + self.name + "`\n" + `errors`.join("\n")});
|
293
|
-
return #{`errors`.count > 0 ? `error` : `undefined`};
|
294
|
-
}
|
295
|
-
}
|
296
|
-
}
|
297
|
-
else
|
298
|
-
{}
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
def default_props
|
303
|
-
validator.default_props
|
304
|
-
end
|
305
|
-
|
306
|
-
def params(&block)
|
307
|
-
validator.build(&block)
|
308
|
-
end
|
309
|
-
|
310
|
-
def define_param_method(name, param_type)
|
311
|
-
if param_type == React::Observable
|
312
|
-
(@two_way_params ||= []) << name
|
313
|
-
define_method("#{name}") do
|
314
|
-
params[name].instance_variable_get("@value") if params[name]
|
315
|
-
end
|
316
|
-
define_method("#{name}!") do |*args|
|
317
|
-
return unless params[name]
|
318
|
-
if args.count > 0
|
319
|
-
current_value = params[name].instance_variable_get("@value")
|
320
|
-
params[name].call args[0]
|
321
|
-
current_value
|
322
|
-
else
|
323
|
-
current_value = params[name].instance_variable_get("@value")
|
324
|
-
params[name].call current_value unless @dont_update_state rescue nil # rescue in case we in middle of render
|
325
|
-
params[name]
|
326
|
-
end
|
327
|
-
end
|
328
|
-
elsif param_type == Proc
|
329
|
-
define_method("#{name}") do |*args, &block|
|
330
|
-
params[name].call(*args, &block) if params[name]
|
331
|
-
end
|
332
|
-
else
|
333
|
-
define_method("#{name}") do
|
334
|
-
@processed_params[name] ||= if param_type.respond_to? :_react_param_conversion
|
335
|
-
param_type._react_param_conversion params[name]
|
336
|
-
elsif param_type.is_a? Array and param_type[0].respond_to? :_react_param_conversion
|
337
|
-
params[name].collect { |param| param_type[0]._react_param_conversion param }
|
338
|
-
else
|
339
|
-
params[name]
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
def required_param(name, options = {})
|
346
|
-
validator.requires(name, options)
|
347
|
-
define_param_method(name, options[:type])
|
348
|
-
end
|
349
|
-
|
350
|
-
alias_method :require_param, :required_param
|
351
|
-
|
352
|
-
def optional_param(name, options = {})
|
353
|
-
validator.optional(name, options)
|
354
|
-
define_param_method(name, options[:type]) unless name == :params
|
355
|
-
end
|
356
|
-
|
357
|
-
def collect_other_params_as(name)
|
358
|
-
validator.all_others(name)
|
359
|
-
define_method(name) do
|
360
|
-
@_all_others ||= self.class.validator.collect_all_others(params)
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
def define_state(*states, &block)
|
365
|
-
default_initial_value = (block and block.arity == 0) ? yield : nil
|
366
|
-
states_hash = (states.last.is_a? Hash) ? states.pop : {}
|
367
|
-
states.each { |name| states_hash[name] = default_initial_value }
|
368
|
-
(self.initial_state ||= {}).merge! states_hash
|
369
|
-
states_hash.each do |name, initial_value|
|
370
|
-
define_state_methods(self, name, &block)
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
def export_state(*states, &block)
|
375
|
-
default_initial_value = (block and block.arity == 0) ? yield : nil
|
376
|
-
states_hash = (states.last.is_a? Hash) ? states.pop : {}
|
377
|
-
states.each { |name| states_hash[name] = default_initial_value }
|
378
|
-
React::State.initialize_states(self, states_hash)
|
379
|
-
states_hash.each do |name, initial_value|
|
380
|
-
define_state_methods(self, name, self, &block)
|
381
|
-
define_state_methods(singleton_class, name, self, &block)
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
def define_state_methods(this, name, from = nil, &block)
|
386
|
-
this.define_method("#{name}") do
|
387
|
-
React::State.get_state(from || self, name)
|
388
|
-
end
|
389
|
-
this.define_method("#{name}=") do |new_state|
|
390
|
-
yield name, React::State.get_state(from || self, name), new_state if block and block.arity > 0
|
391
|
-
React::State.set_state(from || self, name, new_state)
|
392
|
-
end
|
393
|
-
this.define_method("#{name}!") do |*args|
|
394
|
-
#return unless @native
|
395
|
-
if args.count > 0
|
396
|
-
yield name, React::State.get_state(from || self, name), args[0] if block and block.arity > 0
|
397
|
-
current_value = React::State.get_state(from || self, name)
|
398
|
-
React::State.set_state(from || self, name, args[0])
|
399
|
-
current_value
|
400
|
-
else
|
401
|
-
current_state = React::State.get_state(from || self, name)
|
402
|
-
yield name, React::State.get_state(from || self, name), current_state if block and block.arity > 0
|
403
|
-
React::State.set_state(from || self, name, current_state)
|
404
|
-
React::Observable.new(current_state) do |update|
|
405
|
-
yield name, React::State.get_state(from || self, name), update if block and block.arity > 0
|
406
|
-
React::State.set_state(from || self, name, update)
|
407
|
-
end
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
def native_mixin(item)
|
413
|
-
native_mixins << item
|
414
|
-
end
|
415
|
-
|
416
|
-
def native_mixins
|
417
|
-
@native_mixins ||= []
|
418
|
-
end
|
419
|
-
|
420
|
-
def static_call_back(name, &block)
|
421
|
-
static_call_backs[name] = block
|
422
|
-
end
|
423
|
-
|
424
|
-
def static_call_backs
|
425
|
-
@static_call_backs ||= {}
|
426
|
-
end
|
427
|
-
|
428
|
-
def export_component(opts = {})
|
429
|
-
export_name = (opts[:as] || name).split("::")
|
430
|
-
first_name = export_name.first
|
431
|
-
Native(`window`)[first_name] = add_item_to_tree(Native(`window`)[first_name], [React::API.create_native_react_class(self)] + export_name[1..-1].reverse).to_n
|
432
|
-
end
|
433
|
-
|
434
|
-
def add_item_to_tree(current_tree, new_item)
|
435
|
-
if Native(current_tree).class != Native::Object or new_item.length == 1
|
436
|
-
new_item.inject do |memo, sub_name| {sub_name => memo} end
|
437
|
-
else
|
438
|
-
Native(current_tree)[new_item.last] = add_item_to_tree(Native(current_tree)[new_item.last], new_item[0..-2])
|
439
|
-
current_tree
|
440
|
-
end
|
441
|
-
end
|
442
|
-
|
443
|
-
end
|
444
|
-
|
445
|
-
module API
|
446
|
-
#include Native
|
447
|
-
|
448
|
-
def dom_node
|
449
|
-
if `typeof React.findDOMNode === 'undefined'`
|
450
|
-
`#{self}.native.getDOMNode` # v0.12.0
|
451
|
-
else
|
452
|
-
`React.findDOMNode(#{self}.native)` # v0.13.0
|
453
|
-
end
|
454
|
-
end
|
455
|
-
|
456
|
-
def mounted?
|
457
|
-
`#{self}.native.isMounted()`
|
458
|
-
end
|
459
|
-
|
460
|
-
def force_update!
|
461
|
-
`#{self}.native.forceUpdate()`
|
462
|
-
end
|
463
|
-
|
464
|
-
def set_props(prop, &block)
|
465
|
-
raise "No native ReactComponent associated" unless @native
|
466
|
-
%x{
|
467
|
-
#{@native}.setProps(#{prop.shallow_to_n}, function(){
|
468
|
-
#{block.call if block}
|
469
|
-
});
|
470
|
-
}
|
471
|
-
end
|
472
|
-
|
473
|
-
def set_props!(prop, &block)
|
474
|
-
raise "No native ReactComponent associated" unless @native
|
475
|
-
%x{
|
476
|
-
#{@native}.replaceProps(#{prop.shallow_to_n}, function(){
|
477
|
-
#{block.call if block}
|
478
|
-
});
|
479
|
-
}
|
480
|
-
end
|
481
|
-
|
482
|
-
def set_state(state, &block)
|
483
|
-
raise "No native ReactComponent associated" unless @native
|
484
|
-
%x{
|
485
|
-
#{@native}.setState(#{state.shallow_to_n}, function(){
|
486
|
-
#{block.call if block}
|
487
|
-
});
|
488
|
-
}
|
489
|
-
end
|
490
|
-
|
491
|
-
def set_state!(state, &block)
|
492
|
-
raise "No native ReactComponent associated" unless @native
|
493
|
-
%x{
|
494
|
-
#{@native}.replaceState(#{state.shallow_to_n}, function(){
|
495
|
-
#{block.call if block}
|
496
|
-
});
|
497
|
-
}
|
498
|
-
end
|
499
|
-
end
|
500
|
-
|
501
|
-
end
|
502
|
-
end
|