diff --git a/lib/routing.js b/lib/routing.js index f3b4a36..f28d05d 100644 --- a/lib/routing.js +++ b/lib/routing.js @@ -9,11 +9,35 @@ const mapper = new Morph({ if (v == null) return undefined if (v === 'false') return false return Boolean(v) + }, + parse: v => { + try { + const x = JSON.parse(v) + return x + } catch (e) { + return v + } + }, + decode: v => { + if (v == null) return undefined + try { + return decodeURIComponent(v) + } catch (e) { + return v + } + }, + encode: v => { + if (v == null) return undefined + try { + return encodeURIComponent(v) + } catch (e) { + return v + } } } }) -const mappings = [ +const readMappings = [ { field: 'bg:backgroundColor' }, { field: 't:theme' }, { field: 'wt:windowTheme' }, @@ -30,23 +54,36 @@ const mappings = [ { field: 'fs:fontSize' }, { field: 'lh:lineHeight' }, { field: 'si:squaredImage', type: 'bool' }, - { field: 'code:code' }, { field: 'es:exportSize' }, { field: 'wm:watermark', type: 'bool' }, { field: 'copy', type: 'bool' }, { field: 'readonly', type: 'bool' }, { field: 'id' }, - { field: 'highlights' } + { field: 'highlights', type: 'parse' }, + { field: 'code', type: 'decode' } ] -const reverseMappings = mappings.map(mapping => - Object.assign({}, mapping, { - field: mapping.field - .split(':') - .reverse() - .join(':') - }) -) +const writeMappings = [ + { field: 'backgroundColor:bg' }, + { field: 'theme:t' }, + { field: 'windowTheme:wt' }, + { field: 'language:l' }, + { field: 'dropShadow:ds', type: 'bool' }, + { field: 'dropShadowOffsetY:dsyoff' }, + { field: 'dropShadowBlurRadius:dsblur' }, + { field: 'windowControls:wc', type: 'bool' }, + { field: 'widthAdjustment:wa', type: 'bool' }, + { field: 'paddingVertical:pv' }, + { field: 'paddingHorizontal:ph' }, + { field: 'lineNumbers:ln', type: 'bool' }, + { field: 'fontFamily:fm' }, + { field: 'fontSize:fs' }, + { field: 'lineHeight:lh' }, + { field: 'squaredImage:si', type: 'bool' }, + { field: 'exportSize:es' }, + { field: 'watermark:wm', type: 'bool' }, + { field: 'code', type: 'encode' } +] export const serializeState = state => { const stateString = encodeURIComponent(JSON.stringify(state)) @@ -82,8 +119,7 @@ export const getRouteState = router => { } export const updateRouteState = (router, state) => { - const mappedState = mapper.map(reverseMappings, state) - serializeCode(mappedState) + const mappedState = mapper.map(writeMappings, state) // calls `encodeURIComponent` on each key internally // const query = qs.stringify(mappedState) @@ -105,10 +141,7 @@ const getQueryStringObject = query => { return deserializeState(query.state) } - const state = mapper.map(mappings, query) - - deserializeHighlights(state) - deserializeCode(state) + const state = mapper.map(readMappings, query) Object.keys(state).forEach(key => { if (state[key] === '') state[key] = undefined @@ -121,27 +154,3 @@ function getQueryStringState(query) { const queryParams = getQueryStringObject(query) return Object.keys(queryParams).length ? queryParams : {} } - -function serializeCode(state) { - try { - if (state.code) state.code = encodeURIComponent(state.code) - } catch (e) { - // encoding errors should not crash the app - } -} - -function deserializeCode(state) { - try { - if (state.code) state.code = decodeURIComponent(state.code) - } catch (e) { - // decoding errors should not crash the app - } -} - -function deserializeHighlights(state) { - try { - if (state.highlights) state.highlights = JSON.parse(state.highlights) - } catch (e) { - // parsing errors should not crash the app - } -} diff --git a/pages/index.js b/pages/index.js index 6c43738..c55a2cd 100644 --- a/pages/index.js +++ b/pages/index.js @@ -23,7 +23,7 @@ class Index extends React.Component { onEditorUpdate = debounce( state => { - updateRouteState(this.props.router, omit(state, ['themes'])) + updateRouteState(this.props.router, state) saveSettings( localStorage, omit(state, ['code', 'backgroundImage', 'backgroundImageSelection', 'filename', 'themes'])