From f0992ba668a6baee433e9630eb54209a175bf07e Mon Sep 17 00:00:00 2001 From: cybice Date: Sat, 3 Oct 2015 19:20:59 +0300 Subject: [PATCH] Switch to last airnbnb eslint config --- .eslintrc | 238 ++----------------------- package.json | 4 + src/__tests__/eye_test.js | 4 +- src/google_map.js | 207 +++++++++++---------- src/google_map_map.js | 2 +- src/google_map_markers.js | 54 +++--- src/google_map_markers_prerender.js | 4 +- src/utils/detect.js | 11 +- src/utils/geo.js | 15 +- src/utils/lib_geo/lat_lng.js | 38 ++-- src/utils/lib_geo/lat_lng_bounds.js | 138 +++++++------- src/utils/lib_geo/transform.js | 140 ++++++++------- src/utils/lib_geo/wrap.js | 10 +- src/utils/loaders/google_map_loader.js | 16 +- 14 files changed, 364 insertions(+), 517 deletions(-) diff --git a/.eslintrc b/.eslintrc index ad6b9f8..f7bae48 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,232 +1,24 @@ { - "parser": 'babel-eslint', + "extends": "eslint-config-airbnb", "env": { "browser": true, - "node": true, - "es6": true + "mocha": true, + "node": true }, "globals": { - "__DEV__": false + "__DEV__": false, + "__DEV_TOOLS__": false }, - "ecmaFeatures": { - "arrowFunctions": true, - "binaryLiterals": true, - "blockBindings": true, - "classes": true, - "defaultParams": true, - "destructuring": true, - "forOf": true, - "generators": true, - "modules": true, - "objectLiteralComputedProperties": true, - "objectLiteralDuplicateProperties": true, - "objectLiteralShorthandMethods": true, - "objectLiteralShorthandProperties": true, - "octalLiterals": true, - "regexUFlag": true, - "regexYFlag": true, - "spread": true, - "superInFunctions": true, - "templateStrings": true, - "unicodeCodePointEscapes": true, - "globalReturn": true, - "jsx": true + "rules": { + "id-length": 0, + "max-len": [1, 100, 2], + "react/jsx-uses-react": 2, + "react/jsx-uses-vars": 2, + "react/react-in-jsx-scope": 2, + "block-scoped-var": 0, + "padded-blocks": 0 }, "plugins": [ "react" - ], - "rules": { - "react/display-name": 0, - "react/jsx-boolean-value": 1, - "react/jsx-quotes": 1, - "react/jsx-no-undef": 1, - "react/jsx-sort-props": 0, - "react/jsx-sort-prop-types": 0, - "react/jsx-uses-react": 1, - "react/jsx-uses-vars": 1, - "react/no-did-mount-set-state": 1, - "react/no-did-update-set-state": 1, - "react/no-multi-comp": 1, - "react/no-unknown-property": 1, - "react/prop-types": 1, - "react/react-in-jsx-scope": 1, - "react/self-closing-comp": 1, - "react/wrap-multilines": 1, - /** - * Strict mode - */ - // babel inserts "use strict"; for us - // http://eslint.org/docs/rules/strict - "strict": [2, "never"], - /** - * ES6 - */ - "no-var": 2, // http://eslint.org/docs/rules/no-var - - /** - * Variables - */ - "no-shadow": 1, // http://eslint.org/docs/rules/no-shadow - "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names - "no-unused-vars": [ - 1, - { - // http://eslint.org/docs/rules/no-unused-vars - "vars": "local", - "args": "after-used" - } - ], - "no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define - - /** - * Possible errors - */ - "comma-dangle": [2, "never"], // http://eslint.org/docs/rules/comma-dangle - "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign - "no-console": 1, // http://eslint.org/docs/rules/no-console - "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger - "no-alert": 1, // http://eslint.org/docs/rules/no-alert - "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition - "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys - "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case - "no-empty": 2, // http://eslint.org/docs/rules/no-empty - "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign - "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast - "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi - "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign - "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations - "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp - "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace - "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls - "no-reserved-keys": 2, // http://eslint.org/docs/rules/no-reserved-keys - "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays - "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable - "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan - "block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var - - /** - * Best practices - */ - "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return - "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly - "default-case": 2, // http://eslint.org/docs/rules/default-case - "dot-notation": [ - 2, - { - // http://eslint.org/docs/rules/dot-notation - "allowKeywords": true - } - ], - "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq - "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in - "no-caller": 2, // http://eslint.org/docs/rules/no-caller - "no-else-return": 2, // http://eslint.org/docs/rules/no-else-return - "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null - "no-eval": 2, // http://eslint.org/docs/rules/no-eval - "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native - "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind - "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough - "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal - "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval - "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks - "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func - "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str - "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign - "no-new": 2, // http://eslint.org/docs/rules/no-new - "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func - "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers - "no-octal": 2, // http://eslint.org/docs/rules/no-octal - "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape - "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign - "no-proto": 2, // http://eslint.org/docs/rules/no-proto - "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare - "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign - "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url - "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare - "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences - "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal - "no-with": 2, // http://eslint.org/docs/rules/no-with - "radix": 2, // http://eslint.org/docs/rules/radix - "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top - "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife - "yoda": 2, // http://eslint.org/docs/rules/yoda - - /** - * Style - */ - "indent": [2, 2], // http://eslint.org/docs/rules/ - "brace-style": [ - 2, // http://eslint.org/docs/rules/brace-style - "1tbs", - { - "allowSingleLine": true - } - ], - "quotes": [ - 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes - ], - "camelcase": [ - 2, - { - // http://eslint.org/docs/rules/camelcase - "properties": "never" - } - ], - "comma-spacing": [ - 2, - { - // http://eslint.org/docs/rules/comma-spacing - "before": false, - "after": true - } - ], - "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style - "eol-last": 2, // http://eslint.org/docs/rules/eol-last - "func-names": 1, // http://eslint.org/docs/rules/func-names - "key-spacing": [ - 2, - { - // http://eslint.org/docs/rules/key-spacing - "beforeColon": false, - "afterColon": true - } - ], - "new-cap": [ - 2, - { - // http://eslint.org/docs/rules/new-cap - "newIsCap": true - } - ], - "no-multiple-empty-lines": [ - 2, - { - // http://eslint.org/docs/rules/no-multiple-empty-lines - "max": 2 - } - ], - "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary - "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object - "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func - "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces - "no-wrap-func": 2, // http://eslint.org/docs/rules/no-wrap-func - "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle - "one-var": [2, "never"], // http://eslint.org/docs/rules/one-var - "padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks - "semi": [2, "always"], // http://eslint.org/docs/rules/semi - "semi-spacing": [ - 2, - { - // http://eslint.org/docs/rules/semi-spacing - "before": false, - "after": true - } - ], - "space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords - "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks - "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren - "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops - "space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case - "spaced-line-comment": 2 // http://eslint.org/docs/rules/spaced-line-comment - } -} \ No newline at end of file + ] +} diff --git a/package.json b/package.json index 02dba04..3bf9326 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,10 @@ }, "homepage": "https://github.com/istarkov/google-map-react#readme", "dependencies": { + "babel-eslint": "^4.1.3", + "eslint": "^1.6.0", + "eslint-config-airbnb": "^0.1.0", + "eslint-plugin-react": "^3.5.1", "eventemitter3": "^1.1.0", "lodash.assign": "^3.2.0", "lodash.isfunction": "^3.0.5", diff --git a/src/__tests__/eye_test.js b/src/__tests__/eye_test.js index cde17e8..0472547 100644 --- a/src/__tests__/eye_test.js +++ b/src/__tests__/eye_test.js @@ -8,13 +8,13 @@ export default class SimpleTest extends Component { static propTypes = { center: PropTypes.array, zoom: PropTypes.number, - greatPlaceCoords: PropTypes.any + greatPlaceCoords: PropTypes.any, }; static defaultProps = { center: [59.938043, 30.337157], zoom: 9, - greatPlaceCoords: {lat: 59.724465, lng: 30.080121} + greatPlaceCoords: {lat: 59.724465, lng: 30.080121}, }; constructor(props) { diff --git a/src/google_map.js b/src/google_map.js index 19d483b..ac10424 100644 --- a/src/google_map.js +++ b/src/google_map.js @@ -29,7 +29,7 @@ const ReactDOM = isReact14(React) const kEPS = 0.00001; const K_GOOGLE_TILE_SIZE = 256; -function defaultOptions_(/*maps*/) { +function defaultOptions_(/* maps */) { return { overviewMapControl: false, streetViewControl: false, @@ -37,7 +37,7 @@ function defaultOptions_(/*maps*/) { mapTypeControl: false, // disable poi styles: [{ featureType: 'poi', elementType: 'labels', stylers: [{ visibility: 'off' }]}], - minZoom: 3 // i need to dynamically calculate possible zoom value + minZoom: 3, // i need to dynamically calculate possible zoom value }; } @@ -46,7 +46,7 @@ const style = { height: '100%', margin: 0, padding: 0, - position: 'relative' + position: 'relative', }; export default class GoogleMap extends Component { @@ -67,23 +67,21 @@ export default class GoogleMap extends Component { hoverDistance: PropTypes.number, debounced: PropTypes.bool, margin: PropTypes.array, - googleMapLoader: PropTypes.any + googleMapLoader: PropTypes.any, }; static defaultProps = { - distanceToMouse(pt, mousePos /*, markerProps*/) { - const x = pt.x; - const y = pt.y; // - 20; - return Math.sqrt((x - mousePos.x) * (x - mousePos.x) + (y - mousePos.y) * (y - mousePos.y)); + distanceToMouse(pt, mousePos /* , markerProps */) { + return Math.sqrt( + (pt.x - mousePos.x) * (pt.x - mousePos.x) + (pt.y - mousePos.y) * (pt.y - mousePos.y) + ); }, hoverDistance: 30, debounced: true, options: defaultOptions_, - googleMapLoader + googleMapLoader, }; - shouldComponentUpdate = shouldPureComponentUpdate; - constructor(props) { super(props); this.mounted_ = false; @@ -110,10 +108,76 @@ export default class GoogleMap extends Component { this.zoomAnimationInProgress_ = false; this.state = { - overlayCreated: false + overlayCreated: false, }; } + componentDidMount() { + this.mounted_ = true; + window.addEventListener('resize', this._onWindowResize); + + setTimeout(() => { // to detect size + this._setViewSize(); + if (this._isCenterDefined(this.props.center)) { + this._initMap(); + } else { + this.props.googleMapLoader(this.props.apiKey); // начать подгружать можно уже сейчас + } + }, 0, this); + } + + + componentWillReceiveProps(nextProps) { + if (!this._isCenterDefined(this.props.center) && this._isCenterDefined(nextProps.center)) { + setTimeout(() => + this._initMap(), 0); + } + + if (this.map_) { + const centerLatLng = this.geoService_.getCenter(); + if (nextProps.center) { + if (Math.abs(nextProps.center[0] - centerLatLng.lat) + + Math.abs(nextProps.center[1] - centerLatLng.lng) > kEPS) { + this.map_.panTo({lat: nextProps.center[0], lng: nextProps.center[1]}); + } + } + + // if zoom chaged by user + if (Math.abs(nextProps.zoom - this.props.zoom) > 0) { + this.map_.setZoom(nextProps.zoom); + } + } + } + + shouldComponentUpdate = shouldPureComponentUpdate; + + componentDidUpdate() { + this.markersDispatcher_.emit('kON_CHANGE'); + } + + componentWillUnmount() { + this.mounted_ = false; + + window.removeEventListener('resize', this._onWindowResize); + + if (this.overlay_) { + // this triggers overlay_.onRemove(), which will unmount the + this.overlay_.setMap(null); + } + + if (this.maps_ && this.map_) { + this.maps_.event.clearInstanceListeners(this.map_); + } + + this.map_ = null; + this.maps_ = null; + this.markersDispatcher_.dispose(); + + this.resetSizeOnIdle_ = false; + + delete this.map_; + delete this.markersDispatcher_; + } _initMap = () => { const center = this.props.center; @@ -131,18 +195,24 @@ export default class GoogleMap extends Component { const propsOptions = { zoom: this.props.zoom, - center: new maps.LatLng(centerLatLng.lat, centerLatLng.lng) + center: new maps.LatLng(centerLatLng.lat, centerLatLng.lng), }; // prevent to exapose full api // next props must be exposed (console.log(Object.keys(pick(maps, isPlainObject)))) // "Animation", "ControlPosition", "MapTypeControlStyle", "MapTypeId", - // "NavigationControlStyle", "ScaleControlStyle", "StrokePosition", "SymbolPath", "ZoomControlStyle", - // "event", "DirectionsStatus", "DirectionsTravelMode", "DirectionsUnitSystem", "DistanceMatrixStatus", - // "DistanceMatrixElementStatus", "ElevationStatus", "GeocoderLocationType", "GeocoderStatus", "KmlLayerStatus", - // "MaxZoomStatus", "StreetViewStatus", "TransitMode", "TransitRoutePreference", "TravelMode", "UnitSystem" + // "NavigationControlStyle", "ScaleControlStyle", "StrokePosition", + // "SymbolPath", "ZoomControlStyle", + // "event", "DirectionsStatus", "DirectionsTravelMode", "DirectionsUnitSystem", + // "DistanceMatrixStatus", + // "DistanceMatrixElementStatus", "ElevationStatus", "GeocoderLocationType", + // "GeocoderStatus", "KmlLayerStatus", + // "MaxZoomStatus", "StreetViewStatus", "TransitMode", "TransitRoutePreference", + // "TravelMode", "UnitSystem" const mapPlainObjects = pick(maps, isPlainObject); - const options = isFunction(this.props.options) ? this.props.options(mapPlainObjects) : this.props.options; + const options = isFunction(this.props.options) + ? this.props.options(mapPlainObjects) + : this.props.options; const defaultOptions = defaultOptions_(mapPlainObjects); const mapOptions = {...defaultOptions, ...options, ...propsOptions}; @@ -176,7 +246,7 @@ export default class GoogleMap extends Component { onChildMouseEnter={this_._onChildMouseEnter} onChildMouseLeave={this_._onChildMouseLeave} geoService={this_.geoService_} - projectFromLeftTop={true} + projectFromLeftTop distanceToMouse={this_.props.distanceToMouse} hoverDistance={this_.props.hoverDistance} dispatcher={this_.markersDispatcher_} />), @@ -201,7 +271,9 @@ export default class GoogleMap extends Component { const ptx = overlayProjection.fromLatLngToDivPixel(new maps.LatLng(ne.lat(), sw.lng())); // need round for safari still can't find what need for firefox - const ptxRounded = detectBrowser().isSafari ? {x: Math.round(ptx.x), y: Math.round(ptx.y)} : {x: ptx.x, y: ptx.y}; + const ptxRounded = detectBrowser().isSafari + ? {x: Math.round(ptx.x), y: Math.round(ptx.y)} + : {x: ptx.x, y: ptx.y}; this_.updateCounter_++; this_._onBoundsChanged(map, maps, !this_.props.debounced); @@ -211,14 +283,14 @@ export default class GoogleMap extends Component { if (this_.markersDispatcher_) { this_.markersDispatcher_.emit('kON_CHANGE'); } - } + }, }); overlay.setMap(map); maps.event.addListener(map, 'zoom_changed', () => { // recalc position at zoom start - if(this_.geoService_.getZoom() !== map.getZoom()) { + if (this_.geoService_.getZoom() !== map.getZoom()) { if (!this_.zoomAnimationInProgress_) { this_.zoomAnimationInProgress_ = true; this_._onZoomAnimationStart(); @@ -235,9 +307,9 @@ export default class GoogleMap extends Component { this.resetSizeOnIdle_ = false; } - if(this_.zoomAnimationInProgress_) { + if (this_.zoomAnimationInProgress_) { this_.zoomAnimationInProgress_ = false; - this_._onZoomAnimationEnd() + this_._onZoomAnimationEnd(); } const div = overlay.div; @@ -247,7 +319,9 @@ export default class GoogleMap extends Component { const sw = bounds.getSouthWest(); const ptx = overlayProjection.fromLatLngToDivPixel(new maps.LatLng(ne.lat(), sw.lng())); // need round for safari still can't find what need for firefox - const ptxRounded = detectBrowser().isSafari ? {x: Math.round(ptx.x), y: Math.round(ptx.y)} : {x: ptx.x, y: ptx.y}; + const ptxRounded = detectBrowser().isSafari + ? {x: Math.round(ptx.x), y: Math.round(ptx.y)} + : {x: ptx.x, y: ptx.y}; this_.updateCounter_++; this_._onBoundsChanged(map, maps); @@ -331,7 +405,12 @@ export default class GoogleMap extends Component { if (!isArraysEqualEps(bounds, this.prevBounds_, kEPS)) { if (callExtBoundsChange !== false) { const marginBounds = this.geoService_.getBounds(this.props.margin); - this.props.onBoundsChange([centerLatLng.lat, centerLatLng.lng], zoom, bounds, marginBounds); + this.props.onBoundsChange( + [centerLatLng.lat, centerLatLng.lng], + zoom, + bounds, + marginBounds + ); this.prevBounds_ = bounds; } } @@ -345,13 +424,18 @@ export default class GoogleMap extends Component { const gmC = map.getCenter(); // compare with google map - if (!isArraysEqualEps([centerLatLng.lat, centerLatLng.lng], [gmC.lat(), gmC.lng()], kEPS)) { - console.info('GoogleMap center not eq:', [centerLatLng.lat, centerLatLng.lng], [gmC.lat(), gmC.lng()]); // eslint-disable-line no-console + if (!isArraysEqualEps( + [centerLatLng.lat, centerLatLng.lng], + [gmC.lat(), gmC.lng()], kEPS + )) { + console.info('GoogleMap center not eq:', // eslint-disable-line no-console + [centerLatLng.lat, centerLatLng.lng], [gmC.lat(), gmC.lng()]); } if (!isArraysEqualEps(bounds, [ne.lat(), sw.lng(), sw.lat(), ne.lng()], kEPS)) { // this is normal if this message occured on resize - console.info('GoogleMap bounds not eq:', '\n', bounds, '\n', [ne.lat(), sw.lng(), sw.lat(), ne.lng()]); // eslint-disable-line no-console + console.info('GoogleMap bounds not eq:', '\n', // eslint-disable-line no-console + bounds, '\n', [ne.lat(), sw.lng(), sw.lat(), ne.lng()]); } } } @@ -414,69 +498,6 @@ export default class GoogleMap extends Component { return center && center.length === 2 && isNumber(center[0]) && isNumber(center[1]); } - componentDidMount() { - this.mounted_ = true; - window.addEventListener('resize', this._onWindowResize); - - setTimeout(() => { // to detect size - this._setViewSize(); - if (this._isCenterDefined(this.props.center)) { - this._initMap(); - } else { - this.props.googleMapLoader(this.props.apiKey); // начать подгружать можно уже сейчас - } - }, 0, this); - } - - componentWillUnmount() { - this.mounted_ = false; - - window.removeEventListener('resize', this._onWindowResize); - - if (this.overlay_) { - // this triggers overlay_.onRemove(), which will unmount the - this.overlay_.setMap(null); - } - - if (this.maps_ && this.map_) { - this.maps_.event.clearInstanceListeners(this.map_); - } - - this.map_ = null; - this.maps_ = null; - this.markersDispatcher_.dispose(); - - this.resetSizeOnIdle_ = false; - - delete this.map_; - delete this.markersDispatcher_; - } - - componentWillReceiveProps(nextProps) { - if (!this._isCenterDefined(this.props.center) && this._isCenterDefined(nextProps.center)) { - setTimeout(() => - this._initMap(), 0); - } - - if (this.map_) { - const centerLatLng = this.geoService_.getCenter(); - if (nextProps.center) { - if (Math.abs(nextProps.center[0] - centerLatLng.lat) + Math.abs(nextProps.center[1] - centerLatLng.lng) > kEPS) { - this.map_.panTo({lat: nextProps.center[0], lng: nextProps.center[1]}); - } - } - - // if zoom chaged by user - if (Math.abs(nextProps.zoom - this.props.zoom) > 0) { - this.map_.setZoom(nextProps.zoom); - } - } - } - - componentDidUpdate() { - this.markersDispatcher_.emit('kON_CHANGE'); - } - render() { const mapMarkerPrerender = !this.state.overlayCreated ? ( - {/*render markers before map load done*/} + {/* render markers before map load done */} {mapMarkerPrerender} ); diff --git a/src/google_map_map.js b/src/google_map_map.js index af76ddd..c2df4e3 100644 --- a/src/google_map_map.js +++ b/src/google_map_map.js @@ -7,7 +7,7 @@ const style = { top: 0, margin: 0, padding: 0, - position: 'absolute' + position: 'absolute', }; export default class GoogleMapMap extends Component { diff --git a/src/google_map_markers.js b/src/google_map_markers.js index 68a085a..15ab7b1 100644 --- a/src/google_map_markers.js +++ b/src/google_map_markers.js @@ -9,7 +9,7 @@ const mainStyle = { top: 0, margin: 0, padding: 0, - position: 'absolute' + position: 'absolute', }; const style = { @@ -18,7 +18,7 @@ const style = { left: 0, top: 0, backgroundColor: 'transparent', - position: 'absolute' + position: 'absolute', }; export default class GoogleMapMarkers extends Component { @@ -31,15 +31,13 @@ export default class GoogleMapMarkers extends Component { onChildMouseLeave: PropTypes.func, onChildMouseEnter: PropTypes.func, hoverDistance: PropTypes.number, - projectFromLeftTop: PropTypes.bool + projectFromLeftTop: PropTypes.bool, }; static defaultProps = { - projectFromLeftTop: false + projectFromLeftTop: false, }; - shouldComponentUpdate = shouldPureComponentUpdate; - constructor(props) { super(props); this.props.dispatcher.on('kON_CHANGE', this._onChangeHandler); @@ -54,10 +52,20 @@ export default class GoogleMapMarkers extends Component { this.state = {...this._getState(), hoverKey: null}; } + shouldComponentUpdate = shouldPureComponentUpdate; + + componentWillUnmount() { + this.props.dispatcher.removeListener('kON_CHANGE', this._onChangeHandler); + this.props.dispatcher.removeListener('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler); + this.props.dispatcher.removeListener('kON_CLICK', this._onChildClick); + + this.dimesionsCache_ = null; + } + _getState = () => { return { children: this.props.dispatcher.getChildren(), - updateCounter: this.props.dispatcher.getUpdateCounter() + updateCounter: this.props.dispatcher.getUpdateCounter(), }; } @@ -138,7 +146,7 @@ export default class GoogleMapMarkers extends Component { const mp = this.props.dispatcher.getMousePosition(); if (mp) { - let distances = []; + const distances = []; React.Children.forEach(this.state.children, (child, childIndex) => { const childKey = child.key !== undefined && child.key !== null ? child.key : childIndex; @@ -148,7 +156,7 @@ export default class GoogleMapMarkers extends Component { { key: childKey, dist: dist, - props: child.props + props: child.props, }); } }); @@ -176,24 +184,20 @@ export default class GoogleMapMarkers extends Component { return this.dimesionsCache_[childKey]; } - componentWillUnmount() { - this.props.dispatcher.removeListener('kON_CHANGE', this._onChangeHandler); - this.props.dispatcher.removeListener('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler); - this.props.dispatcher.removeListener('kON_CLICK', this._onChildClick); - - this.dimesionsCache_ = null; - } - render() { const mainElementStyle = this.props.style || mainStyle; this.dimesionsCache_ = {}; const markers = React.Children.map(this.state.children, (child, childIndex) => { - const pt = this.props.geoService.project({lat: child.props.lat, lng: child.props.lng}, this.props.projectFromLeftTop); + const pt = this.props.geoService.project({ + lat: child.props.lat, + lng: child.props.lng, + }, this.props.projectFromLeftTop); + const stylePtPos = { left: pt.x, - top: pt.y + top: pt.y, }; let dx = 0; @@ -206,9 +210,15 @@ export default class GoogleMapMarkers extends Component { } } - // to prevent rerender on child element i need to pass const params $getDimensions and $dimensionKey instead of dimension object + // to prevent rerender on child element i need to pass + // const params $getDimensions and $dimensionKey instead of dimension object const childKey = child.key !== undefined && child.key !== null ? child.key : childIndex; - this.dimesionsCache_[childKey] = {x: pt.x + dx, y: pt.y + dy, lat: child.props.lat, lng: child.props.lng}; + this.dimesionsCache_[childKey] = { + x: pt.x + dx, + y: pt.y + dy, + lat: child.props.lat, + lng: child.props.lng, + }; return (
@@ -217,7 +227,7 @@ export default class GoogleMapMarkers extends Component { $getDimensions: this._getDimensions, $dimensionKey: childKey, $geoService: this.props.geoService, - $onMouseAllow: this._onMouseAllow + $onMouseAllow: this._onMouseAllow, })}
); diff --git a/src/google_map_markers_prerender.js b/src/google_map_markers_prerender.js index 6e6a3e6..fbc7c76 100644 --- a/src/google_map_markers_prerender.js +++ b/src/google_map_markers_prerender.js @@ -1,4 +1,4 @@ -import React, {PropTypes, Component} from 'react'; +import React, {/* PropTypes, */ Component} from 'react'; import GoogleMapMarkers from './google_map_markers.js'; const style = { @@ -9,7 +9,7 @@ const style = { // backgroundColor: 'red', margin: 0, padding: 0, - position: 'absolute' + position: 'absolute', // opacity: 0.3 }; diff --git a/src/utils/detect.js b/src/utils/detect.js index c9d91ce..07efe9e 100644 --- a/src/utils/detect.js +++ b/src/utils/detect.js @@ -1,4 +1,4 @@ -// code here http://stackoverflow.com/questions/5899783/detect-safari-chrome-ie-firefox-opera-with-user-agent +// http://stackoverflow.com/questions/5899783/detect-safari-chrome-ie-firefox-opera-with-user-agent let detectBrowserResult_ = null; export default function detectBrowser() { @@ -26,6 +26,13 @@ export default function detectBrowser() { return detectBrowserResult_; } - detectBrowserResult_ = {isChrome: true, isExplorer: false, isFirefox: false, isOpera: false, isSafari: false}; + detectBrowserResult_ = { + isChrome: true, + isExplorer: false, + isFirefox: false, + isOpera: false, + isSafari: false, + }; + return detectBrowserResult_; } diff --git a/src/utils/geo.js b/src/utils/geo.js index 24af9c0..2aea36d 100644 --- a/src/utils/geo.js +++ b/src/utils/geo.js @@ -75,7 +75,7 @@ export default class Geo { } getCenter() { - let ptRes = this.transform_.pointLocation({x: 0, y: 0}); + const ptRes = this.transform_.pointLocation({x: 0, y: 0}); return ptRes; } @@ -87,12 +87,18 @@ export default class Geo { const bndL = margins && margins[3] || 0; if (this.getWidth() - bndR - bndL > 0 && this.getHeight() - bndT - bndB > 0) { - const topLeftCorner = this.unproject({x: bndL - this.getWidth() / 2, y: bndT - this.getHeight() / 2}); - const bottomRightCorner = this.unproject({x: this.getWidth() / 2 - bndR, y: this.getHeight() / 2 - bndB}); + const topLeftCorner = this.unproject({ + x: bndL - this.getWidth() / 2, + y: bndT - this.getHeight() / 2, + }); + const bottomRightCorner = this.unproject({ + x: this.getWidth() / 2 - bndR, + y: this.getHeight() / 2 - bndB, + }); let res = [ topLeftCorner.lat, topLeftCorner.lng, - bottomRightCorner.lat, bottomRightCorner.lng + bottomRightCorner.lat, bottomRightCorner.lng, ]; if (roundFactor) { @@ -104,4 +110,3 @@ export default class Geo { return [0, 0, 0, 0]; } } - diff --git a/src/utils/lib_geo/lat_lng.js b/src/utils/lib_geo/lat_lng.js index 78ee4a6..ab8cfcd 100644 --- a/src/utils/lib_geo/lat_lng.js +++ b/src/utils/lib_geo/lat_lng.js @@ -1,29 +1,25 @@ -'use strict'; +import { wrap } from './wrap.js'; -module.exports = LatLng; +export default class LatLng { + static convert = (a) => { + if (a instanceof LatLng) { + return a; + } + if (Array.isArray(a)) { + return new LatLng(a[0], a[1]); + } + return a; + } -var wrap = require('./wrap.js').wrap; - -function LatLng(lat, lng) { + constructor(lat, lng) { if (isNaN(lat) || isNaN(lng)) { - throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); + throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); } this.lat = +lat; this.lng = +lng; -} + } -LatLng.prototype.wrap = function () { + wrap() { return new LatLng(this.lat, wrap(this.lng, -180, 180)); -}; - -// constructs LatLng from an array if necessary - -LatLng.convert = function (a) { - if (a instanceof LatLng) { - return a; - } - if (Array.isArray(a)) { - return new LatLng(a[0], a[1]); - } - return a; -}; + } +} diff --git a/src/utils/lib_geo/lat_lng_bounds.js b/src/utils/lib_geo/lat_lng_bounds.js index 9c6d6b0..069c53c 100644 --- a/src/utils/lib_geo/lat_lng_bounds.js +++ b/src/utils/lib_geo/lat_lng_bounds.js @@ -1,72 +1,72 @@ -'use strict'; +import LatLng from './lat_lng'; -module.exports = LatLngBounds; - -var LatLng = require('./lat_lng'); - -function LatLngBounds(sw, ne) { - if (!sw) return; - - var latlngs = ne ? [sw, ne] : sw; - - for (var i = 0, len = latlngs.length; i < len; i++) { - this.extend(latlngs[i]); - } -} - -LatLngBounds.prototype = { - - // extend the bounds to contain the given point or bounds - extend: function (obj) { - var sw = this._sw, - ne = this._ne, - sw2, ne2; - - if (obj instanceof LatLng) { - sw2 = obj; - ne2 = obj; - - } else if (obj instanceof LatLngBounds) { - sw2 = obj._sw; - ne2 = obj._ne; - - if (!sw2 || !ne2) return this; - - } else { - return obj ? this.extend(LatLng.convert(obj) || LatLngBounds.convert(obj)) : this; - } - - if (!sw && !ne) { - this._sw = new LatLng(sw2.lat, sw2.lng); - this._ne = new LatLng(ne2.lat, ne2.lng); - - } else { - sw.lat = Math.min(sw2.lat, sw.lat); - sw.lng = Math.min(sw2.lng, sw.lng); - ne.lat = Math.max(ne2.lat, ne.lat); - ne.lng = Math.max(ne2.lng, ne.lng); - } - - return this; - }, - - getCenter: function () { - return new LatLng((this._sw.lat + this._ne.lat) / 2, (this._sw.lng + this._ne.lng) / 2); - }, - - getSouthWest: function () { return this._sw; }, - getNorthEast: function () { return this._ne; }, - getNorthWest: function () { return new LatLng(this.getNorth(), this.getWest()); }, - getSouthEast: function () { return new LatLng(this.getSouth(), this.getEast()); }, - - getWest: function () { return this._sw.lng; }, - getSouth: function () { return this._sw.lat; }, - getEast: function () { return this._ne.lng; }, - getNorth: function () { return this._ne.lat; } -}; - -// constructs LatLngBounds from an array if necessary -LatLngBounds.convert = function (a) { +export default class LatLngBounds { + static convert = (a) => { if (!a || a instanceof LatLngBounds) return a; return new LatLngBounds(a); -}; + } + + constructor(sw, ne) { + if (!sw) return; + + const latlngs = ne ? [sw, ne] : sw; + + for (let i = 0, len = latlngs.length; i < len; i++) { + this.extend(latlngs[i]); + } + } + + extend(obj) { + const sw = this._sw; + const ne = this._ne; + let sw2; + let ne2; + + if (obj instanceof LatLng) { + sw2 = obj; + ne2 = obj; + } else if (obj instanceof LatLngBounds) { + sw2 = obj._sw; + ne2 = obj._ne; + + if (!sw2 || !ne2) return this; + } else { + return obj + ? this.extend(LatLng.convert(obj) || LatLngBounds.convert(obj)) + : this; + } + + if (!sw && !ne) { + this._sw = new LatLng(sw2.lat, sw2.lng); + this._ne = new LatLng(ne2.lat, ne2.lng); + + } else { + sw.lat = Math.min(sw2.lat, sw.lat); + sw.lng = Math.min(sw2.lng, sw.lng); + ne.lat = Math.max(ne2.lat, ne.lat); + ne.lng = Math.max(ne2.lng, ne.lng); + } + + return this; + } + + getCenter = () => new LatLng( + (this._sw.lat + this._ne.lat) / 2, + (this._sw.lng + this._ne.lng) / 2) + + getSouthWest = () => this._sw + + getNorthEast = () => this._ne + + getNorthWest = () => new LatLng(this.getNorth(), this.getWest()) + + getSouthEast = () => new LatLng(this.getSouth(), this.getEast()) + + getWest = () => this._sw.lng + + getSouth = () => this._sw.lat + + getEast = () => this._ne.lng + + getNorth = () => this._ne.lat +} diff --git a/src/utils/lib_geo/transform.js b/src/utils/lib_geo/transform.js index c9c585f..6294d80 100644 --- a/src/utils/lib_geo/transform.js +++ b/src/utils/lib_geo/transform.js @@ -1,121 +1,133 @@ - -const LatLng = require('./lat_lng'); -const Point = require('point-geometry'); -const wrap = require('./wrap.js').wrap; - +import LatLng from './lat_lng'; +import Point from 'point-geometry'; +import { wrap } from './wrap.js'; // A single transform, generally used for a single tile to be scaled, rotated, and zoomed. +export default class Transform { + constructor(tileSize, minZoom, maxZoom) { + this.tileSize = tileSize || 512; // constant -function Transform(tileSize, minZoom, maxZoom) { - this.tileSize = tileSize || 512; // constant + this._minZoom = minZoom || 0; + this._maxZoom = maxZoom || 52; - this._minZoom = minZoom || 0; - this._maxZoom = maxZoom || 52; + this.latRange = [-85.05113, 85.05113]; - this.latRange = [-85.05113, 85.05113]; + this.width = 0; + this.height = 0; + this.zoom = 0; + this.center = new LatLng(0, 0); + this.angle = 0; + } - this.width = 0; - this.height = 0; - this.zoom = 0; - this.center = new LatLng(0, 0); - this.angle = 0; -} + get minZoom() { + return this._minZoom; + } -Transform.prototype = { - get minZoom() { return this._minZoom; }, set minZoom(zoom) { this._minZoom = zoom; this.zoom = Math.max(this.zoom, zoom); - }, + } + + get maxZoom() { + return this._maxZoom; + } - get maxZoom() { return this._maxZoom; }, set maxZoom(zoom) { this._maxZoom = zoom; this.zoom = Math.min(this.zoom, zoom); - }, + } get worldSize() { return this.tileSize * this.scale; - }, + } get centerPoint() { return new Point(0, 0); // this.size._div(2); - }, + } get size() { return new Point(this.width, this.height); - }, + } get bearing() { return -this.angle / Math.PI * 180; - }, + } + set bearing(bearing) { this.angle = -wrap(bearing, -180, 180) * Math.PI / 180; - }, + } + + get zoom() { + return this._zoom; + } - get zoom() { return this._zoom; }, set zoom(zoom) { - zoom = Math.min(Math.max(zoom, this.minZoom), this.maxZoom); - this._zoom = zoom; - this.scale = this.zoomScale(zoom); - this.tileZoom = Math.floor(zoom); - this.zoomFraction = zoom - this.tileZoom; - }, + const zoomV = Math.min(Math.max(zoom, this.minZoom), this.maxZoom); + this._zoom = zoomV; + this.scale = this.zoomScale(zoomV); + this.tileZoom = Math.floor(zoomV); + this.zoomFraction = zoomV - this.tileZoom; + } - zoomScale: function(zoom) { return Math.pow(2, zoom); }, - scaleZoom: function(scale) { return Math.log(scale) / Math.LN2; }, + zoomScale(zoom) { + return Math.pow(2, zoom); + } - project: function(latlng, worldSize) { + scaleZoom(scale) { + return Math.log(scale) / Math.LN2; + } + + project(latlng, worldSize) { return new Point( this.lngX(latlng.lng, worldSize), this.latY(latlng.lat, worldSize)); - }, + } - unproject: function(point, worldSize) { + unproject(point, worldSize) { return new LatLng( this.yLat(point.y, worldSize), this.xLng(point.x, worldSize)); - }, + } get x() { return this.lngX(this.center.lng); - }, + } + get y() { return this.latY(this.center.lat); - }, + } - get point() { return new Point(this.x, this.y); }, + get point() { + return new Point(this.x, this.y); + } // lat/lon <-> absolute pixel coords convertion - lngX: function(lon, worldSize) { + lngX(lon, worldSize) { return (180 + lon) * (worldSize || this.worldSize) / 360; - }, + } + // latitude to absolute y coord - latY: function(lat, worldSize) { - var y = 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)); + latY(lat, worldSize) { + const y = 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)); return (180 - y) * (worldSize || this.worldSize) / 360; - }, + } - xLng: function(x, worldSize) { + xLng(x, worldSize) { return x * 360 / (worldSize || this.worldSize) - 180; - }, - yLat: function(y, worldSize) { - var y2 = 180 - y * 360 / (worldSize || this.worldSize); + } + + yLat(y, worldSize) { + const y2 = 180 - y * 360 / (worldSize || this.worldSize); return 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90; - }, + } - - locationPoint: function(latlng) { - var p = this.project(latlng); + locationPoint(latlng) { + const p = this.project(latlng); return this.centerPoint._sub(this.point._sub(p)._rotate(this.angle)); - }, + } - pointLocation: function(p) { - var p2 = this.centerPoint._sub(p)._rotate(-this.angle); + pointLocation(p) { + const p2 = this.centerPoint._sub(p)._rotate(-this.angle); return this.unproject(this.point.sub(p2)); - }, - - -}; - -module.exports = Transform; + } +} diff --git a/src/utils/lib_geo/wrap.js b/src/utils/lib_geo/wrap.js index 9789b00..6a83e3d 100644 --- a/src/utils/lib_geo/wrap.js +++ b/src/utils/lib_geo/wrap.js @@ -1,6 +1,4 @@ -'use strict'; - -exports.wrap = function (n, min, max) { - var d = max - min; - return n === max ? n : ((n - min) % d + d) % d + min; -}; +export function wrap(n, min, max) { + const d = max - min; + return n === max ? n : ((n - min) % d + d) % d + min; +} diff --git a/src/utils/loaders/google_map_loader.js b/src/utils/loaders/google_map_loader.js index cc7db98..8684e9f 100644 --- a/src/utils/loaders/google_map_loader.js +++ b/src/utils/loaders/google_map_loader.js @@ -3,7 +3,7 @@ let $script_ = null; let _loadPromise; // TODO add libraries language and other map options -module.exports = function googleMapLoader(apiKey) { +export default function googleMapLoader(apiKey) { if (!$script_) { $script_ = require('scriptjs'); } @@ -34,12 +34,14 @@ module.exports = function googleMapLoader(apiKey) { const apiKeyString = apiKey ? `&key=${apiKey}` : ''; - $script_(`https://maps.googleapis.com/maps/api/js?callback=_$_google_map_initialize_$_${apiKeyString}`, () => { - if (typeof window.google === 'undefined') { - reject(new Error('google map initialization error (not loaded)')); - } - }); + $script_( + `https://maps.googleapis.com/maps/api/js?callback=_$_google_map_initialize_$_${apiKeyString}`, + () => { + if (typeof window.google === 'undefined') { + reject(new Error('google map initialization error (not loaded)')); + } + }); }); return _loadPromise; -}; +}