socmap_adf 0.0.1

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