Merge remote-tracking branch 'upstream/master' into fix/lighthouse-errors

This commit is contained in:
orangemug 2017-11-29 11:14:54 +00:00
commit 2d87e162f1
12 changed files with 13293 additions and 27 deletions

View file

@ -3,24 +3,24 @@ addons:
firefox: latest firefox: latest
matrix: matrix:
include: include:
# - os: linux
# node_js: "4"
- os: linux
env: CXX=g++-4.8
node_js: "5"
- os: linux - os: linux
node_js: "6" node_js: "6"
- os: linux - os: linux
env: CXX=g++-4.8 env: CXX=g++-4.8
node_js: "7" node_js: "7"
# - os: osx - os: linux
# node_js: "4" node_js: "8"
- os: osx - os: linux
node_js: "5" env: CXX=g++-4.8
node_js: "9"
- os: osx - os: osx
node_js: "6" node_js: "6"
- os: osx - os: osx
node_js: "7" node_js: "7"
- os: osx
node_js: "8"
- os: osx
node_js: "9"
before_install: before_install:
- export CHROME_BIN=chromium-browser - export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0 - export DISPLAY=:99.0

View file

@ -1,8 +1,9 @@
environment: environment:
matrix: matrix:
# - nodejs_version: "4"
- nodejs_version: "6" - nodejs_version: "6"
- nodejs_version: "7" - nodejs_version: "7"
- nodejs_version: "8"
- nodejs_version: "9"
platform: platform:
- x86 - x86
- x64 - x64

View file

@ -29,6 +29,9 @@ exports.config = {
services: ['phantomjs'], services: ['phantomjs'],
framework: 'mocha', framework: 'mocha',
reporters: ['spec'], reporters: ['spec'],
phantomjsOpts: {
webdriverLogfile: 'phantomjs.log'
},
mochaOpts: { mochaOpts: {
ui: 'bdd', ui: 'bdd',
// Because we don't know how long the initial build will take... // Because we don't know how long the initial build will take...

View file

@ -5,6 +5,7 @@ var loaders = require('./webpack.loaders');
var ExtractTextPlugin = require('extract-text-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin');
var WebpackCleanupPlugin = require('webpack-cleanup-plugin'); var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
var OUTPATH; var OUTPATH;
if(process.env.CIRCLE_ARTIFACTS) { if(process.env.CIRCLE_ARTIFACTS) {
@ -78,6 +79,14 @@ module.exports = {
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
template: './src/template.html', template: './src/template.html',
title: 'Maputnik' title: 'Maputnik'
}),
new BundleAnalyzerPlugin({
analyzerMode: 'static',
defaultSizes: 'gzip',
openAnalyzer: false,
generateStatsFile: true,
reportFilename: 'bundle-stats.html',
statsFilename: 'bundle-stats.json',
}) })
] ]
}; };

13171
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -39,14 +39,14 @@
"ol-mapbox-style": "^1.0.1", "ol-mapbox-style": "^1.0.1",
"openlayers": "^4.4.2", "openlayers": "^4.4.2",
"prop-types": "^15.6.0", "prop-types": "^15.6.0",
"react": "^16.0.0", "react": "16.0.0",
"react-addons-pure-render-mixin": "^15.6.2", "react-addons-pure-render-mixin": "^15.6.2",
"react-autocomplete": "^1.7.2", "react-autocomplete": "^1.7.2",
"react-codemirror": "^1.0.0", "react-codemirror": "^1.0.0",
"react-collapse": "^4.0.3", "react-collapse": "^4.0.3",
"react-color": "^2.13.8", "react-color": "^2.13.8",
"react-copy-to-clipboard": "^5.0.1", "react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.0.0", "react-dom": "16.0.0",
"react-file-reader-input": "^1.1.4", "react-file-reader-input": "^1.1.4",
"react-height": "^3.0.0", "react-height": "^3.0.0",
"react-icon-base": "^2.1.1", "react-icon-base": "^2.1.1",
@ -126,6 +126,7 @@
"wdio-spec-reporter": "^0.1.2", "wdio-spec-reporter": "^0.1.2",
"webdriverio": "^4.8.0", "webdriverio": "^4.8.0",
"webpack": "^3.8.1", "webpack": "^3.8.1",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-cleanup-plugin": "^0.5.1", "webpack-cleanup-plugin": "^0.5.1",
"webpack-dev-server": "^2.9.4" "webpack-dev-server": "^2.9.4"
} }

