Comparing version 1.2.0 to 1.3.0
{ | ||
"name": "preact", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Tiny & fast Component-based virtual DOM framework.", | ||
@@ -11,3 +11,5 @@ "main": "preact.js", | ||
"size": "size=$(gzip-size $npm_package_main) && echo \"gzip size: $size / $(pretty-bytes $size)\"", | ||
"test": "jshint {src,tests}/**.js && mocha --compilers js:babel/register test", | ||
"test": "eslint src test && npm run test:mocha && npm run test:karma", | ||
"test:mocha": "mocha --recursive --compilers js:babel/register test/shared test/node", | ||
"test:karma": "karma start --single-run", | ||
"prepublish": "npm run build", | ||
@@ -28,8 +30,23 @@ "release": "npm run build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish" | ||
"babel": "^5.8.23", | ||
"babel-core": "^5.8.24", | ||
"babel-eslint": "^4.1.1", | ||
"babel-loader": "^5.3.2", | ||
"babel-runtime": "^5.8.24", | ||
"chai": "^3.2.0", | ||
"eslint": "^1.3.1", | ||
"gzip-size": "^3.0.0", | ||
"jshint": "^2.8.0", | ||
"karma": "^0.13.9", | ||
"karma-babel-preprocessor": "^5.2.2", | ||
"karma-chai": "^0.1.0", | ||
"karma-mocha": "^0.2.0", | ||
"karma-mocha-reporter": "^1.1.1", | ||
"karma-phantomjs-launcher": "^0.2.1", | ||
"karma-sourcemap-loader": "^0.3.5", | ||
"karma-webpack": "^1.7.0", | ||
"mocha": "^2.3.2", | ||
"phantomjs": "^1.9.18", | ||
"pretty-bytes": "^2.0.1", | ||
"sinon": "^1.16.1", | ||
"uglify-js": "^2.4.24", | ||
"webpack": "^1.12.1", | ||
"xo": "^0.8.0" | ||
@@ -36,0 +53,0 @@ }, |
@@ -1,2 +0,2 @@ | ||
!function(e,t){if("function"==typeof define&&define.amd)define(["exports"],t);else if("undefined"!=typeof exports)t(exports);else{var n={exports:{}};t(n.exports),e.preact=n.exports}}(this,function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){var n=f(null,e),r=n._component;return r&&s(r,"componentWillMount"),t.appendChild(n),r&&s(r,"componentDidMount"),f}function r(e){var t="",n=": ",r="; ";for(var o in e)if(e.hasOwnProperty(o)){var i=e[o];t+=D(o),t+=n,t+=i,"number"!=typeof i||T.hasOwnProperty(o)||(t+="px"),t+=r}return t}function o(e){var t="";for(var n in e)e[n]&&(t&&(t+=" "),t+=n);return t}function i(e,t){for(var n=null,r=[],o=void 0,i=void 0,l=arguments.length,u=Array(l>2?l-2:0),p=2;l>p;p++)u[p-2]=arguments[p];if(u.length){n=[];for(var d=0;d<u.length;d++){Array.isArray(u[d])?o=u[d]:(o=r,o[0]=u[d]);for(var f=0;f<o.length;f++){var h=o[f],v=c(h)&&!a(h);v&&(h=String(h)),v&&i?n[n.length-1]+=h:null!==h&&void 0!==h&&n.push(h),i=v}}}var m=new L(e,t,n);return s(k,"vnode",m),m}function s(e,t){for(var n=e[t],r=arguments.length,o=Array(r>2?r-2:0),i=2;r>i;i++)o[i-2]=arguments[i];return n&&"function"==typeof n?n.apply(e,o):void 0}function a(e){return e&&e.__isVNode===!0}function c(e){return null!==e&&void 0!==e}function l(e,t){if(3===e.nodeType)return"string"==typeof t;var n=t.nodeName;return"function"==typeof n?e._componentConstructor===n:e.nodeName.toLowerCase()===n}function u(e,t){var n=e&&e._component;if(n&&e._componentConstructor===t.nodeName){var r=C(t);return n.setProps(r,O),e}return n&&d(e,n),p(t)}function p(e){var t=E.create(e.nodeName),n=C(e);t.setProps(n,P),t._render(A);var r=t.base;return r._component=t,r._componentConstructor=e.nodeName,r}function d(e,t){delete e._component,s(t,"componentWillUnmount");var n=t.base;n&&n.parentNode&&n.parentNode.removeChild(n),s(t,"componentDidUnmount"),E.collect(t)}function f(e,t){var n=e,r=t.nodeName;if("function"==typeof r)return u(e,t);if("string"==typeof t){if(e){if(3===e.nodeType)return e.textContent=t,e;1===e.nodeType&&z.collect(e)}return document.createTextNode(t)}e?e.nodeName.toLowerCase()!==r&&(n=z.create(r),h(n,U.call(e.childNodes)),1===e.nodeType&&z.collect(e)):n=z.create(r);var o=_(n)||w,i=t.attributes||w;if(o!==w)for(var a in o)if(o.hasOwnProperty(a)){var c=i[a];(void 0===c||null===c||c===!1)&&m(n,a,null,o[a])}if(i!==w)for(var p in i)if(i.hasOwnProperty(p)){var d=i[p];if(void 0!==d&&null!==d&&d!==!1){var g=v(n,p,o[p]);d!==g&&m(n,p,d,g)}}for(var y=U.call(n.childNodes),b={},N=y.length;N--;){var C=y[N].nodeType,x=void 0;if(3===C)x=C.key;else{if(1!==C)continue;x=y[N].getAttribute("key")}x&&(b[x]=y.splice(N,1)[0])}var P=[];if(t.children)for(var N=0,O=t.children.length;O>N;N++){var A=t.children[N],T=A.attributes,x=void 0,R=void 0;if(T&&(x=T.key,R=x&&b[x]),!R){var k=y.length;if(y.length)for(var D=0;k>D;D++)if(l(y[D],A)){R=y.splice(D,1)[0];break}}P.push(f(R,A))}for(var N=0,k=P.length;k>N;N++)if(n.childNodes[N]!==P[N]){var R=P[N],W=R._component,L=n.childNodes[N+1];W&&s(W,"componentWillMount"),L?n.insertBefore(R,L):n.appendChild(R),W&&s(W,"componentDidMount")}for(var N=0,k=y.length;k>N;N++){var R=y[N],W=R._component;W&&s(W,"componentWillUnmount"),R.parentNode.removeChild(R),W?(s(W,"componentDidUnmount"),E.collect(W)):1===R.nodeType&&z.collect(R)}return n}function h(e,t){var n=t.length;if(2>=n)return e.appendChild(t[0]),void(2===n&&e.appendChild(t[1]));for(var r=document.createDocumentFragment(),o=0;n>o;o++)r.appendChild(t[o]);e.appendChild(r)}function v(e,t,n){return"class"===t?e.className:"style"===t?e.style.cssText:n}function m(e,t,n,r){"class"===t?e.className=n:"style"===t?e.style.cssText=n:y(e,t,n,r)}function g(e){var t=this._listeners,n=t[e.type.toLowerCase()];return n?n.call(t,s(k,"event",e)||e):void 0}function y(e,t,n,r){if("on"===t.substring(0,2)){var o=t.substring(2).toLowerCase(),i=e._listeners||(e._listeners={});return i[o]||e.addEventListener(o,g),void(i[o]=n)}var s=b(t);e[s]&&"function"==typeof e[s]?e[s](n):null!==n?e.setAttribute(t,n):e.removeAttribute(t)}function b(e){var t=F[e];return t||(t="set"+e.charAt(0).toUpperCase()+e.substring(1),F[e]=t),t}function _(e){var t=e.attributes;return t.getNamedItem?t.length?N(t):void 0:t}function N(e){for(var t={},n=e.length;n--;){var r=e[n];t[r.name]=r.value}return t}function C(e){var t=x({},e.attributes);return e.children&&(t.children=e.children),e.text&&(t._content=e.text),t}function x(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}e.render=n,e.h=i;var w={},P={render:!1},O={renderSync:!0},A={build:!0},T="\n boxFlex boxFlexGroup columnCount fillOpacity flex flexGrow\n flexPositive flexShrink flexNegative fontWeight lineClamp\n lineHeight opacity order orphans strokeOpacity widows zIndex zoom\n".trim().split(/\s+/g).reduce(function(e,t){return e[t]=!0,e},{}),U=Array.prototype.slice,R={syncComponentUpdates:!0},k={};e.options=R,e.hooks=k,k.vnode=function(e){var t=e.attributes;if(t){var n=t.style;n&&!n.substring&&(t.style=r(n));var i=t["class"];t.hasOwnProperty("className")&&(i=t["class"]=t.className,delete t.className),i&&!i.substring&&(t["class"]=o(i))}};var D=function(e){return e.replace(/([A-Z])/,"-$1").toLowerCase()},W=function(){function e(){t(this,e),this._dirty=!1,this.props=s(this,"getDefaultProps")||{},this.state=s(this,"getInitialState")||{},s(this,"initialize")}return e.prototype.shouldComponentUpdate=function(e,t){return!0},e.prototype.setState=function(e){x(this.state,e),this.triggerRender()},e.prototype.setProps=function(e){var t=arguments.length<=1||void 0===arguments[1]?w:arguments[1],n=this._disableRendering===!0;this._disableRendering=!0,s(this,"componentWillReceiveProps",e,this.props),this.nextProps=e,this._disableRendering=n,t.renderSync===!0&&R.syncComponentUpdates===!0?this._render():t.render!==!1&&this.triggerRender()},e.prototype.triggerRender=function(){this._dirty!==!0&&(this._dirty=!0,S.add(this))},e.prototype.render=function(e,t){return i("div",{component:this.constructor.name},e.children)},e.prototype._render=function(){var e=arguments.length<=0||void 0===arguments[0]?w:arguments[0];if(this._disableRendering!==!0){if(this._dirty=!1,this.base&&s(this,"shouldComponentUpdate",this.props,this.state)===!1)return void(this.props=this.nextProps);this.props=this.nextProps,s(this,"componentWillUpdate");var t=s(this,"render",this.props,this.state);if(this.base||e.build===!0){var n=f(this.base,t);this.base&&n!==this.base&&(this.base.parentNode.insertBefore(n,this.base),this.base.parentNode.removeChild(this.base)),this.base=n}s(this,"componentDidUpdate")}},e}();e.Component=W;var L=function I(e,n,r){t(this,I),this.nodeName=e,this.attributes=n,this.children=r};L.prototype.__isVNode=!0;var S={items:[],itemsOffline:[],pending:!1,add:function(e){if(1===S.items.push(e)){var t=k.debounceRendering;t?t(S.process):setTimeout(S.process,0)}},process:function(){var e=S.items,t=e.length;if(t)for(S.items=S.itemsOffline,S.items.length=0,S.itemsOffline=e;t--;)e[t]._dirty&&e[t]._render()}},M=S.process;e.rerender=M;var z={nodes:{},collect:function(e){var t=e.nodeName;z.clean(e);var n=z.nodes[t]||(z.nodes[t]=[]);n.push(e)},create:function(e){var t=z.nodes[name];return t&&t.length?t.splice(0,1)[0]:document.createElement(e)},clean:function(e){if(e.remove(),e.attributes){var t=_(e);for(var n in t)t.hasOwnProperty(n)&&e.removeAttribute(n)}}},E={components:{},collect:function(e){var t=e.constructor.name,n=E.components[t]||(E.components[t]=[]);n.push(e)},create:function(e){var t=e.name,n=E.components[t];return n&&n.length?n.splice(0,1)[0]:new e}},F={}}); | ||
!function(e,t){if("function"==typeof define&&define.amd)define(["exports"],t);else if("undefined"!=typeof exports)t(exports);else{var n={exports:{}};t(n.exports),e.preact=n.exports}}(this,function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){var n=d(null,e),r=n._component;return r&&o(r,"componentWillMount"),t.appendChild(n),r&&o(r,"componentDidMount"),d}function r(e,t){for(var n=arguments.length,r=Array(n>2?n-2:0),a=2;n>a;a++)r[a-2]=arguments[a];var c=void 0,l=[],u=r.length,d=void 0,p=void 0;if(u){c=[];for(var f=0;u>f;f++){var h=r[f];if(null!==h&&void 0!==h){h.join?d=h:(d=l,d[0]=h);for(var v=0;v<d.length;v++){var m=d[v],g=s(m)&&!i(m);g&&(m=String(m)),g&&p?c[c.length-1]+=m:s(m)&&c.push(m),p=g}}}}t&&t.children&&delete t.children;var y=new z(e,t||void 0,c||void 0);return o(D,"vnode",y),y}function o(e,t){for(var n=e[t],r=arguments.length,o=Array(r>2?r-2:0),i=2;r>i;i++)o[i-2]=arguments[i];return n&&"function"==typeof n?n.apply(e,o):void 0}function i(e){return e&&e.__isVNode===!0}function s(e){return null!==e&&void 0!==e}function a(e,t){if(3===e.nodeType)return"string"==typeof t;var n=t.nodeName;return"function"==typeof n?e._componentConstructor===n:e.nodeName.toLowerCase()===n}function c(e,t){var n=e&&e._component;if(n&&e._componentConstructor===t.nodeName){var r=b(t);return n.setProps(r,P),e}return n&&u(e,n),l(t)}function l(e){var t=M.create(e.nodeName),n=b(e);t.setProps(n,w),t._render(O);var r=t.base;return r._component=t,r._componentConstructor=e.nodeName,r}function u(e,t){delete e._component,o(t,"componentWillUnmount");var n=t.base;n&&n.parentNode&&n.parentNode.removeChild(n),o(t,"componentDidUnmount"),M.collect(t)}function d(e,t,n){var r=e,i=t.nodeName;if("function"==typeof i)return c(e,t);if("string"==typeof t){if(e){if(3===e.nodeType)return e.textContent=t,e;1===e.nodeType&&E.collect(e)}return document.createTextNode(t)}(null===i||void 0===i)&&(i="x-undefined-element"),e?e.nodeName.toLowerCase()!==i?(r=E.create(i),p(r,R.call(e.childNodes)),1===e.nodeType&&E.collect(e)):e._component&&e._component!==n&&u(e,e._component):r=E.create(i);var s=g(r)||C,l=t.attributes||C;if(s!==C)for(var v in s)if(s.hasOwnProperty(v)){var m=l[v];(void 0===m||null===m||m===!1)&&h(r,v,null,s[v])}if(l!==C)for(var y in l)if(l.hasOwnProperty(y)){var b=l[y];if(void 0!==b&&null!==b&&b!==!1){var _=f(r,y,s[y]);b!==_&&h(r,y,b,_)}}for(var N=R.call(r.childNodes),x={},w=N.length;w--;){var P=N[w].nodeType,O=void 0;if(3===P)O=P.key;else{if(1!==P)continue;O=N[w].getAttribute("key")}O&&(x[O]=N.splice(w,1)[0])}var T=[];if(t.children)for(var w=0,U=t.children.length;U>w;w++){var k=t.children[w],A=k.attributes,O=void 0,D=void 0;if(A&&(O=A.key,D=O&&x[O]),!D){var W=N.length;if(N.length)for(var z=0;W>z;z++)if(a(N[z],k)){D=N.splice(z,1)[0];break}}T.push(d(D,k))}for(var w=0,W=T.length;W>w;w++)if(r.childNodes[w]!==T[w]){var D=T[w],L=D._component,S=r.childNodes[w+1];L&&o(L,"componentWillMount"),S?r.insertBefore(D,S):r.appendChild(D),L&&o(L,"componentDidMount")}for(var w=0,W=N.length;W>w;w++){var D=N[w],L=D._component;L&&o(L,"componentWillUnmount"),D.parentNode.removeChild(D),L?(o(L,"componentDidUnmount"),M.collect(L)):1===D.nodeType&&E.collect(D)}return r}function p(e,t){var n=t.length;if(2>=n)return e.appendChild(t[0]),void(2===n&&e.appendChild(t[1]));for(var r=document.createDocumentFragment(),o=0;n>o;o++)r.appendChild(t[o]);e.appendChild(r)}function f(e,t,n){return"class"===t?e.className:"style"===t?e.style.cssText:n}function h(e,t,n,r){"class"===t?e.className=n:"style"===t?e.style.cssText=n:v(e,t,n,r)}function v(e,t,n,r){if("on"===t.substring(0,2)){var o=t.substring(2).toLowerCase(),i=e._listeners||(e._listeners={});return i[o]||e.addEventListener(o,m),void(i[o]=n)}var s=typeof n;null===n?e.removeAttribute(t):"function"!==s&&"object"!==s&&e.setAttribute(t,n)}function m(e){var t=this._listeners,n=t[F(e.type)];return n?n.call(this,o(D,"event",e)||e):void 0}function g(e){var t=e.attributes;return t&&t.getNamedItem?t.length?y(t):void 0:t}function y(e){for(var t={},n=e.length;n--;){var r=e[n];t[r.name]=r.value}return t}function b(e){var t=x({},e.attributes);return e.children&&(t.children=e.children),e.text&&(t._content=e.text),t}function _(e){var t="",n=": ",r="; ";for(var o in e)if(e.hasOwnProperty(o)){var i=e[o];t+=I(o),t+=n,t+=i,"number"!=typeof i||U.hasOwnProperty(o)||(t+="px"),t+=r}return t}function N(e){var t="";for(var n in e)e[n]&&(t&&(t+=" "),t+=n);return t}function x(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}e.render=n,e.h=r;var C={},w={render:!1},P={renderSync:!0},O={build:!0},T="",U={};"boxFlex boxFlexGroup columnCount fillOpacity flex flexGrow flexPositive flexShrink flexNegative fontWeight lineClamp lineHeight opacity order orphans strokeOpacity widows zIndex zoom".split(" ").forEach(function(e){return U[e]=!0});var R=Array.prototype.slice,k=function(e){var t=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return function(n){return t.hasOwnProperty(n)?t[n]:t[n]=e(n)}},A={syncComponentUpdates:!0},D={};D.vnode=function(e){var t=e.attributes;if(t){var n=t.style;n&&!n.substring&&(t.style=_(n));var r=t["class"];t.hasOwnProperty("className")&&(r=t["class"]=t.className,delete t.className),r&&!r.substring&&(t["class"]=N(r))}};var W=function(){function e(){t(this,e),this._dirty=this._disableRendering=!1,this.nextProps=this.base=null,this.props=o(this,"getDefaultProps")||{},this.state=o(this,"getInitialState")||{},o(this,"initialize")}return e.prototype.shouldComponentUpdate=function(e,t){return!0},e.prototype.setState=function(e){x(this.state,e),this.triggerRender()},e.prototype.setProps=function(e){var t=arguments.length<=1||void 0===arguments[1]?C:arguments[1],n=this._disableRendering===!0;this._disableRendering=!0,o(this,"componentWillReceiveProps",e,this.props),this.nextProps=e,this._disableRendering=n,t.renderSync===!0&&A.syncComponentUpdates===!0?this._render():t.render!==!1&&this.triggerRender()},e.prototype.triggerRender=function(){this._dirty!==!0&&(this._dirty=!0,L.add(this))},e.prototype.render=function(e,t){return r("div",{component:this.constructor.name},e.children)},e.prototype._render=function(){var e=arguments.length<=0||void 0===arguments[0]?C:arguments[0];if(this._disableRendering!==!0){if(this._dirty=!1,this.base&&o(this,"shouldComponentUpdate",this.props,this.state)===!1)return void(this.props=this.nextProps);this.props=this.nextProps,o(this,"componentWillUpdate");var t=o(this,"render",this.props,this.state);if(this.base||e.build===!0){var n=d(this.base,t||T,this);if(this.base&&n!==this.base){var r=this.base.parentNode;r&&r.replaceChild(n,this.base)}this.base=n}o(this,"componentDidUpdate")}},e}();e.Component=W;var z=function V(e,n,r){t(this,V),this.nodeName=e,this.attributes=n,this.children=r};e.VNode=z,z.prototype.__isVNode=!0;var L={items:[],itemsOffline:[],pending:!1,add:function(e){if(1===L.items.push(e)){var t=D.debounceRendering;t?t(L.process):setTimeout(L.process,0)}},process:function(){var e=L.items,t=e.length;if(t)for(L.items=L.itemsOffline,L.items.length=0,L.itemsOffline=e;t--;)e[t]._dirty&&e[t]._render()}},S=L.process,E={nodes:{},collect:function(e){E.clean(e);var t=E.normalizeName(e.nodeName),n=E.nodes[t];n?n.push(e):E.nodes[t]=[e]},create:function(e){var t=E.normalizeName(e),n=E.nodes[t];return n&&n.pop()||document.createElement(e)},clean:function(e){e.remove();var t=e.attributes&&e.attributes.length;if(t)for(var n=t;n--;)e.removeAttribute(e.attributes[n].name)},normalizeName:k(function(e){return e.toUpperCase()})},M={components:{},collect:function(e){var t=e.constructor.name,n=M.components[t]||(M.components[t]=[]);n.push(e)},create:function(e){var t=e.name,n=M.components[t];return n&&n.length?n.splice(0,1)[0]:new e}},F=k(function(e){return e.toLowerCase()}),I=k(function(e){return e.replace(/([A-Z])/,"-$1").toLowerCase()});e.options=A,e.hooks=D,e.rerender=S,e["default"]={options:A,hooks:D,render:n,rerender:S,h:r,Component:W}}); | ||
//# sourceMappingURL=preact.js.map |
@@ -5,17 +5,24 @@ const EMPTY = {}; | ||
const DOM_RENDER = { build: true }; | ||
const NON_DIMENSION_PROPS = ` | ||
boxFlex boxFlexGroup columnCount fillOpacity flex flexGrow | ||
flexPositive flexShrink flexNegative fontWeight lineClamp | ||
lineHeight opacity order orphans strokeOpacity widows zIndex zoom | ||
`.trim().split(/\s+/g).reduce( (acc, prop) => (acc[prop] = true, acc), {}); | ||
const EMPTY_BASE = ''; | ||
const NON_DIMENSION_PROPS = {}; | ||
let slice = Array.prototype.slice, | ||
options = { | ||
syncComponentUpdates: true | ||
}, | ||
hooks = {}; | ||
'boxFlex boxFlexGroup columnCount fillOpacity flex flexGrow flexPositive flexShrink flexNegative fontWeight lineClamp lineHeight opacity order orphans strokeOpacity widows zIndex zoom'.split(' ').forEach(k => NON_DIMENSION_PROPS[k] = true); | ||
export { options, hooks }; | ||
/** @private */ | ||
let slice = Array.prototype.slice; | ||
/** @private */ | ||
let memoize = (fn, mem={}) => k => mem.hasOwnProperty(k) ? mem[k] : (mem[k] = fn(k)); | ||
/** @public @object Global options */ | ||
let options = { | ||
/** If `true`, `prop` changes trigger synchronous component updates. */ | ||
syncComponentUpdates: true | ||
}; | ||
/** @public @object Global hook methods */ | ||
let hooks = {}; | ||
/** @public Render JSX into a `parent` Element. */ | ||
export function render(component, parent) { | ||
@@ -31,2 +38,3 @@ let built = build(null, component), | ||
/** @protected Processes all created VNodes */ | ||
hooks.vnode = ({ attributes }) => { | ||
@@ -50,41 +58,13 @@ if (!attributes) return; | ||
function styleObjToCss(s) { | ||
let str = '', | ||
sep = ': ', | ||
term = '; '; | ||
for (let prop in s) { | ||
if (s.hasOwnProperty(prop)) { | ||
let val = s[prop]; | ||
str += jsToCss(prop); | ||
str += sep; | ||
str += val; | ||
if (typeof val==='number' && !NON_DIMENSION_PROPS.hasOwnProperty(prop)) { | ||
str += 'px'; | ||
} | ||
str += term; | ||
} | ||
} | ||
return str; | ||
} | ||
function hashToClassName(c) { | ||
let str = ''; | ||
for (let prop in c) { | ||
if (c[prop]) { | ||
if (str) str += ' '; | ||
str += prop; | ||
} | ||
} | ||
return str; | ||
} | ||
let jsToCss = s => s.replace(/([A-Z])/,'-$1').toLowerCase(); | ||
/** Provides a base Component class with an API similar to React. */ | ||
/** @public Base Component, with API similar to React. */ | ||
export class Component { | ||
constructor() { | ||
this._dirty = false; | ||
/** @private */ | ||
this._dirty = this._disableRendering = false; | ||
/** @public */ | ||
this.nextProps = this.base = null; | ||
/** @type {object} */ | ||
this.props = hook(this, 'getDefaultProps') || {}; | ||
/** @type {object} */ | ||
this.state = hook(this, 'getInitialState') || {}; | ||
@@ -94,2 +74,6 @@ hook(this, 'initialize'); | ||
/** Returns a `boolean` value indicating if the component should re-render when receiving the given `props` and `state`. | ||
* @param {object} props | ||
* @param {object} state | ||
*/ | ||
shouldComponentUpdate(props, state) { | ||
@@ -99,2 +83,5 @@ return true; | ||
/** Update component state by copying values from `state` to `this.state`. | ||
* @param {object} state | ||
*/ | ||
setState(state) { | ||
@@ -105,2 +92,8 @@ extend(this.state, state); | ||
/** Set `props` for the component. | ||
* @param {object} props | ||
* @param {object} [opts] | ||
* @param {object} [opts.renderSync] - If `true` and {@link options.syncComponentUpdates} is `true`, triggers synchronous rendering. | ||
* @param {object} [opts.render=true] - If `false`, no render will be triggered. | ||
*/ | ||
setProps(props, opts=EMPTY) { | ||
@@ -110,3 +103,2 @@ let d = this._disableRendering===true; | ||
hook(this, 'componentWillReceiveProps', props, this.props); | ||
//this.props = props; | ||
this.nextProps = props; | ||
@@ -122,2 +114,3 @@ this._disableRendering = d; | ||
/** Mark component as dirty and queue up a render. */ | ||
triggerRender() { | ||
@@ -130,2 +123,6 @@ if (this._dirty!==true) { | ||
/** Accepts `props` and `state`, and returns a new Virtual DOM tree to build. | ||
* Virtual DOM is generally constructed via [JSX](http://jasonformat.com/wtf-is-jsx). | ||
* @returns VNode | ||
*/ | ||
render(props, state) { | ||
@@ -135,2 +132,3 @@ return h('div', { component:this.constructor.name }, props.children); | ||
/** @private */ | ||
_render(opts=EMPTY) { | ||
@@ -153,6 +151,6 @@ if (this._disableRendering===true) return; | ||
if (this.base || opts.build===true) { | ||
let base = build(this.base, rendered); | ||
let base = build(this.base, rendered || EMPTY_BASE, this); | ||
if (this.base && base!==this.base) { | ||
this.base.parentNode.insertBefore(base, this.base); | ||
this.base.parentNode.removeChild(this.base); | ||
let p = this.base.parentNode; | ||
if (p) p.replaceChild(base, this.base); | ||
} | ||
@@ -168,25 +166,29 @@ this.base = base; | ||
/** jsx hyperscript generator | ||
* To use, add the directive: | ||
/** @public JSX/hyperscript reviver | ||
* @see http://jasonformat.com/wtf-is-jsx | ||
* @example | ||
* /** @jsx h *\/ | ||
* import { render, h } from 'react-compat'; | ||
* import { render, h } from 'preact'; | ||
* render(<span>foo</span>, document.body); | ||
*/ | ||
export function h(nodeName, attributes, ...args) { | ||
let children = null, | ||
let children, | ||
sharedArr = [], | ||
len = args.length, | ||
arr, lastSimple; | ||
if (args.length) { | ||
if (len) { | ||
children = []; | ||
for (let i=0; i<args.length; i++) { | ||
if (Array.isArray(args[i])) { | ||
arr = args[i]; | ||
for (let i=0; i<len; i++) { | ||
let p = args[i]; | ||
if (p===null || p===undefined) continue; | ||
if (p.join) { // Array.isArray(args[i]) | ||
arr = p; | ||
} | ||
else { | ||
arr = sharedArr; | ||
arr[0] = args[i]; | ||
arr[0] = p; | ||
} | ||
for (let j=0; j<arr.length; j++) { | ||
let child = arr[j]; | ||
let simple = notEmpty(child) && !isVNode(child); | ||
let child = arr[j], | ||
simple = notEmpty(child) && !isVNode(child); | ||
if (simple) child = String(child); | ||
@@ -196,3 +198,3 @@ if (simple && lastSimple) { | ||
} | ||
else if (child!==null && child!==undefined) { | ||
else if (notEmpty(child)) { | ||
children.push(child); | ||
@@ -205,3 +207,7 @@ } | ||
let p = new VNode(nodeName, attributes, children); | ||
if (attributes && attributes.children) { | ||
delete attributes.children; | ||
} | ||
let p = new VNode(nodeName, attributes || undefined, children || undefined); | ||
hook(hooks, 'vnode', p); | ||
@@ -211,6 +217,13 @@ return p; | ||
class VNode { | ||
/** Virtual DOM Node */ | ||
export class VNode { | ||
constructor(nodeName, attributes, children) { | ||
/** @type {string|class} */ | ||
this.nodeName = nodeName; | ||
/** @type {object<string>|undefined} */ | ||
this.attributes = attributes; | ||
/** @type {array<VNode>|undefined} */ | ||
this.children = children; | ||
@@ -222,5 +235,3 @@ } | ||
/** invoke a hook method gracefully */ | ||
/** @private Invoke a "hook" method with arguments if it exists. */ | ||
function hook(obj, name, ...args) { | ||
@@ -231,2 +242,4 @@ let fn = obj[name]; | ||
/** @private Fast check if an object is a VNode. */ | ||
function isVNode(obj) { | ||
@@ -236,2 +249,4 @@ return obj && obj.__isVNode===true; | ||
/** @private Check if a value is `null` or `undefined`. */ | ||
function notEmpty(x) { | ||
@@ -241,2 +256,4 @@ return x!==null && x!==undefined; | ||
/** @private Check if two nodes are equivalent. */ | ||
function isSameNodeType(node, vnode) { | ||
@@ -252,2 +269,3 @@ if (node.nodeType===3) { | ||
/** @private Apply the component referenced by a VNode to the DOM. */ | ||
function buildComponentFromVNode(dom, vnode) { | ||
@@ -263,6 +281,8 @@ let c = dom && dom._component; | ||
if (c) unmountComponent(dom, c); | ||
return createComponentFromVNode(vnode) | ||
return createComponentFromVNode(vnode); | ||
} | ||
} | ||
/** @private Instantiate and render a Component, given a VNode whose nodeName is a constructor. */ | ||
function createComponentFromVNode(vnode) { | ||
@@ -278,5 +298,8 @@ let component = componentRecycler.create(vnode.nodeName); | ||
node._componentConstructor = vnode.nodeName; | ||
return node; | ||
} | ||
/** @private Remove a component from the DOM and recycle it. */ | ||
function unmountComponent(dom, component) { | ||
@@ -296,4 +319,4 @@ console.warn('unmounting mismatched component', component); | ||
/** Apply differences in a given vnode (and it's deep children) to a real DOM Node. */ | ||
function build(dom, vnode) { | ||
/** @private Apply differences in a given vnode (and it's deep children) to a real DOM Node. */ | ||
function build(dom, vnode, rootComponent) { | ||
let out = dom, | ||
@@ -319,2 +342,6 @@ nodeName = vnode.nodeName; | ||
if (nodeName===null || nodeName===undefined) { | ||
nodeName = 'x-undefined-element'; | ||
} | ||
if (!dom) { | ||
@@ -329,2 +356,5 @@ out = recycler.create(nodeName); | ||
} | ||
else if (dom._component && dom._component!==rootComponent) { | ||
unmountComponent(dom, dom._component); | ||
} | ||
@@ -446,2 +476,3 @@ // apply attributes | ||
/** @private Managed re-rendering queue for dirty components. */ | ||
let renderQueue = { | ||
@@ -473,30 +504,26 @@ items: [], | ||
let rerender = renderQueue.process; | ||
export { rerender }; | ||
/** @private @function Trigger all pending render() calls. */ | ||
let rerender = renderQueue.process | ||
/** Typed DOM node factory with reclaimation */ | ||
/** @private DOM node pool, keyed on nodeName. */ | ||
let recycler = { | ||
nodes: {}, | ||
collect(node) { | ||
let name = node.nodeName; | ||
recycler.clean(node); | ||
let list = recycler.nodes[name] || (recycler.nodes[name] = []); | ||
list.push(node); | ||
let name = recycler.normalizeName(node.nodeName), | ||
list = recycler.nodes[name]; | ||
if (list) list.push(node); | ||
else recycler.nodes[name] = [node]; | ||
}, | ||
create(nodeName) { | ||
let list = recycler.nodes[name]; | ||
if (list && list.length) { | ||
return list.splice(0, 1)[0]; | ||
} | ||
return document.createElement(nodeName); | ||
let name = recycler.normalizeName(nodeName), | ||
list = recycler.nodes[name]; | ||
return list && list.pop() || document.createElement(nodeName); | ||
}, | ||
clean(node) { | ||
node.remove(); | ||
if (node.attributes) { | ||
let attrs = getNodeAttributes(node); | ||
for (let attr in attrs) if (attrs.hasOwnProperty(attr)) { | ||
node.removeAttribute(attr); | ||
} | ||
let len = node.attributes && node.attributes.length; | ||
if (len) for (let i=len; i--; ) { | ||
node.removeAttribute(node.attributes[i].name); | ||
} | ||
@@ -508,6 +535,8 @@ | ||
// } | ||
} | ||
}, | ||
normalizeName: memoize(name => name.toUpperCase()) | ||
}; | ||
/** @private Retains a pool of Components for re-use, keyed on component name. */ | ||
let componentRecycler = { | ||
@@ -531,2 +560,5 @@ components: {}, | ||
/** @private Append children to a Node. | ||
* Uses a Document Fragment to batch when appending 2 or more children | ||
*/ | ||
function appendChildren(parent, children) { | ||
@@ -546,2 +578,3 @@ let len = children.length; | ||
/** @private Get the value of a rendered attribute */ | ||
function getAccessor(node, name, value) { | ||
@@ -551,17 +584,7 @@ if (name==='class') return node.className; | ||
return value; | ||
//return getComplexAccessor(node, name, value); | ||
} | ||
// function getComplexAccessor(node, name, value) { | ||
// let uc = 'g'+nameToAccessor(name).substring(1); | ||
// if (node[uc] && typeof node[uc]==='function') { | ||
// return node[uc](); | ||
// } | ||
// return value; | ||
// } | ||
/** Attempt to set via an accessor method, falling back to setAttribute(). | ||
* Automatically detects and adds/removes event handlers based for "attributes" beginning with "on". | ||
* If `value=null`, triggers attribute/handler removal. | ||
/** @private Set a named attribute on the given Node, with special behavior for some names and event handlers. | ||
* If `value` is `null`, the attribute/handler will be removed. | ||
*/ | ||
@@ -580,8 +603,4 @@ function setAccessor(node, name, value, old) { | ||
function eventProxy(e) { | ||
let l = this._listeners, | ||
fn = l[e.type.toLowerCase()]; | ||
if (fn) return fn.call(l, hook(hooks, 'event', e) || e); | ||
} | ||
/** @private For props without explicit behavior, apply to a Node as event handlers or attributes. */ | ||
function setComplexAccessor(node, name, value, old) { | ||
@@ -593,34 +612,37 @@ if (name.substring(0,2)==='on') { | ||
l[type] = value; | ||
// @TODO automatically remove proxy event listener when no handlers are left | ||
return; | ||
} | ||
let uc = nameToAccessor(name); | ||
if (node[uc] && typeof node[uc]==='function') { | ||
node[uc](value); | ||
let type = typeof value; | ||
if (value===null) { | ||
node.removeAttribute(name); | ||
} | ||
else if (value!==null) { | ||
else if (type!=='function' && type!=='object') { | ||
node.setAttribute(name, value); | ||
} | ||
else { | ||
node.removeAttribute(name); | ||
} | ||
} | ||
function nameToAccessor(name) { | ||
let c = nameToAccessorCache[name]; | ||
if (!c) { | ||
c = 'set' + name.charAt(0).toUpperCase() + name.substring(1); | ||
nameToAccessorCache[name] = c; | ||
} | ||
return c; | ||
/** @private Proxy an event to hooked event handlers */ | ||
function eventProxy(e) { | ||
let l = this._listeners, | ||
fn = l[normalizeEventType(e.type)]; | ||
if (fn) return fn.call(this, hook(hooks, 'event', e) || e); | ||
} | ||
let nameToAccessorCache = {}; | ||
/** @private @function Normalize an event type/name to lowercase */ | ||
let normalizeEventType = memoize(type => type.toLowerCase()); | ||
/** @private Get a node's attributes as a hashmap, regardless of type. */ | ||
function getNodeAttributes(node) { | ||
let list = node.attributes; | ||
if (!list.getNamedItem) return list; | ||
if (!list || !list.getNamedItem) return list; | ||
if (list.length) return getAttributesAsObject(list); | ||
} | ||
/** @private Convert a DOM `.attributes` NamedNodeMap to a hashmap. */ | ||
function getAttributesAsObject(list) { | ||
@@ -636,2 +658,3 @@ let attrs = {}; | ||
/** @private Reconstruct `props` from a VNode */ | ||
function getNodeProps(vnode) { | ||
@@ -649,2 +672,41 @@ let props = extend({}, vnode.attributes); | ||
/** @private Convert a hashmap of styles to CSSText */ | ||
function styleObjToCss(s) { | ||
let str = '', | ||
sep = ': ', | ||
term = '; '; | ||
for (let prop in s) { | ||
if (s.hasOwnProperty(prop)) { | ||
let val = s[prop]; | ||
str += jsToCss(prop); | ||
str += sep; | ||
str += val; | ||
if (typeof val==='number' && !NON_DIMENSION_PROPS.hasOwnProperty(prop)) { | ||
str += 'px'; | ||
} | ||
str += term; | ||
} | ||
} | ||
return str; | ||
} | ||
/** @private Convert a hashmap of CSS classes to a space-delimited className string */ | ||
function hashToClassName(c) { | ||
let str = ''; | ||
for (let prop in c) { | ||
if (c[prop]) { | ||
if (str) str += ' '; | ||
str += prop; | ||
} | ||
} | ||
return str; | ||
} | ||
/** @private @function Convert a JavaScript camel-case CSS property name to a CSS property name */ | ||
let jsToCss = memoize( s => s.replace(/([A-Z])/,'-$1').toLowerCase() ); | ||
/** @private Copy own-properties from `props` onto `obj`. Returns `obj`. */ | ||
function extend(obj, props) { | ||
@@ -656,1 +718,5 @@ for (let i in props) if (props.hasOwnProperty(i)) { | ||
} | ||
export { options, hooks, rerender }; | ||
export default { options, hooks, render, rerender, h, Component }; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
90606
13
751
23