1/** 2 * @name MarkerWithLabel for V3 3 * @author Gary Little (inspired by code from Marc Ridey of Google). 4 * @copyright Copyright 2012 Gary Little [gary at luxcentral.com] 5 * @fileoverview MarkerWithLabel extends the Google Maps JavaScript API V3 6 * <code>google.maps.Marker</code> class. 7 * <p> 8 * MarkerWithLabel allows you to define markers with associated labels. As you would expect, 9 * if the marker is draggable, so too will be the label. In addition, a marker with a label 10 * responds to all mouse events in the same manner as a regular marker. It also fires mouse 11 * events and "property changed" events just as a regular marker would. 12 */ 13 14/*! 15 * 16 * Licensed under the Apache License, Version 2.0 (the "License"); 17 * you may not use this file except in compliance with the License. 18 * You may obtain a copy of the License at 19 * 20 * http://www.apache.org/licenses/LICENSE-2.0 21 * 22 * Unless required by applicable law or agreed to in writing, software 23 * distributed under the License is distributed on an "AS IS" BASIS, 24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 * See the License for the specific language governing permissions and 26 * limitations under the License. 27 */ 28 29/*jslint browser:true */ 30/*global document,google */ 31 32/** 33 * @param {Function} childCtor Child class. 34 * @param {Function} parentCtor Parent class. 35 * @private 36 */ 37function inherits(childCtor, parentCtor) { 38 /* @constructor */ 39 function tempCtor() {} 40 tempCtor.prototype = parentCtor.prototype; 41 childCtor.superClass_ = parentCtor.prototype; 42 childCtor.prototype = new tempCtor(); 43 /* @override */ 44 childCtor.prototype.constructor = childCtor; 45} 46 47/** 48 * This constructor creates a label and associates it with a marker. 49 * It is for the private use of the MarkerWithLabel class. 50 * @constructor 51 * @param {Marker} marker The marker with which the label is to be associated. 52 * @param {string} crossURL The URL of the cross image =. 53 * @private 54 */ 55function MarkerLabel_(marker, crossURL) { 56 this.marker_ = marker; 57 58 this.labelDiv_ = document.createElement("div"); 59 this.labelDiv_.style.cssText = "position: absolute; overflow: hidden;"; 60 61 // Set up the DIV for handling mouse events in the label. This DIV forms a transparent veil 62 // in the "overlayMouseTarget" pane, a veil that covers just the label. This is done so that 63 // events can be captured even if the label is in the shadow of a google.maps.InfoWindow. 64 // Code is included here to ensure the veil is always exactly the same size as the label. 65 this.eventDiv_ = document.createElement("div"); 66 this.eventDiv_.style.cssText = this.labelDiv_.style.cssText; 67 68 // This is needed for proper behavior on MSIE: 69 this.eventDiv_.setAttribute("onselectstart", "return false;"); 70 this.eventDiv_.setAttribute("ondragstart", "return false;"); 71 72 // Get the DIV for the "X" to be displayed when the marker is raised. 73 this.crossDiv_ = MarkerLabel_.getSharedCross(crossURL); 74} 75 76if (typeof google !== 'undefined') { 77 inherits(MarkerLabel_, google.maps.OverlayView); 78} 79 80 81/** 82 * Returns the DIV for the cross used when dragging a marker when the 83 * crossOnDrag parameter set to true. One cross is shared with all markers. 84 * @param {string} crossURL The URL of the cross image. 85 * @private 86 */ 87MarkerLabel_.getSharedCross = function (crossURL) { 88 var div; 89 if (typeof MarkerLabel_.getSharedCross.crossDiv === "undefined") { 90 div = document.createElement("img"); 91 div.style.cssText = "position: absolute; z-index: 1000002; display: none;"; 92 // Hopefully Google never changes the standard "X" attributes: 93 div.style.marginLeft = "-8px"; 94 div.style.marginTop = "-9px"; 95 div.src = crossURL; 96 MarkerLabel_.getSharedCross.crossDiv = div; 97 } 98 return MarkerLabel_.getSharedCross.crossDiv; 99}; 100 101/** 102 * Adds the DIV representing the label to the DOM. This method is called 103 * automatically when the marker's <code>setMap</code> method is called. 104 * @private 105 */ 106MarkerLabel_.prototype.onAdd = function () { 107 var me = this; 108 109 this.getPanes().markerLayer.appendChild(this.labelDiv_); 110 this.getPanes().overlayMouseTarget.appendChild(this.eventDiv_); 111 // One cross is shared with all markers, so only add it once: 112 if (typeof MarkerLabel_.getSharedCross.processed === "undefined") { 113 this.getPanes().overlayImage.appendChild(this.crossDiv_); 114 MarkerLabel_.getSharedCross.processed = true; 115 } 116 117 this.addMouseListeners(); 118 119 this.listeners2_ = [ 120 google.maps.event.addListener(this.marker_, "clickable_changed", function () { 121 me.setClickable(); 122 }), 123 google.maps.event.addListener(this.marker_, "cursor_changed", function () { 124 me.setCursor(); 125 }), 126 google.maps.event.addListener(this.marker_, "draggable_changed", function () { 127 me.setClickable(); 128 }), 129 google.maps.event.addListener(this.marker_, "position_changed", function () { 130 me.setPosition(); 131 }), 132 google.maps.event.addListener(this.marker_, "visible_changed", function () { 133 me.setVisible(); 134 }), 135 google.maps.event.addListener(this.marker_, "title_changed", function () { 136 me.setTitle(); 137 }), 138 google.maps.event.addListener(this.marker_, "zindex_changed", function () { 139 me.setZIndex(); 140 }), 141 google.maps.event.addListener(this.marker_, "labelanchor_changed", function () { 142 me.setAnchor(); 143 }), 144 google.maps.event.addListener(this.marker_, "labelclass_changed", function () { 145 me.setStyles(); 146 }), 147 google.maps.event.addListener(this.marker_, "labelcontent_changed", function () { 148 me.setContent(); 149 }), 150 google.maps.event.addListener(this.marker_, "labelstyle_changed", function () { 151 me.setStyles(); 152 }), 153 google.maps.event.addListener(this.marker_, "labelvisible_changed", function () { 154 me.setVisible(); 155 }) 156 ]; 157}; 158 159/** 160 * Adds the listeners for a clickable label. 161 * @private 162 */ 163MarkerLabel_.prototype.addMouseListeners = function () { 164 var me = this; 165 var cTouchScreen = false;
166 var cMouseIsDown = false; 167 var cDraggingLabel = false; 168 var cIgnoreClick; 169 var cLatOffset, cLngOffset; 170 171 // Stop all processing of an event. 172 // 173 var cAbortEvent = function (e) { 174 e = e || window.event; 175 if (e.stopPropagation) { 176 e.stopPropagation(); 177 } else { 178 e.cancelBubble = true; 179 } 180 if (e.preventDefault) { 181 e.preventDefault(); 182 } else { 183 e.returnValue = false; 184 } 185 }; 186 187 // Stop an event from propagating. 188 // 189 var cStopPropagation = function (e) { 190 e = e || window.event; 191 if (e.stopPropagation) { 192 e.stopPropagation(); 193 } else { 194 e.cancelBubble = true; 195 } 196 }; 197 198 this.listeners1_ = [ 199 google.maps.event.addDomListener(this.eventDiv_, "mouseover", function (e) { 200 var mEvent = {latLng: me.marker_.getPosition()}; 201 if (me.marker_.getClickable() || me.marker_.getDraggable()) { 202 if (!cTouchScreen) { 203 this.style.cursor = (me.marker_.getCursor() || "pointer"); 204 google.maps.event.trigger(me.marker_, "mouseover", mEvent); 205 cAbortEvent(e); 206 } 207 } else { 208 this.style.cursor = null; 209 } 210 }), 211 google.maps.event.addDomListener(this.eventDiv_, "mouseout", function (e) { 212 var mEvent = {latLng: me.marker_.getPosition()}; 213 if (me.marker_.getClickable() || me.marker_.getDraggable()) { 214 if (!cTouchScreen) { 215 google.maps.event.trigger(me.marker_, "mouseout", mEvent); 216 cAbortEvent(e); 217 } 218 } 219 }), 220 google.maps.event.addDomListener(this.eventDiv_, "mousedown", function (e) { 221 var mEvent = {latLng: me.marker_.getPosition()}; 222 cDraggingLabel = false; 223 if (me.marker_.getClickable() || me.marker_.getDraggable()) { 224 cMouseIsDown = true; 225 google.maps.event.trigger(me.marker_, "mousedown", mEvent); 226 if (!cTouchScreen) { 227 cAbortEvent(e); // Prevent map pan when starting a drag on a label 228 } 229 } 230 }), 231 google.maps.event.addDomListener(this.eventDiv_, "mouseup", function (e) { 232 var mEvent = {latLng: me.marker_.getPosition()}; 233 if (cMouseIsDown) { 234 cMouseIsDown = false; 235 google.maps.event.trigger(me.marker_, "mouseup", mEvent); 236 if (cDraggingLabel) { 237 cDraggingLabel = false; 238 me.crossDiv_.style.display = "none"; 239 cIgnoreClick = true; // Set flag to ignore the click event reported after a label drag 240 google.maps.event.trigger(me.marker_, "dragend", mEvent); 241 } 242 if (!me.marker_.getDraggable()) { 243 cAbortEvent(e); 244 } 245 } 246 }), 247 google.maps.event.addDomListener(this.eventDiv_, "click", function (e) { 248 var mEvent = {latLng: me.marker_.getPosition()}; 249 if (me.marker_.getClickable() || me.marker_.getDraggable()) { 250 if (cIgnoreClick) { // Ignore the click reported when a label drag ends 251 cIgnoreClick = false; 252 } else { 253 google.maps.event.trigger(me.marker_, "click", mEvent); 254 } 255 cAbortEvent(e); // Prevent click from being passed on to map 256 } 257 }), 258 google.maps.event.addDomListener(this.eventDiv_, "dblclick", function (e) { 259 var mEvent = {latLng: me.marker_.getPosition()}; 260 if (me.marker_.getClickable() || me.marker_.getDraggable()) { 261 google.maps.event.trigger(me.marker_, "dblclick", mEvent); 262 cAbortEvent(e); // Prevent map zoom when double-clicking on a label 263 } 264 }), 265 google.maps.event.addListener(this.marker_.getMap(), "mousemove", function (mEvent) { 266 var position; 267 if (cMouseIsDown && me.marker_.getDraggable()) { 268 if (cDraggingLabel) { 269 // Change the reported location from the mouse position to the marker position: 270 mEvent.latLng = new google.maps.LatLng(mEvent.latLng.lat() - cLatOffset, mEvent.latLng.lng() - cLngOffset); 271 if (me.marker_.get("crossOnDrag")) { // Position and display the cross 272 position = me.getProjection().fromLatLngToDivPixel(mEvent.latLng); 273 me.crossDiv_.style.left = position.x + "px"; 274 me.crossDiv_.style.top = position.y + "px"; 275 me.crossDiv_.style.display = ""; 276 } 277 google.maps.event.trigger(me.marker_, "drag", mEvent); 278 } else { 279 // Calculate offsets from the click point to the marker position: 280 cLatOffset = mEvent.latLng.lat() - me.marker_.getPosition().lat(); 281 cLngOffset = mEvent.latLng.lng() - me.marker_.getPosition().lng(); 282 cDraggingLabel = true; 283 mEvent.latLng = me.marker_.getPosition(); 284 google.maps.event.trigger(me.marker_, "dragstart", mEvent); 285 } 286 } 287 }), 288 google.maps.event.addListener(this.marker_, "dragstart", function (mEvent) { 289 // During a drag, the marker's z-index is temporarily set to 1000000 to ensure 290 // it appears above all other markers. Here we also set the label's z-index 291 // to 1000000 (plus or minus 1 depending on whether the label is supposed 292 // to be above or below the marker). (NOTE: For some reason, Google does not 293 // fire a zindex_changed event when changing the marker's z-index to 100000 294 // or else this task would be handled by the MarkerLabel_.setZIndex() method.) 295 // 296 me.labelDiv_.style.zIndex = 1000000 + (this.get("labelInBackgroun
296d") ? -1 : +1); 297 me.eventDiv_.style.zIndex = me.labelDiv_.style.zIndex; 298 }), 299 google.maps.event.addListener(this.marker_, "drag", function (mEvent) { 300 this.setPosition(mEvent.latLng); 301 }), 302 google.maps.event.addListener(this.marker_, "dragend", function (mEvent) { 303 me.setZIndex(); 304 }), 305 // Prevent touch events from passing through the label DIV to the underlying map. 306 // 307 google.maps.event.addDomListener(this.eventDiv_, "touchstart", function (e) { 308 cTouchScreen = true; 309 cStopPropagation(e); 310 }), 311 google.maps.event.addDomListener(this.eventDiv_, "touchmove", function (e) { 312 cStopPropagation(e); 313 }), 314 google.maps.event.addDomListener(this.eventDiv_, "touchend", function (e) { 315 cStopPropagation(e); 316 }) 317 ]; 318}; 319 320/** 321 * Removes the listeners for a clickable label. 322 * @private 323 */ 324MarkerLabel_.prototype.removeMouseListeners = function () { 325 var i; 326 327 if (this.listeners1_) { 328 for (i = 0; i < this.listeners1_.length; i++) { 329 google.maps.event.removeListener(this.listeners1_[
329i]); 330 } 331 } 332}; 333 334/** 335 * Removes the DIV for the label from the DOM. It also removes all event handlers. 336 * This method is called automatically when the marker's <code>setMap(null)</code> 337 * method is called. 338 * @private 339 */ 340MarkerLabel_.prototype.onRemove = function () { 341 var i; 342 if (this.labelDiv_.parentNode) { 343 this.labelDiv_.parentNode.removeChild(this.labelDiv_); 344 } 345 if (this.eventDiv_.parentNode) { 346 this.eventDiv_.parentNode.removeChild(this.eventDiv_); 347 } 348 // Remove event listeners: 349 this.removeMouseListeners(); 350 351 if (this.listeners2_) { 352 for (i = 0; i < this.listeners2_.length; i++) { 353 google.maps.event.removeListener(this.listeners2_[i]); 354 } 355 } 356}; 357 358/** 359 * Draws the label on the map. 360 * @private 361 */ 362MarkerLabel_.prototype.draw = function () { 363 this.setContent(); 364 this.setTitle(); 365 this.setStyles(); 366}; 367 368/** 369 * Sets the content of the label. 370 * The content can be plain text or an HTML DOM node. 371 * @private 372 */ 373MarkerLabel_.prototype.setContent = function () { 374 var content = this.marker_.get("labelContent"); 375 var previousContent = this.marker_._previousContent; 376 if(previousContent !== content){ 377 this.marker_._previousContent = content; 378 if (typeof content.nodeType === "undefined") { 379 this.labelDiv_.innerHTML = content; 380 this.eventDiv_.innerHTML = this.labelDiv_.innerHTML; 381 } else { 382 this.labelDiv_.innerHTML = ""; // Remove current content 383 this.labelDiv_.appendChild(content); 384 content = content.cloneNode(true); 385 this.eventDiv_.innerHTML = ""; // Remove current content 386 this.eventDiv_.appendChild(content); 387 } 388 } 389}; 390 391/** 392 * Sets the content of the tool tip for the label. It is 393 * always set to be the same as for the marker itself. 394 * @private 395 */ 396MarkerLabel_.prototype.setTitle = function () { 397 this.eventDiv_.title = this.marker_.getTitle() || ""; 398}; 399 400/** 401 * Sets the style of the label by setting the style sheet and applying 402 * other specific styles requested. 403 * @private 404 */ 405MarkerLabel_.prototype.setStyles = function () { 406 var i, labelStyle; 407 408 // Apply style values from the style sheet defined in the labelClass parameter: 409 this.labelDiv_.className = this.marker_.get("labelClass"); 410 this.eventDiv_.className = this.labelDiv_.className; 411 412 // Clear existing inline style values: 413 this.labelDiv_.style.cssText = ""; 414 this.eventDiv_.style.cssText = ""; 415 // Apply style values defined in the labelStyle parameter: 416 labelStyle = this.marker_.get("labelStyle"); 417 for (i in labelStyle) { 418 if (labelStyle.hasOwnProperty(i)) { 419 this.labelDiv_.style[i] = labelStyle[i]; 420 this.eventDiv_.style[i] = labelStyle[i]; 421 } 422 } 423 this.setMandatoryStyles(); 424}; 425 426/** 427 * Sets the mandatory styles to the DIV representing the label as well as to the 428 * associated event DIV. This includes setting the DIV position, z-index, and visibility. 429 * @private 430 */ 431MarkerLabel_.prototype.setMandatoryStyles = function () { 432 this.labelDiv_.style.position = "absolute"; 433 this.labelDiv_.style.overflow = "hidden"; 434 // Make sure the opacity setting causes the desired effect on MSIE: 435 if (typeof this.labelDiv_.style.opacity !== "undefined" && this.labelDiv_.style.opacity !== "") { 436 this.labelDiv_.style.MsFilter = "\"progid:DXImageTransform.Microsoft.Alpha(opacity=" + (this.labelDiv_.style.opacity * 100) + ")\""; 437 this.labelDiv_.style.filter = "alpha(opacity=" + (this.labelDiv_.style.opacity * 100) + ")"; 438 } 439 440 this.eventDiv_.style.position = this.labelDiv_.style.position; 441 this.eventDiv_.style.overflow = this.labelDiv_.style.overflow; 442 this.eventDiv_.style.cursor = "pointer"; // Required to make this clickable on iOS 443 this.eventDiv_.style.opacity = 0.01; // Don't use 0; DIV won't be clickable on MSIE 444 this.eventDiv_.style.MsFilter = "\"progid:DXImageTransform.Microsoft.Alpha(opacity=1)\""; 445 this.eventDiv_.style.filter = "alpha(opacity=1)"; // For MSIE 446 447 this.setAnchor(); 448 this.setPosition(); 449 this.setZIndex(); 450 this.setVisible(); 451}; 452 453/** 454 * Sets the anchor point of the label. 455 * @private 456 */ 457MarkerLabel_.prototype.setAnchor = function () { 458 var anchor = this.marker_.get("labelAnchor"); 459 this.labelDiv_.style.marginLeft = -anchor.x + "px"; 460 this.labelDiv_.style.marginTop = -anchor.y + "px"; 461 this.eventDiv_.style.marginLeft = -anchor.x + "px"; 462 this.eventDiv_.style.marginTop = -anchor.y + "px"; 463}; 464 465/** 466 * Sets the position of the label. The z-index is also updated, if necessary. 467 * @private 468 */ 469MarkerLabel_.prototype.setPosition = function () { 470 var position = this.getProjection().fromLatLngToDivPixel(this.marker_.getPosition()); 471 this.labelDiv_.style.left = Math.round(position.x) + "px"; 472 this.labelDiv_.style.top = Math.round(position.y) + "px"; 473 this.eventDiv_.style.left = this.labelDiv_.style.left; 474 this.eventDiv_.style.top = this.labelDiv_.style.top; 475}; 476 477/** 478 * Sets the z-index of the label. If the marker's z-index property has not been defined, the z-index 479 * of the label is set to the vertical coordinate of the label. This is in keeping with the default 480 * stacking order for Google Maps: markers to the south are in front of markers to the north. 481 * @private 482 */ 483MarkerLabel_.prototype.setZIndex = function () {
484 var zAdjust = (this.marker_.get("labelInBackground") ? -1 : +1); 485 if (typeof this.marker_.getZIndex() === "undefined") { 486 this.labelDiv_.style.zIndex = parseInt(this.labelDiv_.style.top, 10) + zAdjust; 487 this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex; 488 } else { 489 this.labelDiv_.style.zIndex = this.marker_.getZIndex() + zAdjust; 490 this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex; 491 } 492}; 493 494/** 495 * Sets the clickability of the label. The label is clickable only if the 496 * marker itself is clickable (i.e., its clickable property is true) or if 497 * it is draggable (i.e., its draggable property is true). 498 * @private 499 */ 500MarkerLabel_.prototype.setClickable = function () { 501 this.removeMouseListeners(); 502 this.eventDiv_.style.cursor = null; 503 if (this.marker_.getClickable() || this.marker_.getDraggable()) { 504 this.addMouseListeners(); 505 } 506}; 507 508/** 509 * Sets the cursor for the label. 510 * @private 511 */ 512MarkerLabel_.prototype.setCursor = function () { 513 this.eventDiv_.style.cursor = this.marker_.getCursor(); 514}; 515 516/** 517 * Sets the visibility of the label. The label is visible only if the marker itself is 518 * visible (i.e., its visible property is true) and the labelVisible property is true. 519 * @private 520 */ 521MarkerLabel_.prototype.setVisible = function () { 522 if (this.marker_.get("labelVisible")) { 523 this.labelDiv_.style.display = this.marker_.getVisible() ? "block" : "none"; 524 } else { 525 this.labelDiv_.style.display = "none"; 526 } 527 this.eventDiv_.style.display = this.labelDiv_.style.display; 528}; 529 530/** 531 * @name MarkerWithLabelOptions 532 * @class This class represents the optional parameter passed to the {@link MarkerWithLabel} constructor. 533 * The properties available are the same as for <code>google.maps.Marker</code> with the addition 534 * of the properties listed below. To change any of these additional properties after the labeled 535 * marker has been created, call <code>google.maps.Marker.set(propertyName, propertyValue)</code>. 536 * <p> 537 * When any of these properties changes, a property changed event is fired. The names of these 538 * events are derived from the name of the property and are of the form <code>propertyname_changed</code>. 539 * For example, if the content of the label changes, a <code>labelcontent_changed</code> event 540 * is fired. 541 * <p> 542 * @property {string|Node} [labelContent] The content of the label (plain text or an HTML DOM node). 543 * @property {Point} [labelAnchor] By default, a label is drawn with its anchor point at (0,0) so 544 * that its top left corner is positioned at the anchor point of the associated marker. Use this 545 * property to change the anchor point of the label. For example, to center a 50px-wide label 546 * beneath a marker, specify a <code>labelAnchor</code> of <code>google.maps.Point(25, 0)</code>. 547 * (Note: x-values increase to the right and y-values increase to the top.) 548 * @property {string} [labelClass] The name of the CSS class defining the styles for the label. 549 * Note that style values for <code>position</code>, <code>overflow</code>, <code>top</code>, 550 * <code>left</code>, <code>zIndex</code>, <code>display</code>, <code>marginLeft</code>, and 551 * <code>marginTop</code> are ignored; these styles are for internal use only. 552 * @property {Object} [labelStyle] An object literal whose properties define specific CSS 553 * style values to be applied to the label. Style values defined here override those that may 554 * be defined in the <code>labelClass</code> style sheet. If this property is changed after the 555 * label has been created, all previously set styles (except those defined in the style sheet) 556 * are removed from the label before the new style values are applied. 557 * Note that style values for <code>position</code>, <code>overflow</code>, <code>top</code>, 558 * <code>left</code>, <code>zIndex</code>, <code>display</code>, <code>marginLeft</code>, and 559 * <code>marginTop</code> are ignored; these styles are for internal use only. 560 * @property {boolean} [labelInBackground] A flag indicating whether a label that overlaps its 561 * associated marker should appear in the background (i.e., in a plane below the marker). 562 * The default is <code>false</code>, which causes the label to appear in the foreground. 563 * @property {boolean} [labelVisible] A flag indicating whether the label is to be visible. 564 * The default is <code>true</code>. Note that even if <code>labelVisible</code> is 565 * <code>true</code>, the label will <i>not</i> be visible unless the associated marker is also 566 * visible (i.e., unless the marker's <code>visible</code> property is <code>true</code>). 567 * @property {boolean} [crossOnDrag] A flag indicating whether a cross ("X") is to be 568 * shown when the marker label is dragged. The default is <code>true</code>. The marker 569 * is placed at the position of the cross when the drag ends. 570 * @property {boolean} [optimized] A flag indicating whether rendering is to be optimized 571 * for the marker. <b>Important: The optimized rendering technique is not supported by 572 * MarkerWithLabel, so the value of this parameter is always forced to <code>false</code>. 573 * @property {string}
573 [crossImage="//maps.gstatic.com/intl/en_us/mapfiles/drag_cross_67_16.png"] 574 * The URL of the cross image to be displayed while dragging a marker. 575 */ 576/** 577 * Creates a MarkerWithLabel with the options specified in {@link MarkerWithLabelOptions}. 578 * @constructor 579 * @param {MarkerWithLabelOptions} [opt_options] The optional parameters. 580 */ 581function MarkerWithLabel(opt_options) { 582 opt_options = opt_options || {}; 583 opt_options.labelContent = opt_options.labelContent || ""; 584 opt_options.labelAnchor = opt_options.labelAnchor || new google.maps.Point(0, 0); 585 opt_options.labelClass = opt_options.labelClass || "markerLabels"; 586 opt_options.labelStyle = opt_options.labelStyle || {}; 587 opt_options.labelInBackground = opt_options.labelInBackground || false; 588 if (typeof opt_options.labelVisible === "undefined") { 589 opt_options.labelVisible = true; 590 } 591 if (typeof opt_options.crossOnDrag === "undefined") { 592 opt_options.crossOnDrag = true; 593 } 594 if (typeof opt_options.clickable === "undefined") { 595 opt_options.clickable = true; 596 } 597 if (typeof opt_options.draggable === "undefined") { 598 opt_options.draggable = false; 599 } 600 if (typeof opt_options.optimized === "undefined") { 601 opt_options.optimized = false; 602 } 603 opt_options.crossImage = opt_options.crossImage || "//maps.gstatic.com/intl/en_us/mapfiles/drag_cross_67_16.png"; 604 opt_options.optimized = false; // Optimized rendering is not supported 605 606 this.label = new MarkerLabel_(this, opt_options.crossImage); // Bind the label to the marker 607 608 // Call the parent constructor. It calls Marker.setValues to initialize, so all 609 // the new parameters are conveniently saved and can be accessed with get/set. 610 // Marker.set triggers a property changed event (called "propertyname_changed") 611 // that the marker label listens for in order to react to state changes. 612 google.maps.Marker.apply(this, arguments); 613} 614 615if (typeof google !== 'undefined') { 616 inherits(MarkerWithLabel, google.maps.Marker); 617} 618 619/** 620 * Overrides the standard Marker setMap function. 621 * @param {Map} theMap The map to which the marker is to be added. 622 * @private 623 */ 624MarkerWithLabel.prototype.setMap = function (theMap) { 625 626 // Call the inherited function... 627 google.maps.Marker.prototype.setMap.apply(this, arguments); 628 629 // ... then deal with the label: 630 this.label.setMap(theMap); 631}; 632 633if (typeof module == 'object') { 634 module.exports = MarkerWithLabel; 635}
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.