View file

@ -67,12 +67,12 @@ export default class App extends React.Component {
} }
this.layerWatcher = new LayerWatcher({ this.layerWatcher = new LayerWatcher({
onSourcesChange: v => this.setState({ sources: v }),
onVectorLayersChange: v => this.setState({ vectorLayers: v }) onVectorLayersChange: v => this.setState({ vectorLayers: v })
}) })
} }
componentDidMount() { componentDidMount() {
this.fetchSources();
Mousetrap.bind(['ctrl+z'], this.onUndo.bind(this)); Mousetrap.bind(['ctrl+z'], this.onUndo.bind(this));
Mousetrap.bind(['ctrl+y'], this.onRedo.bind(this)); Mousetrap.bind(['ctrl+y'], this.onRedo.bind(this));
} }
@ -126,6 +126,8 @@ export default class App extends React.Component {
errors: errors.map(err => err.message) errors: errors.map(err => err.message)
}) })
} }
this.fetchSources();
} }
onUndo() { onUndo() {
@ -182,11 +184,53 @@ export default class App extends React.Component {
}) })
} }
fetchSources() {
const sourceList = {};
for(let [key, val] of Object.entries(this.state.mapStyle.sources)) {
sourceList[key] = {
type: val.type,
layers: []
};
if(val.type === "vector") {
const url = val.url;
fetch(url)
.then((response) => {
return response.json();
})
.then((json) => {
// Create new objects before setState
const sourceList = {...this.state.sources};
sourceList[key] = {...sourceList[key]};
for(let layer of json.vector_layers) {
sourceList[key].layers.push(layer.id)
}
this.setState({
sources: sourceList
});
})
.catch((err) => {
console.error("Failed to process sources for '%s'", url, err);
})
}
}
// Note: Each source will be missing layers initially until the fetch is complete
this.setState({
sources: sourceList
})
}
mapRenderer() { mapRenderer() {
const mapProps = { const mapProps = {
mapStyle: style.replaceAccessToken(this.state.mapStyle), mapStyle: style.replaceAccessToken(this.state.mapStyle),
onDataChange: (e) => { onDataChange: (e) => {
this.layerWatcher.analyzeMap(e.map) this.layerWatcher.analyzeMap(e.map)
this.fetchSources();
}, },
} }

View file

@ -134,7 +134,7 @@ export default class LayerEditor extends React.Component {
/> />
} }
{this.props.layer.type !== 'raster' && this.props.layer.type !== 'background' && <LayerSourceLayerBlock {this.props.layer.type !== 'raster' && this.props.layer.type !== 'background' && <LayerSourceLayerBlock
sourceLayerIds={this.props.sources[this.props.layer.source]} sourceLayerIds={this.props.sources[this.props.layer.source].layers}
value={this.props.layer['source-layer']} value={this.props.layer['source-layer']}
onChange={v => this.changeProperty(null, 'source-layer', v)} onChange={v => this.changeProperty(null, 'source-layer', v)}
/> />

View file

@ -56,18 +56,54 @@ class AddModal extends React.Component {
} }
} }
componentWillReceiveProps(nextProps) { componentWillUpdate(nextProps, nextState) {
const sourceIds = Object.keys(nextProps.sources) // Check if source is valid for new type
if(!this.state.source && sourceIds.length > 0) { const availableSources = this.getSources(nextState.type);
if(
this.state.source !== ""
&& availableSources.indexOf(this.state.source) < 0
) {
this.setState({ this.setState({
source: sourceIds[0], source: ""
'source-layer': this.state['source-layer'] || (nextProps.sources[sourceIds[0]] || [])[0] });
})
} }
} }
getLayersForSource(source) {
const sourceObj = this.props.sources[source] || {};
return sourceObj.layers || [];
}
getSources(type) {
const sources = [];
const types = {
vector: [
"fill",
"line",
"symbol",
"circle",
"fill-extrusion"
],
raster: [
"raster"
]
}
for(let [key, val] of Object.entries(this.props.sources)) {
if(types[val.type].indexOf(type) > -1) {
sources.push(key);
}
}
return sources;
}
render() { render() {
const sources = this.getSources(this.state.type);
const layers = this.getLayersForSource(this.state.source);
return <Modal return <Modal
isOpen={this.props.isOpen} isOpen={this.props.isOpen}
onOpenToggle={this.props.onOpenToggle} onOpenToggle={this.props.onOpenToggle}
@ -84,14 +120,14 @@ class AddModal extends React.Component {
/> />
{this.state.type !== 'background' && {this.state.type !== 'background' &&
<LayerSourceBlock <LayerSourceBlock
sourceIds={Object.keys(this.props.sources)} sourceIds={sources}
value={this.state.source} value={this.state.source}
onChange={v => this.setState({ source: v })} onChange={v => this.setState({ source: v })}
/> />
} }
{this.state.type !== 'background' && this.state.type !== 'raster' && {this.state.type !== 'background' && this.state.type !== 'raster' &&
<LayerSourceLayerBlock <LayerSourceLayerBlock
sourceLayerIds={this.props.sources[this.state.source] || []} sourceLayerIds={layers}
value={this.state['source-layer']} value={this.state['source-layer']}
onChange={v => this.setState({ 'source-layer': v })} onChange={v => this.setState({ 'source-layer': v })}
/> />

View file

@ -139,7 +139,7 @@ class AddSource extends React.Component {
onChange={v => this.setState({ sourceId: v})} onChange={v => this.setState({ sourceId: v})}
/> />
</InputBlock> </InputBlock>
<InputBlock label={"Source Type"} doc={styleSpec.latest.source_tile.type.doc}> <InputBlock label={"Source Type"} doc={styleSpec.latest.source_vector.type.doc}>
<SelectInput <SelectInput
options={[ options={[
['geojson', 'GeoJSON'], ['geojson', 'GeoJSON'],

View file

@ -12,7 +12,7 @@ class TileJSONSourceEditor extends React.Component {
} }
render() { render() {
return <InputBlock label={"TileJSON URL"} doc={styleSpec.latest.source_tile.url.doc}> return <InputBlock label={"TileJSON URL"} doc={styleSpec.latest.source_vector.url.doc}>
<StringInput <StringInput
value={this.props.source.url} value={this.props.source.url}
onChange={url => this.props.onChange({ onChange={url => this.props.onChange({
@ -43,7 +43,7 @@ class TileURLSourceEditor extends React.Component {
const prefix = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th'] const prefix = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th']
const tiles = this.props.source.tiles || [] const tiles = this.props.source.tiles || []
return tiles.map((tileUrl, tileIndex) => { return tiles.map((tileUrl, tileIndex) => {
return <InputBlock key={tileIndex} label={prefix[tileIndex] + " Tile URL"} doc={styleSpec.latest.source_tile.tiles.doc}> return <InputBlock key={tileIndex} label={prefix[tileIndex] + " Tile URL"} doc={styleSpec.latest.source_vector.tiles.doc}>
<StringInput <StringInput
value={tileUrl} value={tileUrl}
onChange={this.changeTileUrl.bind(this, tileIndex)} onChange={this.changeTileUrl.bind(this, tileIndex)}
@ -55,7 +55,7 @@ class TileURLSourceEditor extends React.Component {
render() { render() {
return <div> return <div>
{this.renderTileUrls()} {this.renderTileUrls()}
<InputBlock label={"Min Zoom"} doc={styleSpec.latest.source_tile.minzoom.doc}> <InputBlock label={"Min Zoom"} doc={styleSpec.latest.source_vector.minzoom.doc}>
<NumberInput <NumberInput
value={this.props.source.minzoom || 0} value={this.props.source.minzoom || 0}
onChange={minzoom => this.props.onChange({ onChange={minzoom => this.props.onChange({
@ -64,7 +64,7 @@ class TileURLSourceEditor extends React.Component {
})} })}
/> />
</InputBlock> </InputBlock>
<InputBlock label={"Max Zoom"} doc={styleSpec.latest.source_tile.maxzoom.doc}> <InputBlock label={"Max Zoom"} doc={styleSpec.latest.source_vector.maxzoom.doc}>
<NumberInput <NumberInput
value={this.props.source.maxzoom || 22} value={this.props.source.maxzoom || 22}
onChange={maxzoom => this.props.onChange({ onChange={maxzoom => this.props.onChange({

View file

@ -35,6 +35,7 @@
left: 0; left: 0;
width: 120px; width: 120px;
z-index: 10; z-index: 10;
pointer-events: none;
} }
} }