smoothr
Version:
Smoothr: Smooth Router - A custom React router that leverages the Web Animations API and CSS animations.
3 lines (2 loc) • 11.2 kB
JavaScript
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("preact"),require("path-to-regexp")):"function"==typeof define&&define.amd?define(["exports","preact","path-to-regexp"],n):n(t.Smoothr={},t.preact,t.pathToRegexp)}(this,function(t,n,e){"use strict";"default"in n&&n.default;e=e&&e.hasOwnProperty("default")?e.default:e;var o=n.createContext(),i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")},a=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},s=function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function, not "+typeof n);t.prototype=Object.create(n&&n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),n&&(Object.setPrototypeOf?Object.setPrototypeOf(t,n):t.__proto__=n)},u=function(t,n){var e={};for(var o in t)n.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},p=function(t,n){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!n||"object"!=typeof n&&"function"!=typeof n?t:n};function c(t){var n=JSON.parse(localStorage.getItem(t));return n?[].concat(n).filter(function(t){return t}):[]}function l(t,n){var e=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o=c(t);"string"!=typeof n||!e&&-1!==o.indexOf(n)||o.push(n),o.length>=100&&(o=[]),localStorage.setItem(t,JSON.stringify(o))}var f=Object.freeze({VISITED_URL_LIST:"SmoothrVisitedUrls",VISITED_ROUTE_LIST:"SmoothrVisitedRoutes"}),d=function(t){function n(o){r(this,n);var i=p(this,t.call(this,o));return i.deriveCurrentRoute=function(){var t=window.location.href.split("/"),n=(t="/"+t.slice(3,t.length).join("/")).split(i.originPath).join("")||"/";return n+"#"===i.originPath&&(n="/"),n},i.setRouteConsts=function(t,n){i.setState(function(e){var o,r,a,s={routeConsts:(o=e.routeConsts,r=t,o.filter(function(t){return!r.find(function(n){return t[a]===n[a]})}).concat(r))};return i.defaultNotFoundPath&&(i.defaultNotFoundPath=!1,s.notFoundPath=n),s})},i.setRouteGroupVar=function(t,n,e){i.routeVars[t]||(i.routeVars[t]={}),i.routeVars[t][n]=e},i.handlePopState=function(t){if(t.state){var n=t.state.pageNavigated<i.state.pageNavigated;i.handleRouteChange(t.state.url,n)}},i.handleHashChange=function(){var t=i.deriveCurrentRoute();i.handleRouteChange(t)},i.resolveRoutes=function(t){var n=t.replace(/\?(.*)|\#(.*)/,""),o=t.split(n).join(""),r=void 0,s=void 0,u=!1;i.state.routeConsts.forEach(function(p){if(RegExp(p.pathRegexp).test(i.state.currentUrl)&&(s=p.path),RegExp(p.pathRegexp).test(n))if(p.pathResolve){var c=(h=p.path,f=n,(m=e(h,d=[])).exec(f),d.reduce(function(t,n,e){var o;return a(((o={})[n.name]=m.exec(f)[e+1],o),t)},{})),l=p.pathResolve(c);"string"==typeof l&&RegExp(p.pathRegexp).test(l)&&(n=l,t=""+l+o,r=p.path,u=!0)}else r=p.path,u=!0;var h,f,d,m}),u||(t=i.state.notFoundPath,r=i.state.notFoundPath),i.state.currentUrl===i.state.notFoundPath&&(s=i.state.notFoundPath);var p=u?i.state.currentUrl:i.state.notFoundPath;return{incomingRoute:r,incomingUrl:t,outgoingRoute:s,outgoingUrl:p}},i.handleRouteChange=function(t){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],e=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o=i.resolveRoutes(t),r=o.outgoingUrl,s=o.incomingUrl,u=o.outgoingRoute,p=o.incomingRoute,c={};e&&(window.history.pushState({url:s,pageNavigated:i.state.pageNavigated+1},"",""+i.originPath+s),-1===i.state.visitedUrls.indexOf(r)&&(c.visitedUrls=[].concat(i.state.visitedUrls,[r]),l(f.VISITED_URL_LIST,r,!0)),-1===i.state.visitedRoutes.indexOf(u)&&(c.visitedRoutes=[].concat(i.state.visitedRoutes,[u]),l(f.VISITED_ROUTE_LIST,u,!0))),i.initialPageload?(i.initialPageload=!1,window.history.replaceState({url:s,pageNavigated:i.state.pageNavigated},"",""+i.originPath+s),i.setState(a({},c,{currentUrl:s}))):new Promise(function(t){i.props.beforeAnimation&&i.props.beforeAnimation({outgoingUrl:r,incomingUrl:s,outgoingRoute:u,incomingRoute:p,backNavigation:n}),t()}).then(function(){i.props.onAnimationStart&&i.props.onAnimationStart({initialPageload:!1});var t=!1;i.setState(function(e){var o=n?e.pageNavigated-1:e.pageNavigated+1;return e.newUrl?(t=!0,clearTimeout(i.animationTimeout),i.domInAnimation.cancel(),i.domOutAnimation.cancel(),a({},c,{newUrl:null,currentUrl:s,pageNavigated:o,backNavigation:!1})):a({},c,{newUrl:s,pageNavigated:o,backNavigation:n})},function(){t&&(i.domInAnimation.cancel=function(){},i.domOutAnimation.cancel=function(){},i.props.onAnimationEnd&&i.props.onAnimationEnd())})})},i.initialPageload=!0,i.defaultNotFoundPath=!0,i.originPath="",o.originPath&&"/"!==o.originPath&&(i.originPath=o.originPath),i.routeVars={},i.domInAnimation={},i.domInAnimation.cancel=function(){},i.domOutAnimation={},i.domOutAnimation.cancel=function(){},i.state={currentUrl:i.deriveCurrentRoute(),newUrl:null,pageNavigated:1,backNavigation:!1,routeConsts:[],notFoundPath:"/notfound",visitedUrls:c(f.VISITED_URL_LIST),visitedRoutes:c(f.VISITED_ROUTE_LIST)},i}return s(n,t),n.prototype.componentDidMount=function(){var t=this;setTimeout(function(){t.handleRouteChange(t.state.currentUrl)},0),window.addEventListener("popstate",this.handlePopState),window.addEventListener("hashchange",this.handleHashChange)},n.prototype.componentWillUnmount=function(){window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)},n.prototype.componentDidUpdate=function(){var t=this,n=function(){t.setState(function(t){return t.newUrl?{newUrl:null,currentUrl:t.newUrl,backNavigation:!1}:null},function(){t.domInAnimation.cancel=function(){},t.domOutAnimation.cancel=function(){},t.props.onAnimationEnd&&t.props.onAnimationEnd()})};this.state.newUrl&&(clearTimeout(this.animationTimeout),this.domInAnimation.cancel(),this.domOutAnimation.cancel(),Object.keys(this.routeVars).forEach(function(e){var o=t.routeVars[e],r=o.animationIn,a=o.animationOut,s=o.animationOpts;if(t.state.backNavigation&&(r=o.reverseAnimationIn||r,a=o.reverseAnimationOut||a,s=o.reverseAnimationOpts||s),"number"==typeof s)s={duration:s};else if("object"===(void 0===s?"undefined":i(s)))s.fill="forwards";else{if(s)throw"Smoothr Error: animationOpts/reverseAnimationOps prop must be an object or integer";s={duration:0}}if(s.iterations&&s.iterations===1/0)throw"Smoothr Error: Cannot use `iterations: Infinity` as animation options";var u=(s.delay||0)+s.duration*(s.iterations||1)+(s.endDelay||0),p=!1;o.newPageRef&&("string"!=typeof r?(t.domInAnimation=o.newPageRef.animate(r,s),t.domInAnimation.onfinish=n,t.domInAnimation.oncancel=n,t.domInAnimation.play()):p=!0),o.currentPageRef&&("string"!=typeof a&&o.currentPageRef?(t.domOutAnimation=o.currentPageRef.animate(a,s),t.domOutAnimation.onfinish=n,t.domOutAnimation.oncancel=n,t.domOutAnimation.play()):p=!0),p&&(t.animationTimeout=setTimeout(n,u))}))},n.prototype.render=function(){return h(o.Provider,{value:{originPath:this.originPath,state:this.state,handleRouteChange:this.handleRouteChange,setRouteConsts:this.setRouteConsts,setRouteGroupVar:this.setRouteGroupVar}},this.props.children)},n}(n.Component);function m(t,n){Object.keys(t).forEach(function(e){var o;-1===["component","path","animationIn","animationOut","animationOpts","children"].indexOf(e)&&Object.assign(n,((o={})[e]=t[e],o))})}function g(t,n,e,o){var i=t.exec(e);Object.assign(o,n.reduce(function(t,n,e){var o;return a(((o={})[n.name]=i[e+1],o),t)},{}))}var v=function(t){function n(o){r(this,n);var i,a=p(this,t.call(this,o));a.groupHash=(i=window.crypto||window.msCrypto,([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(t){return(t^i.getRandomValues(new Uint8Array(1))[0]&15>>t/4).toString(16)}));var s="/notfound",u=[];return a.props.children.forEach(function(t){if(t.props.notFound&&-1===t.props.path.indexOf(":"))s=t.props.path;else{if(t.props.notFound)throw"Smoothr Error: The `path` on the <Route /> with the `notFound` attribute cannot have any URL variables.";var n=t.props.path.replace(/\?(.*)|\#(.*)/,""),o={path:n,pathRegexp:e(n)};-1!==t.props.path.indexOf(":")&&t.props.pathResolve&&(o.pathResolve=t.props.pathResolve),u.push(o)}}),a.props.context.setRouteConsts(u,s),a}return s(n,t),n.prototype.render=function(){var t=this,n=this.props,o=n.context,i=n.animationIn,r=n.animationOut,s=n.animationOpts,u=n.reverseAnimationIn,p=n.reverseAnimationOut,c=n.reverseAnimationOpts,l=o.state,f=l.newUrl,d=l.currentUrl,v=function(){return null},R=function(){return null},y=function(){return null},O=null,w={},b=null,P=null,A={},I=!1,S=null;this.props.children.forEach(function(n){var a=[],l=e(n.props.path.replace(/\?(.*)|\#(.*)/,""),a),h=n.props.animationIn||i,U=n.props.animationOut||r,C=n.props.animationOpts||s,E=n.props.reverseAnimationIn||u,x=n.props.reverseAnimationOut||p,V=n.props.reverseAnimationOpts||c;f&&RegExp(l).test(f)&&(m(n.props,w),g(l,a,f,w),v=n.props.component,b=t.groupHash+"-"+f,o.setRouteGroupVar(t.groupHash,"animationIn",h),o.setRouteGroupVar(t.groupHash,"animationOut",U),o.setRouteGroupVar(t.groupHash,"animationOpts",C),o.setRouteGroupVar(t.groupHash,"reverseAnimationIn",E),o.setRouteGroupVar(t.groupHash,"reverseAnimationOut",x),o.setRouteGroupVar(t.groupHash,"reverseAnimationOpts",V),"string"!=typeof n.props.animationIn&&"string"!=typeof t.props.animationIn||(O=o.state.backNavigation?E:h),"string"!=typeof n.props.animationOut&&"string"!=typeof t.props.animationOut||(P=o.state.backNavigation?x:U)),RegExp(l).test(d)&&(m(n.props,A),g(l,a,d,A),I=!0,R=n.props.component,S=t.groupHash+"-"+d),n.props.notFound&&(y=n.props.component)}),I||(R=y);var U={height:"100%",width:"100%",position:"absolute",animationFillMode:"forwards"};return f?h("div",{style:U},h("div",{style:U,className:O,ref:function(n){return o.setRouteGroupVar(t.groupHash,"newPageRef",n)}},h(v,a({},w,{key:b}))),h("div",{style:U,className:P,ref:function(n){return o.setRouteGroupVar(t.groupHash,"currentPageRef",n)}},h(R,a({},A,{key:S})))):h(R,a({},A,{key:S}))},n}(n.Component);t.Smoothr=d,t.SmoothRoutes=function(t){return h(o.Consumer,null,function(n){return h(v,a({},t,{context:n}))})},t.Route=function(){return null},t.Link=function(t){return h(o.Consumer,null,function(n){var o=t.href,i=t.fuzzyCurrent,r=t.fuzzyVisited,s=t.onClick,p=t.children,c=u(t,["href","fuzzyCurrent","fuzzyVisited","onClick","children"]),l=n.originPath,f=n.state,d=f.newUrl,m=f.currentUrl,g=f.visitedRoutes,v=f.visitedUrls,R=f.routeConsts,y=d?o===d:o===m;i&&(y=R.some(function(t){var n=RegExp(t.pathRegexp);return d?n.test(d)&&n.test(o):n.test(m)&&n.test(o)}));var O=!1;return O=r?g.some(function(t){var n=e(t);return RegExp(n).test(o)}):-1!==v.indexOf(o),h("a",a({href:""+l+o,onClick:function(e){e.preventDefault(),t.disabled||y||(n.handleRouteChange(o,!1,!0),s&&s())},"data-smoothr-current-link":y,"data-smoothr-visited-link":O},c),p)})},Object.defineProperty(t,"__esModule",{value:!0})});
//# sourceMappingURL=smoothr.umd.min.js.map