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