Hans Muller | 0525071 | 2015-01-15 11:19:21 -0800 | [diff] [blame] | 1 | #!mojo mojo:js_content_handler |
| 2 | |
| 3 | define("main", [ |
| 4 | "console", |
Hans Muller | 0525071 | 2015-01-15 11:19:21 -0800 | [diff] [blame] | 5 | "mojo/public/js/core", |
| 6 | "mojo/public/js/unicode", |
Alhaad Gokhale | 4b5bda4 | 2015-03-06 13:58:49 -0800 | [diff] [blame] | 7 | "mojo/services/location/public/interfaces/geocoder.mojom", |
| 8 | "mojo/services/location/public/interfaces/location.mojom", |
Hans Muller | 0525071 | 2015-01-15 11:19:21 -0800 | [diff] [blame] | 9 | "mojo/services/public/js/application", |
| 10 | "mojo/services/network/public/interfaces/network_service.mojom", |
| 11 | "mojo/services/network/public/interfaces/url_loader.mojom", |
| 12 | "third_party/js/url", |
Alhaad Gokhale | 4b5bda4 | 2015-03-06 13:58:49 -0800 | [diff] [blame] | 13 | ], function(console, core, unicode, geocoder, location, application, network, |
| 14 | loader, url) { |
Hans Muller | 0525071 | 2015-01-15 11:19:21 -0800 | [diff] [blame] | 15 | |
| 16 | const Application = application.Application; |
| 17 | const Bounds = geocoder.Bounds; |
| 18 | const Geocoder = geocoder.Geocoder; |
| 19 | const Geometry = geocoder.Geometry; |
Alhaad Gokhale | 4b5bda4 | 2015-03-06 13:58:49 -0800 | [diff] [blame] | 20 | const Location = location.Location; |
Hans Muller | 0525071 | 2015-01-15 11:19:21 -0800 | [diff] [blame] | 21 | const NetworkService = network.NetworkService; |
| 22 | const Result = geocoder.Result; |
| 23 | const Status = geocoder.Status; |
| 24 | const URLRequest = loader.URLRequest; |
| 25 | const URL = url.URL; |
| 26 | |
| 27 | var netService; |
| 28 | |
| 29 | Location.prototype.queryString = function() { |
| 30 | // TBD: format floats to 6 decimal places |
| 31 | return this.latitude + ", " + this.longitude; |
| 32 | } |
| 33 | |
| 34 | Location.fromJSON = function(json) { |
| 35 | return !json ? null : new Location({ |
| 36 | latitude: json.lat, |
| 37 | longitude: json.lng, |
| 38 | }); |
| 39 | } |
| 40 | |
| 41 | Bounds.fromJSON = function(json) { |
| 42 | return !json ? null : new Bounds({ |
| 43 | northeast: Location.fromJSON(json.northeast), |
| 44 | southwest: Location.fromJSON(json.southwest), |
| 45 | }); |
| 46 | } |
| 47 | |
| 48 | Geometry.fromJSON = function(json) { |
| 49 | return !json ? null : new Geometry({ |
| 50 | location: Location.fromJSON(json.location), |
| 51 | location_type: json.location_type, |
| 52 | viewport: Bounds.fromJSON(json.viewport), |
| 53 | bounds: Bounds.fromJSON(json.bounds), |
| 54 | }); |
| 55 | } |
| 56 | |
| 57 | Result.fromJSON = function(json) { |
| 58 | return !json ? null : new Result({ |
| 59 | partial_match: !!json.partial_match, |
| 60 | formatted_address: json.formatted_address, |
| 61 | geometry: Geometry.fromJSON(json.geometry), |
| 62 | types: json.types, |
| 63 | // TBD: address_components |
| 64 | }); |
| 65 | } |
| 66 | |
| 67 | function parseGeocodeResponse(arrayBuffer) { |
| 68 | return JSON.parse(unicode.decodeUtf8String(new Uint8Array(arrayBuffer))); |
| 69 | } |
| 70 | |
| 71 | function geocodeRequest(url) { |
| 72 | return new Promise(function(resolveRequest) { |
| 73 | var urlLoader; |
| 74 | netService.createURLLoader(function(urlLoaderProxy) { |
| 75 | urlLoader = urlLoaderProxy; |
| 76 | }); |
| 77 | |
| 78 | var urlRequest = new URLRequest({ |
| 79 | url: url.format(), |
| 80 | method: "GET", |
| 81 | auto_follow_redirects: true |
| 82 | }); |
| 83 | |
| 84 | urlLoader.start(urlRequest).then(function(urlLoaderResult) { |
| 85 | core.drainData(urlLoaderResult.response.body).then( |
| 86 | function(drainDataResult) { |
| 87 | // TBD: handle drainData failure |
| 88 | var value = parseGeocodeResponse(drainDataResult.buffer); |
| 89 | resolveRequest({ |
| 90 | status: value.status, |
| 91 | results: value.results.map(Result.fromJSON), |
| 92 | }); |
| 93 | }); |
| 94 | }); |
| 95 | }); |
| 96 | } |
| 97 | |
| 98 | function geocodeURL(key, value, options) { |
| 99 | var url = new URL("https://maps.googleapis.com/maps/api/geocode/json"); |
| 100 | url.query = {}; |
| 101 | url.query[key] = value; |
| 102 | // TBD: add options url.query |
| 103 | return url; |
| 104 | } |
| 105 | |
| 106 | class GeocoderImpl { |
| 107 | addressToLocation(address, options) { |
| 108 | return geocodeRequest(geocodeURL("address", address, options)); |
| 109 | } |
| 110 | |
| 111 | locationToAddress(location, options) { |
| 112 | return geocodeRequest( |
| 113 | geocodeURL("latlng", location.queryString(), options)); |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | class GeocoderService extends Application { |
| 118 | initialize() { |
| 119 | netService = this.shell.connectToService( |
| 120 | "mojo:network_service", NetworkService); |
| 121 | } |
| 122 | |
| 123 | acceptConnection(initiatorURL, serviceProvider) { |
| 124 | serviceProvider.provideService(Geocoder, GeocoderImpl); |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | return GeocoderService; |
| 129 | }); |
| 130 | |