betterplace_explorer 0.0.1.pre.alpha2 → 0.0.1.pre.alpha3
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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 744007d44908e58afb9c3df1132147d461da05b0
|
|
4
|
+
data.tar.gz: d7a826b8fde7e9b7c20bd3d0f2333dd0f570ff64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d35926895739173156e4b1dbb6844b427f76b76b0973ea7e2e11a930b4b696059982a186b4f237ba4a81b745b05858353c853ff5bac169cbac972f322ff9e1a9
|
|
7
|
+
data.tar.gz: 90c5334037a76eb768cee703e6300907b16ca3f5899852901120e093ee521c59cbccaf787fbb16a459b21aecaea7e45f3c62a975ed52fdc281c5a73db28bc90f
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
displayName: 'Explorer',
|
|
79
79
|
getInitialState: function () {
|
|
80
80
|
function getInitialState() {
|
|
81
|
-
return { records: [] };
|
|
81
|
+
return { records: [], currentBounds: {}, currentPage: 1 };
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
return getInitialState;
|
|
@@ -92,10 +92,17 @@
|
|
|
92
92
|
north: parseFloat(this.props.location.query.north),
|
|
93
93
|
south: parseFloat(this.props.location.query.south)
|
|
94
94
|
};
|
|
95
|
-
this.setState({
|
|
95
|
+
this.setState({ currentBounds: currentBounds, changeBounds: currentBounds });
|
|
96
96
|
} else {
|
|
97
|
-
|
|
97
|
+
var defaultBounds = {
|
|
98
|
+
east: 19.90940093749998,
|
|
99
|
+
north: 61.493695009727325,
|
|
100
|
+
south: 39.728030772041244,
|
|
101
|
+
west: -4.612083437500019
|
|
102
|
+
};
|
|
103
|
+
this.setState({ currentBounds: defaultBounds, changeBounds: defaultBounds });
|
|
98
104
|
}
|
|
105
|
+
// this.load('https://www.betterplace.org/de/api_v4/volunteering?per_page=20')
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
return componentDidMount;
|
|
@@ -116,8 +123,8 @@
|
|
|
116
123
|
'div',
|
|
117
124
|
{ className: 'row' },
|
|
118
125
|
_react2['default'].createElement(_Pagination2['default'], { currentPage: this.state.currentPage, totalPages: this.state.totalPages, changePage: this.changePage }),
|
|
119
|
-
_react2['default'].createElement(_VolunteeringList2['default'], { records: this.state.records, totalEntries: this.state.totalEntries }),
|
|
120
|
-
_react2['default'].createElement(_Map2['default'], { records: this.state.records, mapIdle: this.loadByBoundingBox, changeBounds: this.state.changeBounds })
|
|
126
|
+
_react2['default'].createElement(_VolunteeringList2['default'], { records: this.state.records, totalEntries: this.state.totalEntries, setHighlightRecord: this.setHighlightRecord }),
|
|
127
|
+
_react2['default'].createElement(_Map2['default'], { records: this.state.records, mapIdle: this.loadByBoundingBox, changeBounds: this.state.changeBounds, highlightRecord: this.state.highlightRecord })
|
|
121
128
|
)
|
|
122
129
|
);
|
|
123
130
|
}
|
|
@@ -141,7 +148,8 @@
|
|
|
141
148
|
|
|
142
149
|
changePage: function () {
|
|
143
150
|
function changePage(page) {
|
|
144
|
-
this.
|
|
151
|
+
this.setState({ currentPage: page });
|
|
152
|
+
this.load(this.state.currentBounds, page);
|
|
145
153
|
}
|
|
146
154
|
|
|
147
155
|
return changePage;
|
|
@@ -163,16 +171,28 @@
|
|
|
163
171
|
// browserHistory.push({ pathname: `/l/${location}`, query: this.props.location.query })
|
|
164
172
|
|
|
165
173
|
this.updateURLBounds(bounds);
|
|
166
|
-
this.setState({ changeBounds: bounds });
|
|
174
|
+
this.setState({ currentBounds: bounds, changeBounds: bounds, currentPage: 1 });
|
|
167
175
|
}
|
|
168
176
|
|
|
169
177
|
return changeLocation;
|
|
170
178
|
}(),
|
|
171
179
|
|
|
172
180
|
load: function () {
|
|
173
|
-
function load(
|
|
181
|
+
function load(bounds, page) {
|
|
174
182
|
var _this = this;
|
|
175
183
|
|
|
184
|
+
var params = {
|
|
185
|
+
nelat: bounds.north,
|
|
186
|
+
nelng: bounds.east,
|
|
187
|
+
swlat: bounds.south,
|
|
188
|
+
swlng: bounds.west,
|
|
189
|
+
page: page,
|
|
190
|
+
per_page: 20
|
|
191
|
+
};
|
|
192
|
+
var query = Object.keys(params).map(function (k, _) {
|
|
193
|
+
return k + '=' + params[k];
|
|
194
|
+
}).join('&');
|
|
195
|
+
var url = 'https://www.betterplace.org/de/api_v4/volunteering?' + query;
|
|
176
196
|
fetch(url).then(function (response) {
|
|
177
197
|
return response.json();
|
|
178
198
|
}).then(function (json) {
|
|
@@ -187,12 +207,20 @@
|
|
|
187
207
|
|
|
188
208
|
loadByBoundingBox: function () {
|
|
189
209
|
function loadByBoundingBox(bounds) {
|
|
190
|
-
bounds
|
|
210
|
+
this.setState({ currentBounds: bounds, currentPage: 1 });
|
|
191
211
|
this.updateURLBounds(bounds);
|
|
192
|
-
this.load(
|
|
212
|
+
this.load(bounds, 1);
|
|
193
213
|
}
|
|
194
214
|
|
|
195
215
|
return loadByBoundingBox;
|
|
216
|
+
}(),
|
|
217
|
+
|
|
218
|
+
setHighlightRecord: function () {
|
|
219
|
+
function setHighlightRecord(record) {
|
|
220
|
+
this.setState({ highlightRecord: record });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return setHighlightRecord;
|
|
196
224
|
}()
|
|
197
225
|
});
|
|
198
226
|
|
|
@@ -26009,13 +26037,15 @@
|
|
|
26009
26037
|
|
|
26010
26038
|
render: function () {
|
|
26011
26039
|
function render() {
|
|
26040
|
+
var _this = this;
|
|
26041
|
+
|
|
26012
26042
|
var volunteeringNodes = this.props.records.map(function (record) {
|
|
26013
|
-
return _react2['default'].createElement(_Volunteering2['default'], { record: record, key: record.id });
|
|
26043
|
+
return _react2['default'].createElement(_Volunteering2['default'], { record: record, key: record.id, setHighlightRecord: _this.props.setHighlightRecord });
|
|
26014
26044
|
});
|
|
26015
26045
|
|
|
26016
26046
|
return _react2['default'].createElement(
|
|
26017
26047
|
'div',
|
|
26018
|
-
{ className: 'col-md-14' },
|
|
26048
|
+
{ className: 'col-md-14 bpe--volunteering-list' },
|
|
26019
26049
|
_react2['default'].createElement(
|
|
26020
26050
|
'h1',
|
|
26021
26051
|
null,
|
|
@@ -26026,7 +26056,7 @@
|
|
|
26026
26056
|
),
|
|
26027
26057
|
_react2['default'].createElement(
|
|
26028
26058
|
'div',
|
|
26029
|
-
|
|
26059
|
+
null,
|
|
26030
26060
|
volunteeringNodes
|
|
26031
26061
|
)
|
|
26032
26062
|
);
|
|
@@ -26059,12 +26089,13 @@
|
|
|
26059
26089
|
|
|
26060
26090
|
render: function () {
|
|
26061
26091
|
function render() {
|
|
26062
|
-
var imageUrl = this.findLink(this.props.record.image.links,
|
|
26092
|
+
var imageUrl = this.findLink(this.props.record.image.links, 'fill_270x141');
|
|
26063
26093
|
var carrier = this.props.record.carrier || {};
|
|
26094
|
+
var selfUrl = '/volunteering/' + this.props.record.id; // this.findLink(this.props.record.links, 'platform')
|
|
26064
26095
|
|
|
26065
26096
|
return _react2['default'].createElement(
|
|
26066
26097
|
'a',
|
|
26067
|
-
{ href: '
|
|
26098
|
+
{ href: selfUrl, target: '_blank', onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave },
|
|
26068
26099
|
_react2['default'].createElement(
|
|
26069
26100
|
'div',
|
|
26070
26101
|
{ className: 'bpe--volunteering media' },
|
|
@@ -26102,6 +26133,22 @@
|
|
|
26102
26133
|
}
|
|
26103
26134
|
|
|
26104
26135
|
return findLink;
|
|
26136
|
+
}(),
|
|
26137
|
+
|
|
26138
|
+
handleMouseEnter: function () {
|
|
26139
|
+
function handleMouseEnter() {
|
|
26140
|
+
this.props.setHighlightRecord(this.props.record);
|
|
26141
|
+
}
|
|
26142
|
+
|
|
26143
|
+
return handleMouseEnter;
|
|
26144
|
+
}(),
|
|
26145
|
+
|
|
26146
|
+
handleMouseLeave: function () {
|
|
26147
|
+
function handleMouseLeave() {
|
|
26148
|
+
this.props.setHighlightRecord(null);
|
|
26149
|
+
}
|
|
26150
|
+
|
|
26151
|
+
return handleMouseLeave;
|
|
26105
26152
|
}()
|
|
26106
26153
|
});
|
|
26107
26154
|
|
|
@@ -26123,8 +26170,21 @@
|
|
|
26123
26170
|
|
|
26124
26171
|
var _react2 = _interopRequireDefault(_react);
|
|
26125
26172
|
|
|
26173
|
+
var _reactDom = __webpack_require__(99);
|
|
26174
|
+
|
|
26175
|
+
var _reactDom2 = _interopRequireDefault(_reactDom);
|
|
26176
|
+
|
|
26177
|
+
var _Volunteering = __webpack_require__(230);
|
|
26178
|
+
|
|
26179
|
+
var _Volunteering2 = _interopRequireDefault(_Volunteering);
|
|
26180
|
+
|
|
26126
26181
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
26127
26182
|
|
|
26183
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
26184
|
+
|
|
26185
|
+
__webpack_require__(279);
|
|
26186
|
+
|
|
26187
|
+
|
|
26128
26188
|
var Map = _react2['default'].createClass({
|
|
26129
26189
|
displayName: 'Map',
|
|
26130
26190
|
|
|
@@ -26132,11 +26192,31 @@
|
|
|
26132
26192
|
function render() {
|
|
26133
26193
|
var _this = this;
|
|
26134
26194
|
|
|
26135
|
-
|
|
26136
|
-
|
|
26195
|
+
var image = {
|
|
26196
|
+
url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAABCFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD26OP39/cAAADPz88AAAAAAAAAAAD9/f3p6ens7Ozt7e2CgoLb29vt7e0nJyeampqZmZns7OwsLCxKSkqZmZkAAADa2tqHh4cwMDDq6uqEhIT+/v4AAABERETPz89HR0cAAADc3Nzb29u2Og+1OA3PfWG4QRi9TSfKb1C1OQ7luqvJb0/25uHcoY325+K3PRTmu6y2PBLfqJa3PRPowrXcoo7BVzPPfmL26OO9Tii2OhDep5Tluar15eD15N/epZK5Qhkx1ZAbAAAAOnRSTlMAAQcCBA4UDwMVKAUWHBMIIi0GDB0rC/7tHp8nGin70NLVWLHXNGhn0zQ+ZiqxWTXQWfsZPJ49H7SyPeI8ZAAAAXFJREFUeAGFk+MaIzEYhZOMbdW2l7Xdte7/TnbTp2628/7N55wDLkDI0xL6h0TzEIJHIEUjl1MFWRZUzkU0BR+fNYZVdNExDEfUFZbR7kIgZVpsEM9Ekn4i4ScjmXjAWuY1AvKIeROtpr4sZl9Xw0/jxc9UMRpjEA/P+Yiz81lv8K1/ojfwsnmbQ6calMnYb9P7P/0bhtP0e5sxqWMB2oqVc9te/47J91wzZtEQF9DYaH096T8wWXejrEbhAkxQ9Yb9J4ZeMWBoCCBi46nPfQKDUk1AEPCu0l72SAG9ZUNxeUBz+rtDn8ghonM0kFQxOSYHjFuiKgEkOP6IHDDyHQEBJBuJFTlglzDk8IDwFnjI2Ysh8ZqRl2viQ83Jh5ofDwWREC8NXpwaf1aB/FmFDwwNT989ff7u6UcRf/d/BfP7JJiT5CqPkvuRrmDJ3Yu2RxTtSfaxaBHLfrTZjGaLX6nCSfbPxul0HowTZr1w84ba/y8wjYohV+qwEQAAAABJRU5ErkJggg==',
|
|
26197
|
+
size: new google.maps.Size(32, 32),
|
|
26198
|
+
origin: new google.maps.Point(0, 0),
|
|
26199
|
+
anchor: new google.maps.Point(16, 16)
|
|
26200
|
+
};
|
|
26201
|
+
|
|
26202
|
+
var highlightImage = {
|
|
26203
|
+
url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAABDlBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADr4eH39/fPz88AAAAAAAAAAADp6ekAAAD9/f3s7Ozt7e3t7e2CgoInJyfb29uZmZmamprs7OyEhISHh4cwMDBKSkr+/v7a2toAAAAsLCzq6uqZmZlEREQAAADPz89HR0cAAADb29vc3NxjGxtSAgJRAABZDAyNWFhUBQVSAQHEqKiBRkaBR0eth4fp39+OWVlWBwfq4OCzkJCuiIhsKCjCpqZaDQ1kHBzr4eHDp6exjIzo3t7CpaXKsbFVBgayjo5TAwPo3d2OWlqAlY+pAAAAOnRSTlMAAQcCBA4UDwMVKAUWHBMIIi0GDB0rC/7tnx4nGtAp+9LV11g0sWdo01lZNT77sSo00GY8GZ49H7K0BXS41QAAAXhJREFUeAGFk/OiG0EYxXdmbSvGdZwytnXr9v1fpJkYi9+/83nOwU4AwBA83MITDADYLQAnoEVLrCCwEm1BAge3zzJJiQpnqqrJKSJFylchANd0KpLIunEnmXTibjYRoXTtHAEYSH6MVlObYX89aS0Gw++pp2iMhAw45kPaeHi0x3+aBxpj+/HBoOGhBq6Rxof0z1XzgtYy/dkgNXxXgNBj5cys0byi+zuTi+kEQAVkKlrsdZs3dHtfo5SMowJkpGq3mne07KcIuS0BIJVI/Wt60H4psRBgjCW+ThteAY3pm2gxGEErn+ZNT+auQhMYL3HxgXfAoMJJPAZZ06l7B9Qdk4UYFNTkxDvgV1IVwgPCW6Ah+wFDojXdwDXRoUbehxrtDgUgm3hpB5wafdaz92c9fyEJcPju9/vvfq9x6Lt9BfPtIJiD5PK3kvuRziPJXYm2fSrSaJ9Ee5J9LPqEZF/vdOr94d/U80n2t8YpFG6NE269UPOG2P8/TQCL+fVhnpUAAAAASUVORK5CYII=',
|
|
26204
|
+
size: new google.maps.Size(32, 32),
|
|
26205
|
+
origin: new google.maps.Point(0, 0),
|
|
26206
|
+
anchor: new google.maps.Point(16, 16)
|
|
26207
|
+
};
|
|
26208
|
+
|
|
26209
|
+
var markers = this.props.records.map(function (record) {
|
|
26210
|
+
return _react2['default'].createElement(_reactGoogleMaps.Marker, {
|
|
26211
|
+
position: { lat: record.latitude, lng: record.longitude },
|
|
26212
|
+
key: record.id,
|
|
26213
|
+
icon: record == _this.props.highlightRecord ? highlightImage : image,
|
|
26214
|
+
zIndex: record == _this.props.highlightRecord ? 10000 : null,
|
|
26215
|
+
onClick: _this.handleMarkerClick.bind(_this, record),
|
|
26216
|
+
customInfo: 'Marker A'
|
|
26217
|
+
});
|
|
26218
|
+
});
|
|
26137
26219
|
|
|
26138
|
-
// if(this.props.bounds)
|
|
26139
|
-
// this.googlemap.fitBounds(this.props.bounds)
|
|
26140
26220
|
return _react2['default'].createElement(
|
|
26141
26221
|
'div',
|
|
26142
26222
|
{ className: 'col-md-10' },
|
|
@@ -26157,11 +26237,10 @@
|
|
|
26157
26237
|
}(),
|
|
26158
26238
|
defaultZoom: 5,
|
|
26159
26239
|
defaultCenter: { lat: 52.49928, lng: 13.44944 },
|
|
26160
|
-
onIdle: this.idle
|
|
26240
|
+
onIdle: this.idle,
|
|
26241
|
+
onClick: this.handleMapClick
|
|
26161
26242
|
},
|
|
26162
|
-
|
|
26163
|
-
return _react2['default'].createElement(_reactGoogleMaps.Marker, { position: { lat: record.latitude, lng: record.longitude }, key: record.id });
|
|
26164
|
-
})
|
|
26243
|
+
markers
|
|
26165
26244
|
)
|
|
26166
26245
|
})
|
|
26167
26246
|
)
|
|
@@ -26191,12 +26270,61 @@
|
|
|
26191
26270
|
return resize;
|
|
26192
26271
|
}(),
|
|
26193
26272
|
|
|
26273
|
+
// Trigger loading of new API results for the current bounds. Since it triggers
|
|
26274
|
+
// multiple times when `fitBounds` is called, we prevent multiple API calls
|
|
26275
|
+
// by comparing the last loaded bounds with the current ones.
|
|
26194
26276
|
idle: function () {
|
|
26195
26277
|
function idle() {
|
|
26196
|
-
|
|
26278
|
+
if (this.preventReloadOnce) {
|
|
26279
|
+
this.preventReloadOnce = false;
|
|
26280
|
+
return;
|
|
26281
|
+
}
|
|
26282
|
+
|
|
26283
|
+
if (this.infoBubble) this.infoBubble.close();
|
|
26284
|
+
|
|
26285
|
+
var newBounds = JSON.stringify(this.googlemap.getBounds());
|
|
26286
|
+
|
|
26287
|
+
if (this.loadedBounds != newBounds) {
|
|
26288
|
+
this.loadedBounds = newBounds;
|
|
26289
|
+
this.props.mapIdle(this.googlemap.getBounds().toJSON());
|
|
26290
|
+
}
|
|
26197
26291
|
}
|
|
26198
26292
|
|
|
26199
26293
|
return idle;
|
|
26294
|
+
}(),
|
|
26295
|
+
|
|
26296
|
+
handleMapClick: function () {
|
|
26297
|
+
function handleMapClick() {
|
|
26298
|
+
if (this.infoBubble) this.infoBubble.close();
|
|
26299
|
+
}
|
|
26300
|
+
|
|
26301
|
+
return handleMapClick;
|
|
26302
|
+
}(),
|
|
26303
|
+
|
|
26304
|
+
handleMarkerClick: function () {
|
|
26305
|
+
function handleMarkerClick(record) {
|
|
26306
|
+
var _ref;
|
|
26307
|
+
|
|
26308
|
+
if (this.infoBubble) this.infoBubble.close();
|
|
26309
|
+
|
|
26310
|
+
var div = document.createElement('div');
|
|
26311
|
+
_reactDom2['default'].render(_react2['default'].createElement(_Volunteering2['default'], { record: record, key: record.id }), div);
|
|
26312
|
+
|
|
26313
|
+
this.infoBubble = new InfoBubble((_ref = {
|
|
26314
|
+
content: div,
|
|
26315
|
+
maxWidth: 300,
|
|
26316
|
+
position: new google.maps.LatLng(record.latitude, record.longitude),
|
|
26317
|
+
map: this.googlemap.props.map,
|
|
26318
|
+
borderRadius: 0,
|
|
26319
|
+
shadowStyle: 0,
|
|
26320
|
+
minWidth: 200
|
|
26321
|
+
}, _defineProperty(_ref, 'maxWidth', 300), _defineProperty(_ref, 'minHeight', 200), _defineProperty(_ref, 'maxHeight', 200), _defineProperty(_ref, 'hideCloseButton', true), _defineProperty(_ref, 'padding', 0), _ref));
|
|
26322
|
+
|
|
26323
|
+
this.preventReloadOnce = true;
|
|
26324
|
+
this.infoBubble.open();
|
|
26325
|
+
}
|
|
26326
|
+
|
|
26327
|
+
return handleMarkerClick;
|
|
26200
26328
|
}()
|
|
26201
26329
|
});
|
|
26202
26330
|
|
|
@@ -30630,5 +30758,1790 @@
|
|
|
30630
30758
|
|
|
30631
30759
|
exports["default"] = Pagination;
|
|
30632
30760
|
|
|
30761
|
+
/***/ },
|
|
30762
|
+
/* 279 */
|
|
30763
|
+
/***/ function(module, exports) {
|
|
30764
|
+
|
|
30765
|
+
// ==ClosureCompiler==
|
|
30766
|
+
// @compilation_level ADVANCED_OPTIMIZATIONS
|
|
30767
|
+
// @externs_url https://raw.githubusercontent.com/google/closure-compiler/master/contrib/externs/maps/google_maps_api_v3_16.js
|
|
30768
|
+
// ==/ClosureCompiler==
|
|
30769
|
+
|
|
30770
|
+
/**
|
|
30771
|
+
* @name CSS3 InfoBubble with tabs for Google Maps API V3
|
|
30772
|
+
* @version 0.8
|
|
30773
|
+
* @author Luke Mahe
|
|
30774
|
+
* @fileoverview
|
|
30775
|
+
* This library is a CSS Infobubble with tabs. It uses css3 rounded corners and
|
|
30776
|
+
* drop shadows and animations. It also allows tabs
|
|
30777
|
+
*/
|
|
30778
|
+
|
|
30779
|
+
/*
|
|
30780
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
30781
|
+
* you may not use this file except in compliance with the License.
|
|
30782
|
+
* You may obtain a copy of the License at
|
|
30783
|
+
*
|
|
30784
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
30785
|
+
*
|
|
30786
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
30787
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
30788
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
30789
|
+
* See the License for the specific language governing permissions and
|
|
30790
|
+
* limitations under the License.
|
|
30791
|
+
*/
|
|
30792
|
+
|
|
30793
|
+
|
|
30794
|
+
/**
|
|
30795
|
+
* A CSS3 InfoBubble v0.8
|
|
30796
|
+
* @param {Object.<string, *>=} opt_options Optional properties to set.
|
|
30797
|
+
* @extends {google.maps.OverlayView}
|
|
30798
|
+
* @constructor
|
|
30799
|
+
*/
|
|
30800
|
+
function InfoBubble(opt_options) {
|
|
30801
|
+
this.extend(InfoBubble, google.maps.OverlayView);
|
|
30802
|
+
this.tabs_ = [];
|
|
30803
|
+
this.activeTab_ = null;
|
|
30804
|
+
this.baseZIndex_ = 100;
|
|
30805
|
+
this.isOpen_ = false;
|
|
30806
|
+
|
|
30807
|
+
var options = opt_options || {};
|
|
30808
|
+
|
|
30809
|
+
if (options['backgroundColor'] == undefined) {
|
|
30810
|
+
options['backgroundColor'] = this.BACKGROUND_COLOR_;
|
|
30811
|
+
}
|
|
30812
|
+
|
|
30813
|
+
if (options['borderColor'] == undefined) {
|
|
30814
|
+
options['borderColor'] = this.BORDER_COLOR_;
|
|
30815
|
+
}
|
|
30816
|
+
|
|
30817
|
+
if (options['borderRadius'] == undefined) {
|
|
30818
|
+
options['borderRadius'] = this.BORDER_RADIUS_;
|
|
30819
|
+
}
|
|
30820
|
+
|
|
30821
|
+
if (options['borderWidth'] == undefined) {
|
|
30822
|
+
options['borderWidth'] = this.BORDER_WIDTH_;
|
|
30823
|
+
}
|
|
30824
|
+
|
|
30825
|
+
if (options['padding'] == undefined) {
|
|
30826
|
+
options['padding'] = this.PADDING_;
|
|
30827
|
+
}
|
|
30828
|
+
|
|
30829
|
+
if (options['arrowPosition'] == undefined) {
|
|
30830
|
+
options['arrowPosition'] = this.ARROW_POSITION_;
|
|
30831
|
+
}
|
|
30832
|
+
|
|
30833
|
+
if (options['disableAutoPan'] == undefined) {
|
|
30834
|
+
options['disableAutoPan'] = false;
|
|
30835
|
+
}
|
|
30836
|
+
|
|
30837
|
+
if (options['disableAnimation'] == undefined) {
|
|
30838
|
+
options['disableAnimation'] = false;
|
|
30839
|
+
}
|
|
30840
|
+
|
|
30841
|
+
if (options['minWidth'] == undefined) {
|
|
30842
|
+
options['minWidth'] = this.MIN_WIDTH_;
|
|
30843
|
+
}
|
|
30844
|
+
|
|
30845
|
+
if (options['shadowStyle'] == undefined) {
|
|
30846
|
+
options['shadowStyle'] = this.SHADOW_STYLE_;
|
|
30847
|
+
}
|
|
30848
|
+
|
|
30849
|
+
if (options['arrowSize'] == undefined) {
|
|
30850
|
+
options['arrowSize'] = this.ARROW_SIZE_;
|
|
30851
|
+
}
|
|
30852
|
+
|
|
30853
|
+
if (options['arrowStyle'] == undefined) {
|
|
30854
|
+
options['arrowStyle'] = this.ARROW_STYLE_;
|
|
30855
|
+
}
|
|
30856
|
+
|
|
30857
|
+
if (options['closeSrc'] == undefined) {
|
|
30858
|
+
options['closeSrc'] = this.CLOSE_SRC_;
|
|
30859
|
+
}
|
|
30860
|
+
|
|
30861
|
+
this.buildDom_();
|
|
30862
|
+
this.setValues(options);
|
|
30863
|
+
}
|
|
30864
|
+
window['InfoBubble'] = InfoBubble;
|
|
30865
|
+
|
|
30866
|
+
|
|
30867
|
+
/**
|
|
30868
|
+
* Default arrow size
|
|
30869
|
+
* @const
|
|
30870
|
+
* @private
|
|
30871
|
+
*/
|
|
30872
|
+
InfoBubble.prototype.ARROW_SIZE_ = 15;
|
|
30873
|
+
|
|
30874
|
+
|
|
30875
|
+
/**
|
|
30876
|
+
* Default arrow style
|
|
30877
|
+
* @const
|
|
30878
|
+
* @private
|
|
30879
|
+
*/
|
|
30880
|
+
InfoBubble.prototype.ARROW_STYLE_ = 0;
|
|
30881
|
+
|
|
30882
|
+
|
|
30883
|
+
/**
|
|
30884
|
+
* Default shadow style
|
|
30885
|
+
* @const
|
|
30886
|
+
* @private
|
|
30887
|
+
*/
|
|
30888
|
+
InfoBubble.prototype.SHADOW_STYLE_ = 1;
|
|
30889
|
+
|
|
30890
|
+
|
|
30891
|
+
/**
|
|
30892
|
+
* Default min width
|
|
30893
|
+
* @const
|
|
30894
|
+
* @private
|
|
30895
|
+
*/
|
|
30896
|
+
InfoBubble.prototype.MIN_WIDTH_ = 50;
|
|
30897
|
+
|
|
30898
|
+
|
|
30899
|
+
/**
|
|
30900
|
+
* Default arrow position
|
|
30901
|
+
* @const
|
|
30902
|
+
* @private
|
|
30903
|
+
*/
|
|
30904
|
+
InfoBubble.prototype.ARROW_POSITION_ = 50;
|
|
30905
|
+
|
|
30906
|
+
|
|
30907
|
+
/**
|
|
30908
|
+
* Default padding
|
|
30909
|
+
* @const
|
|
30910
|
+
* @private
|
|
30911
|
+
*/
|
|
30912
|
+
InfoBubble.prototype.PADDING_ = 10;
|
|
30913
|
+
|
|
30914
|
+
|
|
30915
|
+
/**
|
|
30916
|
+
* Default border width
|
|
30917
|
+
* @const
|
|
30918
|
+
* @private
|
|
30919
|
+
*/
|
|
30920
|
+
InfoBubble.prototype.BORDER_WIDTH_ = 1;
|
|
30921
|
+
|
|
30922
|
+
|
|
30923
|
+
/**
|
|
30924
|
+
* Default border color
|
|
30925
|
+
* @const
|
|
30926
|
+
* @private
|
|
30927
|
+
*/
|
|
30928
|
+
InfoBubble.prototype.BORDER_COLOR_ = '#ccc';
|
|
30929
|
+
|
|
30930
|
+
|
|
30931
|
+
/**
|
|
30932
|
+
* Default border radius
|
|
30933
|
+
* @const
|
|
30934
|
+
* @private
|
|
30935
|
+
*/
|
|
30936
|
+
InfoBubble.prototype.BORDER_RADIUS_ = 10;
|
|
30937
|
+
|
|
30938
|
+
|
|
30939
|
+
/**
|
|
30940
|
+
* Default background color
|
|
30941
|
+
* @const
|
|
30942
|
+
* @private
|
|
30943
|
+
*/
|
|
30944
|
+
InfoBubble.prototype.BACKGROUND_COLOR_ = '#fff';
|
|
30945
|
+
|
|
30946
|
+
/**
|
|
30947
|
+
* Default close image source
|
|
30948
|
+
* @const
|
|
30949
|
+
* @private
|
|
30950
|
+
*/
|
|
30951
|
+
InfoBubble.prototype.CLOSE_SRC_ = 'https://maps.gstatic.com/intl/en_us/mapfiles/iw_close.gif';
|
|
30952
|
+
|
|
30953
|
+
/**
|
|
30954
|
+
* Extends a objects prototype by anothers.
|
|
30955
|
+
*
|
|
30956
|
+
* @param {Object} obj1 The object to be extended.
|
|
30957
|
+
* @param {Object} obj2 The object to extend with.
|
|
30958
|
+
* @return {Object} The new extended object.
|
|
30959
|
+
* @ignore
|
|
30960
|
+
*/
|
|
30961
|
+
InfoBubble.prototype.extend = function(obj1, obj2) {
|
|
30962
|
+
return (function(object) {
|
|
30963
|
+
for (var property in object.prototype) {
|
|
30964
|
+
this.prototype[property] = object.prototype[property];
|
|
30965
|
+
}
|
|
30966
|
+
return this;
|
|
30967
|
+
}).apply(obj1, [obj2]);
|
|
30968
|
+
};
|
|
30969
|
+
|
|
30970
|
+
|
|
30971
|
+
/**
|
|
30972
|
+
* Builds the InfoBubble dom
|
|
30973
|
+
* @private
|
|
30974
|
+
*/
|
|
30975
|
+
InfoBubble.prototype.buildDom_ = function() {
|
|
30976
|
+
var bubble = this.bubble_ = document.createElement('DIV');
|
|
30977
|
+
bubble.style['position'] = 'absolute';
|
|
30978
|
+
bubble.style['zIndex'] = this.baseZIndex_;
|
|
30979
|
+
|
|
30980
|
+
var tabsContainer = this.tabsContainer_ = document.createElement('DIV');
|
|
30981
|
+
tabsContainer.style['position'] = 'relative';
|
|
30982
|
+
|
|
30983
|
+
// Close button
|
|
30984
|
+
var close = this.close_ = document.createElement('IMG');
|
|
30985
|
+
close.style['position'] = 'absolute';
|
|
30986
|
+
close.style['border'] = 0;
|
|
30987
|
+
close.style['zIndex'] = this.baseZIndex_ + 1;
|
|
30988
|
+
close.style['cursor'] = 'pointer';
|
|
30989
|
+
close.src = this.get('closeSrc');
|
|
30990
|
+
|
|
30991
|
+
var that = this;
|
|
30992
|
+
google.maps.event.addDomListener(close, 'click', function() {
|
|
30993
|
+
that.close();
|
|
30994
|
+
google.maps.event.trigger(that, 'closeclick');
|
|
30995
|
+
});
|
|
30996
|
+
|
|
30997
|
+
// Content area
|
|
30998
|
+
var contentContainer = this.contentContainer_ = document.createElement('DIV');
|
|
30999
|
+
contentContainer.style['overflowX'] = 'auto';
|
|
31000
|
+
contentContainer.style['overflowY'] = 'auto';
|
|
31001
|
+
contentContainer.style['cursor'] = 'default';
|
|
31002
|
+
contentContainer.style['clear'] = 'both';
|
|
31003
|
+
contentContainer.style['position'] = 'relative';
|
|
31004
|
+
|
|
31005
|
+
var content = this.content_ = document.createElement('DIV');
|
|
31006
|
+
contentContainer.appendChild(content);
|
|
31007
|
+
|
|
31008
|
+
// Arrow
|
|
31009
|
+
var arrow = this.arrow_ = document.createElement('DIV');
|
|
31010
|
+
arrow.style['position'] = 'relative';
|
|
31011
|
+
|
|
31012
|
+
var arrowOuter = this.arrowOuter_ = document.createElement('DIV');
|
|
31013
|
+
var arrowInner = this.arrowInner_ = document.createElement('DIV');
|
|
31014
|
+
|
|
31015
|
+
var arrowSize = this.getArrowSize_();
|
|
31016
|
+
|
|
31017
|
+
arrowOuter.style['position'] = arrowInner.style['position'] = 'absolute';
|
|
31018
|
+
arrowOuter.style['left'] = arrowInner.style['left'] = '50%';
|
|
31019
|
+
arrowOuter.style['height'] = arrowInner.style['height'] = '0';
|
|
31020
|
+
arrowOuter.style['width'] = arrowInner.style['width'] = '0';
|
|
31021
|
+
arrowOuter.style['marginLeft'] = this.px(-arrowSize);
|
|
31022
|
+
arrowOuter.style['borderWidth'] = this.px(arrowSize);
|
|
31023
|
+
arrowOuter.style['borderBottomWidth'] = 0;
|
|
31024
|
+
|
|
31025
|
+
// Shadow
|
|
31026
|
+
var bubbleShadow = this.bubbleShadow_ = document.createElement('DIV');
|
|
31027
|
+
bubbleShadow.style['position'] = 'absolute';
|
|
31028
|
+
|
|
31029
|
+
// Hide the InfoBubble by default
|
|
31030
|
+
bubble.style['display'] = bubbleShadow.style['display'] = 'none';
|
|
31031
|
+
|
|
31032
|
+
bubble.appendChild(this.tabsContainer_);
|
|
31033
|
+
bubble.appendChild(close);
|
|
31034
|
+
bubble.appendChild(contentContainer);
|
|
31035
|
+
arrow.appendChild(arrowOuter);
|
|
31036
|
+
arrow.appendChild(arrowInner);
|
|
31037
|
+
bubble.appendChild(arrow);
|
|
31038
|
+
|
|
31039
|
+
var stylesheet = document.createElement('style');
|
|
31040
|
+
stylesheet.setAttribute('type', 'text/css');
|
|
31041
|
+
|
|
31042
|
+
/**
|
|
31043
|
+
* The animation for the infobubble
|
|
31044
|
+
* @type {string}
|
|
31045
|
+
*/
|
|
31046
|
+
this.animationName_ = '_ibani_' + Math.round(Math.random() * 10000);
|
|
31047
|
+
|
|
31048
|
+
var css = '.' + this.animationName_ + '{-webkit-animation-name:' +
|
|
31049
|
+
this.animationName_ + ';-webkit-animation-duration:0.5s;' +
|
|
31050
|
+
'-webkit-animation-iteration-count:1;}' +
|
|
31051
|
+
'@-webkit-keyframes ' + this.animationName_ + ' {from {' +
|
|
31052
|
+
'-webkit-transform: scale(0)}50% {-webkit-transform: scale(1.2)}90% ' +
|
|
31053
|
+
'{-webkit-transform: scale(0.95)}to {-webkit-transform: scale(1)}}';
|
|
31054
|
+
|
|
31055
|
+
stylesheet.textContent = css;
|
|
31056
|
+
document.getElementsByTagName('head')[0].appendChild(stylesheet);
|
|
31057
|
+
};
|
|
31058
|
+
|
|
31059
|
+
|
|
31060
|
+
/**
|
|
31061
|
+
* Sets the background class name
|
|
31062
|
+
*
|
|
31063
|
+
* @param {string} className The class name to set.
|
|
31064
|
+
*/
|
|
31065
|
+
InfoBubble.prototype.setBackgroundClassName = function(className) {
|
|
31066
|
+
this.set('backgroundClassName', className);
|
|
31067
|
+
};
|
|
31068
|
+
InfoBubble.prototype['setBackgroundClassName'] = InfoBubble.prototype.setBackgroundClassName;
|
|
31069
|
+
|
|
31070
|
+
|
|
31071
|
+
/**
|
|
31072
|
+
* changed MVC callback
|
|
31073
|
+
*/
|
|
31074
|
+
InfoBubble.prototype.backgroundClassName_changed = function() {
|
|
31075
|
+
this.content_.className = this.get('backgroundClassName');
|
|
31076
|
+
};
|
|
31077
|
+
InfoBubble.prototype['backgroundClassName_changed'] = InfoBubble.prototype.backgroundClassName_changed;
|
|
31078
|
+
|
|
31079
|
+
|
|
31080
|
+
/**
|
|
31081
|
+
* Sets the class of the tab
|
|
31082
|
+
*
|
|
31083
|
+
* @param {string} className the class name to set.
|
|
31084
|
+
*/
|
|
31085
|
+
InfoBubble.prototype.setTabClassName = function(className) {
|
|
31086
|
+
this.set('tabClassName', className);
|
|
31087
|
+
};
|
|
31088
|
+
InfoBubble.prototype['setTabClassName'] = InfoBubble.prototype.setTabClassName;
|
|
31089
|
+
|
|
31090
|
+
|
|
31091
|
+
/**
|
|
31092
|
+
* tabClassName changed MVC callback
|
|
31093
|
+
*/
|
|
31094
|
+
InfoBubble.prototype.tabClassName_changed = function() {
|
|
31095
|
+
this.updateTabStyles_();
|
|
31096
|
+
};
|
|
31097
|
+
InfoBubble.prototype['tabClassName_changed'] = InfoBubble.prototype.tabClassName_changed;
|
|
31098
|
+
|
|
31099
|
+
|
|
31100
|
+
/**
|
|
31101
|
+
* Gets the style of the arrow
|
|
31102
|
+
*
|
|
31103
|
+
* @private
|
|
31104
|
+
* @return {number} The style of the arrow.
|
|
31105
|
+
*/
|
|
31106
|
+
InfoBubble.prototype.getArrowStyle_ = function() {
|
|
31107
|
+
return parseInt(this.get('arrowStyle'), 10) || 0;
|
|
31108
|
+
};
|
|
31109
|
+
|
|
31110
|
+
|
|
31111
|
+
/**
|
|
31112
|
+
* Sets the style of the arrow
|
|
31113
|
+
*
|
|
31114
|
+
* @param {number} style The style of the arrow.
|
|
31115
|
+
*/
|
|
31116
|
+
InfoBubble.prototype.setArrowStyle = function(style) {
|
|
31117
|
+
this.set('arrowStyle', style);
|
|
31118
|
+
};
|
|
31119
|
+
InfoBubble.prototype['setArrowStyle'] = InfoBubble.prototype.setArrowStyle;
|
|
31120
|
+
|
|
31121
|
+
|
|
31122
|
+
/**
|
|
31123
|
+
* Arrow style changed MVC callback
|
|
31124
|
+
*/
|
|
31125
|
+
InfoBubble.prototype.arrowStyle_changed = function() {
|
|
31126
|
+
this.arrowSize_changed();
|
|
31127
|
+
};
|
|
31128
|
+
InfoBubble.prototype['arrowStyle_changed'] = InfoBubble.prototype.arrowStyle_changed;
|
|
31129
|
+
|
|
31130
|
+
|
|
31131
|
+
/**
|
|
31132
|
+
* Gets the size of the arrow
|
|
31133
|
+
*
|
|
31134
|
+
* @private
|
|
31135
|
+
* @return {number} The size of the arrow.
|
|
31136
|
+
*/
|
|
31137
|
+
InfoBubble.prototype.getArrowSize_ = function() {
|
|
31138
|
+
return parseInt(this.get('arrowSize'), 10) || 0;
|
|
31139
|
+
};
|
|
31140
|
+
|
|
31141
|
+
|
|
31142
|
+
/**
|
|
31143
|
+
* Sets the size of the arrow
|
|
31144
|
+
*
|
|
31145
|
+
* @param {number} size The size of the arrow.
|
|
31146
|
+
*/
|
|
31147
|
+
InfoBubble.prototype.setArrowSize = function(size) {
|
|
31148
|
+
this.set('arrowSize', size);
|
|
31149
|
+
};
|
|
31150
|
+
InfoBubble.prototype['setArrowSize'] = InfoBubble.prototype.setArrowSize;
|
|
31151
|
+
|
|
31152
|
+
|
|
31153
|
+
/**
|
|
31154
|
+
* Arrow size changed MVC callback
|
|
31155
|
+
*/
|
|
31156
|
+
InfoBubble.prototype.arrowSize_changed = function() {
|
|
31157
|
+
this.borderWidth_changed();
|
|
31158
|
+
};
|
|
31159
|
+
InfoBubble.prototype['arrowSize_changed'] = InfoBubble.prototype.arrowSize_changed;
|
|
31160
|
+
|
|
31161
|
+
|
|
31162
|
+
/**
|
|
31163
|
+
* Set the position of the InfoBubble arrow
|
|
31164
|
+
*
|
|
31165
|
+
* @param {number} pos The position to set.
|
|
31166
|
+
*/
|
|
31167
|
+
InfoBubble.prototype.setArrowPosition = function(pos) {
|
|
31168
|
+
this.set('arrowPosition', pos);
|
|
31169
|
+
};
|
|
31170
|
+
InfoBubble.prototype['setArrowPosition'] = InfoBubble.prototype.setArrowPosition;
|
|
31171
|
+
|
|
31172
|
+
|
|
31173
|
+
/**
|
|
31174
|
+
* Get the position of the InfoBubble arrow
|
|
31175
|
+
*
|
|
31176
|
+
* @private
|
|
31177
|
+
* @return {number} The position..
|
|
31178
|
+
*/
|
|
31179
|
+
InfoBubble.prototype.getArrowPosition_ = function() {
|
|
31180
|
+
return parseInt(this.get('arrowPosition'), 10) || 0;
|
|
31181
|
+
};
|
|
31182
|
+
|
|
31183
|
+
|
|
31184
|
+
/**
|
|
31185
|
+
* arrowPosition changed MVC callback
|
|
31186
|
+
*/
|
|
31187
|
+
InfoBubble.prototype.arrowPosition_changed = function() {
|
|
31188
|
+
var pos = this.getArrowPosition_();
|
|
31189
|
+
this.arrowOuter_.style['left'] = this.arrowInner_.style['left'] = pos + '%';
|
|
31190
|
+
|
|
31191
|
+
this.redraw_();
|
|
31192
|
+
};
|
|
31193
|
+
InfoBubble.prototype['arrowPosition_changed'] = InfoBubble.prototype.arrowPosition_changed;
|
|
31194
|
+
|
|
31195
|
+
|
|
31196
|
+
/**
|
|
31197
|
+
* Set the zIndex of the InfoBubble
|
|
31198
|
+
*
|
|
31199
|
+
* @param {number} zIndex The zIndex to set.
|
|
31200
|
+
*/
|
|
31201
|
+
InfoBubble.prototype.setZIndex = function(zIndex) {
|
|
31202
|
+
this.set('zIndex', zIndex);
|
|
31203
|
+
};
|
|
31204
|
+
InfoBubble.prototype['setZIndex'] = InfoBubble.prototype.setZIndex;
|
|
31205
|
+
|
|
31206
|
+
|
|
31207
|
+
/**
|
|
31208
|
+
* Get the zIndex of the InfoBubble
|
|
31209
|
+
*
|
|
31210
|
+
* @return {number} The zIndex to set.
|
|
31211
|
+
*/
|
|
31212
|
+
InfoBubble.prototype.getZIndex = function() {
|
|
31213
|
+
return parseInt(this.get('zIndex'), 10) || this.baseZIndex_;
|
|
31214
|
+
};
|
|
31215
|
+
|
|
31216
|
+
|
|
31217
|
+
/**
|
|
31218
|
+
* zIndex changed MVC callback
|
|
31219
|
+
*/
|
|
31220
|
+
InfoBubble.prototype.zIndex_changed = function() {
|
|
31221
|
+
var zIndex = this.getZIndex();
|
|
31222
|
+
|
|
31223
|
+
this.bubble_.style['zIndex'] = this.baseZIndex_ = zIndex;
|
|
31224
|
+
this.close_.style['zIndex'] = zIndex + 1;
|
|
31225
|
+
};
|
|
31226
|
+
InfoBubble.prototype['zIndex_changed'] = InfoBubble.prototype.zIndex_changed;
|
|
31227
|
+
|
|
31228
|
+
|
|
31229
|
+
/**
|
|
31230
|
+
* Set the style of the shadow
|
|
31231
|
+
*
|
|
31232
|
+
* @param {number} shadowStyle The style of the shadow.
|
|
31233
|
+
*/
|
|
31234
|
+
InfoBubble.prototype.setShadowStyle = function(shadowStyle) {
|
|
31235
|
+
this.set('shadowStyle', shadowStyle);
|
|
31236
|
+
};
|
|
31237
|
+
InfoBubble.prototype['setShadowStyle'] = InfoBubble.prototype.setShadowStyle;
|
|
31238
|
+
|
|
31239
|
+
|
|
31240
|
+
/**
|
|
31241
|
+
* Get the style of the shadow
|
|
31242
|
+
*
|
|
31243
|
+
* @private
|
|
31244
|
+
* @return {number} The style of the shadow.
|
|
31245
|
+
*/
|
|
31246
|
+
InfoBubble.prototype.getShadowStyle_ = function() {
|
|
31247
|
+
return parseInt(this.get('shadowStyle'), 10) || 0;
|
|
31248
|
+
};
|
|
31249
|
+
|
|
31250
|
+
|
|
31251
|
+
/**
|
|
31252
|
+
* shadowStyle changed MVC callback
|
|
31253
|
+
*/
|
|
31254
|
+
InfoBubble.prototype.shadowStyle_changed = function() {
|
|
31255
|
+
var shadowStyle = this.getShadowStyle_();
|
|
31256
|
+
|
|
31257
|
+
var display = '';
|
|
31258
|
+
var shadow = '';
|
|
31259
|
+
var backgroundColor = '';
|
|
31260
|
+
switch (shadowStyle) {
|
|
31261
|
+
case 0:
|
|
31262
|
+
display = 'none';
|
|
31263
|
+
break;
|
|
31264
|
+
case 1:
|
|
31265
|
+
shadow = '40px 15px 10px rgba(33,33,33,0.3)';
|
|
31266
|
+
backgroundColor = 'transparent';
|
|
31267
|
+
break;
|
|
31268
|
+
case 2:
|
|
31269
|
+
shadow = '0 0 2px rgba(33,33,33,0.3)';
|
|
31270
|
+
backgroundColor = 'rgba(33,33,33,0.35)';
|
|
31271
|
+
break;
|
|
31272
|
+
}
|
|
31273
|
+
this.bubbleShadow_.style['boxShadow'] =
|
|
31274
|
+
this.bubbleShadow_.style['webkitBoxShadow'] =
|
|
31275
|
+
this.bubbleShadow_.style['MozBoxShadow'] = shadow;
|
|
31276
|
+
this.bubbleShadow_.style['backgroundColor'] = backgroundColor;
|
|
31277
|
+
if (this.isOpen_) {
|
|
31278
|
+
this.bubbleShadow_.style['display'] = display;
|
|
31279
|
+
this.draw();
|
|
31280
|
+
}
|
|
31281
|
+
};
|
|
31282
|
+
InfoBubble.prototype['shadowStyle_changed'] = InfoBubble.prototype.shadowStyle_changed;
|
|
31283
|
+
|
|
31284
|
+
|
|
31285
|
+
/**
|
|
31286
|
+
* Show the close button
|
|
31287
|
+
*/
|
|
31288
|
+
InfoBubble.prototype.showCloseButton = function() {
|
|
31289
|
+
this.set('hideCloseButton', false);
|
|
31290
|
+
};
|
|
31291
|
+
InfoBubble.prototype['showCloseButton'] = InfoBubble.prototype.showCloseButton;
|
|
31292
|
+
|
|
31293
|
+
|
|
31294
|
+
/**
|
|
31295
|
+
* Hide the close button
|
|
31296
|
+
*/
|
|
31297
|
+
InfoBubble.prototype.hideCloseButton = function() {
|
|
31298
|
+
this.set('hideCloseButton', true);
|
|
31299
|
+
};
|
|
31300
|
+
InfoBubble.prototype['hideCloseButton'] = InfoBubble.prototype.hideCloseButton;
|
|
31301
|
+
|
|
31302
|
+
|
|
31303
|
+
/**
|
|
31304
|
+
* hideCloseButton changed MVC callback
|
|
31305
|
+
*/
|
|
31306
|
+
InfoBubble.prototype.hideCloseButton_changed = function() {
|
|
31307
|
+
this.close_.style['display'] = this.get('hideCloseButton') ? 'none' : '';
|
|
31308
|
+
};
|
|
31309
|
+
InfoBubble.prototype['hideCloseButton_changed'] = InfoBubble.prototype.hideCloseButton_changed;
|
|
31310
|
+
|
|
31311
|
+
|
|
31312
|
+
/**
|
|
31313
|
+
* Set the background color
|
|
31314
|
+
*
|
|
31315
|
+
* @param {string} color The color to set.
|
|
31316
|
+
*/
|
|
31317
|
+
InfoBubble.prototype.setBackgroundColor = function(color) {
|
|
31318
|
+
if (color) {
|
|
31319
|
+
this.set('backgroundColor', color);
|
|
31320
|
+
}
|
|
31321
|
+
};
|
|
31322
|
+
InfoBubble.prototype['setBackgroundColor'] = InfoBubble.prototype.setBackgroundColor;
|
|
31323
|
+
|
|
31324
|
+
|
|
31325
|
+
/**
|
|
31326
|
+
* backgroundColor changed MVC callback
|
|
31327
|
+
*/
|
|
31328
|
+
InfoBubble.prototype.backgroundColor_changed = function() {
|
|
31329
|
+
var backgroundColor = this.get('backgroundColor');
|
|
31330
|
+
this.contentContainer_.style['backgroundColor'] = backgroundColor;
|
|
31331
|
+
|
|
31332
|
+
this.arrowInner_.style['borderColor'] = backgroundColor +
|
|
31333
|
+
' transparent transparent';
|
|
31334
|
+
this.updateTabStyles_();
|
|
31335
|
+
};
|
|
31336
|
+
InfoBubble.prototype['backgroundColor_changed'] = InfoBubble.prototype.backgroundColor_changed;
|
|
31337
|
+
|
|
31338
|
+
|
|
31339
|
+
/**
|
|
31340
|
+
* Set the border color
|
|
31341
|
+
*
|
|
31342
|
+
* @param {string} color The border color.
|
|
31343
|
+
*/
|
|
31344
|
+
InfoBubble.prototype.setBorderColor = function(color) {
|
|
31345
|
+
if (color) {
|
|
31346
|
+
this.set('borderColor', color);
|
|
31347
|
+
}
|
|
31348
|
+
};
|
|
31349
|
+
InfoBubble.prototype['setBorderColor'] = InfoBubble.prototype.setBorderColor;
|
|
31350
|
+
|
|
31351
|
+
|
|
31352
|
+
/**
|
|
31353
|
+
* borderColor changed MVC callback
|
|
31354
|
+
*/
|
|
31355
|
+
InfoBubble.prototype.borderColor_changed = function() {
|
|
31356
|
+
var borderColor = this.get('borderColor');
|
|
31357
|
+
|
|
31358
|
+
var contentContainer = this.contentContainer_;
|
|
31359
|
+
var arrowOuter = this.arrowOuter_;
|
|
31360
|
+
contentContainer.style['borderColor'] = borderColor;
|
|
31361
|
+
|
|
31362
|
+
arrowOuter.style['borderColor'] = borderColor +
|
|
31363
|
+
' transparent transparent';
|
|
31364
|
+
|
|
31365
|
+
contentContainer.style['borderStyle'] =
|
|
31366
|
+
arrowOuter.style['borderStyle'] =
|
|
31367
|
+
this.arrowInner_.style['borderStyle'] = 'solid';
|
|
31368
|
+
|
|
31369
|
+
this.updateTabStyles_();
|
|
31370
|
+
};
|
|
31371
|
+
InfoBubble.prototype['borderColor_changed'] = InfoBubble.prototype.borderColor_changed;
|
|
31372
|
+
|
|
31373
|
+
|
|
31374
|
+
/**
|
|
31375
|
+
* Set the radius of the border
|
|
31376
|
+
*
|
|
31377
|
+
* @param {number} radius The radius of the border.
|
|
31378
|
+
*/
|
|
31379
|
+
InfoBubble.prototype.setBorderRadius = function(radius) {
|
|
31380
|
+
this.set('borderRadius', radius);
|
|
31381
|
+
};
|
|
31382
|
+
InfoBubble.prototype['setBorderRadius'] = InfoBubble.prototype.setBorderRadius;
|
|
31383
|
+
|
|
31384
|
+
|
|
31385
|
+
/**
|
|
31386
|
+
* Get the radius of the border
|
|
31387
|
+
*
|
|
31388
|
+
* @private
|
|
31389
|
+
* @return {number} The radius of the border.
|
|
31390
|
+
*/
|
|
31391
|
+
InfoBubble.prototype.getBorderRadius_ = function() {
|
|
31392
|
+
return parseInt(this.get('borderRadius'), 10) || 0;
|
|
31393
|
+
};
|
|
31394
|
+
|
|
31395
|
+
|
|
31396
|
+
/**
|
|
31397
|
+
* borderRadius changed MVC callback
|
|
31398
|
+
*/
|
|
31399
|
+
InfoBubble.prototype.borderRadius_changed = function() {
|
|
31400
|
+
var borderRadius = this.getBorderRadius_();
|
|
31401
|
+
var borderWidth = this.getBorderWidth_();
|
|
31402
|
+
|
|
31403
|
+
this.contentContainer_.style['borderRadius'] =
|
|
31404
|
+
this.contentContainer_.style['MozBorderRadius'] =
|
|
31405
|
+
this.contentContainer_.style['webkitBorderRadius'] =
|
|
31406
|
+
this.bubbleShadow_.style['borderRadius'] =
|
|
31407
|
+
this.bubbleShadow_.style['MozBorderRadius'] =
|
|
31408
|
+
this.bubbleShadow_.style['webkitBorderRadius'] = this.px(borderRadius);
|
|
31409
|
+
|
|
31410
|
+
this.tabsContainer_.style['paddingLeft'] =
|
|
31411
|
+
this.tabsContainer_.style['paddingRight'] =
|
|
31412
|
+
this.px(borderRadius + borderWidth);
|
|
31413
|
+
|
|
31414
|
+
this.redraw_();
|
|
31415
|
+
};
|
|
31416
|
+
InfoBubble.prototype['borderRadius_changed'] = InfoBubble.prototype.borderRadius_changed;
|
|
31417
|
+
|
|
31418
|
+
|
|
31419
|
+
/**
|
|
31420
|
+
* Get the width of the border
|
|
31421
|
+
*
|
|
31422
|
+
* @private
|
|
31423
|
+
* @return {number} width The width of the border.
|
|
31424
|
+
*/
|
|
31425
|
+
InfoBubble.prototype.getBorderWidth_ = function() {
|
|
31426
|
+
return parseInt(this.get('borderWidth'), 10) || 0;
|
|
31427
|
+
};
|
|
31428
|
+
|
|
31429
|
+
|
|
31430
|
+
/**
|
|
31431
|
+
* Set the width of the border
|
|
31432
|
+
*
|
|
31433
|
+
* @param {number} width The width of the border.
|
|
31434
|
+
*/
|
|
31435
|
+
InfoBubble.prototype.setBorderWidth = function(width) {
|
|
31436
|
+
this.set('borderWidth', width);
|
|
31437
|
+
};
|
|
31438
|
+
InfoBubble.prototype['setBorderWidth'] = InfoBubble.prototype.setBorderWidth;
|
|
31439
|
+
|
|
31440
|
+
|
|
31441
|
+
/**
|
|
31442
|
+
* borderWidth change MVC callback
|
|
31443
|
+
*/
|
|
31444
|
+
InfoBubble.prototype.borderWidth_changed = function() {
|
|
31445
|
+
var borderWidth = this.getBorderWidth_();
|
|
31446
|
+
|
|
31447
|
+
this.contentContainer_.style['borderWidth'] = this.px(borderWidth);
|
|
31448
|
+
this.tabsContainer_.style['top'] = this.px(borderWidth);
|
|
31449
|
+
|
|
31450
|
+
this.updateArrowStyle_();
|
|
31451
|
+
this.updateTabStyles_();
|
|
31452
|
+
this.borderRadius_changed();
|
|
31453
|
+
this.redraw_();
|
|
31454
|
+
};
|
|
31455
|
+
InfoBubble.prototype['borderWidth_changed'] = InfoBubble.prototype.borderWidth_changed;
|
|
31456
|
+
|
|
31457
|
+
|
|
31458
|
+
/**
|
|
31459
|
+
* Update the arrow style
|
|
31460
|
+
* @private
|
|
31461
|
+
*/
|
|
31462
|
+
InfoBubble.prototype.updateArrowStyle_ = function() {
|
|
31463
|
+
var borderWidth = this.getBorderWidth_();
|
|
31464
|
+
var arrowSize = this.getArrowSize_();
|
|
31465
|
+
var arrowStyle = this.getArrowStyle_();
|
|
31466
|
+
var arrowOuterSizePx = this.px(arrowSize);
|
|
31467
|
+
var arrowInnerSizePx = this.px(Math.max(0, arrowSize - borderWidth));
|
|
31468
|
+
|
|
31469
|
+
var outer = this.arrowOuter_;
|
|
31470
|
+
var inner = this.arrowInner_;
|
|
31471
|
+
|
|
31472
|
+
this.arrow_.style['marginTop'] = this.px(-borderWidth);
|
|
31473
|
+
outer.style['borderTopWidth'] = arrowOuterSizePx;
|
|
31474
|
+
inner.style['borderTopWidth'] = arrowInnerSizePx;
|
|
31475
|
+
|
|
31476
|
+
// Full arrow or arrow pointing to the left
|
|
31477
|
+
if (arrowStyle == 0 || arrowStyle == 1) {
|
|
31478
|
+
outer.style['borderLeftWidth'] = arrowOuterSizePx;
|
|
31479
|
+
inner.style['borderLeftWidth'] = arrowInnerSizePx;
|
|
31480
|
+
} else {
|
|
31481
|
+
outer.style['borderLeftWidth'] = inner.style['borderLeftWidth'] = 0;
|
|
31482
|
+
}
|
|
31483
|
+
|
|
31484
|
+
// Full arrow or arrow pointing to the right
|
|
31485
|
+
if (arrowStyle == 0 || arrowStyle == 2) {
|
|
31486
|
+
outer.style['borderRightWidth'] = arrowOuterSizePx;
|
|
31487
|
+
inner.style['borderRightWidth'] = arrowInnerSizePx;
|
|
31488
|
+
} else {
|
|
31489
|
+
outer.style['borderRightWidth'] = inner.style['borderRightWidth'] = 0;
|
|
31490
|
+
}
|
|
31491
|
+
|
|
31492
|
+
if (arrowStyle < 2) {
|
|
31493
|
+
outer.style['marginLeft'] = this.px(-(arrowSize));
|
|
31494
|
+
inner.style['marginLeft'] = this.px(-(arrowSize - borderWidth));
|
|
31495
|
+
} else {
|
|
31496
|
+
outer.style['marginLeft'] = inner.style['marginLeft'] = 0;
|
|
31497
|
+
}
|
|
31498
|
+
|
|
31499
|
+
// If there is no border then don't show thw outer arrow
|
|
31500
|
+
if (borderWidth == 0) {
|
|
31501
|
+
outer.style['display'] = 'none';
|
|
31502
|
+
} else {
|
|
31503
|
+
outer.style['display'] = '';
|
|
31504
|
+
}
|
|
31505
|
+
};
|
|
31506
|
+
|
|
31507
|
+
|
|
31508
|
+
/**
|
|
31509
|
+
* Set the padding of the InfoBubble
|
|
31510
|
+
*
|
|
31511
|
+
* @param {number} padding The padding to apply.
|
|
31512
|
+
*/
|
|
31513
|
+
InfoBubble.prototype.setPadding = function(padding) {
|
|
31514
|
+
this.set('padding', padding);
|
|
31515
|
+
};
|
|
31516
|
+
InfoBubble.prototype['setPadding'] = InfoBubble.prototype.setPadding;
|
|
31517
|
+
|
|
31518
|
+
|
|
31519
|
+
/**
|
|
31520
|
+
* Set the close image url
|
|
31521
|
+
*
|
|
31522
|
+
* @param {string} src The url of the image used as a close icon
|
|
31523
|
+
*/
|
|
31524
|
+
InfoBubble.prototype.setCloseSrc = function(src) {
|
|
31525
|
+
if (src && this.close_) {
|
|
31526
|
+
this.close_.src = src;
|
|
31527
|
+
}
|
|
31528
|
+
};
|
|
31529
|
+
InfoBubble.prototype['setCloseSrc'] = InfoBubble.prototype.setCloseSrc;
|
|
31530
|
+
|
|
31531
|
+
|
|
31532
|
+
/**
|
|
31533
|
+
* Set the padding of the InfoBubble
|
|
31534
|
+
*
|
|
31535
|
+
* @private
|
|
31536
|
+
* @return {number} padding The padding to apply.
|
|
31537
|
+
*/
|
|
31538
|
+
InfoBubble.prototype.getPadding_ = function() {
|
|
31539
|
+
return parseInt(this.get('padding'), 10) || 0;
|
|
31540
|
+
};
|
|
31541
|
+
|
|
31542
|
+
|
|
31543
|
+
/**
|
|
31544
|
+
* padding changed MVC callback
|
|
31545
|
+
*/
|
|
31546
|
+
InfoBubble.prototype.padding_changed = function() {
|
|
31547
|
+
var padding = this.getPadding_();
|
|
31548
|
+
this.contentContainer_.style['padding'] = this.px(padding);
|
|
31549
|
+
this.updateTabStyles_();
|
|
31550
|
+
|
|
31551
|
+
this.redraw_();
|
|
31552
|
+
};
|
|
31553
|
+
InfoBubble.prototype['padding_changed'] = InfoBubble.prototype.padding_changed;
|
|
31554
|
+
|
|
31555
|
+
|
|
31556
|
+
/**
|
|
31557
|
+
* Add px extention to the number
|
|
31558
|
+
*
|
|
31559
|
+
* @param {number} num The number to wrap.
|
|
31560
|
+
* @return {string|number} A wrapped number.
|
|
31561
|
+
*/
|
|
31562
|
+
InfoBubble.prototype.px = function(num) {
|
|
31563
|
+
if (num) {
|
|
31564
|
+
// 0 doesn't need to be wrapped
|
|
31565
|
+
return num + 'px';
|
|
31566
|
+
}
|
|
31567
|
+
return num;
|
|
31568
|
+
};
|
|
31569
|
+
|
|
31570
|
+
|
|
31571
|
+
/**
|
|
31572
|
+
* Add events to stop propagation
|
|
31573
|
+
* @private
|
|
31574
|
+
*/
|
|
31575
|
+
InfoBubble.prototype.addEvents_ = function() {
|
|
31576
|
+
// We want to cancel all the events so they do not go to the map
|
|
31577
|
+
var events = ['mousedown', 'mousemove', 'mouseover', 'mouseout', 'mouseup',
|
|
31578
|
+
'mousewheel', 'DOMMouseScroll', 'touchstart', 'touchend', 'touchmove',
|
|
31579
|
+
'dblclick', 'contextmenu', 'click'];
|
|
31580
|
+
|
|
31581
|
+
var bubble = this.bubble_;
|
|
31582
|
+
this.listeners_ = [];
|
|
31583
|
+
for (var i = 0, event; event = events[i]; i++) {
|
|
31584
|
+
this.listeners_.push(
|
|
31585
|
+
google.maps.event.addDomListener(bubble, event, function(e) {
|
|
31586
|
+
e.cancelBubble = true;
|
|
31587
|
+
if (e.stopPropagation) {
|
|
31588
|
+
e.stopPropagation();
|
|
31589
|
+
}
|
|
31590
|
+
})
|
|
31591
|
+
);
|
|
31592
|
+
}
|
|
31593
|
+
};
|
|
31594
|
+
|
|
31595
|
+
|
|
31596
|
+
/**
|
|
31597
|
+
* On Adding the InfoBubble to a map
|
|
31598
|
+
* Implementing the OverlayView interface
|
|
31599
|
+
*/
|
|
31600
|
+
InfoBubble.prototype.onAdd = function() {
|
|
31601
|
+
if (!this.bubble_) {
|
|
31602
|
+
this.buildDom_();
|
|
31603
|
+
}
|
|
31604
|
+
|
|
31605
|
+
this.addEvents_();
|
|
31606
|
+
|
|
31607
|
+
var panes = this.getPanes();
|
|
31608
|
+
if (panes) {
|
|
31609
|
+
panes.floatPane.appendChild(this.bubble_);
|
|
31610
|
+
panes.floatShadow.appendChild(this.bubbleShadow_);
|
|
31611
|
+
}
|
|
31612
|
+
|
|
31613
|
+
/* once the infoBubble has been added to the DOM, fire 'domready' event */
|
|
31614
|
+
google.maps.event.trigger(this, 'domready');
|
|
31615
|
+
};
|
|
31616
|
+
InfoBubble.prototype['onAdd'] = InfoBubble.prototype.onAdd;
|
|
31617
|
+
|
|
31618
|
+
|
|
31619
|
+
/**
|
|
31620
|
+
* Draw the InfoBubble
|
|
31621
|
+
* Implementing the OverlayView interface
|
|
31622
|
+
*/
|
|
31623
|
+
InfoBubble.prototype.draw = function() {
|
|
31624
|
+
var projection = this.getProjection();
|
|
31625
|
+
|
|
31626
|
+
if (!projection) {
|
|
31627
|
+
// The map projection is not ready yet so do nothing
|
|
31628
|
+
return;
|
|
31629
|
+
}
|
|
31630
|
+
|
|
31631
|
+
var latLng = /** @type {google.maps.LatLng} */ (this.get('position'));
|
|
31632
|
+
|
|
31633
|
+
if (!latLng) {
|
|
31634
|
+
this.close();
|
|
31635
|
+
return;
|
|
31636
|
+
}
|
|
31637
|
+
|
|
31638
|
+
var tabHeight = 0;
|
|
31639
|
+
|
|
31640
|
+
if (this.activeTab_) {
|
|
31641
|
+
tabHeight = this.activeTab_.offsetHeight;
|
|
31642
|
+
}
|
|
31643
|
+
|
|
31644
|
+
var anchorHeight = this.getAnchorHeight_();
|
|
31645
|
+
var arrowSize = this.getArrowSize_();
|
|
31646
|
+
var arrowPosition = this.getArrowPosition_();
|
|
31647
|
+
|
|
31648
|
+
arrowPosition = arrowPosition / 100;
|
|
31649
|
+
|
|
31650
|
+
var pos = projection.fromLatLngToDivPixel(latLng);
|
|
31651
|
+
var width = this.contentContainer_.offsetWidth;
|
|
31652
|
+
var height = this.bubble_.offsetHeight;
|
|
31653
|
+
|
|
31654
|
+
if (!width) {
|
|
31655
|
+
return;
|
|
31656
|
+
}
|
|
31657
|
+
|
|
31658
|
+
// Adjust for the height of the info bubble
|
|
31659
|
+
var top = pos.y - (height + arrowSize);
|
|
31660
|
+
|
|
31661
|
+
if (anchorHeight) {
|
|
31662
|
+
// If there is an anchor then include the height
|
|
31663
|
+
top -= anchorHeight;
|
|
31664
|
+
}
|
|
31665
|
+
|
|
31666
|
+
var left = pos.x - (width * arrowPosition);
|
|
31667
|
+
|
|
31668
|
+
this.bubble_.style['top'] = this.px(top);
|
|
31669
|
+
this.bubble_.style['left'] = this.px(left);
|
|
31670
|
+
|
|
31671
|
+
var shadowStyle = parseInt(this.get('shadowStyle'), 10);
|
|
31672
|
+
|
|
31673
|
+
switch (shadowStyle) {
|
|
31674
|
+
case 1:
|
|
31675
|
+
// Shadow is behind
|
|
31676
|
+
this.bubbleShadow_.style['top'] = this.px(top + tabHeight - 1);
|
|
31677
|
+
this.bubbleShadow_.style['left'] = this.px(left);
|
|
31678
|
+
this.bubbleShadow_.style['width'] = this.px(width);
|
|
31679
|
+
this.bubbleShadow_.style['height'] =
|
|
31680
|
+
this.px(this.contentContainer_.offsetHeight - arrowSize);
|
|
31681
|
+
break;
|
|
31682
|
+
case 2:
|
|
31683
|
+
// Shadow is below
|
|
31684
|
+
width = width * 0.8;
|
|
31685
|
+
if (anchorHeight) {
|
|
31686
|
+
this.bubbleShadow_.style['top'] = this.px(pos.y);
|
|
31687
|
+
} else {
|
|
31688
|
+
this.bubbleShadow_.style['top'] = this.px(pos.y + arrowSize);
|
|
31689
|
+
}
|
|
31690
|
+
this.bubbleShadow_.style['left'] = this.px(pos.x - width * arrowPosition);
|
|
31691
|
+
|
|
31692
|
+
this.bubbleShadow_.style['width'] = this.px(width);
|
|
31693
|
+
this.bubbleShadow_.style['height'] = this.px(2);
|
|
31694
|
+
break;
|
|
31695
|
+
}
|
|
31696
|
+
};
|
|
31697
|
+
InfoBubble.prototype['draw'] = InfoBubble.prototype.draw;
|
|
31698
|
+
|
|
31699
|
+
|
|
31700
|
+
/**
|
|
31701
|
+
* Removing the InfoBubble from a map
|
|
31702
|
+
*/
|
|
31703
|
+
InfoBubble.prototype.onRemove = function() {
|
|
31704
|
+
if (this.bubble_ && this.bubble_.parentNode) {
|
|
31705
|
+
this.bubble_.parentNode.removeChild(this.bubble_);
|
|
31706
|
+
}
|
|
31707
|
+
if (this.bubbleShadow_ && this.bubbleShadow_.parentNode) {
|
|
31708
|
+
this.bubbleShadow_.parentNode.removeChild(this.bubbleShadow_);
|
|
31709
|
+
}
|
|
31710
|
+
|
|
31711
|
+
for (var i = 0, listener; listener = this.listeners_[i]; i++) {
|
|
31712
|
+
google.maps.event.removeListener(listener);
|
|
31713
|
+
}
|
|
31714
|
+
};
|
|
31715
|
+
InfoBubble.prototype['onRemove'] = InfoBubble.prototype.onRemove;
|
|
31716
|
+
|
|
31717
|
+
|
|
31718
|
+
/**
|
|
31719
|
+
* Is the InfoBubble open
|
|
31720
|
+
*
|
|
31721
|
+
* @return {boolean} If the InfoBubble is open.
|
|
31722
|
+
*/
|
|
31723
|
+
InfoBubble.prototype.isOpen = function() {
|
|
31724
|
+
return this.isOpen_;
|
|
31725
|
+
};
|
|
31726
|
+
InfoBubble.prototype['isOpen'] = InfoBubble.prototype.isOpen;
|
|
31727
|
+
|
|
31728
|
+
|
|
31729
|
+
/**
|
|
31730
|
+
* Close the InfoBubble
|
|
31731
|
+
*/
|
|
31732
|
+
InfoBubble.prototype.close = function() {
|
|
31733
|
+
if (this.bubble_) {
|
|
31734
|
+
this.bubble_.style['display'] = 'none';
|
|
31735
|
+
// Remove the animation so we next time it opens it will animate again
|
|
31736
|
+
this.bubble_.className =
|
|
31737
|
+
this.bubble_.className.replace(this.animationName_, '');
|
|
31738
|
+
}
|
|
31739
|
+
|
|
31740
|
+
if (this.bubbleShadow_) {
|
|
31741
|
+
this.bubbleShadow_.style['display'] = 'none';
|
|
31742
|
+
this.bubbleShadow_.className =
|
|
31743
|
+
this.bubbleShadow_.className.replace(this.animationName_, '');
|
|
31744
|
+
}
|
|
31745
|
+
this.isOpen_ = false;
|
|
31746
|
+
};
|
|
31747
|
+
InfoBubble.prototype['close'] = InfoBubble.prototype.close;
|
|
31748
|
+
|
|
31749
|
+
|
|
31750
|
+
/**
|
|
31751
|
+
* Open the InfoBubble (asynchronous).
|
|
31752
|
+
*
|
|
31753
|
+
* @param {google.maps.Map=} opt_map Optional map to open on.
|
|
31754
|
+
* @param {google.maps.MVCObject=} opt_anchor Optional anchor to position at.
|
|
31755
|
+
*/
|
|
31756
|
+
InfoBubble.prototype.open = function(opt_map, opt_anchor) {
|
|
31757
|
+
var that = this;
|
|
31758
|
+
window.setTimeout(function() {
|
|
31759
|
+
that.open_(opt_map, opt_anchor);
|
|
31760
|
+
}, 0);
|
|
31761
|
+
};
|
|
31762
|
+
|
|
31763
|
+
|
|
31764
|
+
/**
|
|
31765
|
+
* Open the InfoBubble
|
|
31766
|
+
* @private
|
|
31767
|
+
* @param {google.maps.Map=} opt_map Optional map to open on.
|
|
31768
|
+
* @param {google.maps.MVCObject=} opt_anchor Optional anchor to position at.
|
|
31769
|
+
*/
|
|
31770
|
+
InfoBubble.prototype.open_ = function(opt_map, opt_anchor) {
|
|
31771
|
+
this.updateContent_();
|
|
31772
|
+
|
|
31773
|
+
if (opt_map) {
|
|
31774
|
+
this.setMap(opt_map);
|
|
31775
|
+
}
|
|
31776
|
+
|
|
31777
|
+
if (opt_anchor) {
|
|
31778
|
+
this.set('anchor', opt_anchor);
|
|
31779
|
+
this.bindTo('anchorPoint', opt_anchor);
|
|
31780
|
+
this.bindTo('position', opt_anchor);
|
|
31781
|
+
}
|
|
31782
|
+
|
|
31783
|
+
// Show the bubble and the show
|
|
31784
|
+
this.bubble_.style['display'] = this.bubbleShadow_.style['display'] = '';
|
|
31785
|
+
var animation = !this.get('disableAnimation');
|
|
31786
|
+
|
|
31787
|
+
if (animation) {
|
|
31788
|
+
// Add the animation
|
|
31789
|
+
this.bubble_.className += ' ' + this.animationName_;
|
|
31790
|
+
this.bubbleShadow_.className += ' ' + this.animationName_;
|
|
31791
|
+
}
|
|
31792
|
+
|
|
31793
|
+
this.redraw_();
|
|
31794
|
+
this.isOpen_ = true;
|
|
31795
|
+
|
|
31796
|
+
var pan = !this.get('disableAutoPan');
|
|
31797
|
+
if (pan) {
|
|
31798
|
+
var that = this;
|
|
31799
|
+
window.setTimeout(function() {
|
|
31800
|
+
// Pan into view, done in a time out to make it feel nicer :)
|
|
31801
|
+
that.panToView();
|
|
31802
|
+
}, 200);
|
|
31803
|
+
}
|
|
31804
|
+
};
|
|
31805
|
+
InfoBubble.prototype['open'] = InfoBubble.prototype.open;
|
|
31806
|
+
|
|
31807
|
+
|
|
31808
|
+
/**
|
|
31809
|
+
* Set the position of the InfoBubble
|
|
31810
|
+
*
|
|
31811
|
+
* @param {google.maps.LatLng} position The position to set.
|
|
31812
|
+
*/
|
|
31813
|
+
InfoBubble.prototype.setPosition = function(position) {
|
|
31814
|
+
if (position) {
|
|
31815
|
+
this.set('position', position);
|
|
31816
|
+
}
|
|
31817
|
+
};
|
|
31818
|
+
InfoBubble.prototype['setPosition'] = InfoBubble.prototype.setPosition;
|
|
31819
|
+
|
|
31820
|
+
|
|
31821
|
+
/**
|
|
31822
|
+
* Returns the position of the InfoBubble
|
|
31823
|
+
*
|
|
31824
|
+
* @return {google.maps.LatLng} the position.
|
|
31825
|
+
*/
|
|
31826
|
+
InfoBubble.prototype.getPosition = function() {
|
|
31827
|
+
return /** @type {google.maps.LatLng} */ (this.get('position'));
|
|
31828
|
+
};
|
|
31829
|
+
InfoBubble.prototype['getPosition'] = InfoBubble.prototype.getPosition;
|
|
31830
|
+
|
|
31831
|
+
|
|
31832
|
+
/**
|
|
31833
|
+
* position changed MVC callback
|
|
31834
|
+
*/
|
|
31835
|
+
InfoBubble.prototype.position_changed = function() {
|
|
31836
|
+
this.draw();
|
|
31837
|
+
};
|
|
31838
|
+
InfoBubble.prototype['position_changed'] = InfoBubble.prototype.position_changed;
|
|
31839
|
+
|
|
31840
|
+
|
|
31841
|
+
/**
|
|
31842
|
+
* Pan the InfoBubble into view
|
|
31843
|
+
*/
|
|
31844
|
+
InfoBubble.prototype.panToView = function() {
|
|
31845
|
+
var projection = this.getProjection();
|
|
31846
|
+
|
|
31847
|
+
if (!projection) {
|
|
31848
|
+
// The map projection is not ready yet so do nothing
|
|
31849
|
+
return;
|
|
31850
|
+
}
|
|
31851
|
+
|
|
31852
|
+
if (!this.bubble_) {
|
|
31853
|
+
// No Bubble yet so do nothing
|
|
31854
|
+
return;
|
|
31855
|
+
}
|
|
31856
|
+
|
|
31857
|
+
var anchorHeight = this.getAnchorHeight_();
|
|
31858
|
+
var height = this.bubble_.offsetHeight + anchorHeight;
|
|
31859
|
+
var map = this.get('map');
|
|
31860
|
+
var mapDiv = map.getDiv();
|
|
31861
|
+
var mapHeight = mapDiv.offsetHeight;
|
|
31862
|
+
|
|
31863
|
+
var latLng = this.getPosition();
|
|
31864
|
+
var centerPos = projection.fromLatLngToContainerPixel(map.getCenter());
|
|
31865
|
+
var pos = projection.fromLatLngToContainerPixel(latLng);
|
|
31866
|
+
|
|
31867
|
+
// Find out how much space at the top is free
|
|
31868
|
+
var spaceTop = centerPos.y - height;
|
|
31869
|
+
|
|
31870
|
+
// Fine out how much space at the bottom is free
|
|
31871
|
+
var spaceBottom = mapHeight - centerPos.y;
|
|
31872
|
+
|
|
31873
|
+
var needsTop = spaceTop < 0;
|
|
31874
|
+
var deltaY = 0;
|
|
31875
|
+
|
|
31876
|
+
if (needsTop) {
|
|
31877
|
+
spaceTop *= -1;
|
|
31878
|
+
deltaY = (spaceTop + spaceBottom) / 2;
|
|
31879
|
+
}
|
|
31880
|
+
|
|
31881
|
+
pos.y -= deltaY;
|
|
31882
|
+
latLng = projection.fromContainerPixelToLatLng(pos);
|
|
31883
|
+
|
|
31884
|
+
if (map.getCenter() != latLng) {
|
|
31885
|
+
map.panTo(latLng);
|
|
31886
|
+
}
|
|
31887
|
+
};
|
|
31888
|
+
InfoBubble.prototype['panToView'] = InfoBubble.prototype.panToView;
|
|
31889
|
+
|
|
31890
|
+
|
|
31891
|
+
/**
|
|
31892
|
+
* Converts a HTML string to a document fragment.
|
|
31893
|
+
*
|
|
31894
|
+
* @param {string} htmlString The HTML string to convert.
|
|
31895
|
+
* @return {Node} A HTML document fragment.
|
|
31896
|
+
* @private
|
|
31897
|
+
*/
|
|
31898
|
+
InfoBubble.prototype.htmlToDocumentFragment_ = function(htmlString) {
|
|
31899
|
+
htmlString = htmlString.replace(/^\s*([\S\s]*)\b\s*$/, '$1');
|
|
31900
|
+
var tempDiv = document.createElement('DIV');
|
|
31901
|
+
tempDiv.innerHTML = htmlString;
|
|
31902
|
+
if (tempDiv.childNodes.length == 1) {
|
|
31903
|
+
return /** @type {!Node} */ (tempDiv.removeChild(tempDiv.firstChild));
|
|
31904
|
+
} else {
|
|
31905
|
+
var fragment = document.createDocumentFragment();
|
|
31906
|
+
while (tempDiv.firstChild) {
|
|
31907
|
+
fragment.appendChild(tempDiv.firstChild);
|
|
31908
|
+
}
|
|
31909
|
+
return fragment;
|
|
31910
|
+
}
|
|
31911
|
+
};
|
|
31912
|
+
|
|
31913
|
+
|
|
31914
|
+
/**
|
|
31915
|
+
* Removes all children from the node.
|
|
31916
|
+
*
|
|
31917
|
+
* @param {Node} node The node to remove all children from.
|
|
31918
|
+
* @private
|
|
31919
|
+
*/
|
|
31920
|
+
InfoBubble.prototype.removeChildren_ = function(node) {
|
|
31921
|
+
if (!node) {
|
|
31922
|
+
return;
|
|
31923
|
+
}
|
|
31924
|
+
|
|
31925
|
+
var child;
|
|
31926
|
+
while (child = node.firstChild) {
|
|
31927
|
+
node.removeChild(child);
|
|
31928
|
+
}
|
|
31929
|
+
};
|
|
31930
|
+
|
|
31931
|
+
|
|
31932
|
+
/**
|
|
31933
|
+
* Sets the content of the infobubble.
|
|
31934
|
+
*
|
|
31935
|
+
* @param {string|Node} content The content to set.
|
|
31936
|
+
*/
|
|
31937
|
+
InfoBubble.prototype.setContent = function(content) {
|
|
31938
|
+
this.set('content', content);
|
|
31939
|
+
};
|
|
31940
|
+
InfoBubble.prototype['setContent'] = InfoBubble.prototype.setContent;
|
|
31941
|
+
|
|
31942
|
+
|
|
31943
|
+
/**
|
|
31944
|
+
* Get the content of the infobubble.
|
|
31945
|
+
*
|
|
31946
|
+
* @return {string|Node} The marker content.
|
|
31947
|
+
*/
|
|
31948
|
+
InfoBubble.prototype.getContent = function() {
|
|
31949
|
+
return /** @type {Node|string} */ (this.get('content'));
|
|
31950
|
+
};
|
|
31951
|
+
InfoBubble.prototype['getContent'] = InfoBubble.prototype.getContent;
|
|
31952
|
+
|
|
31953
|
+
|
|
31954
|
+
/**
|
|
31955
|
+
* Sets the marker content and adds loading events to images
|
|
31956
|
+
*/
|
|
31957
|
+
InfoBubble.prototype.updateContent_ = function() {
|
|
31958
|
+
if (!this.content_) {
|
|
31959
|
+
// The Content area doesnt exist.
|
|
31960
|
+
return;
|
|
31961
|
+
}
|
|
31962
|
+
|
|
31963
|
+
this.removeChildren_(this.content_);
|
|
31964
|
+
var content = this.getContent();
|
|
31965
|
+
if (content) {
|
|
31966
|
+
if (typeof content == 'string') {
|
|
31967
|
+
content = this.htmlToDocumentFragment_(content);
|
|
31968
|
+
}
|
|
31969
|
+
this.content_.appendChild(content);
|
|
31970
|
+
|
|
31971
|
+
var that = this;
|
|
31972
|
+
var images = this.content_.getElementsByTagName('IMG');
|
|
31973
|
+
for (var i = 0, image; image = images[i]; i++) {
|
|
31974
|
+
// Because we don't know the size of an image till it loads, add a
|
|
31975
|
+
// listener to the image load so the marker can resize and reposition
|
|
31976
|
+
// itself to be the correct height.
|
|
31977
|
+
google.maps.event.addDomListener(image, 'load', function() {
|
|
31978
|
+
that.imageLoaded_();
|
|
31979
|
+
});
|
|
31980
|
+
}
|
|
31981
|
+
}
|
|
31982
|
+
this.redraw_();
|
|
31983
|
+
};
|
|
31984
|
+
|
|
31985
|
+
|
|
31986
|
+
/**
|
|
31987
|
+
* Image loaded
|
|
31988
|
+
* @private
|
|
31989
|
+
*/
|
|
31990
|
+
InfoBubble.prototype.imageLoaded_ = function() {
|
|
31991
|
+
var pan = !this.get('disableAutoPan');
|
|
31992
|
+
this.redraw_();
|
|
31993
|
+
if (pan && (this.tabs_.length == 0 || this.activeTab_.index == 0)) {
|
|
31994
|
+
this.panToView();
|
|
31995
|
+
}
|
|
31996
|
+
};
|
|
31997
|
+
|
|
31998
|
+
|
|
31999
|
+
/**
|
|
32000
|
+
* Updates the styles of the tabs
|
|
32001
|
+
* @private
|
|
32002
|
+
*/
|
|
32003
|
+
InfoBubble.prototype.updateTabStyles_ = function() {
|
|
32004
|
+
if (this.tabs_ && this.tabs_.length) {
|
|
32005
|
+
for (var i = 0, tab; tab = this.tabs_[i]; i++) {
|
|
32006
|
+
this.setTabStyle_(tab.tab);
|
|
32007
|
+
}
|
|
32008
|
+
this.activeTab_.style['zIndex'] = this.baseZIndex_;
|
|
32009
|
+
var borderWidth = this.getBorderWidth_();
|
|
32010
|
+
var padding = this.getPadding_() / 2;
|
|
32011
|
+
this.activeTab_.style['borderBottomWidth'] = 0;
|
|
32012
|
+
this.activeTab_.style['paddingBottom'] = this.px(padding + borderWidth);
|
|
32013
|
+
}
|
|
32014
|
+
};
|
|
32015
|
+
|
|
32016
|
+
|
|
32017
|
+
/**
|
|
32018
|
+
* Sets the style of a tab
|
|
32019
|
+
* @private
|
|
32020
|
+
* @param {Element} tab The tab to style.
|
|
32021
|
+
*/
|
|
32022
|
+
InfoBubble.prototype.setTabStyle_ = function(tab) {
|
|
32023
|
+
var backgroundColor = this.get('backgroundColor');
|
|
32024
|
+
var borderColor = this.get('borderColor');
|
|
32025
|
+
var borderRadius = this.getBorderRadius_();
|
|
32026
|
+
var borderWidth = this.getBorderWidth_();
|
|
32027
|
+
var padding = this.getPadding_();
|
|
32028
|
+
|
|
32029
|
+
var marginRight = this.px(-(Math.max(padding, borderRadius)));
|
|
32030
|
+
var borderRadiusPx = this.px(borderRadius);
|
|
32031
|
+
|
|
32032
|
+
var index = this.baseZIndex_;
|
|
32033
|
+
if (tab.index) {
|
|
32034
|
+
index -= tab.index;
|
|
32035
|
+
}
|
|
32036
|
+
|
|
32037
|
+
// The styles for the tab
|
|
32038
|
+
var styles = {
|
|
32039
|
+
'cssFloat': 'left',
|
|
32040
|
+
'position': 'relative',
|
|
32041
|
+
'cursor': 'pointer',
|
|
32042
|
+
'backgroundColor': backgroundColor,
|
|
32043
|
+
'border': this.px(borderWidth) + ' solid ' + borderColor,
|
|
32044
|
+
'padding': this.px(padding / 2) + ' ' + this.px(padding),
|
|
32045
|
+
'marginRight': marginRight,
|
|
32046
|
+
'whiteSpace': 'nowrap',
|
|
32047
|
+
'borderRadiusTopLeft': borderRadiusPx,
|
|
32048
|
+
'MozBorderRadiusTopleft': borderRadiusPx,
|
|
32049
|
+
'webkitBorderTopLeftRadius': borderRadiusPx,
|
|
32050
|
+
'borderRadiusTopRight': borderRadiusPx,
|
|
32051
|
+
'MozBorderRadiusTopright': borderRadiusPx,
|
|
32052
|
+
'webkitBorderTopRightRadius': borderRadiusPx,
|
|
32053
|
+
'zIndex': index,
|
|
32054
|
+
'display': 'inline'
|
|
32055
|
+
};
|
|
32056
|
+
|
|
32057
|
+
for (var style in styles) {
|
|
32058
|
+
tab.style[style] = styles[style];
|
|
32059
|
+
}
|
|
32060
|
+
|
|
32061
|
+
var className = this.get('tabClassName');
|
|
32062
|
+
if (className != undefined) {
|
|
32063
|
+
tab.className += ' ' + className;
|
|
32064
|
+
}
|
|
32065
|
+
};
|
|
32066
|
+
|
|
32067
|
+
|
|
32068
|
+
/**
|
|
32069
|
+
* Add user actions to a tab
|
|
32070
|
+
* @private
|
|
32071
|
+
* @param {Object} tab The tab to add the actions to.
|
|
32072
|
+
*/
|
|
32073
|
+
InfoBubble.prototype.addTabActions_ = function(tab) {
|
|
32074
|
+
var that = this;
|
|
32075
|
+
tab.listener_ = google.maps.event.addDomListener(tab, 'click', function() {
|
|
32076
|
+
that.setTabActive_(this);
|
|
32077
|
+
});
|
|
32078
|
+
};
|
|
32079
|
+
|
|
32080
|
+
|
|
32081
|
+
/**
|
|
32082
|
+
* Set a tab at a index to be active
|
|
32083
|
+
*
|
|
32084
|
+
* @param {number} index The index of the tab.
|
|
32085
|
+
*/
|
|
32086
|
+
InfoBubble.prototype.setTabActive = function(index) {
|
|
32087
|
+
var tab = this.tabs_[index - 1];
|
|
32088
|
+
|
|
32089
|
+
if (tab) {
|
|
32090
|
+
this.setTabActive_(tab.tab);
|
|
32091
|
+
}
|
|
32092
|
+
};
|
|
32093
|
+
InfoBubble.prototype['setTabActive'] = InfoBubble.prototype.setTabActive;
|
|
32094
|
+
|
|
32095
|
+
|
|
32096
|
+
/**
|
|
32097
|
+
* Set a tab to be active
|
|
32098
|
+
* @private
|
|
32099
|
+
* @param {Object} tab The tab to set active.
|
|
32100
|
+
*/
|
|
32101
|
+
InfoBubble.prototype.setTabActive_ = function(tab) {
|
|
32102
|
+
if (!tab) {
|
|
32103
|
+
this.setContent('');
|
|
32104
|
+
this.updateContent_();
|
|
32105
|
+
return;
|
|
32106
|
+
}
|
|
32107
|
+
|
|
32108
|
+
var padding = this.getPadding_() / 2;
|
|
32109
|
+
var borderWidth = this.getBorderWidth_();
|
|
32110
|
+
|
|
32111
|
+
if (this.activeTab_) {
|
|
32112
|
+
var activeTab = this.activeTab_;
|
|
32113
|
+
activeTab.style['zIndex'] = this.baseZIndex_ - activeTab.index;
|
|
32114
|
+
activeTab.style['paddingBottom'] = this.px(padding);
|
|
32115
|
+
activeTab.style['borderBottomWidth'] = this.px(borderWidth);
|
|
32116
|
+
}
|
|
32117
|
+
|
|
32118
|
+
tab.style['zIndex'] = this.baseZIndex_;
|
|
32119
|
+
tab.style['borderBottomWidth'] = 0;
|
|
32120
|
+
tab.style['marginBottomWidth'] = '-10px';
|
|
32121
|
+
tab.style['paddingBottom'] = this.px(padding + borderWidth);
|
|
32122
|
+
|
|
32123
|
+
this.setContent(this.tabs_[tab.index].content);
|
|
32124
|
+
this.updateContent_();
|
|
32125
|
+
|
|
32126
|
+
this.activeTab_ = tab;
|
|
32127
|
+
|
|
32128
|
+
this.redraw_();
|
|
32129
|
+
};
|
|
32130
|
+
|
|
32131
|
+
|
|
32132
|
+
/**
|
|
32133
|
+
* Set the max width of the InfoBubble
|
|
32134
|
+
*
|
|
32135
|
+
* @param {number} width The max width.
|
|
32136
|
+
*/
|
|
32137
|
+
InfoBubble.prototype.setMaxWidth = function(width) {
|
|
32138
|
+
this.set('maxWidth', width);
|
|
32139
|
+
};
|
|
32140
|
+
InfoBubble.prototype['setMaxWidth'] = InfoBubble.prototype.setMaxWidth;
|
|
32141
|
+
|
|
32142
|
+
|
|
32143
|
+
/**
|
|
32144
|
+
* maxWidth changed MVC callback
|
|
32145
|
+
*/
|
|
32146
|
+
InfoBubble.prototype.maxWidth_changed = function() {
|
|
32147
|
+
this.redraw_();
|
|
32148
|
+
};
|
|
32149
|
+
InfoBubble.prototype['maxWidth_changed'] = InfoBubble.prototype.maxWidth_changed;
|
|
32150
|
+
|
|
32151
|
+
|
|
32152
|
+
/**
|
|
32153
|
+
* Set the max height of the InfoBubble
|
|
32154
|
+
*
|
|
32155
|
+
* @param {number} height The max height.
|
|
32156
|
+
*/
|
|
32157
|
+
InfoBubble.prototype.setMaxHeight = function(height) {
|
|
32158
|
+
this.set('maxHeight', height);
|
|
32159
|
+
};
|
|
32160
|
+
InfoBubble.prototype['setMaxHeight'] = InfoBubble.prototype.setMaxHeight;
|
|
32161
|
+
|
|
32162
|
+
|
|
32163
|
+
/**
|
|
32164
|
+
* maxHeight changed MVC callback
|
|
32165
|
+
*/
|
|
32166
|
+
InfoBubble.prototype.maxHeight_changed = function() {
|
|
32167
|
+
this.redraw_();
|
|
32168
|
+
};
|
|
32169
|
+
InfoBubble.prototype['maxHeight_changed'] = InfoBubble.prototype.maxHeight_changed;
|
|
32170
|
+
|
|
32171
|
+
|
|
32172
|
+
/**
|
|
32173
|
+
* Set the min width of the InfoBubble
|
|
32174
|
+
*
|
|
32175
|
+
* @param {number} width The min width.
|
|
32176
|
+
*/
|
|
32177
|
+
InfoBubble.prototype.setMinWidth = function(width) {
|
|
32178
|
+
this.set('minWidth', width);
|
|
32179
|
+
};
|
|
32180
|
+
InfoBubble.prototype['setMinWidth'] = InfoBubble.prototype.setMinWidth;
|
|
32181
|
+
|
|
32182
|
+
|
|
32183
|
+
/**
|
|
32184
|
+
* minWidth changed MVC callback
|
|
32185
|
+
*/
|
|
32186
|
+
InfoBubble.prototype.minWidth_changed = function() {
|
|
32187
|
+
this.redraw_();
|
|
32188
|
+
};
|
|
32189
|
+
InfoBubble.prototype['minWidth_changed'] = InfoBubble.prototype.minWidth_changed;
|
|
32190
|
+
|
|
32191
|
+
|
|
32192
|
+
/**
|
|
32193
|
+
* Set the min height of the InfoBubble
|
|
32194
|
+
*
|
|
32195
|
+
* @param {number} height The min height.
|
|
32196
|
+
*/
|
|
32197
|
+
InfoBubble.prototype.setMinHeight = function(height) {
|
|
32198
|
+
this.set('minHeight', height);
|
|
32199
|
+
};
|
|
32200
|
+
InfoBubble.prototype['setMinHeight'] = InfoBubble.prototype.setMinHeight;
|
|
32201
|
+
|
|
32202
|
+
|
|
32203
|
+
/**
|
|
32204
|
+
* minHeight changed MVC callback
|
|
32205
|
+
*/
|
|
32206
|
+
InfoBubble.prototype.minHeight_changed = function() {
|
|
32207
|
+
this.redraw_();
|
|
32208
|
+
};
|
|
32209
|
+
InfoBubble.prototype['minHeight_changed'] = InfoBubble.prototype.minHeight_changed;
|
|
32210
|
+
|
|
32211
|
+
|
|
32212
|
+
/**
|
|
32213
|
+
* Add a tab
|
|
32214
|
+
*
|
|
32215
|
+
* @param {string} label The label of the tab.
|
|
32216
|
+
* @param {string|Element} content The content of the tab.
|
|
32217
|
+
*/
|
|
32218
|
+
InfoBubble.prototype.addTab = function(label, content) {
|
|
32219
|
+
var tab = document.createElement('DIV');
|
|
32220
|
+
tab.innerHTML = label;
|
|
32221
|
+
|
|
32222
|
+
this.setTabStyle_(tab);
|
|
32223
|
+
this.addTabActions_(tab);
|
|
32224
|
+
|
|
32225
|
+
this.tabsContainer_.appendChild(tab);
|
|
32226
|
+
|
|
32227
|
+
this.tabs_.push({
|
|
32228
|
+
label: label,
|
|
32229
|
+
content: content,
|
|
32230
|
+
tab: tab
|
|
32231
|
+
});
|
|
32232
|
+
|
|
32233
|
+
tab.index = this.tabs_.length - 1;
|
|
32234
|
+
tab.style['zIndex'] = this.baseZIndex_ - tab.index;
|
|
32235
|
+
|
|
32236
|
+
if (!this.activeTab_) {
|
|
32237
|
+
this.setTabActive_(tab);
|
|
32238
|
+
}
|
|
32239
|
+
|
|
32240
|
+
tab.className = tab.className + ' ' + this.animationName_;
|
|
32241
|
+
|
|
32242
|
+
this.redraw_();
|
|
32243
|
+
};
|
|
32244
|
+
InfoBubble.prototype['addTab'] = InfoBubble.prototype.addTab;
|
|
32245
|
+
|
|
32246
|
+
|
|
32247
|
+
/**
|
|
32248
|
+
* Update a tab at a speicifc index
|
|
32249
|
+
*
|
|
32250
|
+
* @param {number} index The index of the tab.
|
|
32251
|
+
* @param {?string} opt_label The label to change to.
|
|
32252
|
+
* @param {?string} opt_content The content to update to.
|
|
32253
|
+
*/
|
|
32254
|
+
InfoBubble.prototype.updateTab = function(index, opt_label, opt_content) {
|
|
32255
|
+
if (!this.tabs_.length || index < 0 || index >= this.tabs_.length) {
|
|
32256
|
+
return;
|
|
32257
|
+
}
|
|
32258
|
+
|
|
32259
|
+
var tab = this.tabs_[index];
|
|
32260
|
+
if (opt_label != undefined) {
|
|
32261
|
+
tab.tab.innerHTML = tab.label = opt_label;
|
|
32262
|
+
}
|
|
32263
|
+
|
|
32264
|
+
if (opt_content != undefined) {
|
|
32265
|
+
tab.content = opt_content;
|
|
32266
|
+
}
|
|
32267
|
+
|
|
32268
|
+
if (this.activeTab_ == tab.tab) {
|
|
32269
|
+
this.setContent(tab.content);
|
|
32270
|
+
this.updateContent_();
|
|
32271
|
+
}
|
|
32272
|
+
this.redraw_();
|
|
32273
|
+
};
|
|
32274
|
+
InfoBubble.prototype['updateTab'] = InfoBubble.prototype.updateTab;
|
|
32275
|
+
|
|
32276
|
+
|
|
32277
|
+
/**
|
|
32278
|
+
* Remove a tab at a specific index
|
|
32279
|
+
*
|
|
32280
|
+
* @param {number} index The index of the tab to remove.
|
|
32281
|
+
*/
|
|
32282
|
+
InfoBubble.prototype.removeTab = function(index) {
|
|
32283
|
+
if (!this.tabs_.length || index < 0 || index >= this.tabs_.length) {
|
|
32284
|
+
return;
|
|
32285
|
+
}
|
|
32286
|
+
|
|
32287
|
+
var tab = this.tabs_[index];
|
|
32288
|
+
tab.tab.parentNode.removeChild(tab.tab);
|
|
32289
|
+
|
|
32290
|
+
google.maps.event.removeListener(tab.tab.listener_);
|
|
32291
|
+
|
|
32292
|
+
this.tabs_.splice(index, 1);
|
|
32293
|
+
|
|
32294
|
+
delete tab;
|
|
32295
|
+
|
|
32296
|
+
for (var i = 0, t; t = this.tabs_[i]; i++) {
|
|
32297
|
+
t.tab.index = i;
|
|
32298
|
+
}
|
|
32299
|
+
|
|
32300
|
+
if (tab.tab == this.activeTab_) {
|
|
32301
|
+
// Removing the current active tab
|
|
32302
|
+
if (this.tabs_[index]) {
|
|
32303
|
+
// Show the tab to the right
|
|
32304
|
+
this.activeTab_ = this.tabs_[index].tab;
|
|
32305
|
+
} else if (this.tabs_[index - 1]) {
|
|
32306
|
+
// Show a tab to the left
|
|
32307
|
+
this.activeTab_ = this.tabs_[index - 1].tab;
|
|
32308
|
+
} else {
|
|
32309
|
+
// No tabs left to sho
|
|
32310
|
+
this.activeTab_ = undefined;
|
|
32311
|
+
}
|
|
32312
|
+
|
|
32313
|
+
this.setTabActive_(this.activeTab_);
|
|
32314
|
+
}
|
|
32315
|
+
|
|
32316
|
+
this.redraw_();
|
|
32317
|
+
};
|
|
32318
|
+
InfoBubble.prototype['removeTab'] = InfoBubble.prototype.removeTab;
|
|
32319
|
+
|
|
32320
|
+
|
|
32321
|
+
/**
|
|
32322
|
+
* Get the size of an element
|
|
32323
|
+
* @private
|
|
32324
|
+
* @param {Node|string} element The element to size.
|
|
32325
|
+
* @param {number=} opt_maxWidth Optional max width of the element.
|
|
32326
|
+
* @param {number=} opt_maxHeight Optional max height of the element.
|
|
32327
|
+
* @return {google.maps.Size} The size of the element.
|
|
32328
|
+
*/
|
|
32329
|
+
InfoBubble.prototype.getElementSize_ = function(element, opt_maxWidth,
|
|
32330
|
+
opt_maxHeight) {
|
|
32331
|
+
var sizer = document.createElement('DIV');
|
|
32332
|
+
sizer.style['display'] = 'inline';
|
|
32333
|
+
sizer.style['position'] = 'absolute';
|
|
32334
|
+
sizer.style['visibility'] = 'hidden';
|
|
32335
|
+
|
|
32336
|
+
if (typeof element == 'string') {
|
|
32337
|
+
sizer.innerHTML = element;
|
|
32338
|
+
} else {
|
|
32339
|
+
sizer.appendChild(element.cloneNode(true));
|
|
32340
|
+
}
|
|
32341
|
+
|
|
32342
|
+
document.body.appendChild(sizer);
|
|
32343
|
+
var size = new google.maps.Size(sizer.offsetWidth, sizer.offsetHeight);
|
|
32344
|
+
|
|
32345
|
+
// If the width is bigger than the max width then set the width and size again
|
|
32346
|
+
if (opt_maxWidth && size.width > opt_maxWidth) {
|
|
32347
|
+
sizer.style['width'] = this.px(opt_maxWidth);
|
|
32348
|
+
size = new google.maps.Size(sizer.offsetWidth, sizer.offsetHeight);
|
|
32349
|
+
}
|
|
32350
|
+
|
|
32351
|
+
// If the height is bigger than the max height then set the height and size
|
|
32352
|
+
// again
|
|
32353
|
+
if (opt_maxHeight && size.height > opt_maxHeight) {
|
|
32354
|
+
sizer.style['height'] = this.px(opt_maxHeight);
|
|
32355
|
+
size = new google.maps.Size(sizer.offsetWidth, sizer.offsetHeight);
|
|
32356
|
+
}
|
|
32357
|
+
|
|
32358
|
+
document.body.removeChild(sizer);
|
|
32359
|
+
delete sizer;
|
|
32360
|
+
return size;
|
|
32361
|
+
};
|
|
32362
|
+
|
|
32363
|
+
|
|
32364
|
+
/**
|
|
32365
|
+
* Redraw the InfoBubble
|
|
32366
|
+
* @private
|
|
32367
|
+
*/
|
|
32368
|
+
InfoBubble.prototype.redraw_ = function() {
|
|
32369
|
+
this.figureOutSize_();
|
|
32370
|
+
this.positionCloseButton_();
|
|
32371
|
+
this.draw();
|
|
32372
|
+
};
|
|
32373
|
+
|
|
32374
|
+
|
|
32375
|
+
/**
|
|
32376
|
+
* Figure out the optimum size of the InfoBubble
|
|
32377
|
+
* @private
|
|
32378
|
+
*/
|
|
32379
|
+
InfoBubble.prototype.figureOutSize_ = function() {
|
|
32380
|
+
var map = this.get('map');
|
|
32381
|
+
|
|
32382
|
+
if (!map) {
|
|
32383
|
+
return;
|
|
32384
|
+
}
|
|
32385
|
+
|
|
32386
|
+
var padding = this.getPadding_();
|
|
32387
|
+
var borderWidth = this.getBorderWidth_();
|
|
32388
|
+
var borderRadius = this.getBorderRadius_();
|
|
32389
|
+
var arrowSize = this.getArrowSize_();
|
|
32390
|
+
|
|
32391
|
+
var mapDiv = map.getDiv();
|
|
32392
|
+
var gutter = arrowSize * 2;
|
|
32393
|
+
var mapWidth = mapDiv.offsetWidth - gutter;
|
|
32394
|
+
var mapHeight = mapDiv.offsetHeight - gutter - this.getAnchorHeight_();
|
|
32395
|
+
var tabHeight = 0;
|
|
32396
|
+
var width = /** @type {number} */ (this.get('minWidth') || 0);
|
|
32397
|
+
var height = /** @type {number} */ (this.get('minHeight') || 0);
|
|
32398
|
+
var maxWidth = /** @type {number} */ (this.get('maxWidth') || 0);
|
|
32399
|
+
var maxHeight = /** @type {number} */ (this.get('maxHeight') || 0);
|
|
32400
|
+
|
|
32401
|
+
maxWidth = Math.min(mapWidth, maxWidth);
|
|
32402
|
+
maxHeight = Math.min(mapHeight, maxHeight);
|
|
32403
|
+
|
|
32404
|
+
var tabWidth = 0;
|
|
32405
|
+
if (this.tabs_.length) {
|
|
32406
|
+
// If there are tabs then you need to check the size of each tab's content
|
|
32407
|
+
for (var i = 0, tab; tab = this.tabs_[i]; i++) {
|
|
32408
|
+
var tabSize = this.getElementSize_(tab.tab, maxWidth, maxHeight);
|
|
32409
|
+
var contentSize = this.getElementSize_(tab.content, maxWidth, maxHeight);
|
|
32410
|
+
|
|
32411
|
+
if (width < tabSize.width) {
|
|
32412
|
+
width = tabSize.width;
|
|
32413
|
+
}
|
|
32414
|
+
|
|
32415
|
+
// Add up all the tab widths because they might end up being wider than
|
|
32416
|
+
// the content
|
|
32417
|
+
tabWidth += tabSize.width;
|
|
32418
|
+
|
|
32419
|
+
if (height < tabSize.height) {
|
|
32420
|
+
height = tabSize.height;
|
|
32421
|
+
}
|
|
32422
|
+
|
|
32423
|
+
if (tabSize.height > tabHeight) {
|
|
32424
|
+
tabHeight = tabSize.height;
|
|
32425
|
+
}
|
|
32426
|
+
|
|
32427
|
+
if (width < contentSize.width) {
|
|
32428
|
+
width = contentSize.width;
|
|
32429
|
+
}
|
|
32430
|
+
|
|
32431
|
+
if (height < contentSize.height) {
|
|
32432
|
+
height = contentSize.height;
|
|
32433
|
+
}
|
|
32434
|
+
}
|
|
32435
|
+
} else {
|
|
32436
|
+
var content = /** @type {string|Node} */ (this.get('content'));
|
|
32437
|
+
if (typeof content == 'string') {
|
|
32438
|
+
content = this.htmlToDocumentFragment_(content);
|
|
32439
|
+
}
|
|
32440
|
+
if (content) {
|
|
32441
|
+
var contentSize = this.getElementSize_(content, maxWidth, maxHeight);
|
|
32442
|
+
|
|
32443
|
+
if (width < contentSize.width) {
|
|
32444
|
+
width = contentSize.width;
|
|
32445
|
+
}
|
|
32446
|
+
|
|
32447
|
+
if (height < contentSize.height) {
|
|
32448
|
+
height = contentSize.height;
|
|
32449
|
+
}
|
|
32450
|
+
}
|
|
32451
|
+
}
|
|
32452
|
+
|
|
32453
|
+
if (maxWidth) {
|
|
32454
|
+
width = Math.min(width, maxWidth);
|
|
32455
|
+
}
|
|
32456
|
+
|
|
32457
|
+
if (maxHeight) {
|
|
32458
|
+
height = Math.min(height, maxHeight);
|
|
32459
|
+
}
|
|
32460
|
+
|
|
32461
|
+
width = Math.max(width, tabWidth);
|
|
32462
|
+
|
|
32463
|
+
if (width == tabWidth) {
|
|
32464
|
+
width = width + 2 * padding;
|
|
32465
|
+
}
|
|
32466
|
+
|
|
32467
|
+
arrowSize = arrowSize * 2;
|
|
32468
|
+
width = Math.max(width, arrowSize);
|
|
32469
|
+
|
|
32470
|
+
// Maybe add this as a option so they can go bigger than the map if the user
|
|
32471
|
+
// wants
|
|
32472
|
+
if (width > mapWidth) {
|
|
32473
|
+
width = mapWidth;
|
|
32474
|
+
}
|
|
32475
|
+
|
|
32476
|
+
if (height > mapHeight) {
|
|
32477
|
+
height = mapHeight - tabHeight;
|
|
32478
|
+
}
|
|
32479
|
+
|
|
32480
|
+
if (this.tabsContainer_) {
|
|
32481
|
+
this.tabHeight_ = tabHeight;
|
|
32482
|
+
this.tabsContainer_.style['width'] = this.px(tabWidth);
|
|
32483
|
+
}
|
|
32484
|
+
|
|
32485
|
+
this.contentContainer_.style['width'] = this.px(width);
|
|
32486
|
+
this.contentContainer_.style['height'] = this.px(height);
|
|
32487
|
+
};
|
|
32488
|
+
|
|
32489
|
+
|
|
32490
|
+
/**
|
|
32491
|
+
* Get the height of the anchor
|
|
32492
|
+
*
|
|
32493
|
+
* This function is a hack for now and doesn't really work that good, need to
|
|
32494
|
+
* wait for pixelBounds to be correctly exposed.
|
|
32495
|
+
* @private
|
|
32496
|
+
* @return {number} The height of the anchor.
|
|
32497
|
+
*/
|
|
32498
|
+
InfoBubble.prototype.getAnchorHeight_ = function() {
|
|
32499
|
+
var anchor = this.get('anchor');
|
|
32500
|
+
if (anchor) {
|
|
32501
|
+
var anchorPoint = /** @type google.maps.Point */(this.get('anchorPoint'));
|
|
32502
|
+
|
|
32503
|
+
if (anchorPoint) {
|
|
32504
|
+
return -1 * anchorPoint.y;
|
|
32505
|
+
}
|
|
32506
|
+
}
|
|
32507
|
+
return 0;
|
|
32508
|
+
};
|
|
32509
|
+
|
|
32510
|
+
InfoBubble.prototype.anchorPoint_changed = function() {
|
|
32511
|
+
this.draw();
|
|
32512
|
+
};
|
|
32513
|
+
InfoBubble.prototype['anchorPoint_changed'] = InfoBubble.prototype.anchorPoint_changed;
|
|
32514
|
+
|
|
32515
|
+
|
|
32516
|
+
/**
|
|
32517
|
+
* Position the close button in the right spot.
|
|
32518
|
+
* @private
|
|
32519
|
+
*/
|
|
32520
|
+
InfoBubble.prototype.positionCloseButton_ = function() {
|
|
32521
|
+
var br = this.getBorderRadius_();
|
|
32522
|
+
var bw = this.getBorderWidth_();
|
|
32523
|
+
|
|
32524
|
+
var right = 2;
|
|
32525
|
+
var top = 2;
|
|
32526
|
+
|
|
32527
|
+
if (this.tabs_.length && this.tabHeight_) {
|
|
32528
|
+
top += this.tabHeight_;
|
|
32529
|
+
}
|
|
32530
|
+
|
|
32531
|
+
top += bw;
|
|
32532
|
+
right += bw;
|
|
32533
|
+
|
|
32534
|
+
var c = this.contentContainer_;
|
|
32535
|
+
if (c && c.clientHeight < c.scrollHeight) {
|
|
32536
|
+
// If there are scrollbars then move the cross in so it is not over
|
|
32537
|
+
// scrollbar
|
|
32538
|
+
right += 15;
|
|
32539
|
+
}
|
|
32540
|
+
|
|
32541
|
+
this.close_.style['right'] = this.px(right);
|
|
32542
|
+
this.close_.style['top'] = this.px(top);
|
|
32543
|
+
};
|
|
32544
|
+
|
|
32545
|
+
|
|
30633
32546
|
/***/ }
|
|
30634
32547
|
/******/ ]);
|