diff --git a/.babelrc b/.babelrc
index adae42d..27baf2a 100644
--- a/.babelrc
+++ b/.babelrc
@@ -5,9 +5,9 @@
"test": {
"plugins": [
["istanbul", {
- exclude: ["node_modules/**", "test/**"]
+ "exclude": ["node_modules/**", "test/**"]
}]
]
}
}
-}
+}
\ No newline at end of file
diff --git a/config/webpack.production.config.js b/config/webpack.production.config.js
index c015f4a..a1e1e58 100644
--- a/config/webpack.production.config.js
+++ b/config/webpack.production.config.js
@@ -14,25 +14,6 @@ var OUTPATH = artifacts.pathSync("/build");
module.exports = {
entry: {
app: './src/index.jsx',
- vendor: [
- 'file-saver',
- 'mapbox-gl/dist/mapbox-gl.js',
- "lodash.clonedeep",
- "lodash.throttle",
- 'color',
- 'react',
- "react-dom",
- "react-color",
- "react-file-reader-input",
- "react-collapse",
- "react-height",
- "react-icon-base",
- "react-motion",
- "react-sortable-hoc",
- "request",
- //TODO: Icons raise multi vendor errors?
- //"react-icons",
- ]
},
output: {
path: OUTPATH,
@@ -55,7 +36,6 @@ module.exports = {
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
- new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: '[chunkhash].vendor.js' }),
new WebpackCleanupPlugin(),
new webpack.DefinePlugin({
'process.env': {
diff --git a/package-lock.json b/package-lock.json
index 4e61878..320039f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "maputnik",
- "version": "1.4.0",
+ "version": "1.5.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 317bfc2..90d191b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "maputnik",
- "version": "1.4.0",
+ "version": "1.5.0",
"description": "A MapboxGL visual style editor",
"main": "''",
"scripts": {
@@ -10,8 +10,7 @@
"test-watch": "cross-env NODE_ENV=test wdio config/wdio.conf.js --watch",
"start": "webpack-dev-server --progress --profile --colors --config config/webpack.config.js",
"lint": "eslint --ext js --ext jsx {src,test}",
- "lint-styles": "stylelint 'src/styles/*.scss'",
- "nsp": "nsp check --reporter summary"
+ "lint-styles": "stylelint 'src/styles/*.scss'"
},
"repository": {
"type": "git",
@@ -27,7 +26,6 @@
"codemirror": "^5.37.0",
"color": "^3.0.0",
"file-saver": "^1.3.8",
- "github-api": "^3.0.0",
"jsonlint": "github:josdejong/jsonlint#85a19d7",
"lodash.capitalize": "^4.2.1",
"lodash.clamp": "^4.0.3",
@@ -37,28 +35,24 @@
"mapbox-gl": "^0.47.0",
"mapbox-gl-inspect": "^1.3.1",
"maputnik-design": "github:maputnik/design",
- "mousetrap": "^1.6.1",
"ol-mapbox-style": "^2.10.1",
"ol": "^4.6.5",
"prop-types": "^15.6.0",
"react": "^16.3.2",
- "react-addons-pure-render-mixin": "^15.6.2",
"react-aria-menubutton": "^5.1.1",
"react-aria-modal": "^2.12.1",
+ "react-autobind": "^1.0.6",
"react-autocomplete": "^1.7.2",
"react-codemirror2": "^4.2.1",
"react-collapse": "^4.0.3",
"react-color": "^2.14.1",
- "react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.3.2",
"react-file-reader-input": "^1.1.4",
- "react-height": "^3.0.0",
"react-icon-base": "^2.1.1",
"react-icons": "^2.2.7",
"react-motion": "^0.5.2",
"react-sortable-hoc": "^0.6.8",
"reconnecting-websocket": "^3.2.2",
- "request": "^2.85.0",
"url": "^0.11.0"
},
"jshintConfig": {
@@ -117,7 +111,6 @@
"babel-preset-react": "^6.24.1",
"babel-register": "^6.26.0",
"babel-runtime": "^6.26.0",
- "base64-loader": "^1.0.0",
"copy-webpack-plugin": "^4.5.1",
"cors": "^2.8.4",
"cross-env": "^5.1.4",
@@ -135,7 +128,7 @@
"mkdirp": "^0.5.1",
"mocha": "^5.1.1",
"node-sass": "^4.9.0",
- "nsp": "^3.1.0",
+ "raw-loader": "^0.5.1",
"react-hot-loader": "^3.1.1",
"sass-loader": "^7.0.1",
"selenium-standalone": "^6.14.0",
@@ -147,7 +140,6 @@
"uglifyjs-webpack-plugin": "^1.2.4",
"uuid": "^3.1.0",
"wdio-mocha-framework": "^0.5.13",
- "wdio-phantomjs-service": "^0.2.2",
"wdio-selenium-standalone-service": "0.0.10",
"wdio-spec-reporter": "^0.1.2",
"webdriverio": "^4.12.0",
diff --git a/src/components/App.jsx b/src/components/App.jsx
index da0aef4..8c9eae4 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -1,12 +1,11 @@
+import autoBind from 'react-autobind';
import React from 'react'
-import Mousetrap from 'mousetrap'
import cloneDeep from 'lodash.clonedeep'
import clamp from 'lodash.clamp'
import {arrayMove} from 'react-sortable-hoc'
import url from 'url'
import MapboxGlMap from './map/MapboxGlMap'
-import OpenLayers3Map from './map/OpenLayers3Map'
import LayerList from './layers/LayerList'
import LayerEditor from './layers/LayerEditor'
import Toolbar from './Toolbar'
@@ -25,7 +24,7 @@ import * as styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import style from '../libs/style'
import { initialStyleUrl, loadStyleUrl } from '../libs/urlopen'
import { undoMessages, redoMessages } from '../libs/diffmessage'
-import { loadDefaultStyle, StyleStore } from '../libs/stylestore'
+import { StyleStore } from '../libs/stylestore'
import { ApiStyleStore } from '../libs/apistore'
import { RevisionStore } from '../libs/revisions'
import LayerWatcher from '../libs/layerwatcher'
@@ -54,6 +53,8 @@ function updateRootSpec(spec, fieldName, newValues) {
export default class App extends React.Component {
constructor(props) {
super(props)
+ autoBind(this);
+
this.revisionStore = new RevisionStore()
this.styleStore = new ApiStyleStore({
onLocalStyleChange: mapStyle => this.onStyleChanged(mapStyle, false)
@@ -176,7 +177,8 @@ export default class App extends React.Component {
survey: localStorage.hasOwnProperty('survey') ? false : true
},
mapOptions: {
- showTileBoundaries: queryUtil.asBool(queryObj, "show-tile-boundaries")
+ showTileBoundaries: queryUtil.asBool(queryObj, "show-tile-boundaries"),
+ showCollisionBoxes: queryUtil.asBool(queryObj, "show-collision-boxes")
},
mapFilter: queryObj["color-blindness-emulation"],
}
@@ -186,14 +188,31 @@ export default class App extends React.Component {
})
}
+ handleKeyPress(e) {
+ if(navigator.platform.toUpperCase().indexOf('MAC') >= 0) {
+ if(e.metaKey && e.shiftKey && e.keyCode === 90) {
+ this.onRedo(e);
+ }
+ else if(e.metaKey && e.keyCode === 90) {
+ this.onUndo(e);
+ }
+ }
+ else {
+ if(e.ctrlKey && e.keyCode === 90) {
+ this.onUndo(e);
+ }
+ else if(e.ctrlKey && e.keyCode === 89) {
+ this.onRedo(e);
+ }
+ }
+ }
+
componentDidMount() {
- Mousetrap.bind(['mod+z'], this.onUndo.bind(this));
- Mousetrap.bind(['mod+y', 'mod+shift+z'], this.onRedo.bind(this));
+ window.addEventListener("keydown", this.handleKeyPress);
}
componentWillUnmount() {
- Mousetrap.unbind(['mod+z'], this.onUndo.bind(this));
- Mousetrap.unbind(['mod+y', 'mod+shift+z'], this.onRedo.bind(this));
+ window.removeEventListener("keydown", this.handleKeyPress);
}
saveStyle(snapshotStyle) {
@@ -216,7 +235,7 @@ export default class App extends React.Component {
})
}
- onStyleChanged(newStyle, save=true) {
+ onStyleChanged = (newStyle, save=true) => {
const errors = styleSpec.validate(newStyle, styleSpec.latest)
if(errors.length === 0) {
@@ -243,7 +262,7 @@ export default class App extends React.Component {
this.fetchSources();
}
- onUndo() {
+ onUndo = () => {
const activeStyle = this.revisionStore.undo()
const messages = undoMessages(this.state.mapStyle, activeStyle)
this.saveStyle(activeStyle)
@@ -253,7 +272,7 @@ export default class App extends React.Component {
})
}
- onRedo() {
+ onRedo = () => {
const activeStyle = this.revisionStore.redo()
const messages = redoMessages(this.state.mapStyle, activeStyle)
this.saveStyle(activeStyle)
@@ -263,7 +282,7 @@ export default class App extends React.Component {
})
}
- onMoveLayer(move) {
+ onMoveLayer = (move) => {
let { oldIndex, newIndex } = move;
let layers = this.state.mapStyle.layers;
oldIndex = clamp(oldIndex, 0, layers.length-1);
@@ -281,7 +300,7 @@ export default class App extends React.Component {
this.onLayersChange(layers);
}
- onLayersChange(changedLayers) {
+ onLayersChange = (changedLayers) => {
const changedStyle = {
...this.state.mapStyle,
layers: changedLayers
@@ -289,7 +308,7 @@ export default class App extends React.Component {
this.onStyleChanged(changedStyle)
}
- onLayerDestroy(layerId) {
+ onLayerDestroy = (layerId) => {
let layers = this.state.mapStyle.layers;
const remainingLayers = layers.slice(0);
const idx = style.indexOfLayer(remainingLayers, layerId)
@@ -297,7 +316,7 @@ export default class App extends React.Component {
this.onLayersChange(remainingLayers);
}
- onLayerCopy(layerId) {
+ onLayerCopy = (layerId) => {
let layers = this.state.mapStyle.layers;
const changedLayers = layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layerId)
@@ -308,7 +327,7 @@ export default class App extends React.Component {
this.onLayersChange(changedLayers)
}
- onLayerVisibilityToggle(layerId) {
+ onLayerVisibilityToggle = (layerId) => {
let layers = this.state.mapStyle.layers;
const changedLayers = layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layerId)
@@ -323,7 +342,7 @@ export default class App extends React.Component {
}
- onLayerIdChange(oldId, newId) {
+ onLayerIdChange = (oldId, newId) => {
const changedLayers = this.state.mapStyle.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, oldId)
@@ -335,7 +354,7 @@ export default class App extends React.Component {
this.onLayersChange(changedLayers)
}
- onLayerChanged(layer) {
+ onLayerChanged = (layer) => {
const changedLayers = this.state.mapStyle.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layer.id)
changedLayers[idx] = layer
@@ -343,7 +362,7 @@ export default class App extends React.Component {
this.onLayersChange(changedLayers)
}
- changeInspectMode() {
+ changeInspectMode = () => {
this.setState({
inspectModeEnabled: !this.state.inspectModeEnabled
})
@@ -370,7 +389,9 @@ export default class App extends React.Component {
console.warn("Failed to normalizeSourceURL: ", err);
}
- fetch(url)
+ fetch(url, {
+ mode: 'cors',
+ })
.then((response) => {
return response.json();
})
@@ -422,12 +443,12 @@ export default class App extends React.Component {
// Check if OL3 code has been loaded?
if(renderer === 'ol3') {
- mapElement =
+ mapElement =
TODO
} else {
mapElement =
+ onLayerSelect={this.onLayerSelect} />
}
const elementStyle = {};
@@ -440,7 +461,7 @@ export default class App extends React.Component {
}
- onLayerSelect(layerId) {
+ onLayerSelect = (layerId) => {
const idx = style.indexOfLayer(this.state.mapStyle.layers, layerId)
this.setState({ selectedLayerIndex: idx })
}
@@ -467,19 +488,19 @@ export default class App extends React.Component {
mapStyle={this.state.mapStyle}
inspectModeEnabled={this.state.inspectModeEnabled}
sources={this.state.sources}
- onStyleChanged={this.onStyleChanged.bind(this)}
- onStyleOpen={this.onStyleChanged.bind(this)}
- onInspectModeToggle={this.changeInspectMode.bind(this)}
+ onStyleChanged={this.onStyleChanged}
+ onStyleOpen={this.onStyleChanged}
+ onInspectModeToggle={this.changeInspectMode}
onToggleModal={this.toggleModal.bind(this)}
/>
const layerList = : null
const bottomPanel = (this.state.errors.length + this.state.infos.length) > 0 ?
diff --git a/src/components/Toolbar.jsx b/src/components/Toolbar.jsx
index ede36f2..77ee1ad 100644
--- a/src/components/Toolbar.jsx
+++ b/src/components/Toolbar.jsx
@@ -1,19 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
-import FileReaderInput from 'react-file-reader-input'
import classnames from 'classnames'
import MdFileDownload from 'react-icons/lib/md/file-download'
-import MdFileUpload from 'react-icons/lib/md/file-upload'
import OpenIcon from 'react-icons/lib/md/open-in-browser'
import SettingsIcon from 'react-icons/lib/md/settings'
-import MdInfo from 'react-icons/lib/md/info'
import SourcesIcon from 'react-icons/lib/md/layers'
-import MdSave from 'react-icons/lib/md/save'
-import MdStyle from 'react-icons/lib/md/style'
-import MdMap from 'react-icons/lib/md/map'
-import MdInsertEmoticon from 'react-icons/lib/md/insert-emoticon'
-import MdFontDownload from 'react-icons/lib/md/font-download'
import HelpIcon from 'react-icons/lib/md/help-outline'
import InspectionIcon from 'react-icons/lib/md/find-in-page'
import SurveyIcon from 'react-icons/lib/md/assignment-turned-in'
@@ -21,7 +13,6 @@ import SurveyIcon from 'react-icons/lib/md/assignment-turned-in'
import logoImage from 'maputnik-design/logos/logo-color.svg'
import pkgJson from '../../package.json'
-import style from '../libs/style'
class IconText extends React.Component {
static propTypes = {
@@ -107,16 +98,13 @@ export default class Toolbar extends React.Component {
onToggleModal: PropTypes.func,
}
- constructor(props) {
- super(props)
- this.state = {
- isOpen: {
- settings: false,
- sources: false,
- open: false,
- add: false,
- export: false,
- }
+ state = {
+ isOpen: {
+ settings: false,
+ sources: false,
+ open: false,
+ add: false,
+ export: false,
}
}
diff --git a/src/components/fields/ColorField.jsx b/src/components/fields/ColorField.jsx
index 6e538c9..9a40090 100644
--- a/src/components/fields/ColorField.jsx
+++ b/src/components/fields/ColorField.jsx
@@ -19,17 +19,14 @@ class ColorField extends React.Component {
default: PropTypes.string,
}
- constructor(props) {
- super(props)
- this.state = {
- pickerOpened: false,
- }
+ state = {
+ pickerOpened: false
}
//TODO: I much rather would do this with absolute positioning
//but I am too stupid to get it to work together with fixed position
//and scrollbars so I have to fallback to JavaScript
- calcPickerOffset() {
+ calcPickerOffset = () => {
const elem = this.colorInput
if(elem) {
const pos = elem.getBoundingClientRect()
@@ -45,7 +42,7 @@ class ColorField extends React.Component {
}
}
- togglePicker() {
+ togglePicker = () => {
this.setState({ pickerOpened: !this.state.pickerOpened })
}
@@ -85,7 +82,7 @@ class ColorField extends React.Component {
/>
this.colorInput = input}
- onClick={this.togglePicker.bind(this)}
+ onClick={this.togglePicker}
style={this.props.style}
name={this.props.name}
placeholder={this.props.default}
diff --git a/src/components/fields/DocLabel.jsx b/src/components/fields/DocLabel.jsx
index 9af6a86..65d7193 100644
--- a/src/components/fields/DocLabel.jsx
+++ b/src/components/fields/DocLabel.jsx
@@ -17,7 +17,7 @@ export default class DocLabel extends React.Component {
{this.props.doc}
-
+
}
}
diff --git a/src/components/fields/FunctionSpecField.jsx b/src/components/fields/FunctionSpecField.jsx
index 981bb1c..3067c1b 100644
--- a/src/components/fields/FunctionSpecField.jsx
+++ b/src/components/fields/FunctionSpecField.jsx
@@ -32,7 +32,7 @@ export default class FunctionSpecProperty extends React.Component {
]),
}
- addStop() {
+ addStop = () => {
const stops = this.props.value.stops.slice(0)
const lastStop = stops[stops.length - 1]
if (typeof lastStop[0] === "object") {
@@ -53,7 +53,7 @@ export default class FunctionSpecProperty extends React.Component {
this.props.onChange(this.props.fieldName, changedValue)
}
- deleteStop(stopIdx) {
+ deleteStop = (stopIdx) => {
const stops = this.props.value.stops.slice(0)
stops.splice(stopIdx, 1)
@@ -69,7 +69,7 @@ export default class FunctionSpecProperty extends React.Component {
this.props.onChange(this.props.fieldName, changedValue)
}
- makeZoomFunction() {
+ makeZoomFunction = () => {
const zoomFunc = {
stops: [
[6, this.props.value],
@@ -79,7 +79,7 @@ export default class FunctionSpecProperty extends React.Component {
this.props.onChange(this.props.fieldName, zoomFunc)
}
- makeDataFunction() {
+ makeDataFunction = () => {
const dataFunc = {
property: "",
type: "categorical",
@@ -102,8 +102,8 @@ export default class FunctionSpecProperty extends React.Component {
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={this.props.value}
- onDeleteStop={this.deleteStop.bind(this)}
- onAddStop={this.addStop.bind(this)}
+ onDeleteStop={this.deleteStop}
+ onAddStop={this.addStop}
/>
)
}
@@ -114,8 +114,8 @@ export default class FunctionSpecProperty extends React.Component {
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={this.props.value}
- onDeleteStop={this.deleteStop.bind(this)}
- onAddStop={this.addStop.bind(this)}
+ onDeleteStop={this.deleteStop}
+ onAddStop={this.addStop}
/>
)
}
@@ -126,8 +126,8 @@ export default class FunctionSpecProperty extends React.Component {
fieldName={this.props.fieldName}
fieldSpec={this.props.fieldSpec}
value={this.props.value}
- onZoomClick={this.makeZoomFunction.bind(this)}
- onDataClick={this.makeDataFunction.bind(this)}
+ onZoomClick={this.makeZoomFunction}
+ onDataClick={this.makeDataFunction}
/>
)
}
diff --git a/src/components/fields/PropertyGroup.jsx b/src/components/fields/PropertyGroup.jsx
index 5d3c72c..efb567b 100644
--- a/src/components/fields/PropertyGroup.jsx
+++ b/src/components/fields/PropertyGroup.jsx
@@ -42,7 +42,7 @@ export default class PropertyGroup extends React.Component {
spec: PropTypes.object.isRequired,
}
- onPropertyChange(property, newValue) {
+ onPropertyChange = (property, newValue) => {
const group = getGroupName(this.props.spec, this.props.layer.type, property)
this.props.onChange(group , property, newValue)
}
@@ -56,7 +56,7 @@ export default class PropertyGroup extends React.Component {
const fieldValue = fieldName in paint ? paint[fieldName] : layout[fieldName]
return = 0
}
@@ -60,7 +57,7 @@ export default class CombiningFilterEditor extends React.Component {
this.props.onChange(newFilter)
}
- addFilterItem() {
+ addFilterItem = () => {
const newFilterItem = this.combiningFilter().slice(0)
newFilterItem.push(['==', 'name', ''])
this.props.onChange(newFilterItem)
@@ -105,7 +102,7 @@ export default class CombiningFilterEditor extends React.Component {
diff --git a/src/components/inputs/AutocompleteInput.jsx b/src/components/inputs/AutocompleteInput.jsx
index d33bdbd..2ba6ef8 100644
--- a/src/components/inputs/AutocompleteInput.jsx
+++ b/src/components/inputs/AutocompleteInput.jsx
@@ -14,18 +14,15 @@ class AutocompleteInput extends React.Component {
keepMenuWithinWindowBounds: PropTypes.bool
}
+ state = {
+ maxHeight: MAX_HEIGHT
+ }
+
static defaultProps = {
onChange: () => {},
options: [],
}
- constructor(props) {
- super(props);
- this.state = {
- maxHeight: MAX_HEIGHT
- };
- }
-
calcMaxHeight() {
if(this.props.keepMenuWithinWindowBounds) {
const maxHeight = window.innerHeight - this.autocompleteMenuEl.getBoundingClientRect().top;
@@ -38,6 +35,7 @@ class AutocompleteInput extends React.Component {
}
}
}
+
componentDidMount() {
this.calcMaxHeight();
}
diff --git a/src/components/inputs/DynamicArrayInput.jsx b/src/components/inputs/DynamicArrayInput.jsx
index 5596e24..6e58d56 100644
--- a/src/components/inputs/DynamicArrayInput.jsx
+++ b/src/components/inputs/DynamicArrayInput.jsx
@@ -27,14 +27,13 @@ class DynamicArrayInput extends React.Component {
return this.props.value || this.props.default || []
}
- addValue() {
+ addValue = () => {
const values = this.values.slice(0)
if (this.props.type === 'number') {
values.push(0)
} else {
values.push("")
}
-
this.props.onChange(values)
}
@@ -77,7 +76,7 @@ class DynamicArrayInput extends React.Component {
{inputs}
diff --git a/src/components/inputs/NumberInput.jsx b/src/components/inputs/NumberInput.jsx
index 90cf969..75ed148 100644
--- a/src/components/inputs/NumberInput.jsx
+++ b/src/components/inputs/NumberInput.jsx
@@ -51,7 +51,7 @@ class NumberInput extends React.Component {
return true
}
- resetValue() {
+ resetValue = () => {
// Reset explicitly to default value if value has been cleared
if(this.state.value === "") {
return this.changeValue(this.props.default)
@@ -74,7 +74,7 @@ class NumberInput extends React.Component {
placeholder={this.props.default}
value={this.state.value}
onChange={e => this.changeValue(e.target.value)}
- onBlur={this.resetValue.bind(this)}
+ onBlur={this.resetValue}
/>
}
}
diff --git a/src/components/layers/LayerEditor.jsx b/src/components/layers/LayerEditor.jsx
index 6e245b3..913cef7 100644
--- a/src/components/layers/LayerEditor.jsx
+++ b/src/components/layers/LayerEditor.jsx
@@ -16,9 +16,6 @@ import LayerSourceLayerBlock from './LayerSourceLayerBlock'
import MoreVertIcon from 'react-icons/lib/md/more-vert'
-import InputBlock from '../inputs/InputBlock'
-import MultiButtonInput from '../inputs/MultiButtonInput'
-
import { changeType, changeProperty } from '../../libs/layer'
import layout from '../../config/layout.json'
@@ -36,7 +33,7 @@ function layoutGroups(layerType) {
title: 'JSON Editor',
type: 'jsoneditor'
}
- return [layerGroup, filterGroup].concat(layout[layerType].groups).concat([editorGroup])
+ return [layerGroup, filterGroup].concat(layout[layerType].groups).concat([editorGroup])
}
/** Layer editor supporting multiple types of layers. */
diff --git a/src/components/layers/LayerList.jsx b/src/components/layers/LayerList.jsx
index 83ebe33..dcabe6b 100644
--- a/src/components/layers/LayerList.jsx
+++ b/src/components/layers/LayerList.jsx
@@ -2,13 +2,10 @@ import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
-import Button from '../Button'
import LayerListGroup from './LayerListGroup'
import LayerListItem from './LayerListItem'
-import AddIcon from 'react-icons/lib/md/add-circle-outline'
import AddModal from '../modals/AddModal'
-import style from '../../libs/style.js'
import {SortableContainer, SortableHandle} from 'react-sortable-hoc';
const layerListPropTypes = {
@@ -45,15 +42,12 @@ class LayerListContainer extends React.Component {
onLayerSelect: () => {},
}
- constructor(props) {
- super(props)
- this.state = {
- collapsedGroups: {},
- areAllGroupsExpanded: false,
- isOpen: {
- add: false,
- }
- }
+ state = {
+ collapsedGroups: {},
+ areAllGroupsExpanded: false,
+ isOpen: {
+ add: false,
+ }
}
toggleModal(modalName) {
@@ -65,7 +59,7 @@ class LayerListContainer extends React.Component {
})
}
- toggleLayers() {
+ toggleLayers = () => {
let idx=0
let newGroups=[]
@@ -179,7 +173,7 @@ class LayerListContainer extends React.Component {
diff --git a/src/components/layers/LayerListItem.jsx b/src/components/layers/LayerListItem.jsx
index 5c65188..805e50f 100644
--- a/src/components/layers/LayerListItem.jsx
+++ b/src/components/layers/LayerListItem.jsx
@@ -1,6 +1,5 @@
import React from 'react'
import PropTypes from 'prop-types'
-import Color from 'color'
import classnames from 'classnames'
import CopyIcon from 'react-icons/lib/md/content-copy'
@@ -9,7 +8,6 @@ import VisibilityOffIcon from 'react-icons/lib/md/visibility-off'
import DeleteIcon from 'react-icons/lib/md/delete'
import LayerIcon from '../icons/LayerIcon'
-import LayerEditor from './LayerEditor'
import {SortableElement, SortableHandle} from 'react-sortable-hoc'
@SortableHandle
diff --git a/src/components/layers/LayerSourceBlock.jsx b/src/components/layers/LayerSourceBlock.jsx
index 3773f73..9a6b9e2 100644
--- a/src/components/layers/LayerSourceBlock.jsx
+++ b/src/components/layers/LayerSourceBlock.jsx
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types'
import * as styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
-import StringInput from '../inputs/StringInput'
import AutocompleteInput from '../inputs/AutocompleteInput'
class LayerSourceBlock extends React.Component {
diff --git a/src/components/layers/LayerSourceLayerBlock.jsx b/src/components/layers/LayerSourceLayerBlock.jsx
index 804e93f..15b48b5 100644
--- a/src/components/layers/LayerSourceLayerBlock.jsx
+++ b/src/components/layers/LayerSourceLayerBlock.jsx
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types'
import * as styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import InputBlock from '../inputs/InputBlock'
-import StringInput from '../inputs/StringInput'
import AutocompleteInput from '../inputs/AutocompleteInput'
class LayerSourceLayer extends React.Component {
diff --git a/src/components/map/FeatureLayerPopup.jsx b/src/components/map/FeatureLayerPopup.jsx
index 5d14d01..2d0eacb 100644
--- a/src/components/map/FeatureLayerPopup.jsx
+++ b/src/components/map/FeatureLayerPopup.jsx
@@ -1,7 +1,5 @@
import React from 'react'
import PropTypes from 'prop-types'
-import InputBlock from '../inputs/InputBlock'
-import StringInput from '../inputs/StringInput'
import LayerIcon from '../icons/LayerIcon'
function groupFeaturesBySourceLayer(features) {
diff --git a/src/components/map/MapboxGlMap.jsx b/src/components/map/MapboxGlMap.jsx
index 1858e46..1eb59f6 100644
--- a/src/components/map/MapboxGlMap.jsx
+++ b/src/components/map/MapboxGlMap.jsx
@@ -5,7 +5,6 @@ import MapboxGl from 'mapbox-gl'
import MapboxInspect from 'mapbox-gl-inspect'
import FeatureLayerPopup from './FeatureLayerPopup'
import FeaturePropertyPopup from './FeaturePropertyPopup'
-import style from '../../libs/style.js'
import tokens from '../../config/tokens.json'
import colors from 'mapbox-gl-inspect/lib/colors'
import Color from 'color'
@@ -15,6 +14,9 @@ import 'mapbox-gl/dist/mapbox-gl.css'
import '../../mapboxgl.css'
import '../../libs/mapbox-rtl'
+
+const IS_SUPPORTED = MapboxGl.supported();
+
function renderPropertyPopup(features) {
var mountNode = document.createElement('div');
ReactDOM.render(
, mountNode)
@@ -82,6 +84,8 @@ export default class MapboxGlMap extends React.Component {
}
updateMapFromProps(props) {
+ if(!IS_SUPPORTED) return;
+
if(!this.state.map) return
const metadata = props.mapStyle.metadata || {}
MapboxGl.accessToken = metadata['maputnik:mapbox_access_token'] || tokens.mapbox
@@ -94,6 +98,8 @@ export default class MapboxGlMap extends React.Component {
}
componentDidUpdate(prevProps) {
+ if(!IS_SUPPORTED) return;
+
const map = this.state.map;
this.updateMapFromProps(this.props);
@@ -106,9 +112,12 @@ export default class MapboxGlMap extends React.Component {
}
map.showTileBoundaries = this.props.options.showTileBoundaries;
+ map.showCollisionBoxes = this.props.options.showCollisionBoxes;
}
componentDidMount() {
+ if(!IS_SUPPORTED) return;
+
const mapOpts = {
...this.props.options,
container: this.container,
@@ -119,6 +128,7 @@ export default class MapboxGlMap extends React.Component {
const map = new MapboxGl.Map(mapOpts);
map.showTileBoundaries = mapOpts.showTileBoundaries;
+ map.showCollisionBoxes = mapOpts.showCollisionBoxes;
const zoom = new ZoomControl;
map.addControl(zoom, 'top-right');
@@ -164,9 +174,20 @@ export default class MapboxGlMap extends React.Component {
}
render() {
- return
this.container = x}
- >
+ if(IS_SUPPORTED) {
+ return
this.container = x}
+ >
+ }
+ else {
+ return
+
+ Error: Cannot load MapboxGL, WebGL is either unsupported or disabled
+
+
+ }
}
}
diff --git a/src/components/map/OpenLayers3Map.jsx b/src/components/map/OpenLayers3Map.jsx
index a5881de..fade6b2 100644
--- a/src/components/map/OpenLayers3Map.jsx
+++ b/src/components/map/OpenLayers3Map.jsx
@@ -1,7 +1,5 @@
import React from 'react'
import PropTypes from 'prop-types'
-import style from '../../libs/style.js'
-import isEqual from 'lodash.isequal'
import { loadJSON } from '../../libs/urlopen'
import 'ol/ol.css'
diff --git a/src/components/modals/AddModal.jsx b/src/components/modals/AddModal.jsx
index b42b736..0cdac51 100644
--- a/src/components/modals/AddModal.jsx
+++ b/src/components/modals/AddModal.jsx
@@ -2,8 +2,6 @@ import React from 'react'
import PropTypes from 'prop-types'
import Button from '../Button'
-import InputBlock from '../inputs/InputBlock'
-import StringInput from '../inputs/StringInput'
import Modal from './Modal'
import LayerTypeBlock from '../layers/LayerTypeBlock'
@@ -22,7 +20,7 @@ class AddModal extends React.Component {
sources: PropTypes.object.isRequired,
}
- addLayer() {
+ addLayer = () => {
const changedLayers = this.props.layers.slice(0)
const layer = {
id: this.state.id,
@@ -151,7 +149,7 @@ class AddModal extends React.Component {
}
-
-
Save style
-
-
}
}
diff --git a/src/components/modals/LoadingModal.jsx b/src/components/modals/LoadingModal.jsx
index 42b8eca..f4ef6bb 100644
--- a/src/components/modals/LoadingModal.jsx
+++ b/src/components/modals/LoadingModal.jsx
@@ -13,10 +13,6 @@ class LoadingModal extends React.Component {
message: PropTypes.node.isRequired,
}
- constructor(props) {
- super(props);
- }
-
underlayOnClick(e) {
// This stops click events falling through to underlying modals.
e.stopPropagation();
diff --git a/src/components/modals/OpenModal.jsx b/src/components/modals/OpenModal.jsx
index d9df74c..5d9901f 100644
--- a/src/components/modals/OpenModal.jsx
+++ b/src/components/modals/OpenModal.jsx
@@ -4,7 +4,6 @@ import LoadingModal from './LoadingModal'
import Modal from './Modal'
import Button from '../Button'
import FileReaderInput from 'react-file-reader-input'
-import request from 'request'
import FileUploadIcon from 'react-icons/lib/md/file-upload'
import AddIcon from 'react-icons/lib/md/add-circle-outline'
@@ -74,42 +73,48 @@ class OpenModal extends React.Component {
}
}
- onStyleSelect(styleUrl) {
+ onStyleSelect = (styleUrl) => {
this.clearError();
- const reqOpts = {
- url: styleUrl,
- withCredentials: false,
- }
-
- const activeRequest = request(reqOpts, (error, response, body) => {
+ const activeRequest = fetch(styleUrl, {
+ mode: 'cors',
+ credentials: "same-origin"
+ })
+ .then(function(response) {
+ return response.json();
+ })
+ .then((body) => {
this.setState({
activeRequest: null,
activeRequestUrl: null
});
- if (!error && response.statusCode == 200) {
- const mapStyle = style.ensureStyleValidity(JSON.parse(body))
- console.log('Loaded style ', mapStyle.id)
- this.props.onStyleOpen(mapStyle)
- this.onOpenToggle()
- } else {
- console.warn('Could not open the style URL', styleUrl)
- }
+ const mapStyle = style.ensureStyleValidity(body)
+ console.log('Loaded style ', mapStyle.id)
+ this.props.onStyleOpen(mapStyle)
+ this.onOpenToggle()
+ })
+ .catch((err) => {
+ this.setState({
+ activeRequest: null,
+ activeRequestUrl: null
+ });
+ console.error(err);
+ console.warn('Could not open the style URL', styleUrl)
})
this.setState({
activeRequest: activeRequest,
- activeRequestUrl: reqOpts.url
+ activeRequestUrl: styleUrl
})
}
- onOpenUrl() {
+ onOpenUrl = () => {
const url = this.styleUrlElement.value;
this.onStyleSelect(url);
}
- onUpload(_, files) {
+ onUpload = (_, files) => {
const [e, file] = files[0];
const reader = new FileReader();
@@ -146,7 +151,7 @@ class OpenModal extends React.Component {
url={style.url}
title={style.title}
thumbnailUrl={style.thumbnail}
- onSelect={this.onStyleSelect.bind(this)}
+ onSelect={this.onStyleSelect}
/>
})
@@ -170,7 +175,7 @@ class OpenModal extends React.Component {
Upload Style
Upload a JSON style from your computer.
-
+
Upload
@@ -182,7 +187,7 @@ class OpenModal extends React.Component {
this.styleUrlElement = input} className="maputnik-input" placeholder="Enter URL..."/>
- Open URL
+ Open URL
diff --git a/src/components/modals/SettingsModal.jsx b/src/components/modals/SettingsModal.jsx
index b7da0a1..c89aa98 100644
--- a/src/components/modals/SettingsModal.jsx
+++ b/src/components/modals/SettingsModal.jsx
@@ -15,10 +15,6 @@ class SettingsModal extends React.Component {
onOpenToggle: PropTypes.func.isRequired,
}
- constructor(props) {
- super(props);
- }
-
changeStyleProperty(property, value) {
const changedStyle = {
...this.props.mapStyle,
@@ -107,7 +103,7 @@ class SettingsModal extends React.Component {
data-wd-key="modal-settings.maputnik:renderer"
options={[
['mbgljs', 'MapboxGL JS'],
- ['ol3', 'Open Layers 3'],
+ // ['ol3', 'Open Layers 3'],
]}
value={metadata['maputnik:renderer'] || 'mbgljs'}
onChange={this.changeMetadataProperty.bind(this, 'maputnik:renderer')}
diff --git a/src/components/modals/ShortcutsModal.jsx b/src/components/modals/ShortcutsModal.jsx
index 6a17e4b..df8312e 100644
--- a/src/components/modals/ShortcutsModal.jsx
+++ b/src/components/modals/ShortcutsModal.jsx
@@ -1,7 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
-import Button from '../Button'
import Modal from './Modal'
@@ -11,10 +10,6 @@ class ShortcutsModal extends React.Component {
onOpenToggle: PropTypes.func.isRequired,
}
- constructor(props) {
- super(props);
- }
-
render() {
const help = [
{
diff --git a/src/components/modals/SurveyModal.jsx b/src/components/modals/SurveyModal.jsx
index e1ae021..7f10bc3 100644
--- a/src/components/modals/SurveyModal.jsx
+++ b/src/components/modals/SurveyModal.jsx
@@ -12,8 +12,6 @@ class SurveyModal extends React.Component {
onOpenToggle: PropTypes.func.isRequired,
}
- constructor(props) { super(props); }
-
onClick = () => {
window.open('https://gregorywolanski.typeform.com/to/cPgaSY', '_blank');
diff --git a/src/libs/accessibility.js b/src/libs/accessibility.js
index 095e953..23c1339 100644
--- a/src/libs/accessibility.js
+++ b/src/libs/accessibility.js
@@ -1,8 +1,8 @@
-import lodash from 'lodash'
+import throttle from 'lodash.throttle'
// Throttle for 3 seconds so when a user enables it they don't have to refresh the page.
-const reducedMotionEnabled = lodash.throttle(() => {
+const reducedMotionEnabled = throttle(() => {
return window.matchMedia("(prefers-reduced-motion: reduce)").matches
}, 3000);
diff --git a/src/libs/apistore.js b/src/libs/apistore.js
index 91fa7e2..aa114b2 100644
--- a/src/libs/apistore.js
+++ b/src/libs/apistore.js
@@ -1,4 +1,3 @@
-import request from 'request'
import style from './style.js'
import ReconnectingWebSocket from 'reconnecting-websocket'
@@ -14,15 +13,20 @@ export class ApiStyleStore {
}
init(cb) {
- request(localUrl + '/styles', (error, response, body) => {
- if (!error && body && response.statusCode == 200) {
- const styleIds = JSON.parse(body)
- this.latestStyleId = styleIds[0]
- this.notifyLocalChanges()
- cb(null)
- } else {
- cb(new Error('Can not connect to style API'))
- }
+ fetch(localUrl + '/styles', {
+ mode: 'cors',
+ })
+ .then(function(response) {
+ return response.json();
+ })
+ .then(function(body) {
+ const styleIds = body;
+ this.latestStyleId = styleIds[0]
+ this.notifyLocalChanges()
+ cb(null)
+ })
+ .catch(function() {
+ cb(new Error('Can not connect to style API'))
})
}
@@ -44,8 +48,14 @@ export class ApiStyleStore {
latestStyle(cb) {
if(this.latestStyleId) {
- request(localUrl + '/styles/' + this.latestStyleId, (error, response, body) => {
- cb(style.ensureStyleValidity(JSON.parse(body)))
+ fetch(localUrl + '/styles/' + this.latestStyleId, {
+ mode: 'cors',
+ })
+ .then(function(response) {
+ return response.json();
+ })
+ .then(function(body) {
+ cb(style.ensureStyleValidity(body))
})
} else {
throw new Error('No latest style available. You need to init the api backend first.')
@@ -55,11 +65,15 @@ export class ApiStyleStore {
// Save current style replacing previous version
save(mapStyle) {
const id = mapStyle.id
- request.put({
- url: localUrl + '/styles/' + id,
- json: true,
- body: mapStyle
- }, (error, response, body) => {
+ fetch(localUrl + '/styles/' + id, {
+ method: "PUT",
+ mode: 'cors',
+ headers: {
+ "Content-Type": "application/json; charset=utf-8",
+ },
+ body: JSON.stringify(mapStyle)
+ })
+ .catch(function(error) {
if(error) console.error(error)
})
return mapStyle
diff --git a/src/libs/mapbox-rtl.js b/src/libs/mapbox-rtl.js
index f9dc199..84d9211 100644
--- a/src/libs/mapbox-rtl.js
+++ b/src/libs/mapbox-rtl.js
@@ -1,9 +1,9 @@
-import MapboxGl from 'mapbox-gl/dist/mapbox-gl.js'
+import MapboxGl from 'mapbox-gl'
// Load mapbox-gl-rtl-text using object urls without needing http://localhost for AJAX.
-const data = require("base64-loader?mimetype=text/javascript!@mapbox/mapbox-gl-rtl-text/mapbox-gl-rtl-text.js");
+const data = require("raw-loader?mimetype=text/javascript!@mapbox/mapbox-gl-rtl-text/mapbox-gl-rtl-text.js");
-const blob = new window.Blob([window.atob(data)]);
+const blob = new window.Blob([data]);
const objectUrl = window.URL.createObjectURL(blob, {
type: "text/javascript"
});
diff --git a/src/libs/metadata.js b/src/libs/metadata.js
index deac199..2e1fb24 100644
--- a/src/libs/metadata.js
+++ b/src/libs/metadata.js
@@ -1,22 +1,19 @@
-import request from 'request'
import npmurl from 'url'
function loadJSON(url, defaultValue, cb) {
- request({
- url: url,
- withCredentials: false,
- }, (error, response, body) => {
- if (!error && body && response.statusCode == 200) {
- try {
- cb(JSON.parse(body))
- } catch(err) {
- console.error(err)
- cb(defaultValue)
- }
- } else {
- console.warn('Can not metadata for ' + url)
- cb(defaultValue)
- }
+ fetch(url, {
+ mode: 'cors',
+ credentials: "same-origin"
+ })
+ .then(function(response) {
+ return response.json();
+ })
+ .then(function(body) {
+ cb(body)
+ })
+ .catch(function() {
+ console.warn('Can not metadata for ' + url)
+ cb(defaultValue)
})
}
diff --git a/src/libs/style.js b/src/libs/style.js
index b867148..60598f5 100644
--- a/src/libs/style.js
+++ b/src/libs/style.js
@@ -1,4 +1,3 @@
-import React from 'react';
import deref from '@mapbox/mapbox-gl-style-spec/deref'
import tokens from '../config/tokens.json'
@@ -54,27 +53,27 @@ function indexOfLayer(layers, layerId) {
return null
}
-function getAccessToken(key, mapStyle, opts) {
- if(key === "thunderforest_transport" || key === "thunderforest_outdoors") {
- key = "thunderforest";
+function getAccessToken(sourceName, mapStyle, opts) {
+ if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") {
+ sourceName = "thunderforest"
}
const metadata = mapStyle.metadata || {}
- let accessToken = metadata['maputnik:'+key+'_access_token'];
+ let accessToken = metadata[`maputnik:${sourceName}_access_token`]
if(opts.allowFallback && !accessToken) {
- accessToken = tokens[key];
+ accessToken = tokens[sourceName]
}
return accessToken;
}
-function replaceSourceAccessToken(mapStyle, key, opts={}) {
- const source = mapStyle.sources[key]
+function replaceSourceAccessToken(mapStyle, sourceName, opts={}) {
+ const source = mapStyle.sources[sourceName]
if(!source) return mapStyle
if(!source.hasOwnProperty("url")) return mapStyle
- const accessToken = getAccessToken(key, mapStyle, opts)
+ const accessToken = getAccessToken(sourceName, mapStyle, opts)
if(!accessToken) {
// Early exit.
@@ -83,7 +82,7 @@ function replaceSourceAccessToken(mapStyle, key, opts={}) {
const changedSources = {
...mapStyle.sources,
- [key]: {
+ [sourceName]: {
...source,
url: source.url.replace('{key}', accessToken)
}
@@ -92,21 +91,20 @@ function replaceSourceAccessToken(mapStyle, key, opts={}) {
...mapStyle,
sources: changedSources
}
-
return changedStyle
}
function replaceAccessTokens(mapStyle, opts={}) {
- let changedStyle = mapStyle;
+ let changedStyle = mapStyle
- Object.keys(mapStyle.sources).forEach((tokenKey) => {
- changedStyle = replaceSourceAccessToken(changedStyle, tokenKey, opts);
+ Object.keys(mapStyle.sources).forEach((sourceName) => {
+ changedStyle = replaceSourceAccessToken(changedStyle, sourceName, opts);
})
- if(mapStyle.glyphs && mapStyle.glyphs.match(/\.tileserver\.org/)) {
+ if (mapStyle.glyphs && mapStyle.glyphs.match(/\.tilehosting\.com/)) {
changedStyle = {
...changedStyle,
- glyphs: mapStyle.glyphs ? mapStyle.glyphs.replace('{key}', getAccessToken("openmaptiles", mapStyle, opts)) : mapStyle.glyphs
+ glyphs: mapStyle.glyphs.replace('{key}', getAccessToken("openmaptiles", mapStyle, opts))
}
}
diff --git a/src/libs/stylestore.js b/src/libs/stylestore.js
index c921d5c..17499bd 100644
--- a/src/libs/stylestore.js
+++ b/src/libs/stylestore.js
@@ -1,8 +1,6 @@
-import { colorizeLayers } from './style.js'
import style from './style.js'
import { loadStyleUrl } from './urlopen'
import publicSources from '../config/styles.json'
-import request from 'request'
const storagePrefix = "maputnik"
const stylePrefix = 'style'
diff --git a/src/libs/urlopen.js b/src/libs/urlopen.js
index 93c550a..20b7aa3 100644
--- a/src/libs/urlopen.js
+++ b/src/libs/urlopen.js
@@ -1,4 +1,3 @@
-import request from 'request'
import url from 'url'
import style from './style.js'
@@ -9,34 +8,40 @@ export function initialStyleUrl() {
export function loadStyleUrl(styleUrl, cb) {
console.log('Loading style', styleUrl)
- request({
- url: styleUrl,
- withCredentials: false,
- }, (error, response, body) => {
- if (!error && response.statusCode == 200) {
- cb(style.ensureStyleValidity(JSON.parse(body)))
- } else {
- console.warn('Could not fetch default style', styleUrl)
- cb(style.emptyStyle)
- }
+ fetch(styleUrl, {
+ mode: 'cors',
+ credentials: "same-origin"
+ })
+ .then(function(response) {
+ return response.json();
+ })
+ .then(function(body) {
+ cb(style.ensureStyleValidity(body))
+ })
+ .catch(function() {
+ console.warn('Could not fetch default style', styleUrl)
+ cb(style.emptyStyle)
})
}
export function loadJSON(url, defaultValue, cb) {
- request({
- url: url,
- withCredentials: false,
- }, (error, response, body) => {
- if (!error && body && response.statusCode == 200) {
- try {
- cb(JSON.parse(body))
- } catch(err) {
- console.error(err)
- cb(defaultValue)
- }
- } else {
- console.error('Can not load JSON from ' + url)
+ fetch(url, {
+ mode: 'cors',
+ credentials: "same-origin"
+ })
+ .then(function(response) {
+ return response.json();
+ })
+ .then(function(body) {
+ try {
+ cb(body)
+ } catch(err) {
+ console.error(err)
cb(defaultValue)
}
})
+ .catch(function() {
+ console.error('Can not load JSON from ' + url)
+ cb(defaultValue)
+ })
}
diff --git a/src/styles/_components.scss b/src/styles/_components.scss
index e257211..302ec52 100644
--- a/src/styles/_components.scss
+++ b/src/styles/_components.scss
@@ -1,5 +1,6 @@
// MAP
.maputnik-map {
+ display: flex;
position: fixed !important;
top: $toolbar-height + $toolbar-offset;
right: 0;
@@ -10,6 +11,16 @@
- 200px /* layer list */
- 350px /* layer editor */
);
+
+ &--error {
+ align-items: center;
+ justify-content: center;
+ }
+
+ &__error-message {
+ margin: 16px;
+ text-align: center;
+ }
}
// DOC LABEL
diff --git a/test/functional/history/index.js b/test/functional/history/index.js
index 2cd5b0e..e788e7e 100644
--- a/test/functional/history/index.js
+++ b/test/functional/history/index.js
@@ -1,7 +1,6 @@
var assert = require("assert");
var config = require("../../config/specs");
var helper = require("../helper");
-var wd = require("../../wd-helper");
describe.skip("history", function() {
diff --git a/test/functional/index.js b/test/functional/index.js
index 5522706..3c9f5ec 100644
--- a/test/functional/index.js
+++ b/test/functional/index.js
@@ -1,6 +1,4 @@
-var assert = require('assert');
var config = require("../config/specs");
-var geoServer = require("../geojson-server");
var helper = require("./helper");
require("./util/webdriverio-ext");
diff --git a/test/functional/map/index.js b/test/functional/map/index.js
index 498c0a1..2df5393 100644
--- a/test/functional/map/index.js
+++ b/test/functional/map/index.js
@@ -1,5 +1,3 @@
-var assert = require('assert');
-var wd = require("../../wd-helper");
var config = require("../../config/specs");
var helper = require("../helper");
diff --git a/test/functional/screenshots/index.js b/test/functional/screenshots/index.js
index 9c5634c..a6d6d2a 100644
--- a/test/functional/screenshots/index.js
+++ b/test/functional/screenshots/index.js
@@ -1,4 +1,3 @@
-var artifacts = require("../../artifacts");
var config = require("../../config/specs");
var helper = require("../helper");
var wd = require("../../wd-helper");