Reduce bundle size

- Use the browsers fetch rather than the request module
 - base64-loader -> raw-loader
 - Remove ol3 because it's been broken for a while
 - Removed old GitHub gist support as it's no longer functional
 - Removed Mousetrap as we were only using a small part of the functionality
 - Moved to single js file to make things simplier
This commit is contained in:
orangemug
2018-08-22 09:33:01 +01:00
parent 70f1f9ffac
commit 922ee616ec
12 changed files with 134 additions and 321 deletions

View File

@@ -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'
@@ -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)
@@ -187,14 +188,33 @@ export default class App extends React.Component {
})
}
handleKeyPress(e) {
if(navigator.platform.toUpperCase().indexOf('MAC') >= 0) {
if(e.metaKey && e.shiftKey && e.keyCode === 90) {
console.log("redo");
this.onRedo(e);
}
else if(e.metaKey && e.keyCode === 90) {
console.log("undo");
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) {
@@ -371,7 +391,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();
})
@@ -423,12 +445,12 @@ export default class App extends React.Component {
// Check if OL3 code has been loaded?
if(renderer === 'ol3') {
mapElement = <OpenLayers3Map {...mapProps} />
mapElement = <div>TODO</div>
} else {
mapElement = <MapboxGlMap {...mapProps}
inspectModeEnabled={this.state.inspectModeEnabled}
highlightedLayer={this.state.mapStyle.layers[this.state.selectedLayerIndex]}
onLayerSelect={this.onLayerSelect.bind(this)} />
onLayerSelect={this.onLayerSelect} />
}
const elementStyle = {};

View File

@@ -11,206 +11,8 @@ import Modal from './Modal'
import MdFileDownload from 'react-icons/lib/md/file-download'
import TiClipboard from 'react-icons/lib/ti/clipboard'
import style from '../../libs/style'
import GitHub from 'github-api'
import { CopyToClipboard } from 'react-copy-to-clipboard'
class Gist extends React.Component {
static propTypes = {
mapStyle: PropTypes.object.isRequired,
onStyleChanged: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
this.state = {
preview: false,
public: false,
saving: false,
latestGist: null,
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
this.setState({
...this.state,
preview: !!(nextProps.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']
})
}
onSave() {
this.setState({
...this.state,
saving: true
});
const preview = this.state.preview;
const mapboxToken = (this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token'];
const mapStyleStr = preview ?
styleSpec.format(stripAccessTokens(style.replaceAccessTokens(this.props.mapStyle))) :
styleSpec.format(stripAccessTokens(this.props.mapStyle));
const styleTitle = this.props.mapStyle.name || 'Style';
const htmlStr = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>`+styleTitle+` Preview</title>
<link rel="stylesheet" type="text/css" href="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.css" />
<script src="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = '${mapboxToken}';
var map = new mapboxgl.Map({
container: 'map',
style: 'style.json',
attributionControl: true,
hash: true
});
map.addControl(new mapboxgl.NavigationControl());
</script>
</body>
</html>
`
const files = {
"style.json": {
content: mapStyleStr
}
}
if(preview) {
files["index.html"] = {
content: htmlStr
}
}
const gh = new GitHub();
let gist = gh.getGist(); // not a gist yet
gist.create({
public: this.state.public,
description: styleTitle,
files: files
}).then(function({data}) {
return gist.read();
}).then(function({data}) {
this.setState({
...this.state,
latestGist: data,
saving: false,
});
}.bind(this));
}
onPreviewChange(value) {
this.setState({
...this.state,
preview: value
})
}
onPublicChange(value) {
this.setState({
...this.state,
public: value
})
}
changeMetadataProperty(property, value) {
const changedStyle = {
...this.props.mapStyle,
metadata: {
...this.props.mapStyle.metadata,
[property]: value
}
}
this.props.onStyleChanged(changedStyle)
}
renderPreviewLink() {
const gist = this.state.latestGist;
const user = gist.user || 'anonymous';
const preview = !!gist.files['index.html'];
if(preview) {
return <span><a target="_blank" rel="noopener noreferrer" href={"https://bl.ocks.org/"+user+"/"+gist.id}>Preview</a>,{' '}</span>
}
return null;
}
renderLatestGist() {
const gist = this.state.latestGist;
const saving = this.state.saving;
if(saving) {
return <p>Saving...</p>
} else if(gist) {
const user = gist.user || 'anonymous';
const rawGistLink = "https://gist.githubusercontent.com/" + user + "/" + gist.id + "/raw/" + gist.history[0].version + "/style.json"
const maputnikStyleLink = "https://maputnik.github.io/editor/?style=" + rawGistLink
return <div className="maputnik-render-gist">
<p>
Latest saved gist:{' '}
{this.renderPreviewLink(this)}
<a target="_blank" rel="noopener noreferrer" href={"https://gist.github.com/" + user + "/" + gist.id}>Source</a>
</p>
<p>
<CopyToClipboard text={maputnikStyleLink}>
<span>Share this style: <Button><TiClipboard size={18} /></Button></span>
</CopyToClipboard>
<StringInput value={maputnikStyleLink} />
</p>
</div>
}
}
render() {
return <div className="maputnik-export-gist">
<Button onClick={this.onSave.bind(this)}>
<MdFileDownload />
Save to Gist (anonymous)
</Button>
<div className="maputnik-modal-sub-section">
<CheckboxInput
value={this.state.public}
name='gist-style-public'
onChange={this.onPublicChange.bind(this)}
/>
<span> Public gist</span>
</div>
<div className="maputnik-modal-sub-section">
<CheckboxInput
value={this.state.preview}
name='gist-style-preview'
onChange={this.onPreviewChange.bind(this)}
/>
<span> Include preview</span>
</div>
{this.state.preview ?
<div>
<InputBlock
label={"OpenMapTiles Access Token: "}>
<StringInput
value={(this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}/>
</InputBlock>
<InputBlock
label={"Mapbox Access Token: "}>
<StringInput
value={(this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}/>
</InputBlock>
<a target="_blank" rel="noopener noreferrer" href="https://openmaptiles.com/hosting/">Get your free access token</a>
</div>
: null}
{this.renderLatestGist()}
</div>
}
}
function stripAccessTokens(mapStyle) {
const changedMetadata = { ...mapStyle.metadata }
@@ -294,10 +96,6 @@ class ExportModal extends React.Component {
</Button>
</div>
<div className="maputnik-modal-section hide">
<h4>Save style</h4>
<Gist mapStyle={this.props.mapStyle} onStyleChanged={this.props.onStyleChanged}/>
</div>
</Modal>
}
}

View File

@@ -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'
@@ -77,30 +76,36 @@ class OpenModal extends React.Component {
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
})
}

View File

@@ -107,7 +107,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')}