Permalink
Browse files

Add url hash params to link to a set of options.

Fixes #6.
  • Loading branch information...
1 parent 01a2000 commit 238ad1b01a6efe243447dfd26ea2015fdeb4b3b0 @oliverzheng committed May 31, 2015
View
@@ -2,11 +2,73 @@
var MainComponent = require('./components/MainComponent');
var React = require('react');
-
+var qs = require('qs');
var attachFastClick = require('fastclick');
+var LocationBar = require('location-bar');
+var serialization = require('./serialization');
+var Options = require('./how/Options');
+
attachFastClick(document.body);
-React.render(
- <MainComponent />,
+var locationBar = new LocationBar();
+
+function onOptionsChange(
+ content: Options.Content,
+ container: Options.Container,
+ horizontalAlignment: Options.HorizontalAlignment,
+ verticalAlignment: Options.VerticalAlignment,
+ browserSupport: Options.BrowserSupport
+) {
+ var serialized = serialization.serializeOptions(
+ content,
+ container,
+ horizontalAlignment,
+ verticalAlignment,
+ browserSupport
+ );
+ var serializedString = qs.stringify(serialized);
+ // qs uses brackets[] for sub objects, but that's ugly. It supports parsing
+ // dot notation, but not generating it. Let's just convert it over, since we
+ // don't have any real user-inputable data that can contain [] anyway.
+ var serializedString = serializedString
+ .replace(/%5B/g, '.')
+ .replace(/%5D/g, '');
+ locationBar.update(serializedString);
+}
+
+var component = React.render(
+ <MainComponent
+ onOptionsChange={onOptionsChange}
+ />,
document.getElementById('app')
);
+
+locationBar.onChange((path) => {
+ var serialized = qs.parse(path);
+ if (!serialized) {
+ return;
+ }
+
+ var options = serialization.deserializeOptions(serialized);
+ if (!options) {
+ return;
+ }
+
+ var {
+ content,
+ container,
+ horizontalAlignment,
+ verticalAlignment,
+ browserSupport,
+ } = options;
+
+ component.setOptions(
+ content,
+ container,
+ horizontalAlignment,
+ verticalAlignment,
+ browserSupport
+ );
+});
+
+locationBar.start();
@@ -14,10 +14,18 @@ class AlignmentComponent extends React.Component {
return this._horizontal.getValue();
}
+ setHorizontalAlignment(alignment: Options.HorizontalAlignment) {
+ this._horizontal.select(alignment);
+ }
+
getVerticalAlignment(): ?Options.VerticalAlignment {
return this._vertical.getValue();
}
+ setVerticalAlignment(alignment: Options.VerticalAlignment) {
+ this._vertical.select(alignment);
+ }
+
render(): ?ReactElement {
return (
<div>
@@ -14,6 +14,8 @@ class BrowserSupportComponent extends React.Component {
};
}
+ _radioList: RadioListComponent;
+
state: {
browserSupport: Options.BrowserSupport;
};
@@ -22,6 +24,18 @@ class BrowserSupportComponent extends React.Component {
return this.state.browserSupport;
}
+ setBrowserSupport(browserSupport: Options.BrowserSupport) {
+ this.setState({browserSupport});
+ // Only do IE for now
+ var browserVersion = browserSupport.browserVersionsRequired[0];
+ if (browserVersion) {
+ this._radioList.select({
+ browser: browserVersion.browser,
+ version: browserVersion.minVersion,
+ });
+ }
+ }
+
_handleBrowserSupportChange(
support: { browser: Options.Browser; version: ?string; }
) {
@@ -31,6 +45,13 @@ class BrowserSupportComponent extends React.Component {
this.setState({browserSupport: this.state.browserSupport});
}
+ _compareBrowserSupports(
+ s1: {browser: Options.Browser; version: ?string;},
+ s2: {browser: Options.Browser; version: ?string;}
+ ): bool {
+ return s1.browser === s2.browser && s1.version === s2.version;
+ }
+
render(): ?ReactElement {
var browser = Options.Browser.IE;
var noSupport = {
@@ -44,6 +65,8 @@ class BrowserSupportComponent extends React.Component {
What is the minimum version of {browser.name} you need to support?
</p>
<RadioListComponent
+ ref={(c) => this._radioList = c}
+ compareValues={this._compareBrowserSupports}
onChange={this._handleBrowserSupportChange.bind(this)}>
<RadioComponent labelText="None" value={noSupport} />
{browser.versions.map(version => {
@@ -15,6 +15,11 @@ class ContainerComponent extends React.Component {
);
}
+ setContainer(container: Options.Container) {
+ this._divSize.setWidth(container.width);
+ this._divSize.setHeight(container.height);
+ }
+
render(): ?ReactElement {
return (
<div>
@@ -1,5 +1,7 @@
/** @flow */
+var invariant = require('invariant');
+
var React = require('react');
var LengthComponent = require('./LengthComponent');
var DivSizeComponent = require('./DivSizeComponent');
@@ -25,6 +27,7 @@ class ContentComponent extends React.Component {
contentType: ?ContentType;
textLines: ?number;
};
+ _typeRadioList: ?RadioListComponent<ContentType>;
_divSize: ?DivSizeComponent;
_textLines: ?TextLinesComponent;
_textFontSize: ?TextFontSizeComponent;
@@ -65,6 +68,48 @@ class ContentComponent extends React.Component {
return null;
}
+ setContent(content: Options.Content) {
+ var contentText = content.text;
+
+ var contentType = contentText ? ContentType.TEXT : ContentType.DIV;
+ var typeRadioList = this._typeRadioList;
+ invariant(typeRadioList, 'should have this');
+ typeRadioList.select(contentType);
+
+ if (contentText) {
+ this.setState({
+ contentType: contentType,
+ textLines: contentText.lines,
+ }, () => {
+ invariant(contentText, 'flow');
+
+ var textLinesComponent = this._textLines;
+ invariant(textLinesComponent, 'should have text lines component');
+ textLinesComponent.setLines(contentText.lines);
+
+ var fontSizeComponent = this._textFontSize;
+ if (fontSizeComponent) {
+ fontSizeComponent.setFontSize(contentText.fontSize);
+ }
+
+ var lineHeightComponent = this._textLineHeight;
+ if (lineHeightComponent) {
+ lineHeightComponent.setLineHeight(contentText.lineHeight);
+ }
+ });
+ } else {
+ this.setState({
+ contentType: contentType,
+ }, () => {
+ var divSizeComponent = this._divSize;
+ invariant(divSizeComponent, 'should have div size component');
+
+ divSizeComponent.setWidth(content.width);
+ divSizeComponent.setHeight(content.height);
+ });
+ }
+ }
+
_handleTypeChange(contentType: ContentType) {
this.setState({contentType});
}
@@ -111,7 +156,9 @@ class ContentComponent extends React.Component {
<div>
<h2>Content</h2>
<p>What do you want to center?</p>
- <RadioListComponent onChange={this._handleTypeChange.bind(this)}>
+ <RadioListComponent
+ ref={(c) => this._typeRadioList = c}
+ onChange={this._handleTypeChange.bind(this)}>
<RadioComponent labelText="Text" value={ContentType.TEXT}>
Just text, or an inline-level block of text and images.
</RadioComponent>
@@ -7,17 +7,37 @@ var RadioComponent = require('./RadioComponent');
var RadioListComponent = require('./RadioListComponent');
class DivSizeComponent extends React.Component {
+ _widthRadioList: RadioListComponent<bool>;
+ _heightRadioList: RadioListComponent<bool>;
_width: LengthComponent;
_height: LengthComponent;
getWidth(): ?Options.Length {
return this._width.getLength();
}
+ setWidth(length: ?Options.Length) {
+ if (length) {
+ this._widthRadioList.select(true);
+ this._width.setLength(length);
+ } else {
+ this._widthRadioList.select(false);
+ }
+ }
+
getHeight(): ?Options.Length {
return this._height.getLength();
}
+ setHeight(length: ?Options.Length) {
+ if (length) {
+ this._heightRadioList.select(true);
+ this._height.setLength(length);
+ } else {
+ this._heightRadioList.select(false);
+ }
+ }
+
_handleWidthKnown(known: bool) {
if (!known) {
if (this.props.onWidthChange) {
@@ -44,7 +64,9 @@ class DivSizeComponent extends React.Component {
return (
<div>
<h3>Width</h3>
- <RadioListComponent onChange={this._handleWidthKnown.bind(this)}>
+ <RadioListComponent
+ ref={(c) => this._widthRadioList = c}
+ onChange={this._handleWidthKnown.bind(this)}>
<RadioComponent labelText="Known" value={true}>
<LengthComponent
onChange={this.props.onWidthChange}
@@ -57,7 +79,9 @@ class DivSizeComponent extends React.Component {
</RadioListComponent>
<h3>Height</h3>
- <RadioListComponent onChange={this._handleHeightKnown.bind(this)}>
+ <RadioListComponent
+ ref={(c) => this._heightRadioList = c}
+ onChange={this._handleHeightKnown.bind(this)}>
<RadioComponent labelText="Known" value={true}>
<LengthComponent
onChange={this.props.onHeightChange}
@@ -25,6 +25,14 @@ class LengthComponent extends React.Component {
return new Options.Length(this.state.value, this.state.type);
}
+ setLength(length: Options.Length) {
+ this.setState({
+ value: length.value,
+ type: length.lengthType,
+ });
+ this._radioList.select(length.lengthType);
+ }
+
selectDefaultType() {
this._radioList.select(Options.LengthType.PIXEL);
}
@@ -4,6 +4,7 @@ var React = require('react');
var OptionsComponent = require('./OptionsComponent');
var CodeComponent = require('./CodeComponent');
+var Options = require('../how/Options');
var findMethod = require('../how/findMethod');
class MainComponent extends React.Component {
@@ -35,6 +36,32 @@ class MainComponent extends React.Component {
} else {
this._code.setNoMethod();
}
+
+ if (this.props.onOptionsChange) {
+ this.props.onOptionsChange(
+ content,
+ container,
+ horizontalAlignment,
+ verticalAlignment,
+ browserSupport
+ );
+ }
+ }
+
+ setOptions(
+ content: Options.Content,
+ container: Options.Container,
+ horizontalAlignment: Options.HorizontalAlignment,
+ verticalAlignment: Options.VerticalAlignment,
+ browserSupport: Options.BrowserSupport
+ ) {
+ this._options.setOptions(
+ content,
+ container,
+ horizontalAlignment,
+ verticalAlignment,
+ browserSupport
+ );
}
render(): ?ReactElement {
@@ -80,4 +107,8 @@ class MainComponent extends React.Component {
}
}
+MainComponent.propTypes = {
+ onOptionsChange: React.PropTypes.func,
+};
+
module.exports = MainComponent;
@@ -46,8 +46,21 @@ class OptionsComponent extends React.Component {
return this._browserSupport.getBrowserSupport();
}
+ setOptions(
+ content: Options.Content,
+ container: Options.Container,
+ horizontalAlignment: Options.HorizontalAlignment,
+ verticalAlignment: Options.VerticalAlignment,
+ browserSupport: Options.BrowserSupport
+ ) {
+ this._content.setContent(content);
+ this._container.setContainer(container);
+ this._alignment.setHorizontalAlignment(horizontalAlignment);
+ this._alignment.setVerticalAlignment(verticalAlignment);
+ this._browserSupport.setBrowserSupport(browserSupport);
+ }
+
render(): ?ReactElement {
- // TODO add browser support back in when we need it.
return (
<div>
<ContentComponent ref={(c) => this._content = c} />
Oops, something went wrong.

0 comments on commit 238ad1b

Please sign in to comment.