From 164556764ac07987a8e89df67b183f8374484081 Mon Sep 17 00:00:00 2001 From: Adrian Heine Date: Thu, 17 Sep 2020 15:13:05 +0200 Subject: [PATCH] Init --- diffDOM.js | 2 ++ index.html | 4 ++++ src/display.js | 45 +++++++++++++++++++++++++++++++++++++++++ src/index.js | 38 ++++++++++++++++++++++++++++++++++ style.css | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 diffDOM.js create mode 100644 index.html create mode 100644 src/display.js create mode 100644 src/index.js create mode 100644 style.css diff --git a/diffDOM.js b/diffDOM.js new file mode 100644 index 0000000..632f2af --- /dev/null +++ b/diffDOM.js @@ -0,0 +1,2 @@ +var diffDOM=function(e){"use strict";function t(e,o,n){var s;return"#text"===e.nodeName?s=n.document.createTextNode(e.data):"#comment"===e.nodeName?s=n.document.createComment(e.data):("svg"===e.nodeName||o?(s=n.document.createElementNS("http://www.w3.org/2000/svg",e.nodeName),o=!0):s=n.document.createElement(e.nodeName),e.attributes&&Object.entries(e.attributes).forEach(function(e){var t=e[0],o=e[1];return s.setAttribute(t,o)}),e.childNodes&&e.childNodes.forEach(function(e){return s.appendChild(t(e,o,n))}),n.valueDiffing&&(e.value&&(s.value=e.value),e.checked&&(s.checked=e.checked),e.selected&&(s.selected=e.selected))),s}function o(e,t){for(t=t.slice();t.length>0;){if(!e.childNodes)return!1;var o=t.splice(0,1)[0];e=e.childNodes[o]}return e}function n(e,n,s){var i,a,l,c,r=o(e,n[s._const.route]),u={diff:n,node:r};if(s.preDiffApply(u))return!0;switch(n[s._const.action]){case s._const.addAttribute:if(!r||!r.setAttribute)return!1;r.setAttribute(n[s._const.name],n[s._const.value]);break;case s._const.modifyAttribute:if(!r||!r.setAttribute)return!1;r.setAttribute(n[s._const.name],n[s._const.newValue]),"INPUT"===r.nodeName&&"value"===n[s._const.name]&&(r.value=n[s._const.newValue]);break;case s._const.removeAttribute:if(!r||!r.removeAttribute)return!1;r.removeAttribute(n[s._const.name]);break;case s._const.modifyTextElement:if(!r||3!==r.nodeType)return!1;s.textDiff(r,r.data,n[s._const.oldValue],n[s._const.newValue]);break;case s._const.modifyValue:if(!r||void 0===r.value)return!1;r.value=n[s._const.newValue];break;case s._const.modifyComment:if(!r||void 0===r.data)return!1;s.textDiff(r,r.data,n[s._const.oldValue],n[s._const.newValue]);break;case s._const.modifyChecked:if(!r||void 0===r.checked)return!1;r.checked=n[s._const.newValue];break;case s._const.modifySelected:if(!r||void 0===r.selected)return!1;r.selected=n[s._const.newValue];break;case s._const.replaceElement:r.parentNode.replaceChild(t(n[s._const.newValue],"http://www.w3.org/2000/svg"===r.namespaceURI,s),r);break;case s._const.relocateGroup:Array.apply(void 0,new Array(n.groupLength)).map(function(){return r.removeChild(r.childNodes[n[s._const.from]])}).forEach(function(e,t){0===t&&(a=r.childNodes[n[s._const.to]]),r.insertBefore(e,a||null)});break;case s._const.removeElement:r.parentNode.removeChild(r);break;case s._const.addElement:c=(l=n[s._const.route].slice()).splice(l.length-1,1)[0],(r=o(e,l)).insertBefore(t(n[s._const.element],"http://www.w3.org/2000/svg"===r.namespaceURI,s),r.childNodes[c]||null);break;case s._const.removeTextElement:if(!r||3!==r.nodeType)return!1;r.parentNode.removeChild(r);break;case s._const.addTextElement:if(c=(l=n[s._const.route].slice()).splice(l.length-1,1)[0],i=s.document.createTextNode(n[s._const.value]),!(r=o(e,l))||!r.childNodes)return!1;r.insertBefore(i,r.childNodes[c]||null);break;default:console.log("unknown action")}return u.newNode=i,s.postDiffApply(u),!0}function s(e,t,o){var n=e[t];e[t]=e[o],e[o]=n}function i(e,t,o){t.length||(t=[t]),(t=t.slice()).reverse(),t.forEach(function(t){!function(e,t,o){switch(t[o._const.action]){case o._const.addAttribute:t[o._const.action]=o._const.removeAttribute,n(e,t,o);break;case o._const.modifyAttribute:s(t,o._const.oldValue,o._const.newValue),n(e,t,o);break;case o._const.removeAttribute:t[o._const.action]=o._const.addAttribute,n(e,t,o);break;case o._const.modifyTextElement:case o._const.modifyValue:case o._const.modifyComment:case o._const.modifyChecked:case o._const.modifySelected:case o._const.replaceElement:s(t,o._const.oldValue,o._const.newValue),n(e,t,o);break;case o._const.relocateGroup:s(t,o._const.from,o._const.to),n(e,t,o);break;case o._const.removeElement:t[o._const.action]=o._const.addElement,n(e,t,o);break;case o._const.addElement:t[o._const.action]=o._const.removeElement,n(e,t,o);break;case o._const.removeTextElement:t[o._const.action]=o._const.addTextElement,n(e,t,o);break;case o._const.addTextElement:t[o._const.action]=o._const.removeTextElement,n(e,t,o);break;default:console.log("unknown action")}}(e,t,o)})}var a=function(e){var t=this;void 0===e&&(e={}),Object.entries(e).forEach(function(e){var o=e[0],n=e[1];return t[o]=n})};function l(e){var t=[];return"#text"!==e.nodeName&&"#comment"!==e.nodeName&&(t.push(e.nodeName),e.attributes&&(e.attributes.class&&t.push(e.nodeName+"."+e.attributes.class.replace(/ /g,".")),e.attributes.id&&t.push(e.nodeName+"#"+e.attributes.id))),t}function c(e){var t={},o={};return e.forEach(function(e){l(e).forEach(function(e){var n=e in t;n||e in o?n&&(delete t[e],o[e]=!0):t[e]=!0})}),t}function r(e,t){var o=c(e),n=c(t),s={};return Object.keys(o).forEach(function(e){n[e]&&(s[e]=!0)}),s}function u(e){return delete e.outerDone,delete e.innerDone,delete e.valueDone,!e.childNodes||e.childNodes.every(u)}function d(e,t){if(!["nodeName","value","checked","selected","data"].every(function(o){return e[o]===t[o]}))return!1;if(Boolean(e.attributes)!==Boolean(t.attributes))return!1;if(Boolean(e.childNodes)!==Boolean(t.childNodes))return!1;if(e.attributes){var o=Object.keys(e.attributes),n=Object.keys(t.attributes);if(o.length!==n.length)return!1;if(!o.every(function(o){return e.attributes[o]===t.attributes[o]}))return!1}if(e.childNodes){if(e.childNodes.length!==t.childNodes.length)return!1;if(!e.childNodes.every(function(e,o){return d(e,t.childNodes[o])}))return!1}return!0}function h(e,t,o,n,s){if(!e||!t)return!1;if(e.nodeName!==t.nodeName)return!1;if("#text"===e.nodeName)return!!s||e.data===t.data;if(e.nodeName in o)return!0;if(e.attributes&&t.attributes){if(e.attributes.id){if(e.attributes.id!==t.attributes.id)return!1;if(e.nodeName+"#"+e.attributes.id in o)return!0}if(e.attributes.class&&e.attributes.class===t.attributes.class)if(e.nodeName+"."+e.attributes.class.replace(/ /g,".")in o)return!0}if(n)return!0;var i=e.childNodes?e.childNodes.slice().reverse():[],a=t.childNodes?t.childNodes.slice().reverse():[];if(i.length!==a.length)return!1;if(s)return i.every(function(e,t){return e.nodeName===a[t].nodeName});var l=r(i,a);return i.every(function(e,t){return h(e,a[t],l,!0,!0)})}function f(e){return JSON.parse(JSON.stringify(e))}function p(e,t,o,n){var s=0,i=[],a=e.length,c=t.length,u=Array.apply(void 0,new Array(a+1)).map(function(){return[]}),d=r(e,t),f=a===c;f&&e.some(function(e,o){var n=l(e),s=l(t[o]);return n.length!==s.length?(f=!1,!0):(n.some(function(e,t){if(e!==s[t])return f=!1,!0}),!f||void 0)});for(var p=0;p=s&&(s=u[p+1][_+1],i=[p+1,_+1]))}return 0!==s&&{oldValue:i[0]-s,newValue:i[1]-s,length:s}}function m(e,t){return Array.apply(void 0,new Array(e)).map(function(){return t})}a.prototype.toString=function(){return JSON.stringify(this)},a.prototype.setValue=function(e,t){return this[e]=t,this};var _=function(){this.list=[]};function V(e,t){var o,n,s=e;for(t=t.slice();t.length>0;){if(!s.childNodes)return!1;n=t.splice(0,1)[0],o=s,s=s.childNodes[n]}return{node:s,parentNode:o,nodeIndex:n}}function g(e,t,o){return t.forEach(function(t){!function(e,t,o){var n,s,i,a=V(e,t[o._const.route]),l=a.node,c=a.parentNode,r=a.nodeIndex,u=[],d={diff:t,node:l};if(o.preDiffApply(d))return!0;switch(t[o._const.action]){case o._const.addAttribute:l.attributes||(l.attributes={}),l.attributes[t[o._const.name]]=t[o._const.value],"checked"===t[o._const.name]?l.checked=!0:"selected"===t[o._const.name]?l.selected=!0:"INPUT"===l.nodeName&&"value"===t[o._const.name]&&(l.value=t[o._const.value]);break;case o._const.modifyAttribute:l.attributes[t[o._const.name]]=t[o._const.newValue];break;case o._const.removeAttribute:delete l.attributes[t[o._const.name]],0===Object.keys(l.attributes).length&&delete l.attributes,"checked"===t[o._const.name]?l.checked=!1:"selected"===t[o._const.name]?delete l.selected:"INPUT"===l.nodeName&&"value"===t[o._const.name]&&delete l.value;break;case o._const.modifyTextElement:l.data=t[o._const.newValue];break;case o._const.modifyValue:l.value=t[o._const.newValue];break;case o._const.modifyComment:l.data=t[o._const.newValue];break;case o._const.modifyChecked:l.checked=t[o._const.newValue];break;case o._const.modifySelected:l.selected=t[o._const.newValue];break;case o._const.replaceElement:(n=f(t[o._const.newValue])).outerDone=!0,n.innerDone=!0,n.valueDone=!0,c.childNodes[r]=n;break;case o._const.relocateGroup:l.childNodes.splice(t[o._const.from],t.groupLength).reverse().forEach(function(e){return l.childNodes.splice(t[o._const.to],0,e)}),l.subsets&&l.subsets.forEach(function(e){if(t[o._const.from]t[o._const.from]){e.oldValue-=t.groupLength;var n=e.oldValue+e.length-t[o._const.to];n>0&&(u.push({oldValue:t[o._const.to]+t.groupLength,newValue:e.newValue+e.length-n,length:n}),e.length-=n)}else if(t[o._const.from]>t[o._const.to]&&e.oldValue>t[o._const.to]&&e.oldValue0&&(u.push({oldValue:t[o._const.to]+t.groupLength,newValue:e.newValue+e.length-s,length:s}),e.length-=s)}else e.oldValue===t[o._const.from]&&(e.oldValue=t[o._const.to])});break;case o._const.removeElement:c.childNodes.splice(r,1),c.subsets&&c.subsets.forEach(function(e){e.oldValue>r?e.oldValue-=1:e.oldValue===r?e.delete=!0:e.oldValuer&&(e.oldValue+e.length-1===r?e.length--:(u.push({newValue:e.newValue+r-e.oldValue,oldValue:r,length:e.length-r+e.oldValue-1}),e.length=r-e.oldValue))}),l=c;break;case o._const.addElement:s=t[o._const.route].slice(),i=s.splice(s.length-1,1)[0],l=V(e,s).node,(n=f(t[o._const.element])).outerDone=!0,n.innerDone=!0,n.valueDone=!0,l.childNodes||(l.childNodes=[]),i>=l.childNodes.length?l.childNodes.push(n):l.childNodes.splice(i,0,n),l.subsets&&l.subsets.forEach(function(e){if(e.oldValue>=i)e.oldValue+=1;else if(e.oldValuei){var t=e.oldValue+e.length-i;u.push({newValue:e.newValue+e.length-t,oldValue:i+1,length:t}),e.length-=t}});break;case o._const.removeTextElement:c.childNodes.splice(r,1),"TEXTAREA"===c.nodeName&&delete c.value,c.subsets&&c.subsets.forEach(function(e){e.oldValue>r?e.oldValue-=1:e.oldValue===r?e.delete=!0:e.oldValuer&&(e.oldValue+e.length-1===r?e.length--:(u.push({newValue:e.newValue+r-e.oldValue,oldValue:r,length:e.length-r+e.oldValue-1}),e.length=r-e.oldValue))}),l=c;break;case o._const.addTextElement:s=t[o._const.route].slice(),i=s.splice(s.length-1,1)[0],(n={}).nodeName="#text",n.data=t[o._const.value],(l=V(e,s).node).childNodes||(l.childNodes=[]),i>=l.childNodes.length?l.childNodes.push(n):l.childNodes.splice(i,0,n),"TEXTAREA"===l.nodeName&&(l.value=t[o._const.newValue]),l.subsets&&l.subsets.forEach(function(e){if(e.oldValue>=i&&(e.oldValue+=1),e.oldValuei){var t=e.oldValue+e.length-i;u.push({newValue:e.newValue+e.length-t,oldValue:i+1,length:t}),e.length-=t}});break;default:console.log("unknown action")}l.subsets&&(l.subsets=l.subsets.filter(function(e){return!e.delete&&e.oldValue!==e.newValue}),u.length&&(l.subsets=l.subsets.concat(u))),d.newNode=n,o.postDiffApply(d)}(e,t,o)}),!0}function v(e,t){void 0===t&&(t={});var o={};if(o.nodeName=e.nodeName,"#text"===o.nodeName||"#comment"===o.nodeName)o.data=e.data;else{if(e.attributes&&e.attributes.length>0)o.attributes={},Array.prototype.slice.call(e.attributes).forEach(function(e){return o.attributes[e.name]=e.value});if("TEXTAREA"===o.nodeName)o.value=e.value;else if(e.childNodes&&e.childNodes.length>0){o.childNodes=[],Array.prototype.slice.call(e.childNodes).forEach(function(e){return o.childNodes.push(v(e,t))})}t.valueDiffing&&(void 0!==e.checked&&e.type&&["radio","checkbox"].includes(e.type.toLowerCase())?o.checked=e.checked:void 0!==e.value&&(o.value=e.value),void 0!==e.selected&&(o.selected=e.selected))}return o}_.prototype.add=function(e){var t;(t=this.list).push.apply(t,e)},_.prototype.forEach=function(e){this.list.forEach(function(t){return e(t)})};var b=/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g,N=Object.create?Object.create(null):{},y=/\s([^'"\/\s><]+?)[\s\/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function w(e){return e.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")}var E={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,menuItem:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0};function k(e,t){void 0===t&&(t={components:N});var o,n=[],s=-1,i=[],a={},l=!1;return e.replace(b,function(c,r){if(l){if(c!=="")return;l=!1}var u,d="/"!==c.charAt(1),h=r+c.length,f=e.charAt(h);if(d&&(s++,"tag"===(o=function(e){var t={nodeName:"",attributes:{}},o=e.match(/<\/?([^\s]+?)[\/\s>]/);o&&(t.nodeName=o[1].toUpperCase(),(E[o[1].toLowerCase()]||"/"===e.charAt(e.length-2))&&(t.voidElement=!0));for(var n=new RegExp(y),s=null,i=!1;!i;)if(null===(s=n.exec(e)))i=!0;else if(s[0].trim())if(s[1]){var a=s[1].trim(),l=[a,""];a.indexOf("=")>-1&&(l=a.split("=")),t.attributes[l[0]]=l[1],n.lastIndex--}else s[2]&&(t.attributes[s[2]]=s[3].trim().substring(1,s[3].length-1));return t}(c)).type&&t.components[o.nodeName]&&(o.type="component",l=!0),o.voidElement||l||!f||"<"===f||(o.childNodes||(o.childNodes=[]),o.childNodes.push({nodeName:"#text",data:w(e.slice(h,e.indexOf("<",h)))})),a[o.tagName]=o,0===s&&n.push(o),(u=i[s-1])&&(u.childNodes||(u.childNodes=[]),u.childNodes.push(o)),i[s]=o),(!d||o.voidElement)&&(s--,!l&&"<"!==f&&f)){u=-1===s?n:i[s].childNodes||[];var p=e.indexOf("<",h),m=w(e.slice(h,-1===p?void 0:p));u.push({nodeName:"#text",data:m})}}),n[0]}function x(e){return function e(t){return delete t.voidElement,t.childNodes&&t.childNodes.forEach(function(t){return e(t)}),t}(k(e))}var A=function(e,t,o){this.options=o,this.t1=e instanceof HTMLElement?v(e,this.options):"string"==typeof e?x(e,this.options):JSON.parse(JSON.stringify(e)),this.t2=t instanceof HTMLElement?v(t,this.options):"string"==typeof t?x(t,this.options):JSON.parse(JSON.stringify(t)),this.diffcount=0,this.foundAll=!1,this.debug&&(this.t1Orig=v(e,this.options),this.t2Orig=v(t,this.options)),this.tracker=new _};A.prototype.init=function(){return this.findDiffs(this.t1,this.t2)},A.prototype.findDiffs=function(e,t){var o;do{if(this.options.debug&&(this.diffcount+=1,this.diffcount>this.options.diffcap))throw window.diffError=[this.t1Orig,this.t2Orig],new Error("surpassed diffcap:"+JSON.stringify(this.t1Orig)+" -> "+JSON.stringify(this.t2Orig));0===(o=this.findNextDiff(e,t,[])).length&&(d(e,t)||(this.foundAll?console.error("Could not find remaining diffs!"):(this.foundAll=!0,u(e),o=this.findNextDiff(e,t,[])))),o.length>0&&(this.foundAll=!1,this.tracker.add(o),g(e,o,this.options))}while(o.length>0);return this.tracker.list},A.prototype.findNextDiff=function(e,t,o){var n,s;if(this.options.maxDepth&&o.length>this.options.maxDepth)return[];if(!e.outerDone){if(n=this.findOuterDiff(e,t,o),this.options.filterOuterDiff&&(s=this.options.filterOuterDiff(e,t,n))&&(n=s),n.length>0)return e.outerDone=!0,n;e.outerDone=!0}if(!e.innerDone){if((n=this.findInnerDiff(e,t,o)).length>0)return n;e.innerDone=!0}if(this.options.valueDiffing&&!e.valueDone){if((n=this.findValueDiff(e,t,o)).length>0)return e.valueDone=!0,n;e.valueDone=!0}return[]},A.prototype.findOuterDiff=function(e,t,o){var n,s,i,l,c,r,u=[];if(e.nodeName!==t.nodeName){if(!o.length)throw new Error("Top level nodes have to be of the same kind.");return[(new a).setValue(this.options._const.action,this.options._const.replaceElement).setValue(this.options._const.oldValue,f(e)).setValue(this.options._const.newValue,f(t)).setValue(this.options._const.route,o)]}if(o.length&&this.options.maxNodeDiffCount0&&(c=this.attemptGroupRelocation(e,t,u,o)).length>0)return c}for(var h=0;hs.length?(c=c.concat([(new a).setValue(this.options._const.action,this.options._const.removeElement).setValue(this.options._const.element,f(_)).setValue(this.options._const.route,o.concat(r))]),n.splice(h,1),r-=1,l-=1):n.lengthu+1&&"#text"===e.childNodes[u+1].nodeName;)if(u+=1,t.childNodes[v].data===e.childNodes[u].data){r=!0;break}if(!r)return g.push((new a).setValue(this.options._const.action,this.options._const.modifyTextElement).setValue(this.options._const.route,n.concat(v)).setValue(this.options._const.oldValue,c.data).setValue(this.options._const.newValue,t.childNodes[v].data)),g}g.push((new a).setValue(this.options._const.action,this.options._const.removeTextElement).setValue(this.options._const.route,n.concat(v)).setValue(this.options._const.value,c.data)),p.splice(v,1),V=Math.min(p.length,_.length),v-=1}else g.push((new a).setValue(this.options._const.action,this.options._const.removeElement).setValue(this.options._const.route,n.concat(v)).setValue(this.options._const.element,f(c))),p.splice(v,1),V=Math.min(p.length,_.length),v-=1;else if(!0===_[v])"#text"===(c=t.childNodes[v]).nodeName?(g.push((new a).setValue(this.options._const.action,this.options._const.addTextElement).setValue(this.options._const.route,n.concat(v)).setValue(this.options._const.value,c.data)),p.splice(v,0,!0),V=Math.min(p.length,_.length),b-=1):(g.push((new a).setValue(this.options._const.action,this.options._const.addElement).setValue(this.options._const.route,n.concat(v)).setValue(this.options._const.element,f(c))),p.splice(v,0,!0),V=Math.min(p.length,_.length),b-=1);else if(p[v]!==_[v]){if(g.length>0)return g;if(l=o[p[v]],(i=Math.min(l.newValue,e.childNodes.length-l.length))!==l.oldValue){s=!1;for(var N=0;N entering "+e,t)},T.prototype.fout=function(e,t){this.log("│<──┘ generated return value",t),this.padding=this.padding.substring(0,this.padding.length-this.pad.length)},T.prototype.format=function(e,t){return function(e){for(e=""+e;e.length<4;)e="0"+e;return e}(t)+"> "+this.padding+e},T.prototype.log=function(){var e=Array.prototype.slice.call(arguments),t=function(e){return e?"string"==typeof e?e:e instanceof HTMLElement?e.outerHTML||"":e instanceof Array?"["+e.map(t).join(",")+"]":e.toString()||e.valueOf()||"":""};e=e.map(t).join(", "),this.messages.push(this.format(e,this.tick++))},T.prototype.toString=function(){for(var e="└───";e.length<=this.padding.length+this.pad.length;)e+="× ";var t=this.padding;return this.padding="",e=this.format(e,this.tick),this.padding=t,this.messages.join("\n")+"\n"+e},e.DiffDOM=O,e.TraceLogger=T,e.nodeToObj=v,e.stringToObj=x,e}({}); +//# sourceMappingURL=diffDOM.js.map diff --git a/index.html b/index.html new file mode 100644 index 0000000..86ab05a --- /dev/null +++ b/index.html @@ -0,0 +1,4 @@ + + + + diff --git a/src/display.js b/src/display.js new file mode 100644 index 0000000..f8739f5 --- /dev/null +++ b/src/display.js @@ -0,0 +1,45 @@ +export class Display { + constructor(baseUrl, dispatch, target) { + this.baseUrl = baseUrl + this.target = target + target.addEventListener('click', e => { + let target = e.target + while (target.nodeName !== 'A') { + target = target.parentNode + if (!target) return + } + window.history.pushState(null, "", target.href) + dispatch(target.getAttribute('href')) + e.preventDefault() + }) + } + render(state) { + const target = document.createElement('div') + target.className = 'wrapper' + const field = document.createElement('ul') + field.className = 'items' + + for (const item of state.items) { + const dom = document.createElement('li') + const a = document.createElement('a') + const action = item.state == 'face-down' ? 'flip' : 'show' + a.href = `/${item.id}/${action}` + dom.className = item.state + dom.appendChild(a) + field.appendChild(dom) + } + target.appendChild(field) + if (state.show !== null) { + const wrapper = document.createElement('a') + wrapper.href = '/' + const fullview = document.createElement('div') + wrapper.className = 'fullview' + wrapper.appendChild(fullview) + target.appendChild(wrapper) + } + + const dd = new diffDOM.DiffDOM() + const diff = dd.diff(this.target, target) + dd.apply(this.target, diff) + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..cb93e3d --- /dev/null +++ b/src/index.js @@ -0,0 +1,38 @@ +import {Display} from './display.js' + +const target = document.createElement('div') + +const state = {items: [], show: null } +for (let i = 0; i < 16; ++i) { + state.items.push({id: i, state: 'face-down'}) +} + +class Actions { + flip(id) { + state.items[id].state = 'face-up' + } + show(id) { + state.show = id + } + reset() { + state.show = null + } +} +const actions = new Actions + +let display +const dispatch = target => { + const match = target.match(/\/([^/]+)\/([^/]+)/) + if (match && Object.hasOwnProperty.call(Actions.prototype, match[2])) { + actions[match[2]](match[1]) + } else actions.reset() + display.render(state) +} +window.onpopstate = e => { + dispatch(document.location.search) +} +display = new Display('', dispatch, target) + +dispatch(document.location.search) +document.body.appendChild(target) + diff --git a/style.css b/style.css new file mode 100644 index 0000000..45b22fd --- /dev/null +++ b/style.css @@ -0,0 +1,55 @@ +body { + background-color: #e2eff3; + margin: 0; +} + +.wrapper { + max-width: 70em; + margin: 0 auto; + background-color: #FFC63F; +} + +.items { + list-style: none; + margin: 0; +} + +.items > li { + display: inline-block; +} + +.items > li a { + width: 8em; + height: 8em; + background: #D66C00; + margin: 2em; + border-radius: 4em; + display: block; +} + +.items > li a:hover { + background: #f39a3f; +} + +.items > li.face-up a { + background-color: #ed8112; +} + +.fullview { + width: 100%; + height: 100%; + position: fixed; + left: 0; + top: 0; + background-color: #858c8f90; + padding: 1em; + box-sizing: border-box; + cursor: default; +} +.fullview > div { + background-color: #858c8f; + width: 20em; + margin: 5em auto; + position: relative; + height: 30em; +}