PageSourceSearch

https://www.jet2holidays.com/assets/Destinations/app/vendors/richmarker.js

js jet2holidays.com collected 2026-09-24 10:14:19 UTC 21,247 bytes, 825 lines download raw bytes

1// MODIFIED!!! DO NOT UPDATE WITH NEW VERSION!!!
2
3
4// ==ClosureCompiler==
5// @compilation_level ADVANCED_OPTIMIZATIONS
6// @externs_url http://closure-compiler.googlecode.com/svn/trunk/contrib/externs/maps/google_maps_api_v3.js
7// @output_wrapper (function() {%output%})();
8// ==/ClosureCompiler==
9
10/**
11 * @license
12 * Copyright 2013 Google Inc. All Rights Reserved.
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 *     http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 */
26
27/**
28 * A RichMarker that allows any HTML/DOM to be added to a map and be draggable.
29 *
30 * @param {Object.<string, *>=} opt_options Optional properties to set.
31 * @extends {google.maps.OverlayView}
32 * @constructor
33 */
34function RichMarker(opt_options) {
35  var options = opt_options || {};
36
37  /**
38   * @type {boolean}
39   * @private
40   */
41  this.ready_ = false;
42
43  /**
44   * @type {boolean}
45   * @private
46   */
47  this.dragging_ = false;
48
49  if (opt_options['visible'] == undefined) {
50    opt_options['visible'] = true;
51  }
52
53  if (opt_options['shadow'] == undefined) {
54    opt_options['shadow'] = '7px -3px 5px rgba(88,88,88,0.7)';
55  }
56
57  if (opt_options['anchor'] == undefined) {
58    opt_options['anchor'] = RichMarkerPosition['BOTTOM'];
59  }
60
61  this.setValues(options);
62}
63RichMarker.prototype = new google.maps.OverlayView();
64window['RichMarker'] = RichMarker;
65
66
67/**
68 * Returns the current visibility state of the marker.
69 *
70 * @return {boolean} The visiblity of the marker.
71 */
72RichMarker.prototype.getVisible = function() {
73  return /** @type {boolean} */ (this.get('visible'));
74};
75RichMarker.prototype['getVisible'] = RichMarker.prototype.getVisible;
76
77
78/**
79 * Sets the visiblility state of the marker.
80 *
81 * @param {boolean} visible The visiblilty of the marker.
82 */
83RichMarker.prototype.setVisible = function(visible) {
84  this.set('visible', visible);
85};
86RichMarker.prototype['setVisible'] = RichMarker.prototype.setVisible;
87
88
89/**
90 *  The visible changed event.
91 */
92RichMarker.prototype.visible_changed = function() {
93  if (this.ready_) {
94    this.markerWrapper_.style['display'] = this.getVisible() ? '' : 'none';
95    this.draw();
96  }
97};
98RichMarker.prototype['visible_changed'] = RichMarker.prototype.visible_changed;
99
100
101/**
102 * Sets the marker to be flat.
103 *
104 * @param {boolean} flat If the marker is to be flat or not.
105 */
106RichMarker.prototype.setFlat = function(flat) {
107  this.set('flat', !!flat);
108};
109RichMarker.prototype['setFlat'] = RichMarker.prototype.setFlat;
110
111
112/**
113 * If the makrer is flat or not.
114 *
115 * @return {boolean} True the marker is flat.
116 */
117RichMarker.prototype.getFlat = function() {
118  return /** @type {boolean} */ (this.get('flat'));
119};
120RichMarker.prototype['getFlat'] = RichMarker.prototype.getFlat;
121
122
123/**
124 * Get the width of the marker.
125 *
126 * @return {Number} The width of the marker.
127 */
128RichMarker.prototype.getWidth = function() {
129  return /** @type {Number} */ (this.get('width'));
130};
131RichMarker.prototype['getWidth'] = RichMarker.prototype.getWidth;
132
133
134/**
135 * Get the height of the marker.
136 *
137 * @return {Number} The height of the marker.
138 */
139RichMarker.prototype.getHeight = function() {
140  return /** @type {Number} */ (this.get('height'));
141};
142RichMarker.prototype['getHeight'] = RichMarker.prototype.getHeight;
143
144
145/**
146 * Sets the marker's box shadow.
147 *
148 * @param {string} shadow The box shadow to set.
149 */
150RichMarker.prototype.setShadow = function(shadow) {
151  this.set('shadow', shadow);
152  this.flat_changed();
153};
154RichMarker.prototype['setShadow'] = RichMarker.prototype.setShadow;
155
156
157/**
158 * Gets the marker's box shadow.
159 *
160 * @return {string} The box shadow.
161 */
162RichMarker.prototype.getShadow = function() {
163  return /** @type {string} */ (this.get('shadow'));
164};
165RichMarker.prototype['getShadow'] = RichMarker.prototype.getShadow;
166
167
168/**
169 * Flat changed event.
170 */
171RichMarker.prototype.flat_changed = function() {
172  if (!this.ready_) {
173    return;
174  }
175
176  this.markerWrapper_.style['boxShadow'] =
177      this.markerWrapper_.style['webkitBoxShadow'] =
178      this.markerWrapper_.style['MozBoxShadow'] =
179      this.getFlat() ? '' : this.getShadow();
180};
181RichMarker.prototype['flat_changed'] = RichMarker.prototype.flat_changed;
182
183
184/**
185 * Sets the zIndex of the marker.
186 *
187 * @param {Number} index The index to set.
188 */
189RichMarker.prototype.setZIndex = function(index) {
190  this.set('zIndex', index);
191};
192RichMarker.prototype['setZIndex'] = RichMarker.prototype.setZIndex;
193
194
195/**
196 * Gets the zIndex of the marker.
197 *
198 * @return {Number} The zIndex of the marker.
199 */
200RichMarker.prototype.getZIndex = function() {
201  return /** @type {Number} */ (this.get('zIndex'));
202};
203RichMarker.prototype['getZIndex'] = RichMarker.prototype.getZIndex;
204
205
206/**
207 * zIndex changed event.
208 */
209RichMarker.prototype.zIndex_changed = function() {
210  if (this.getZIndex() && this.ready_) {
211    this.markerWrapper_.style.zIndex = this.getZIndex();
212  }
213};
214RichMarker.prototype['zIndex_changed'] = RichMarker.prototype.zIndex_changed;
215
216/**
217 * Whether the marker is draggable or not.
218 *
219 * @return {boolean} True if the marker is draggable.
220 */
221RichMarker.prototype.getDraggable = function() {
222  return /** @type {boolean} */ (this.get('draggable'));
223};
224RichMarker.prototype['getDraggable'] = RichMarker.prototype.getDraggable;
225
226
227/**
228 * Sets the marker to be draggable or not.
229 *
230 * @param {boolean} draggable If the marker is draggable or not.
231 */
232RichMarker.prototype.setDraggable = function(draggable) {
233  this.set('draggable', !!draggable);
234};
235RichMarker.prototype['setDraggable'] = RichMarker.prototype.setDraggable;
236
237
238/**
239 * Draggable property changed callback.
240 */
241RichMarker.prototype.draggable_changed = function() {
242  if (this.ready_) {
243    if (this.getDraggable()) {
244      this.addDragging_(this.markerWrapper_);
245    } else {
246      this.removeDragListeners_();
247    }
248  }
249};
250RichMarker.prototype['draggable_changed'] =
251    RichMarker.prototype.draggable_changed;
252
253
254/**
255 * Gets the postiton of the marker.
256 *
257 * @return {google.maps.LatLng} The position of the marker.
258 */
259RichMarker.prototype.getPosition = function() {
260  return /** @type {google.maps.LatLng} */ (this.get('position'));
261};
262RichMarker.prototype['getPosition'] = RichMarker.prototype.getPosition;
263
264
265/**
266 * Sets the position of the marker.
267 *
268 * @param {google.maps.LatLng} position The position to set.
269 */
270RichMarker.prototype.setPosition = function(position) {
271  this.set('position', position);
272};
273RichMarker.prototype['setPosition'] = RichMarker.prototype.setPosition;
274
275
276/**
277 * Position changed event.
278 */
279RichMarker.prototype.position_changed = function() {
280  this.draw();
281};
282RichMarker.prototype['position_changed'] =
283    RichMarker.prototype.position_changed;
284
285
286/**
287 * Gets the anchor.
288 *
289 * @return {google.maps.Size} The position of the anchor.
290 */
291RichMarker.prototype.getAnchor = function() {
292  return /** @type {google.maps.Size} */ (this.get('anchor'));
293};
294RichMarker.prototype['getAnchor'] = RichMarker.prototype.getAnchor;
295
296
297/**
298 * Sets the anchor.
299 *
300 * @param {RichMarkerPosition|google.maps.Size} anchor The anchor to set.
301 */
302RichMarker.prototype.setAnchor = function(anchor) {
303  this.set('anchor', anchor);
304};
305RichMarker.prototype['setAnchor'] = RichMarker.prototype.setAnchor;
306
307
308/**
309 * Anchor changed event.
310 */
311RichMarker.prototype.anchor_changed = function() {
312  this.draw();
313};
314RichMarker.prototype['anchor_changed'] = RichMarker.prototype.anchor_changed;
315
316
317/**
318 * Converts a HTML string to a document fragment.
319 *
320 * @param {string} htmlString The HTML string to convert.
321 * @return {Node} A HTML document fragment.
322 * @private
323 */
324RichMarker.prototype.htmlToDocumentFragment_ = function(htmlString) {
325  var tempDiv = document.createElement('DIV');
326  tempDiv.innerHTML = htmlString;
327  if (tempDiv.childNodes.length == 1) {
328    return /** @type {!Node} */ (tempDiv.removeChild(tempDiv.firstChild));
329  } else {
330    var fragment = document.createDocumentFragment();
331    while (tempDiv.firstChild) {
332      fragment.appendChild(tempDiv.firstChild);
333    }
334    return fragment;
335  }
336};
337
338
339/**
340 * Removes all children from the node.
341 *
342 * @param {Node} node The node to remove all children from.
343 * @private
344 */
345RichMarker.prototype.removeChildren_ = function(node) {
346  if (!node) {
347    return;
348  }
349
350  var child;
351  while (child = node.firstChild) {
352    node.removeChild(child);
353  }
354};
355
356
357/**
358 * Sets the content of the marker.
359 *
360 * @param {string|Node} content The content to set.
361 */
362RichMarker.prototype.setContent = function(content) {
363  this.set('content', content);
364};
365RichMarker.prototype['setContent'] = RichMarker.prototype.setContent;
366
367
368/**
369 * Get the content of the marker.
370 *
371 * @return {string|Node} The marker content.
372 */
373RichMarker.prototype.getContent = function() {
374  return /** @type {Node|string} */ (this.get('content'));
375};
376RichMarker.prototype['getContent'] = RichMarker.prototype.getContent;
377
378
379/**
380 * Sets the marker content and adds loading events to images
381 */
382RichMarker.prototype.content_changed = function() {
383  if (!this.markerContent_) {
384    // Marker content area doesnt exist.
385    return;
386  }
387
388  this.removeChildren_(this.markerContent_);
389  var content = this.getContent();
390  if (content) {
391    if (typeof content == 'string') {
392      content = content.replace(/^\s*([\S\s]*)\b\s*$/, '$1');
393      content = this.htmlToDocumentFragment_(content);
394    }
395    this.markerContent_.appendChild(content);
396
397    var that = this;
398    var images = this.markerContent_.getElementsByTagName('IMG');
399    for (var i = 0, image; image = images[i]; i++) {
400      // By default, a browser lets a image be dragged outside of the browser,
401      // so by calling preventDefault we stop this behaviour and allow the image
402      // to be dragged around the map and now out of the browser and onto the
403      // desktop.
404      google.maps.event.addDomListener(image, 'mousedown', function(e) {
405        if (that.getDraggable()) {
406          if (e.preventDefault) {
407            e.preventDefault();
408          }
409          e.returnValue = false;
410        }
411      });
412
413      // Because we don't know the size of an image till it loads, add a
414      // listener to the image load so the marker can resize and reposition
415      // itself to be the correct height.
416      google.maps.event.addDomListener(image, 'load', function() {
417        that.draw();
418      });
419    }
420
421    google.maps.event.trigger(this, 'domready');
422  }
423
424  if (this.ready_) {
425    this.draw();
426  }
427};
428RichMarker.prototype['content_changed'] = RichMarker.prototype.content_changed;
429
430/**
431 * Sets the cursor.
432 *
433 * @param {string} whichCursor What cursor to show.
434 * @private
435 */
436RichMarker.prototype.setCursor_ = function(whichCursor) {
437  if (!this.ready_) {
438    return;
439  }
440
441  var cursor = '';
442  if (navigator.userAgent.indexOf('Gecko/') !== -1) {
443    // Moz has some nice cursors :)
444    if (whichCursor == 'dragging') {
445      cursor = '-moz-grabbing';
446    }
447
448    if (whichCursor == 'dragready') {
449      cursor = '-moz-grab';
450    }
451
452    if (whichCursor == 'draggable') {
453      cursor = 'pointer';
454    }
455  } else {
456    if (whichCursor == 'dragging' || whichCursor == 'dragready') {
457      cursor = 'move';
458    }
459
460    if (whichCursor == 'draggable') {
461      cursor = 'pointer';
462    }
463  }
464
465  if (this.markerWrapper_.style.cursor != cursor) {
466    this.markerWrapper_.style.cursor = cursor;
467  }
468};
469
470/**
471 * Start dragging.
472 *
473 * @param {Event} e The event.
474 */
475RichMarker.prototype.startDrag = function(e) {
476  if (!this.getDraggable()) {
477    return;
478  }
479
480  if (!this.dragging_) {
481    this.dragging_ = true;
482    var map = this.getMap();
483    this.mapDraggable_ = map.get('draggable');
484    map.set('draggable', false);
485
486    // Store the current mouse position
487    this.mouseX_ = e.clientX;
488    this.mouseY_ = e.clientY;
489
490    this.setCursor_('dragready');
491
492    // Stop the text from being selectable while being dragged
493    this.markerWrapper_.style['MozUserSelect'] = 'none';
494    this.markerWrapper_.style['KhtmlUserSelect'] = 'none';
495    this.markerWrapper_.style['WebkitUserSelect'] = 'none';
496
497    this.markerWrapper_['unselectable'] = 'on';
498    this.markerWrapper_['onselectstart'] = function() {
499      return false;
500    };
501
502    this.addDraggingListeners_();
503
504    google.maps.event.trigger(this, 'dragstart');
505  }
506};
507
508
509/**
510 * Stop dragging.
511 */
512RichMarker.prototype.stopDrag = function() {
513  if (!this.getDraggable()) {
514    return;
515  }
516
517  if (this.dragging_) {
518    this.dragging_ = false;
519    this.getMap().set('draggable', this.mapDraggable_);
520    this.mouseX_ = this.mouseY_ = this.mapDraggable_ = null;
521
522    // Allow the text to be selectable again
523    this.markerWrapper_.style['MozUserSelect'] = '';
524    this.markerWrapper_.style['KhtmlUserSelect'] = '';
525    this.markerWrapper_.style['WebkitUserSelect'] = '';
526    this.markerWrapper_['unselectable'] = 'off';
527    this.markerWrapper_['onselectstart'] = function() {};
528
529    this.removeDraggingListeners_();
530
531    this.setCursor_('draggable');
532    google.maps.event.trigger(this, 'dragend');
533
534    this.draw();
535  }
536};
537
538
539/**
540 * Handles the drag event.
541 *
542 * @param {Event} e The event.
543 */
544RichMarker.prototype.drag = function(e) {
545  if (!this.getDraggable() || !this.dragging_) {
546    // This object isn't draggable or we have stopped dragging
547    this.stopDrag();
548    return;
549  }
550
551  var dx = this.mouseX_ - e.clientX;
552  var dy = this.mouseY_ - e.clientY;
553
554  this.mouseX_ = e.clientX;
555  this.mouseY_ = e.clientY;
556
557  var left = parseInt(this.markerWrapper_.style['left'], 10) - dx;
558  var top = parseInt(this.markerWrapper_.style['top'], 10) - dy;
559
560  this.markerWrapper_.style['left'] = left + 'px';
561  this.markerWrapper_.style['top'] = top + 'px';
562
563  var offset = this.getOffset_();
564
565  // Set the position property and adjust for the anchor offset
566  var point = new google.maps.Point(left - offset.width, top - offset.height);
567  var projection = this.getProjection();
568  this.setPosition(projection.fromDivPixelToLatLng(point));
569
570  this.setCursor_('dragging');
571  google.maps.event.trigger(this, 'drag');
572};
573
574
575/**
576 * Removes the drag listeners associated with the marker.
577 *
578 * @private
579 */
580RichMarker.prototype.removeDragListeners_ = function() {
581  if (this.draggableListener_) {
582    google.maps.event.removeListener(this.draggableListener_);
583    delete this.draggableListener_;
584  }
585  this.setCursor_('');
586};
587
588
589/**
590 * Add dragability events to the marker.
591 *
592 * @param {Node} node The node to apply dragging to.
593 * @private
594 */
595RichMarker.prototype.addDragging_ = function(node) {
596  if (!node) {
597    return;
598  }
599
600  var that = this;
601  this.draggableListener_ =
602    google.maps.event.addDomListener(node, 'mousedown', function(e) {
603      that.startDrag(e);
604    });
605
606  this.setCursor_('draggable');
607};
608
609
610/**
611 * Add dragging listeners.
612 *
613 * @private
614 */
615RichMarker.prototype.addDraggingListeners_ = function() {
616  var that = this;
617  if (this.markerWrapper_.setCapture) {
618    this.markerWrapper_.setCapture(true);
619    this.draggingListeners_ = [
620      google.maps.event.addDomListener(this.markerWrapper_, 'mousemove', function(e) {
621        that.drag(e);
622      }, true),
623      google.maps.event.addDomListener(this.markerWrapper_, 'mouseup', function() {
624        that.stopDrag();
625        that.markerWrapper_.releaseCapture();
626      }, true)
627    ];
628  } else {
629    this.draggingListeners_ = [
630      google.maps.event.addDomListener(window, 'mousemove', function(e) {
631        that.drag(e);
632      }, true),
633      google.maps.event.addDomListener(window, 'mouseup', function() {
634        that.stopDrag();
635      }, true)
636    ];
637  }
638};
639
640
641/**
642 * Remove dragging listeners.
643 *
644 * @private
645 */
646RichMarker.prototype.removeDraggingListeners_ = function() {
647  if (this.draggingListeners_) {
648    for (var i = 0, listener; listener = this.draggingListeners_[i]; i++) {
649      google.maps.event.removeListener(listener);
650    }
651    this.draggingListeners_.length = 0;
652  }
653};
654
655
656/**
657 * Get the anchor offset.
658 *
659 * @return {google.maps.Size} The size offset.
660 * @private
661 */
662RichMarker.prototype.getOffset_ = function() {
663  var anchor = this.getAnchor();
664  if (typeof anchor == 'object') {
665    return /** @type {google.maps.Size} */ (anchor);
666  }
667
668  var offset = new google.maps.Size(0, 0);
669  if (!this.markerContent_) {
670    return offset;
671  }
672
673  var width = this.markerContent_.offsetWidth;
674  var height = this.markerContent_.offsetHeight;
675
676  switch (anchor) {
677   case RichMarkerPosition['TOP_LEFT']:
678     break;
679   case RichMarkerPosition['TOP']:
680     offset.width = -width / 2;
681     break;
682   case RichMarkerPosition['TOP_RIGHT']:
683     offset.width = -width;
684     break;
685   case RichMarkerPosition['LEFT']:
686     offset.height = -height / 2;
687     break;
688   case RichMarkerPosition['MIDDLE']:
689     offset.width = -width / 2;
690     offset.height = -height / 2;
691     break;
692   case RichMarkerPosition['RIGHT']:
693     offset.width = -width;
694     offset.height = -height / 2;
695     break;
696   case RichMarkerPosition['BOTTOM_LEFT']:
697     offset.height = -height;
698     break;
699   case RichMarkerPosition['BOTTOM']:
700     offset.width = -width / 2;
701     offset.height = -height;
702     break;
703   case RichMarkerPosition['BOTTOM_RIGHT']:
704     offset.width = -width;
705     offset.height = -height;
706     break;
707  }
708
709  return offset;
710};
711
712
713/**
714 * Adding the marker to a map.
715 * Implementing the interface.
716 */
717RichMarker.prototype.onAdd = function() {
718  if (!this.markerWrapper_) {
719    this.markerWrapper_ = document.createElement('DIV');
720    this.markerWrapper_.className += 'js-rich-marker';
721    this.markerWrapper_.style['position'] = 'absolute';
722  }
723
724  if (this.getZIndex()) {
725    this.markerWrapper_.style['zIndex'] = this.getZIndex();
726  }
727
728  this.markerWrapper_.style['display'] = this.getVisible() ? '' : 'none';
729
730  if (!this.markerContent_) {
731    this.markerContent_ = document.createElement('DIV');
732    this.markerWrapper_.appendChild(this.markerContent_);
733
734    var that = this;
735    google.maps.event.addDomListener(this.markerContent_, 'click', function(e) {
736      google.maps.event.trigger(that, 'click');
737    });
738    google.maps.event.addDomListener(this.markerContent_, 'mouseover', function(e) {
739      google.maps.event.trigger(that, 'mouseover');
740    });
741    google.maps.event.addDomListener(this.markerContent_, 'mouseout', function(e) {
742      google.maps.event.trigger(that, 'mouseout');
743    });
744  }
745
746  this.ready_ = true;
747  this.content_changed();
748  this.flat_changed();
749  this.draggable_changed();
750
751  var panes = this.getPanes();
752  if (panes) {
753    panes.overlayMouseTarget.appendChild(this.markerWrapper_);
754  }
755
756  google.maps.event.trigger(this, 'ready');
757};
758RichMarker.prototype['onAdd'] = RichMarker.prototype.onAdd;
759
760
761/**
762 * Impelementing the interface.
763 */
764RichMarker.prototype.draw = function() {
765  if (!this.ready_ || this.dragging_) {
766    return;
767  }
768
769  var projection = this.getProjection();
770
771  if (!projection) {
772    // The map projection is not ready yet so do nothing
773    return;
774  }
775
776  var latLng = /** @type {google.maps.LatLng} */ (this.get('position'));
777  var pos = projection.fromLatLngToDivPixel(latLng);
778
779  var offset = this.getOffset_();
780  this.markerWrapper_.style['top'] = (pos.y + offset.height) + 'px';
781  this.markerWrapper_.style['left'] = (pos.x + offset.width) + 'px';
782
783  var height = this.markerContent_.offsetHeight;
784  var width = this.markerContent_.offsetWidth;
785
786  if (width != this.get('width')) {
787    this.set('width', width);
788  }
789
790  if (height != this.get('height')) {
791    this.set('height', height);
792  }
793};
794RichMarker.prototype['draw'] = RichMarker.prototype.draw;
795
796
797/**
798 * Removing a marker from the map.
799 * Implementing the interface.
800 */
801RichMarker.prototype.onRemove = function() {
802  if (this.markerWrapper_ && this.markerWrapper_.parentNode) {
803    this.markerWrapper_.parentNode.removeChild(this.markerWrapper_);
804  }
805  this.removeDragListeners_();
806};
807RichMarker.prototype['onRemove'] = RichMarker.prototype.onRemove;
808
809
810/**
811 * RichMarker Anchor positions
812 * @enum {number}
813 */
814var RichMarkerPosition = {
815  'TOP_LEFT': 1,
816  'TOP': 2,
817  'TOP_RIGHT': 3,
818  'LEFT': 4,
819  'MIDDLE': 5,
820  'RIGHT': 6,
821  'BOTTOM_LEFT': 7,
822  'BOTTOM': 8,
823  'BOTTOM_RIGHT': 9
824};
825window['RichMarkerPosition'] = RichMarkerPosition;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.