vendor: 14,101 bytes, lines 1-333
1/** 2 * jQuery Geocoding and Places Autocomplete Plugin - V 1.7.0 3 * 4 * @author Martin Kleppe <[email protected]>, 2016 5 * @author Ubilabs http://ubilabs.net, 2016 6 * @license MIT License <http://www.opensource.org/licenses/mit-license.php> 7 */ 8(function ($, window, document, undefined) { 9 var defaults = { 10 bounds: true, 11 strictBounds: false, 12 country: null, 13 map: false, 14 details: false, 15 detailsAttribute: "name", 16 detailsScope: null, 17 autoselect: true, 18 location: false, 19 mapOptions: {zoom: 14, scrollwheel: false, mapTypeId: "roadmap"}, 20 markerOptions: {draggable: false}, 21 maxZoom: 16, 22 types: ["geocode"], 23 blur: false, 24 geocodeAfterResult: false, 25 restoreValueAfterBlur: false 26 }; 27 var componentTypes = ("street_address route intersection political " + "country administrative_area_level_1 administrative_area_level_2 " + "administrative_area_level_3 colloquial_area locality sublocality " + "neighborhood premise subpremise postal_code natural_feature airport " + "park point_of_interest post_box street_number floor room " + "lat lng viewport location " + "formatted_address location_type bounds").split(" "); 28 var placesDetails = ("id place_id url website vicinity reference name rating " + "international_phone_number icon formatted_phone_number").split(" "); 29 30 function GeoComplete(input, options) { 31 this.options = $.extend(true, {}, defaults, options); 32 if (options && options.types) { 33 this.options.types = options.types 34 } 35 this.input = input; 36 this.$input = $(input); 37 this._defaults = defaults; 38 this._name = "geocomplete"; 39 this.init() 40 } 41 42 $.extend(GeoComplete.prototype, { 43 init: function () { 44 this.initMap(); 45 this.initMarker(); 46 this.initGeocoder(); 47 this.initDetails(); 48 this.initLocation() 49 }, initMap: function () { 50 if (!this.options.map) { 51 return 52 } 53 if (typeof this.options.map.setCenter == "function") { 54 this.map = this.options.map; 55 return 56 } 57 this.map = new google.maps.Map($(this.options.map)[0], this.options.mapOptions); 58 google.maps.event.addListener(this.map, "click", $.proxy(this.mapClicked, this)); 59 google.maps.event.addListener(this.map, "dragend", $.proxy(this.mapDragged, this)); 60 google.maps.event.addListener(this.map, "idle", $.proxy(this.mapIdle, this)); 61 google.maps.event.addListener(this.map, "zoom_changed", $.proxy(this.mapZoomed, this)) 62 }, initMarker: function () { 63 if (!this.map) { 64 return 65 } 66 var options = $.extend(this.options.markerOptions, {map: this.map}); 67 if (options.disabled) { 68 return 69 } 70 this.marker = new google.maps.Marker(options); 71 google.maps.event.addListener(this.marker, "dragend", $.proxy(this.markerDragged, this)) 72 }, initGeocoder: function () { 73 var selected = false; 74 var options = { 75 types: this.options.types, 76 bounds: this.options.bounds === true ? null : this.options.bounds, 77 componentRestrictions: this.options.componentRestrictions, 78 strictBounds: this.options.strictBounds 79 }; 80 if (this.options.country) { 81 options.componentRestrictions = {country: this.options.country} 82 } 83 this.autocomplete = new google.maps.places.Autocomplete(this.input, options); 84 this.geocoder = new google.maps.Geocoder; 85 if (this.map && this.options.bounds === true) { 86 this.autocomplete.bindTo("bounds", this.map) 87 } 88 google.maps.event.addListener(this.autocomplete, "place_changed", $.proxy(this.placeChanged, this)); 89 this.$input.on("keypress." + this._name, function (event) { 90 if (event.keyCode === 13) { 91 return false 92 } 93 }); 94 if (this.options.geocodeAfterResult === true) { 95 this.$input.bind("keypress." + this._name, $.proxy(function () { 96 if (event.keyCode != 9 && this.selected === true) { 97 this.selected = false 98 } 99 }, this)) 100 } 101 this.$input.bind("geocode." + this._name, $.proxy(function () { 102 this.find() 103 }, this)); 104 this.$input.bind("geocode:result." + this._name, $.proxy(function () { 105 this.lastInputVal = this.$input.val() 106 }, this)); 107 if (this.options.blur === true) { 108 this.$input.on("blur." + this._name, $.proxy(function () { 109 if (this.options.geocodeAfterResult === true && this.selected === true) { 110 return 111 } 112 if (this.options.restoreValueAfterBlur === true && this.selected === true) { 113 setTimeout($.proxy(this.restoreLastValue, this), 0) 114 } else { 115 this.find() 116 } 117 }, this)) 118 } 119 }, initDetails: function () { 120 if (!this.options.details) { 121 return 122 } 123 if (this.options.detailsScope) { 124 var $details = $(this.input).parents(this.options.detailsScope).find(this.options.details) 125 } else { 126 var $details = $(this.options.details) 127 } 128 var attribute = this.options.detailsAttribute, details = {}; 129 130 function setDetail(value) { 131 details[value] = $details.find("[" + attribute + "=" + value + "]") 132 } 133 134 $.each(componentTypes, function (index, key) { 135 setDetail(key); 136 setDetail(key + "_short") 137 }); 138 $.each(placesDetails, function (index, key) { 139 setDetail(key) 140 }); 141 this.$details = $details; 142 this.details = details 143 }, initLocation: function () { 144 var location = this.options.location, latLng; 145 if (!location) { 146 return 147 } 148 if (typeof location == "string") { 149 this.find(location); 150 return 151 } 152 if (location instanceof Array) { 153 latLng = new google.maps.LatLng(location[0], location[1]) 154 } 155 if (location instanceof google.maps.LatLng) { 156 latLng = location 157 } 158 if (latLng) { 159 if (this.map) { 160 this.map.setCenter(latLng) 161 } 162 if (this.marker) { 163 this.marker.setPosition(latLng) 164 } 165 } 166 }, destroy: function () { 167 if (this.map) { 168 google.maps.event.clearInstanceListeners(this.map); 169 google.maps.event.clearInstanceListeners(this.marker) 170 } 171 this.autocomplete.unbindAll(); 172 google.maps.event.clearInstanceListeners(this.autocomplete); 173 google.maps.event.clearInstanceListeners(this.input); 174 this.$input.removeData(); 175 this.$input.off(this._name); 176 this.$input.unbind("." + this._name) 177 }, find: function (address) { 178 this.geocode({address: address || this.$input.val()}) 179 }, geocode: function (request) { 180 if (!request.address) { 181 return 182 } 183 if (this.options.bounds && !request.bounds) { 184 if (this.options.bounds === true) { 185 request.bounds = this.map && this.map.getBounds() 186 } else { 187 request.bounds = this.options.bounds 188 } 189 } 190 if (this.options.country) { 191 request.region = this.options.country 192 } 193 this.geocoder.geocode(request, $.proxy(this.handleGeocode, this)) 194 }, selectFirstResult: function () { 195 var selected = ""; 196 if ($(".pac-item-selected")[0]) { 197 selected = "-selected" 198 } 199 var $span1 = $(".pac-container:visible .pac-item" + selected + ":first span:nth-child(2)").text(); 200 var $span2 = $(".pac-container:visible .pac-item" + selected + ":first span:nth-child(3)").text(); 201 var firstResult = $span1; 202 if ($span2) { 203 firstResult += " - " + $span2 204 } 205 this.$input.val(firstResult); 206 return firstResult 207 }, restoreLastValue: function () { 208 if (this.lastInputVal) { 209 this.$input.val(this.lastInputVal) 210 } 211 }, handleGeocode: function (results, status) { 212 if (status === google.maps.GeocoderStatus.OK) { 213 var result = results[0]; 214 this.$input.val(result.formatted_address); 215 this.update(result); 216 if (results.length > 1) { 217 this.trigger("geocode:multiple", results) 218 } 219 } else { 220 this.trigger("geocode:error", status) 221 } 222 }, trigger: function (event, argument) { 223 this.$input.trigger(event, [argument]) 224 }, center: function (geometry) { 225 if (geometry.viewport) { 226 this.map.fitBounds(geometry.viewport); 227 if (this.map.getZoom() > this.options.maxZoom) { 228 this.map.setZoom(this.options.maxZoom) 229 } 230 } else { 231 this.map.setZoom(this.options.maxZoom); 232 this.map.setCenter(geometry.location) 233 } 234 if (this.marker) { 235 this.marker.setPosition(geometry.location); 236 this.marker.setAnimation(this.options.markerOptions.animation) 237 } 238 }, update: function (result) { 239 if (this.map) { 240 this.center(result.geometry) 241 } 242 if (this.$details) { 243 this.fillDetails(result) 244 } 245 this.trigger("geocode:result", result) 246 }, fillDetails: function (result) { 247 var data = {}, geometry = result.geometry, viewport = geometry.viewport, bounds = geometry.bounds; 248 $.each(result.address_components, function (index, object) { 249 var name = object.types[0]; 250 $.each(object.types, function (index, name) { 251 data[name] = object.long_name; 252 data[name + "_short"] = object.short_name 253 }) 254 }); 255 $.each(placesDetails, function (index, key) { 256 data[key] = result[key] 257 }); 258 $.extend(data, { 259 formatted_address: result.formatted_address, 260 location_type: geometry.location_type || "PLACES", 261 viewport: viewport, 262 bounds: bounds, 263 location: geometry.location, 264 lat: geometry.location.lat(), 265 lng: geometry.location.lng() 266 }); 267 $.each(this.details, $.proxy(function (key, $detail) { 268 var value = data[key]; 269 this.setDetail($detail, value) 270 }, this)); 271 this.data = data 272 }, setDetail: function ($element, value) { 273 if (value === undefined) { 274 value = "" 275 } else if (typeof value.toUrlValue == "function") { 276 value = value.toUrlValue() 277 } 278 if ($element.is(":input")) { 279 $element.val(value) 280 } else { 281 $element.text(value) 282 } 283 }, markerDragged: function (event) { 284 this.trigger("geocode:dragged", event.latLng) 285 }, mapClicked: function (event) { 286 this.trigger("geocode:click", event.latLng) 287 }, mapDragged: function (event) { 288 this.trigger("geocode:mapdragged", this.map.getCenter()) 289 }, mapIdle: function (event) { 290 this.trigger("geocode:idle", this.map.getCenter()) 291 }, mapZoomed: function (event) { 292 this.trigger("geocode:zoom", this.map.getZoom()) 293 }, resetMarker: function () { 294 this.marker.setPosition(this.data.location); 295 this.setDetail(this.details.lat, this.data.location.lat()); 296 this.setDetail(this.details.lng, this.data.location.lng()) 297 }, placeChanged: function () { 298 var place = this.autocomplete.getPlace(); 299 this.selected = true; 300 if (!place.geometry) { 301 if (this.options.autoselect) { 302 var autoSelection = this.selectFirstResult(); 303 this.find(autoSelection) 304 } 305 } else { 306 this.update(place) 307 } 308 } 309 }); 310 $.fn.geocomplete = function (options) { 311 var attribute = "plugin_geocomplete"; 312 if (typeof options == "string") { 313 var instance = $(this).data(attribute) || $(this).geocomplete().data(attribute), prop = instance[options]; 314 if (typeof prop == "function") { 315 prop.apply(instance, Array.prototype.slice.call(arguments, 1)); 316 return $(this) 317 } else { 318 if (arguments.length == 2) { 319 prop = arguments[1] 320 } 321 return prop 322 } 323 } else { 324 return this.each(function () { 325 var instance = $.data(this, attribute); 326 if (!instance) { 327 instance = new GeoComplete(this, options); 328 $.data(this, attribute, instance) 329 } 330 }) 331 } 332 } 333})(jQuery, window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.