diff --git a/package.json b/package.json index d9ed0589..1945ecdc 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "less-loader": "^4.1.0", "localforage": "^1.7.2", "lodash": "^4.17.15", + "lz-string": "^1.4.4", "mini-css-extract-plugin": "^0.4.3", "opn": "^5.4.0", "parse-prop-types": "^0.3.0", diff --git a/src/index.js b/src/index.js index 7acc579c..286ae1f0 100644 --- a/src/index.js +++ b/src/index.js @@ -3,8 +3,10 @@ import { render } from 'react-dom'; import localforage from 'localforage'; import queryString from 'query-string'; import base64url from 'base64-url'; +import lzString from 'lz-string'; import dedent from 'dedent'; import Playroom from './Playroom/Playroom'; +import { createUrl } from '../utils'; const playroomConfig = (window.__playroomConfig__ = __PLAYROOM_GLOBAL__CONFIG__); const staticTypes = __PLAYROOM_GLOBAL__STATIC_TYPES__; @@ -24,17 +26,26 @@ const getCode = () => { const query = queryString.parse(hash); const exampleCode = dedent(playroomConfig.exampleCode || '').trim(); - return query.code - ? Promise.resolve(query.code ? base64url.decode(query.code) : exampleCode) - : store.getItem('code').then(code => code || exampleCode); + if (query.code) { + try { + const { code } = JSON.parse( + lzString.decompressFromEncodedURIComponent(query.code) + ); + + return Promise.resolve(code); + } catch (e) { + // backward compatibility + return Promise.resolve(base64url.decode(query.code)); + } + } + + return store.getItem('code').then(code => code || exampleCode); }; const updateCode = code => { - history.replaceState( - null, - null, - `#?code=${code ? base64url.encode(code) : ''}` - ); + const newUrl = createUrl({ code }); + + history.replaceState(null, null, newUrl); store.setItem('code', code); }; diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 00000000..75844066 --- /dev/null +++ b/utils/index.js @@ -0,0 +1,21 @@ +const lzString = require('lz-string'); + +const createUrl = ({ baseUrl, code }) => { + const data = JSON.stringify({ code }); + + const compressedData = lzString.compressToEncodedURIComponent(data); + + const path = `#?code=${compressedData}`; + + if (baseUrl) { + const trimmedBaseUrl = baseUrl.replace(/\/$/, ''); + + return `${trimmedBaseUrl}/${path}`; + } + + return path; +}; + +module.exports = { + createUrl +}; diff --git a/yarn.lock b/yarn.lock index 4af59022..981ef229 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6391,6 +6391,11 @@ lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3: pseudomap "^1.0.2" yallist "^2.1.2" +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= + macos-release@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb"