JS Mojo Geocoder Demo
Added a JS example that demos encapsulating Google's geocoder web service with a Mojo application.
BUG=
R=eseidel@chromium.org
Review URL: https://codereview.chromium.org/848213003
diff --git a/examples/js/maps/geocoder_service.js b/examples/js/maps/geocoder_service.js
new file mode 100644
index 0000000..351a460
--- /dev/null
+++ b/examples/js/maps/geocoder_service.js
@@ -0,0 +1,128 @@
+#!mojo mojo:js_content_handler
+
+define("main", [
+ "console",
+ "examples/js/maps/geocoder.mojom",
+ "mojo/public/js/core",
+ "mojo/public/js/unicode",
+ "mojo/services/public/js/application",
+ "mojo/services/network/public/interfaces/network_service.mojom",
+ "mojo/services/network/public/interfaces/url_loader.mojom",
+ "third_party/js/url",
+], function(console, geocoder, core, unicode, application, network, loader, url) {
+
+ const Application = application.Application;
+ const Bounds = geocoder.Bounds;
+ const Geocoder = geocoder.Geocoder;
+ const Geometry = geocoder.Geometry;
+ const Location = geocoder.Location;
+ const NetworkService = network.NetworkService;
+ const Result = geocoder.Result;
+ const Status = geocoder.Status;
+ const URLRequest = loader.URLRequest;
+ const URL = url.URL;
+
+ var netService;
+
+ Location.prototype.queryString = function() {
+ // TBD: format floats to 6 decimal places
+ return this.latitude + ", " + this.longitude;
+ }
+
+ Location.fromJSON = function(json) {
+ return !json ? null : new Location({
+ latitude: json.lat,
+ longitude: json.lng,
+ });
+ }
+
+ Bounds.fromJSON = function(json) {
+ return !json ? null : new Bounds({
+ northeast: Location.fromJSON(json.northeast),
+ southwest: Location.fromJSON(json.southwest),
+ });
+ }
+
+ Geometry.fromJSON = function(json) {
+ return !json ? null : new Geometry({
+ location: Location.fromJSON(json.location),
+ location_type: json.location_type,
+ viewport: Bounds.fromJSON(json.viewport),
+ bounds: Bounds.fromJSON(json.bounds),
+ });
+ }
+
+ Result.fromJSON = function(json) {
+ return !json ? null : new Result({
+ partial_match: !!json.partial_match,
+ formatted_address: json.formatted_address,
+ geometry: Geometry.fromJSON(json.geometry),
+ types: json.types,
+ // TBD: address_components
+ });
+ }
+
+ function parseGeocodeResponse(arrayBuffer) {
+ return JSON.parse(unicode.decodeUtf8String(new Uint8Array(arrayBuffer)));
+ }
+
+ function geocodeRequest(url) {
+ return new Promise(function(resolveRequest) {
+ var urlLoader;
+ netService.createURLLoader(function(urlLoaderProxy) {
+ urlLoader = urlLoaderProxy;
+ });
+
+ var urlRequest = new URLRequest({
+ url: url.format(),
+ method: "GET",
+ auto_follow_redirects: true
+ });
+
+ urlLoader.start(urlRequest).then(function(urlLoaderResult) {
+ core.drainData(urlLoaderResult.response.body).then(
+ function(drainDataResult) {
+ // TBD: handle drainData failure
+ var value = parseGeocodeResponse(drainDataResult.buffer);
+ resolveRequest({
+ status: value.status,
+ results: value.results.map(Result.fromJSON),
+ });
+ });
+ });
+ });
+ }
+
+ function geocodeURL(key, value, options) {
+ var url = new URL("https://maps.googleapis.com/maps/api/geocode/json");
+ url.query = {};
+ url.query[key] = value;
+ // TBD: add options url.query
+ return url;
+ }
+
+ class GeocoderImpl {
+ addressToLocation(address, options) {
+ return geocodeRequest(geocodeURL("address", address, options));
+ }
+
+ locationToAddress(location, options) {
+ return geocodeRequest(
+ geocodeURL("latlng", location.queryString(), options));
+ }
+ }
+
+ class GeocoderService extends Application {
+ initialize() {
+ netService = this.shell.connectToService(
+ "mojo:network_service", NetworkService);
+ }
+
+ acceptConnection(initiatorURL, serviceProvider) {
+ serviceProvider.provideService(Geocoder, GeocoderImpl);
+ }
+ }
+
+ return GeocoderService;
+});
+