123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- let $ = s => document.querySelector(s);
- let $$ = s => document.querySelectorAll(s);
- function clearSelector(selector) {
- for (let section of $$(selector)) {
- $('#offscreen').appendChild(section);
- }
- }
- function create(elementType) {
- let newElement = document.createElement(elementType);
- for (let i = 1; i < arguments.length; i++) {
- let currentArgument = arguments[i];
- if (typeof(currentArgument) === 'string') {
- newElement.innerHTML += currentArgument;
- } else if (Array.isArray(currentArgument)) {
- for (let j = 0; j < arguments[i].length; j++) {
- if (typeof(arguments[i][j]) === 'string') {
- newElement.innerHTML += currentArgument[j];
- } else {
- newElement.appendChild(currentArgument[j]);
- }
- }
- } else if (currentArgument instanceof Element) {
- newElement.appendChild(currentArgument);
- } else if (typeof(currentArgument) === 'function') {
- currentArgument(newElement);
- } else {
- Object.getOwnPropertyNames(currentArgument).forEach(
- function (val, idx, array) {
- newElement.setAttribute(val, currentArgument[val]);
- }
- );
- }
- }
- return newElement;
- }
- for (let e of ['div', 'span', 'img', 'canvas', 'svg', 'option', 'button']) {
- window[e] = function() {
- let args = [e].concat(Array.from(arguments));
- return create.apply(null, args);
- }
- }
- function downloadFile(content, title) {
- create('a', { download : title, href : content }).click();
- }
- class StateManager {
- constructor() {
- this.state = {}
- }
- init(key, value) {
- this.state[key] = {'value' : value, 'updaters' : []}
- }
- checkKey(key) {
- if (!this.state.hasOwnProperty(key)) {
- throw `Key '${key}' does not exist in state object.`
- }
- }
- update(key) {
-
- for (let updater of this.state[key].updaters) {
- let current = {};
- for (let updaterKey of updater.keys) {
- current[updaterKey] = this.state[updaterKey].value
- }
- updater.callback(current);
- }
- }
- set(key, value) {
- this.checkKey(key);
- this.state[key].value = value;
- this.update(key);
- }
- mutate(key, callback) {
- this.checkKey(key);
- callback(this.state[key].value);
- this.update(key);
- }
- // This should be used for immutable access,
- // but actually making a copy each time would probably be inefficient,
- // so just be disciplined for now.
- get(key) {
- this.checkKey(key);
- return this.state[key].value;
- }
- render(keys, callback) {
- let current = {}
- for (let key of keys) {
- this.checkKey(key);
- this.state[key].updaters.push({
- "callback": callback,
- "keys": keys
- });
- current[key] = this.state[key].value;
- }
- callback(current);
- }
- sync(stateKey, element, key) {
- this.init(stateKey, element[key]);
- let thisState = this;
- element.addEventListener('change', evt => {
- thisState.set(stateKey, evt.target[key]);
- });
- this.render([stateKey], current => {
- element[key] = current[stateKey];
- });
- this.set(stateKey, element[key]);
- }
- }
|