From c588164190edd853dc314105f6bbe3d71a7feaf8 Mon Sep 17 00:00:00 2001 From: orangemug Date: Sat, 26 Oct 2019 18:27:11 +0100 Subject: [PATCH 01/14] console.log map errors. --- src/components/map/MapboxGlMap.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/map/MapboxGlMap.jsx b/src/components/map/MapboxGlMap.jsx index d5b221f..1530f4e 100644 --- a/src/components/map/MapboxGlMap.jsx +++ b/src/components/map/MapboxGlMap.jsx @@ -180,6 +180,10 @@ export default class MapboxGlMap extends React.Component { }) }) + map.on("error", e => { + console.log("ERROR", e); + }) + map.on("zoom", e => { this.setState({ zoom: map.getZoom() From 663f2956233799ef5a41257ee63ae4052e2c4ba9 Mon Sep 17 00:00:00 2001 From: orangemug Date: Sun, 27 Oct 2019 10:00:22 +0000 Subject: [PATCH 02/14] Added default protocol and stub in error. --- src/components/modals/SourcesModal.jsx | 39 ++++++++++++++++++++------ 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/components/modals/SourcesModal.jsx b/src/components/modals/SourcesModal.jsx index 2d5c8ba..ad66243 100644 --- a/src/components/modals/SourcesModal.jsx +++ b/src/components/modals/SourcesModal.jsx @@ -112,10 +112,12 @@ class AddSource extends React.Component { defaultSource(mode) { const source = (this.state || {}).source || {} + const {protocol} = window.location; + switch(mode) { case 'geojson_url': return { type: 'geojson', - data: 'http://localhost:3000/geojson.json' + data: `${protocol}//localhost:3000/geojson.json` } case 'geojson_json': return { type: 'geojson', @@ -123,31 +125,31 @@ class AddSource extends React.Component { } case 'tilejson_vector': return { type: 'vector', - url: source.url || 'http://localhost:3000/tilejson.json' + url: source.url || `${protocol}//localhost:3000/tilejson.json` } case 'tilexyz_vector': return { type: 'vector', - tiles: source.tiles || ['http://localhost:3000/{x}/{y}/{z}.pbf'], + tiles: source.tiles || [`${protocol}//localhost:3000/{x}/{y}/{z}.pbf`], minZoom: source.minzoom || 0, maxZoom: source.maxzoom || 14 } case 'tilejson_raster': return { type: 'raster', - url: source.url || 'http://localhost:3000/tilejson.json' + url: source.url || `${protocol}//localhost:3000/tilejson.json` } case 'tilexyz_raster': return { type: 'raster', - tiles: source.tiles || ['http://localhost:3000/{x}/{y}/{z}.pbf'], + tiles: source.tiles || [`${protocol}//localhost:3000/{x}/{y}/{z}.pbf`], minzoom: source.minzoom || 0, maxzoom: source.maxzoom || 14 } case 'tilejson_raster-dem': return { type: 'raster-dem', - url: source.url || 'http://localhost:3000/tilejson.json' + url: source.url || `${protocol}//localhost:3000/tilejson.json` } case 'tilexyz_raster-dem': return { type: 'raster-dem', - tiles: source.tiles || ['http://localhost:3000/{x}/{y}/{z}.pbf'], + tiles: source.tiles || [`${protocol}//localhost:3000/{x}/{y}/{z}.pbf`], minzoom: source.minzoom || 0, maxzoom: source.maxzoom || 14 } @@ -155,6 +157,18 @@ class AddSource extends React.Component { } } + onAdd = () => { + this.props.onAdd(this.state.sourceId, this.state.source); + } + + onChangeSource = (source) => { + // let error = "CORs policy won't allow fetching resources served over http from https"; + this.setState({ + source, + error, + }); + } + render() { return
@@ -180,13 +194,20 @@ class AddSource extends React.Component { /> this.setState({ source: src })} + onChange={this.onChangeSource} mode={this.state.mode} source={this.state.source} /> + {this.state.error && +
+ Error: {this.state.error} +
+ }
From 566201fb452a9da67438e79f7b3259c18ad45f1b Mon Sep 17 00:00:00 2001 From: orangemug Date: Sun, 27 Oct 2019 17:08:23 +0000 Subject: [PATCH 03/14] Added UrlInput component to tidy things up a little. --- src/components/inputs/StringInput.jsx | 9 ++- src/components/inputs/UrlInput.jsx | 61 +++++++++++++++++++++ src/components/modals/SourcesModal.jsx | 15 +---- src/components/sources/SourceTypeEditor.jsx | 5 +- src/components/util/SmallError.jsx | 20 +++++++ src/components/util/SmallError.scss | 7 +++ src/styles/_vars.scss | 23 ++++++++ src/styles/index.scss | 24 +------- 8 files changed, 126 insertions(+), 38 deletions(-) create mode 100644 src/components/inputs/UrlInput.jsx create mode 100644 src/components/util/SmallError.jsx create mode 100644 src/components/util/SmallError.scss create mode 100644 src/styles/_vars.scss diff --git a/src/components/inputs/StringInput.jsx b/src/components/inputs/StringInput.jsx index e160d69..87bdd31 100644 --- a/src/components/inputs/StringInput.jsx +++ b/src/components/inputs/StringInput.jsx @@ -8,10 +8,15 @@ class StringInput extends React.Component { style: PropTypes.object, default: PropTypes.string, onChange: PropTypes.func, + onInput: PropTypes.func, multi: PropTypes.bool, required: PropTypes.bool, } + static defaultProps = { + onInput: () => {}, + } + constructor(props) { super(props) this.state = { @@ -57,7 +62,9 @@ class StringInput extends React.Component { this.setState({ editing: true, value: e.target.value - }) + }, () => { + this.props.onInput(this.state.value); + }); }, onBlur: () => { if(this.state.value!==this.props.value) { diff --git a/src/components/inputs/UrlInput.jsx b/src/components/inputs/UrlInput.jsx new file mode 100644 index 0000000..b729b07 --- /dev/null +++ b/src/components/inputs/UrlInput.jsx @@ -0,0 +1,61 @@ +import React from 'react' +import PropTypes from 'prop-types' +import StringInput from './StringInput' +import SmallError from '../util/SmallError' + +class UrlInput extends React.Component { + static propTypes = { + "data-wd-key": PropTypes.string, + value: PropTypes.string, + style: PropTypes.object, + default: PropTypes.string, + onChange: PropTypes.func, + multi: PropTypes.bool, + required: PropTypes.bool, + } + + state = { + error: null, + } + + onInput = (url) => { + let error; + const getProtocol = (url) => { + try { + const urlObj = new URL(url); + return urlObj.protocol; + } + catch (err) { + return undefined; + } + }; + const protocol = getProtocol(url); + if ( + protocol && + protocol === "https:" && + window.location.protocol !== "http:" + ) { + error = ( + + CORs policy won't allow fetching resources served over http from https, use a https:// domain + + ); + } + + this.setState({error}); + } + + render () { + return ( +
+ + {this.state.error} +
+ ); + } +} + +export default UrlInput diff --git a/src/components/modals/SourcesModal.jsx b/src/components/modals/SourcesModal.jsx index ad66243..e291607 100644 --- a/src/components/modals/SourcesModal.jsx +++ b/src/components/modals/SourcesModal.jsx @@ -158,15 +158,12 @@ class AddSource extends React.Component { } onAdd = () => { - this.props.onAdd(this.state.sourceId, this.state.source); + const {source, sourceId} = this.state; + this.props.onAdd(sourceId, source); } onChangeSource = (source) => { - // let error = "CORs policy won't allow fetching resources served over http from https"; - this.setState({ - source, - error, - }); + this.setState({source}); } render() { @@ -198,15 +195,9 @@ class AddSource extends React.Component { mode={this.state.mode} source={this.state.source} /> - {this.state.error && -
- Error: {this.state.error} -
- } diff --git a/src/components/sources/SourceTypeEditor.jsx b/src/components/sources/SourceTypeEditor.jsx index 83672e1..12094c0 100644 --- a/src/components/sources/SourceTypeEditor.jsx +++ b/src/components/sources/SourceTypeEditor.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import {latest} from '@mapbox/mapbox-gl-style-spec' import InputBlock from '../inputs/InputBlock' import StringInput from '../inputs/StringInput' +import UrlInput from '../inputs/UrlInput' import NumberInput from '../inputs/NumberInput' import SelectInput from '../inputs/SelectInput' import JSONEditor from '../layers/JSONEditor' @@ -18,7 +19,7 @@ class TileJSONSourceEditor extends React.Component { render() { return
- this.props.onChange({ ...this.props.source, @@ -52,7 +53,7 @@ class TileURLSourceEditor extends React.Component { const tiles = this.props.source.tiles || [] return tiles.map((tileUrl, tileIndex) => { return - diff --git a/src/components/util/SmallError.jsx b/src/components/util/SmallError.jsx new file mode 100644 index 0000000..03d9c78 --- /dev/null +++ b/src/components/util/SmallError.jsx @@ -0,0 +1,20 @@ +import React from 'react' +import PropTypes from 'prop-types' +import './SmallError.scss'; + + +class SmallError extends React.Component { + static propTypes = { + children: PropTypes.node, + } + + render () { + return ( +
+ Error: {this.props.children} +
+ ); + } +} + +export default SmallError diff --git a/src/components/util/SmallError.scss b/src/components/util/SmallError.scss new file mode 100644 index 0000000..5433091 --- /dev/null +++ b/src/components/util/SmallError.scss @@ -0,0 +1,7 @@ +@import '../../styles/vars'; + +.SmallError { + color: #E57373; + font-size: $font-size-5; + margin-top: $margin-2 +} diff --git a/src/styles/_vars.scss b/src/styles/_vars.scss new file mode 100644 index 0000000..7cb3d17 --- /dev/null +++ b/src/styles/_vars.scss @@ -0,0 +1,23 @@ +$color-black: #191b20; +$color-gray: #222429; +$color-midgray: #303237; +$color-lowgray: #a4a4a4; +$color-white: #f0f0f0; +$color-red: #cf4a4a; +$color-green: #53b972; +$margin-1: 3px; +$margin-2: 5px; +$margin-3: 10px; +$margin-4: 30px; +$margin-5: 40px; +$font-size-1: 24px; +$font-size-2: 20px; +$font-size-3: 18px; +$font-size-4: 16px; +$font-size-5: 14px; +$font-size-6: 12px; +$font-family: Roboto, sans-serif; + +$toolbar-height: 40px; +$toolbar-offset: 0; + diff --git a/src/styles/index.scss b/src/styles/index.scss index 49af915..759b73c 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -1,26 +1,4 @@ -$color-black: #191b20; -$color-gray: #222429; -$color-midgray: #303237; -$color-lowgray: #a4a4a4; -$color-white: #f0f0f0; -$color-red: #cf4a4a; -$color-green: #53b972; -$margin-1: 3px; -$margin-2: 5px; -$margin-3: 10px; -$margin-4: 30px; -$margin-5: 40px; -$font-size-1: 24px; -$font-size-2: 20px; -$font-size-3: 18px; -$font-size-4: 16px; -$font-size-5: 14px; -$font-size-6: 12px; -$font-family: Roboto, sans-serif; - -$toolbar-height: 40px; -$toolbar-offset: 0; - +@import 'vars'; @import 'mixins'; @import 'reset'; @import 'base'; From f39fb34f36449b54cf31302066b114aaa87c1430 Mon Sep 17 00:00:00 2001 From: orangemug Date: Sun, 27 Oct 2019 17:15:17 +0000 Subject: [PATCH 04/14] Protocol logic and lint fixes. --- src/components/inputs/UrlInput.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/inputs/UrlInput.jsx b/src/components/inputs/UrlInput.jsx index b729b07..04bb531 100644 --- a/src/components/inputs/UrlInput.jsx +++ b/src/components/inputs/UrlInput.jsx @@ -32,12 +32,12 @@ class UrlInput extends React.Component { const protocol = getProtocol(url); if ( protocol && - protocol === "https:" && - window.location.protocol !== "http:" + protocol === "http:" && + window.location.protocol === "https:" ) { error = ( - CORs policy won't allow fetching resources served over http from https, use a https:// domain + CORs policy won't allow fetching resources served over http from https, use a https:// domain ); } From a51442921ae6af55e63af0a8702073a664d7482c Mon Sep 17 00:00:00 2001 From: orangemug Date: Sun, 27 Oct 2019 17:19:03 +0000 Subject: [PATCH 05/14] Fix font-size inline with the rest of the UI. --- src/components/util/SmallError.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/util/SmallError.scss b/src/components/util/SmallError.scss index 5433091..1111282 100644 --- a/src/components/util/SmallError.scss +++ b/src/components/util/SmallError.scss @@ -2,6 +2,6 @@ .SmallError { color: #E57373; - font-size: $font-size-5; + font-size: $font-size-6; margin-top: $margin-2 } From f0371b41b1a908c9de7212ea90b7755478c241fb Mon Sep 17 00:00:00 2001 From: orangemug Date: Sun, 27 Oct 2019 17:27:50 +0000 Subject: [PATCH 06/14] Also validate on constructor --- src/components/inputs/UrlInput.jsx | 62 +++++++++++++++++------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/components/inputs/UrlInput.jsx b/src/components/inputs/UrlInput.jsx index 04bb531..971d241 100644 --- a/src/components/inputs/UrlInput.jsx +++ b/src/components/inputs/UrlInput.jsx @@ -3,6 +3,34 @@ import PropTypes from 'prop-types' import StringInput from './StringInput' import SmallError from '../util/SmallError' + +function validate (url) { + let error; + const getProtocol = (url) => { + try { + const urlObj = new URL(url); + return urlObj.protocol; + } + catch (err) { + return undefined; + } + }; + const protocol = getProtocol(url); + if ( + protocol && + protocol === "http:" && + window.location.protocol === "https:" + ) { + error = ( + + CORs policy won't allow fetching resources served over http from https, use a https:// domain + + ); + } + + return error; +} + class UrlInput extends React.Component { static propTypes = { "data-wd-key": PropTypes.string, @@ -14,35 +42,17 @@ class UrlInput extends React.Component { required: PropTypes.bool, } - state = { - error: null, + constructor (props) { + super(props); + this.state = { + error: validate(props.value) + }; } onInput = (url) => { - let error; - const getProtocol = (url) => { - try { - const urlObj = new URL(url); - return urlObj.protocol; - } - catch (err) { - return undefined; - } - }; - const protocol = getProtocol(url); - if ( - protocol && - protocol === "http:" && - window.location.protocol === "https:" - ) { - error = ( - - CORs policy won't allow fetching resources served over http from https, use a https:// domain - - ); - } - - this.setState({error}); + this.setState({ + error: validate(url) + }); } render () { From e728e5f7e43f254acb7039e6c00bbedf2f8905b6 Mon Sep 17 00:00:00 2001 From: orangemug Date: Sun, 27 Oct 2019 17:35:56 +0000 Subject: [PATCH 07/14] Exposed onInput in --- src/components/inputs/UrlInput.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/inputs/UrlInput.jsx b/src/components/inputs/UrlInput.jsx index 971d241..040c2b5 100644 --- a/src/components/inputs/UrlInput.jsx +++ b/src/components/inputs/UrlInput.jsx @@ -42,6 +42,10 @@ class UrlInput extends React.Component { required: PropTypes.bool, } + static defaultProps = { + onInput: () => {}, + } + constructor (props) { super(props); this.state = { @@ -53,6 +57,7 @@ class UrlInput extends React.Component { this.setState({ error: validate(url) }); + this.props.onInput(url); } render () { From 2e017d252aa6420f2fadadfcf533fc3363500f6d Mon Sep 17 00:00:00 2001 From: orangemug Date: Sun, 27 Oct 2019 17:36:20 +0000 Subject: [PATCH 08/14] Added to open modal. --- src/components/modals/OpenModal.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/modals/OpenModal.jsx b/src/components/modals/OpenModal.jsx index d2c6477..dff6f80 100644 --- a/src/components/modals/OpenModal.jsx +++ b/src/components/modals/OpenModal.jsx @@ -4,6 +4,7 @@ import LoadingModal from './LoadingModal' import Modal from './Modal' import Button from '../Button' import FileReaderInput from 'react-file-reader-input' +import UrlInput from '../inputs/UrlInput' import {MdFileUpload} from 'react-icons/md' import {MdAddCircleOutline} from 'react-icons/md' @@ -160,9 +161,9 @@ class OpenModal extends React.Component { this.props.onOpenToggle(); } - onChangeUrl = () => { + onChangeUrl = (url) => { this.setState({ - styleUrl: this.styleUrlElement.value + styleUrl: url, }); } @@ -209,14 +210,13 @@ class OpenModal extends React.Component {

Load from a URL. Note that the URL must have CORS enabled.

- this.styleUrlElement = input} className="maputnik-input" - placeholder="Enter URL..." + default="Enter URL..." value={this.state.styleUrl} - onChange={this.onChangeUrl} + onInput={this.onChangeUrl} />