Use Base 62 for compactness. Note that this requires us to upgrade the
internals to handle bigger bases, even though we don't expose base > 36
elsewhere in the UI.
This fulfils the promise in the README that this feature exists.
+import DIGITS from './DIGITS';
import DynamicField from './DynamicField.react';
import React from 'react';
import type Value from './Field.react';
import Field from './Field.react';
import Label from './Label.react';
import Size from './Size.react';
import DynamicField from './DynamicField.react';
import React from 'react';
import type Value from './Field.react';
import Field from './Field.react';
import Label from './Label.react';
import Size from './Size.react';
+import convert from './convert';
+const SERIALIZATION_BASE = DIGITS.length;
+
+function getInitialValue() {
+ // Extract value from URL fragment, if present.
+ const value = window.location.hash.replace(/^#/, '');
+ const validator = new RegExp(`^[${DIGITS}]+$`);
+ if (!validator.test(value)) {
+ return null;
+ } else {
+ return {
+ base: SERIALIZATION_BASE,
+ value,
+ };
+ }
+}
+
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
+ value: getInitialValue(),
};
}
_onValueChange = (value: Value) => {
this.setState({value});
};
}
_onValueChange = (value: Value) => {
this.setState({value});
+ window.history.replaceState(
+ {},
+ '',
+ '#' + convert(value.value, value.base, SERIALIZATION_BASE)
+ );
--- /dev/null
+/**
+ * Copyright 2015-present Greg Hurrell. All rights reserved.
+ * Licensed under the terms of the MIT license.
+ *
+ * @flow
+ */
+
+'use strict';
+
+const DIGITS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+
+export default DIGITS;
+import DIGITS from './DIGITS';
import React from 'react';
import convert from './convert';
import cx from 'classnames';
import React from 'react';
import convert from './convert';
import cx from 'classnames';
value: React.PropTypes.string,
});
value: React.PropTypes.string,
});
-const DIGITS = '0123456789abcdefghijklmnopqrstuvwxyz';
-
/**
* Convert from `value` to `base`.
*/
/**
* Convert from `value` to `base`.
*/
+import DIGITS from './DIGITS';
+
/**
* Strips the leading prefix from `number` in `base` and returns the remaining
* part of the string.
/**
* Strips the leading prefix from `number` in `base` and returns the remaining
* part of the string.
+function parse(digit: string, base: number) {
+ if (base > 36 && base <= 62) {
+ const position = DIGITS.indexOf(digit);
+ return position !== -1 && position < base ? position + 1 : NaN;
+ } else {
+ return parseInt(digit, base);
+ }
+}
+
/**
* Breaks the string repsentation of `number` in `base` into an array of decimal
* digits (from least significant to most significant) for easier manipulation.
/**
* Breaks the string repsentation of `number` in `base` into an array of decimal
* digits (from least significant to most significant) for easier manipulation.
*/
export default function getDigits(number: string, base: number): Array<number> {
return stripPrefix(number, base).trim().split('').reverse().map(digit => {
*/
export default function getDigits(number: string, base: number): Array<number> {
return stripPrefix(number, base).trim().split('').reverse().map(digit => {
- const result = parseInt(digit, base);
+ const result = parse(digit, base);
if (isNaN(result)) {
throw new Error('Invalid digit `' + digit + '` for base `' + base + '`');
}
if (isNaN(result)) {
throw new Error('Invalid digit `' + digit + '` for base `' + base + '`');
}
+import DIGITS from './DIGITS';
+
+function encode(number: string, base: number) {
+ if (base > 36 && base <=62) {
+ return DIGITS[number - 1];
+ } else {
+ return number.toString(base);
+ }
+}
+
/**
* Turns an unpacked arbitrary-precision representation of a number, `digits`,
* (as produced by `getDigits`) back into a string representation in `base`.
/**
* Turns an unpacked arbitrary-precision representation of a number, `digits`,
* (as produced by `getDigits`) back into a string representation in `base`.
return digits
.slice()
.reverse()
return digits
.slice()
.reverse()
- .map(number => number.toString(base))
+ .map(number => encode(number, base))