148 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// store code in the URL
 | 
						|
window.common = (function(global) {
 | 
						|
  const {
 | 
						|
    encodeURIComponent: encode,
 | 
						|
    decodeURIComponent: decode,
 | 
						|
    location,
 | 
						|
    history,
 | 
						|
    common = { init: [] }
 | 
						|
  } = global;
 | 
						|
 | 
						|
  const {
 | 
						|
    replaceScriptTags,
 | 
						|
    replaceSafeTags,
 | 
						|
    replaceFormActionAttr,
 | 
						|
    replaceFccfaaAttr
 | 
						|
  } = common;
 | 
						|
 | 
						|
  const queryRegex = /^(\?|#\?)/;
 | 
						|
  function encodeFcc(val) {
 | 
						|
    return replaceScriptTags(replaceFormActionAttr(val));
 | 
						|
  }
 | 
						|
 | 
						|
  function decodeFcc(val) {
 | 
						|
    return replaceSafeTags(replaceFccfaaAttr(val));
 | 
						|
  }
 | 
						|
 | 
						|
  var codeUri = {
 | 
						|
    encode: function(code) {
 | 
						|
      return encode(code);
 | 
						|
    },
 | 
						|
    decode: function(code) {
 | 
						|
      try {
 | 
						|
        return decode(code);
 | 
						|
      } catch (ignore) {
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
    },
 | 
						|
    isInQuery: function(query) {
 | 
						|
      var decoded = codeUri.decode(query);
 | 
						|
      if (!decoded || typeof decoded.split !== 'function') {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
      return decoded
 | 
						|
        .replace(queryRegex, '')
 | 
						|
        .split('&')
 | 
						|
        .reduce(function(found, param) {
 | 
						|
          var key = param.split('=')[0];
 | 
						|
          if (key === 'solution') {
 | 
						|
            return true;
 | 
						|
          }
 | 
						|
          return found;
 | 
						|
        }, false);
 | 
						|
    },
 | 
						|
    isAlive: function() {
 | 
						|
      return codeUri.enabled &&
 | 
						|
        codeUri.isInQuery(location.search) ||
 | 
						|
        codeUri.isInQuery(location.hash);
 | 
						|
    },
 | 
						|
    getKeyInQuery(query, keyToFind = '') {
 | 
						|
      return query
 | 
						|
        .split('&')
 | 
						|
        .reduce(function(oldValue, param) {
 | 
						|
          var key = param.split('=')[0];
 | 
						|
          var value = param
 | 
						|
            .split('=')
 | 
						|
            .slice(1)
 | 
						|
            .join('=');
 | 
						|
 | 
						|
          if (key === keyToFind) {
 | 
						|
            return value;
 | 
						|
          }
 | 
						|
          return oldValue;
 | 
						|
        }, null);
 | 
						|
    },
 | 
						|
    getSolutionFromQuery(query = '') {
 | 
						|
      return decodeFcc(
 | 
						|
        codeUri.decode(codeUri.getKeyInQuery(query, 'solution'))
 | 
						|
      );
 | 
						|
    },
 | 
						|
    parse: function() {
 | 
						|
      if (!codeUri.enabled) {
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
      var query;
 | 
						|
      if (location.search && codeUri.isInQuery(location.search)) {
 | 
						|
        query = location.search.replace(/^\?/, '');
 | 
						|
 | 
						|
        if (history && typeof history.replaceState === 'function') {
 | 
						|
          history.replaceState(
 | 
						|
            history.state,
 | 
						|
            null,
 | 
						|
            location.href.split('?')[0]
 | 
						|
          );
 | 
						|
          location.hash = '#?' + encodeFcc(query);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        query = location.hash.replace(/^\#\?/, '');
 | 
						|
      }
 | 
						|
 | 
						|
      if (!query) {
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
 | 
						|
      return this.getSolutionFromQuery(query);
 | 
						|
    },
 | 
						|
    querify: function(solution) {
 | 
						|
      if (!codeUri.enabled) {
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
      if (history && typeof history.replaceState === 'function') {
 | 
						|
        // grab the url up to the query
 | 
						|
        // destroy any hash symbols still clinging to life
 | 
						|
        const url = (location.href.split('?')[0]).replace(/(#*)$/, '');
 | 
						|
        history.replaceState(
 | 
						|
          history.state,
 | 
						|
          null,
 | 
						|
          url +
 | 
						|
            '#?' +
 | 
						|
            (codeUri.shouldRun() ? '' : 'run=disabled&') +
 | 
						|
            'solution=' +
 | 
						|
            codeUri.encode(encodeFcc(solution))
 | 
						|
        );
 | 
						|
      } else {
 | 
						|
        location.hash = '?solution=' +
 | 
						|
          codeUri.encode(encodeFcc(solution));
 | 
						|
      }
 | 
						|
 | 
						|
      return solution;
 | 
						|
    },
 | 
						|
    enabled: true,
 | 
						|
    shouldRun() {
 | 
						|
      return !this.getKeyInQuery(
 | 
						|
        (location.search || location.hash).replace(queryRegex, ''),
 | 
						|
        'run'
 | 
						|
      );
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  common.init.push(function() {
 | 
						|
    codeUri.parse();
 | 
						|
  });
 | 
						|
 | 
						|
  common.codeUri = codeUri;
 | 
						|
  common.shouldRun = () => codeUri.shouldRun();
 | 
						|
 | 
						|
  return common;
 | 
						|
}(window));
 |