socmap_adf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ };