blazer 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +23 -27
  4. data/app/assets/javascripts/blazer/Sortable.js +826 -1162
  5. data/app/assets/javascripts/blazer/ace/ace.js +15775 -13360
  6. data/app/assets/javascripts/blazer/ace/ext-language_tools.js +1411 -668
  7. data/app/assets/javascripts/blazer/ace/mode-sql.js +12 -6
  8. data/app/assets/javascripts/blazer/ace/theme-twilight.js +3 -3
  9. data/app/assets/javascripts/blazer/application.js +94 -52
  10. data/app/assets/javascripts/blazer/chart.umd.js +6 -6
  11. data/app/assets/javascripts/blazer/daterangepicker.js +193 -199
  12. data/app/assets/javascripts/blazer/highlight.min.js +235 -373
  13. data/app/assets/javascripts/blazer/moment-timezone-with-data.js +116 -82
  14. data/app/assets/javascripts/blazer/moment.js +368 -365
  15. data/app/assets/javascripts/blazer/queries.js +68 -58
  16. data/app/assets/javascripts/blazer/routes.js +11 -11
  17. data/app/assets/javascripts/blazer/tablesort.js +42 -0
  18. data/app/assets/javascripts/blazer/tom-select.base.js +4175 -0
  19. data/app/assets/stylesheets/blazer/application.css +114 -5
  20. data/app/assets/stylesheets/blazer/tom-select.css +502 -0
  21. data/app/controllers/blazer/base_controller.rb +1 -1
  22. data/app/controllers/blazer/checks_controller.rb +5 -2
  23. data/app/controllers/blazer/queries_controller.rb +3 -1
  24. data/app/helpers/blazer/base_helper.rb +1 -1
  25. data/app/models/blazer/check.rb +35 -57
  26. data/app/views/blazer/_nav.html.erb +1 -1
  27. data/app/views/blazer/_variables.html.erb +57 -42
  28. data/app/views/blazer/checks/_form.html.erb +20 -16
  29. data/app/views/blazer/checks/index.html.erb +17 -20
  30. data/app/views/blazer/dashboards/_form.html.erb +63 -48
  31. data/app/views/blazer/dashboards/show.html.erb +23 -16
  32. data/app/views/blazer/queries/_caching.html.erb +1 -1
  33. data/app/views/blazer/queries/_chart.html.erb +8 -0
  34. data/app/views/blazer/queries/_form.html.erb +153 -180
  35. data/app/views/blazer/queries/_map.html.erb +8 -0
  36. data/app/views/blazer/queries/docs.html.erb +6 -6
  37. data/app/views/blazer/queries/edit.html.erb +1 -0
  38. data/app/views/blazer/queries/home.html.erb +101 -102
  39. data/app/views/blazer/queries/new.html.erb +1 -0
  40. data/app/views/blazer/queries/run.html.erb +23 -34
  41. data/app/views/blazer/queries/schema.html.erb +20 -20
  42. data/app/views/blazer/queries/show.html.erb +19 -12
  43. data/app/views/blazer/uploads/index.html.erb +10 -10
  44. data/app/views/layouts/blazer/application.html.erb +3 -3
  45. data/lib/blazer/adapters/athena_adapter.rb +12 -6
  46. data/lib/blazer/adapters/clickhouse_adapter.rb +136 -0
  47. data/lib/blazer/adapters/druid_adapter.rb +0 -2
  48. data/lib/blazer/adapters/snowflake2_adapter.rb +198 -0
  49. data/lib/blazer/adapters/soda_adapter.rb +0 -2
  50. data/lib/blazer/adapters/sql_adapter.rb +4 -0
  51. data/lib/blazer/adapters.rb +2 -0
  52. data/lib/blazer/check_types.rb +20 -0
  53. data/lib/blazer/email_notifier.rb +49 -0
  54. data/lib/blazer/result.rb +15 -0
  55. data/lib/blazer/slack_notifier.rb +39 -7
  56. data/lib/blazer/version.rb +1 -1
  57. data/lib/blazer.rb +32 -26
  58. data/lib/generators/blazer/templates/config.yml.tt +0 -2
  59. data/licenses/LICENSE-chart.js.txt +1 -1
  60. metadata +12 -31
  61. data/app/assets/javascripts/blazer/bootstrap.js +0 -2580
  62. data/app/assets/javascripts/blazer/jquery.js +0 -10872
  63. data/app/assets/javascripts/blazer/jquery.stickytableheaders.js +0 -325
  64. data/app/assets/javascripts/blazer/rails-ujs.js +0 -746
  65. data/app/assets/javascripts/blazer/selectize.js +0 -3891
  66. data/app/assets/javascripts/blazer/stupidtable-custom-settings.js +0 -13
  67. data/app/assets/javascripts/blazer/stupidtable.js +0 -281
  68. data/app/assets/javascripts/blazer/vue.global.prod.js +0 -1
  69. data/app/assets/stylesheets/blazer/selectize.css +0 -403
  70. data/licenses/LICENSE-jquery.txt +0 -20
  71. data/licenses/LICENSE-rails-ujs.txt +0 -20
  72. data/licenses/LICENSE-stickytableheaders.txt +0 -20
  73. data/licenses/LICENSE-stupidtable.txt +0 -19
  74. data/licenses/LICENSE-vue.txt +0 -21
  75. /data/licenses/{LICENSE-selectize.txt → LICENSE-tom-select.txt} +0 -0
@@ -33,7 +33,7 @@
33
33
 
34
34
  //default settings for options
35
35
  this.parentEl = 'body';
36
- this.element = $(element);
36
+ this.element = element;
37
37
  this.startDate = moment().startOf('day');
38
38
  this.endDate = moment().endOf('day');
39
39
  this.minDate = false;
@@ -57,11 +57,11 @@
57
57
  this.ranges = {};
58
58
 
59
59
  this.opens = 'right';
60
- if (this.element.hasClass('pull-right'))
60
+ if (this.element.classList.contains('pull-right'))
61
61
  this.opens = 'left';
62
62
 
63
63
  this.drops = 'down';
64
- if (this.element.hasClass('dropup'))
64
+ if (this.element.classList.contains('dropup'))
65
65
  this.drops = 'up';
66
66
 
67
67
  this.buttonClasses = 'btn btn-sm';
@@ -92,12 +92,8 @@
92
92
  if (typeof options !== 'object' || options === null)
93
93
  options = {};
94
94
 
95
- //allow setting options with data attributes
96
- //data-api options will be overwritten with custom javascript options
97
- options = $.extend(this.element.data(), options);
98
-
99
95
  //html template for the picker UI
100
- if (typeof options.template !== 'string' && !(options.template instanceof $))
96
+ if (typeof options.template !== 'string')
101
97
  options.template =
102
98
  '<div class="daterangepicker">' +
103
99
  '<div class="ranges"></div>' +
@@ -116,8 +112,11 @@
116
112
  '</div>' +
117
113
  '</div>';
118
114
 
119
- this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);
120
- this.container = $(options.template).appendTo(this.parentEl);
115
+ this.parentEl = document.querySelector(this.parentEl);
116
+ var template = document.createElement('template');
117
+ template.innerHTML = options.template;
118
+ this.parentEl.append(template.content.firstElementChild);
119
+ this.container = this.parentEl.lastElementChild;
121
120
 
122
121
  //
123
122
  // handle all the possible options overriding defaults
@@ -160,7 +159,7 @@
160
159
  this.locale.customRangeLabel = rangeHtml;
161
160
  }
162
161
  }
163
- this.container.addClass(this.locale.direction);
162
+ this.container.classList.add(this.locale.direction);
164
163
 
165
164
  if (typeof options.startDate === 'string')
166
165
  this.startDate = moment(options.startDate, this.locale.format);
@@ -291,8 +290,8 @@
291
290
 
292
291
  //if no start/end dates set, check if an input element contains initial values
293
292
  if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {
294
- if ($(this.element).is(':text')) {
295
- var val = $(this.element).val(),
293
+ if (this.element.matches(':text')) {
294
+ var val = this.element.value,
296
295
  split = val.split(this.locale.separator);
297
296
 
298
297
  start = end = null;
@@ -357,7 +356,7 @@
357
356
  list += '<li data-range-key="' + this.locale.customRangeLabel + '">' + this.locale.customRangeLabel + '</li>';
358
357
  }
359
358
  list += '</ul>';
360
- this.container.find('.ranges').prepend(list);
359
+ this.container.querySelector('.ranges').prepend(document.createRange().createContextualFragment(list));
361
360
  }
362
361
 
363
362
  if (typeof cb === 'function') {
@@ -367,7 +366,7 @@
367
366
  if (!this.timePicker) {
368
367
  this.startDate = this.startDate.startOf('day');
369
368
  this.endDate = this.endDate.endOf('day');
370
- this.container.find('.calendar-time').hide();
369
+ this.container.querySelector('.calendar-time').style.display = 'none';
371
370
  }
372
371
 
373
372
  //can't be used together for now
@@ -375,67 +374,66 @@
375
374
  this.autoApply = false;
376
375
 
377
376
  if (this.autoApply) {
378
- this.container.addClass('auto-apply');
377
+ this.container.classList.add('auto-apply');
379
378
  }
380
379
 
381
380
  if (typeof options.ranges === 'object')
382
- this.container.addClass('show-ranges');
381
+ this.container.classList.add('show-ranges');
383
382
 
384
383
  if (this.singleDatePicker) {
385
- this.container.addClass('single');
386
- this.container.find('.drp-calendar.left').addClass('single');
387
- this.container.find('.drp-calendar.left').show();
388
- this.container.find('.drp-calendar.right').hide();
384
+ this.container.classList.add('single');
385
+ this.container.querySelector('.drp-calendar.left').classList.add('single');
386
+ this.container.querySelector('.drp-calendar.left').style.display = 'block';
387
+ this.container.querySelector('.drp-calendar.right').style.display = 'none';
389
388
  if (!this.timePicker && this.autoApply) {
390
- this.container.addClass('auto-apply');
389
+ this.container.classList.add('auto-apply');
391
390
  }
392
391
  }
393
392
 
394
393
  if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) {
395
- this.container.addClass('show-calendar');
394
+ this.container.classList.add('show-calendar');
396
395
  }
397
396
 
398
- this.container.addClass('opens' + this.opens);
397
+ this.container.classList.add('opens' + this.opens);
399
398
 
400
399
  //apply CSS classes and labels to buttons
401
- this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses);
400
+ this.container.querySelectorAll('.applyBtn, .cancelBtn').forEach(el => el.classList.add(...this.buttonClasses.split(' ')));
402
401
  if (this.applyButtonClasses.length)
403
- this.container.find('.applyBtn').addClass(this.applyButtonClasses);
402
+ this.container.querySelector('.applyBtn').classList.add(...this.applyButtonClasses.split(' '));
404
403
  if (this.cancelButtonClasses.length)
405
- this.container.find('.cancelBtn').addClass(this.cancelButtonClasses);
406
- this.container.find('.applyBtn').html(this.locale.applyLabel);
407
- this.container.find('.cancelBtn').html(this.locale.cancelLabel);
404
+ this.container.querySelector('.cancelBtn').classList.add(...this.cancelButtonClasses.split(' '));
405
+ this.container.querySelector('.applyBtn').innerHTML = this.locale.applyLabel;
406
+ this.container.querySelector('.cancelBtn').innerHTML = this.locale.cancelLabel;
408
407
 
409
408
  //
410
409
  // event listeners
411
410
  //
412
411
 
413
- this.container.find('.drp-calendar')
414
- .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this))
415
- .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this))
416
- .on('mousedown.daterangepicker', 'td.available', $.proxy(this.clickDate, this))
417
- .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this))
418
- .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this))
419
- .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this))
420
- .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this));
421
-
422
- this.container.find('.ranges')
423
- .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this));
424
-
425
- this.container.find('.drp-buttons')
426
- .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
427
- .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this));
428
-
429
- if (this.element.is('input') || this.element.is('button')) {
430
- this.element.on({
431
- 'click.daterangepicker': $.proxy(this.show, this),
432
- 'focus.daterangepicker': $.proxy(this.show, this),
433
- 'keyup.daterangepicker': $.proxy(this.elementChanged, this),
434
- 'keydown.daterangepicker': $.proxy(this.keydown, this) //IE 11 compatibility
435
- });
412
+ this.container.querySelectorAll('.drp-calendar').forEach(cal => {
413
+ cal.addEventListener('click', e => e.target.closest('.prev') && this.clickPrev(e));
414
+ cal.addEventListener('click', e => e.target.closest('.next') && this.clickNext(e));
415
+ cal.addEventListener('mousedown', e => e.target.closest('td.available') && this.clickDate(e));
416
+ cal.addEventListener('mouseover', e => e.target.closest('td.available') && this.hoverDate(e));
417
+ cal.addEventListener('change', e => e.target.closest('select.yearselect') && this.monthOrYearChanged(e));
418
+ cal.addEventListener('change', e => e.target.closest('select.monthselect') && this.monthOrYearChanged(e));
419
+ cal.addEventListener('change', e => e.target.closest('select.hourselect,select.minuteselect,select.secondselect,select.ampmselect') && this.timeChanged(e));
420
+ });
421
+
422
+ var ranges = this.container.querySelector('.ranges');
423
+ ranges.addEventListener('click', e => e.target.closest('li') && this.clickRange(e));
424
+
425
+ var buttons = this.container.querySelector('.drp-buttons');
426
+ buttons.addEventListener('click', e => e.target.closest('button.applyBtn') && this.clickApply(e));
427
+ buttons.addEventListener('click', e => e.target.closest('button.cancelBtn') && this.clickCancel(e));
428
+
429
+ if (this.element.matches('input') || this.element.matches('button')) {
430
+ this.element.addEventListener('click', e => this.show(e));
431
+ this.element.addEventListener('focus', e => this.show(e));
432
+ this.element.addEventListener('keyup', e => this.elementChanged(e));
433
+ this.element.addEventListener('keydown', e => this.keydown(e));
436
434
  } else {
437
- this.element.on('click.daterangepicker', $.proxy(this.toggle, this));
438
- this.element.on('keydown.daterangepicker', $.proxy(this.toggle, this));
435
+ this.element.addEventListener('click', e => this.toggle(e));
436
+ this.element.addEventListener('keydown', e => this.toggle(e));
439
437
  }
440
438
 
441
439
  //
@@ -505,7 +503,7 @@
505
503
 
506
504
  this.previousRightTime = this.endDate.clone();
507
505
 
508
- this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
506
+ this.container.querySelector('.drp-selected').innerHTML = this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format);
509
507
 
510
508
  if (!this.isShowing)
511
509
  this.updateElement();
@@ -526,13 +524,13 @@
526
524
  this.renderTimePicker('left');
527
525
  this.renderTimePicker('right');
528
526
  if (!this.endDate) {
529
- this.container.find('.right .calendar-time select').prop('disabled', true).addClass('disabled');
527
+ this.container.querySelector('.right .calendar-time select').prop('disabled', true).classList.add('disabled');
530
528
  } else {
531
- this.container.find('.right .calendar-time select').prop('disabled', false).removeClass('disabled');
529
+ this.container.querySelector('.right .calendar-time select').prop('disabled', false).classList.remove('disabled');
532
530
  }
533
531
  }
534
532
  if (this.endDate)
535
- this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
533
+ this.container.querySelector('.drp-selected').innerHTML = this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format);
536
534
  this.updateMonthsInView();
537
535
  this.updateCalendars();
538
536
  this.updateFormInputs();
@@ -574,28 +572,28 @@
574
572
  if (this.timePicker) {
575
573
  var hour, minute, second;
576
574
  if (this.endDate) {
577
- hour = parseInt(this.container.find('.left .hourselect').val(), 10);
578
- minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
575
+ hour = parseInt(this.container.querySelector('.left .hourselect').value, 10);
576
+ minute = parseInt(this.container.querySelector('.left .minuteselect').value, 10);
579
577
  if (isNaN(minute)) {
580
- minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10);
578
+ minute = parseInt(this.container.querySelector('.left .minuteselect option:last').value, 10);
581
579
  }
582
- second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
580
+ second = this.timePickerSeconds ? parseInt(this.container.querySelector('.left .secondselect').value, 10) : 0;
583
581
  if (!this.timePicker24Hour) {
584
- var ampm = this.container.find('.left .ampmselect').val();
582
+ var ampm = this.container.querySelector('.left .ampmselect').value;
585
583
  if (ampm === 'PM' && hour < 12)
586
584
  hour += 12;
587
585
  if (ampm === 'AM' && hour === 12)
588
586
  hour = 0;
589
587
  }
590
588
  } else {
591
- hour = parseInt(this.container.find('.right .hourselect').val(), 10);
592
- minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
589
+ hour = parseInt(this.container.querySelector('.right .hourselect').value, 10);
590
+ minute = parseInt(this.container.querySelector('.right .minuteselect').value, 10);
593
591
  if (isNaN(minute)) {
594
- minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10);
592
+ minute = parseInt(this.container.querySelector('.right .minuteselect option:last').value, 10);
595
593
  }
596
- second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
594
+ second = this.timePickerSeconds ? parseInt(this.container.querySelector('.right .secondselect').value, 10) : 0;
597
595
  if (!this.timePicker24Hour) {
598
- var ampm = this.container.find('.right .ampmselect').val();
596
+ var ampm = this.container.querySelector('.right .ampmselect').value;
599
597
  if (ampm === 'PM' && hour < 12)
600
598
  hour += 12;
601
599
  if (ampm === 'AM' && hour === 12)
@@ -610,7 +608,7 @@
610
608
  this.renderCalendar('right');
611
609
 
612
610
  //highlight any predefined range matching the current start and end dates
613
- this.container.find('.ranges li').removeClass('active');
611
+ this.container.querySelectorAll('.ranges li').forEach(li => li.classList.remove('active'));
614
612
  if (this.endDate == null) return;
615
613
 
616
614
  this.calculateChosenLabel();
@@ -753,7 +751,7 @@
753
751
  if (this.showWeekNumbers || this.showISOWeekNumbers)
754
752
  html += '<th class="week">' + this.locale.weekLabel + '</th>';
755
753
 
756
- $.each(this.locale.daysOfWeek, function(index, dayOfWeek) {
754
+ this.locale.daysOfWeek.forEach(function(dayOfWeek) {
757
755
  html += '<th>' + dayOfWeek + '</th>';
758
756
  });
759
757
 
@@ -846,7 +844,7 @@
846
844
  html += '</tbody>';
847
845
  html += '</table>';
848
846
 
849
- this.container.find('.drp-calendar.' + side + ' .calendar-table').html(html);
847
+ this.container.querySelector('.drp-calendar.' + side + ' .calendar-table').innerHTML = html;
850
848
 
851
849
  },
852
850
 
@@ -869,15 +867,15 @@
869
867
  minDate = this.startDate;
870
868
 
871
869
  //Preserve the time already selected
872
- var timeSelector = this.container.find('.drp-calendar.right .calendar-time');
870
+ var timeSelector = this.container.querySelector('.drp-calendar.right .calendar-time');
873
871
  if (timeSelector.html() != '') {
874
872
 
875
- selected.hour(!isNaN(selected.hour()) ? selected.hour() : timeSelector.find('.hourselect option:selected').val());
876
- selected.minute(!isNaN(selected.minute()) ? selected.minute() : timeSelector.find('.minuteselect option:selected').val());
877
- selected.second(!isNaN(selected.second()) ? selected.second() : timeSelector.find('.secondselect option:selected').val());
873
+ selected.hour(!isNaN(selected.hour()) ? selected.hour() : timeSelector.querySelector('.hourselect option:selected').value);
874
+ selected.minute(!isNaN(selected.minute()) ? selected.minute() : timeSelector.querySelector('.minuteselect option:selected').value);
875
+ selected.second(!isNaN(selected.second()) ? selected.second() : timeSelector.querySelector('.secondselect option:selected').value);
878
876
 
879
877
  if (!this.timePicker24Hour) {
880
- var ampm = timeSelector.find('.ampmselect option:selected').val();
878
+ var ampm = timeSelector.querySelector('.ampmselect option:selected').value;
881
879
  if (ampm === 'PM' && selected.hour() < 12)
882
880
  selected.hour(selected.hour() + 12);
883
881
  if (ampm === 'AM' && selected.hour() === 12)
@@ -1007,16 +1005,16 @@
1007
1005
  html += '</select>';
1008
1006
  }
1009
1007
 
1010
- this.container.find('.drp-calendar.' + side + ' .calendar-time').html(html);
1008
+ this.container.querySelector('.drp-calendar.' + side + ' .calendar-time').innerHTML = html;
1011
1009
 
1012
1010
  },
1013
1011
 
1014
1012
  updateFormInputs: function() {
1015
1013
 
1016
1014
  if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) {
1017
- this.container.find('button.applyBtn').prop('disabled', false);
1015
+ this.container.querySelector('button.applyBtn').disabled = false;
1018
1016
  } else {
1019
- this.container.find('button.applyBtn').prop('disabled', true);
1017
+ this.container.querySelector('button.applyBtn').disabled = true;
1020
1018
  }
1021
1019
 
1022
1020
  },
@@ -1026,90 +1024,90 @@
1026
1024
  containerTop,
1027
1025
  drops = this.drops;
1028
1026
 
1029
- var parentRightEdge = $(window).width();
1030
- if (!this.parentEl.is('body')) {
1027
+ var parentRightEdge = window.innerWidth;
1028
+ if (!this.parentEl.matches('body')) {
1031
1029
  parentOffset = {
1032
- top: this.parentEl.offset().top - this.parentEl.scrollTop(),
1033
- left: this.parentEl.offset().left - this.parentEl.scrollLeft()
1030
+ top: this.parentEl.getBoundingClientRect().top - this.parentEl.scrollTop,
1031
+ left: this.parentEl.getBoundingClientRect().left - this.parentEl.scrollLeft
1034
1032
  };
1035
- parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
1033
+ parentRightEdge = this.parentEl.clientWidth + this.parentEl.getBoundingClientRect().left;
1036
1034
  }
1037
1035
 
1038
1036
  switch (drops) {
1039
1037
  case 'auto':
1040
- containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
1041
- if (containerTop + this.container.outerHeight() >= this.parentEl[0].scrollHeight) {
1042
- containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
1038
+ containerTop = this.element.getBoundingClientRect().top + this.element.offsetHeight - parentOffset.top;
1039
+ if (containerTop + this.container.offsetHeight >= this.parentEl.scrollHeight) {
1040
+ containerTop = this.element.getBoundingClientRect().top - this.container.offsetHeight - parentOffset.top;
1043
1041
  drops = 'up';
1044
1042
  }
1045
1043
  break;
1046
1044
  case 'up':
1047
- containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
1045
+ containerTop = this.element.getBoundingClientRect().top - this.container.offsetHeight - parentOffset.top;
1048
1046
  break;
1049
1047
  default:
1050
- containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
1048
+ containerTop = this.element.getBoundingClientRect().top + this.element.offsetHeight - parentOffset.top;
1051
1049
  break;
1052
1050
  }
1053
1051
 
1054
1052
  // Force the container to it's actual width
1055
- this.container.css({
1053
+ Object.assign(this.container.style, {
1056
1054
  top: 0,
1057
1055
  left: 0,
1058
1056
  right: 'auto'
1059
1057
  });
1060
- var containerWidth = this.container.outerWidth();
1058
+ var containerWidth = this.container.offsetWidth;
1061
1059
 
1062
- this.container.toggleClass('drop-up', drops == 'up');
1060
+ this.container.classList.toggle('drop-up', drops == 'up');
1063
1061
 
1064
1062
  if (this.opens == 'left') {
1065
- var containerRight = parentRightEdge - this.element.offset().left - this.element.outerWidth();
1066
- if (containerWidth + containerRight > $(window).width()) {
1067
- this.container.css({
1068
- top: containerTop,
1063
+ var containerRight = parentRightEdge - this.element.getBoundingClientRect().left - this.element.offsetWidth;
1064
+ if (containerWidth + containerRight > window.innerWidth) {
1065
+ Object.assign(this.container.style, {
1066
+ top: containerTop + 'px',
1069
1067
  right: 'auto',
1070
1068
  left: 9
1071
1069
  });
1072
1070
  } else {
1073
- this.container.css({
1074
- top: containerTop,
1075
- right: containerRight,
1071
+ Object.assign(this.container.style, {
1072
+ top: containerTop + 'px',
1073
+ right: containerRight + 'px',
1076
1074
  left: 'auto'
1077
1075
  });
1078
1076
  }
1079
1077
  } else if (this.opens == 'center') {
1080
- var containerLeft = this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2
1078
+ var containerLeft = this.element.getBoundingClientRect().left - parentOffset.left + this.element.offsetWidth / 2
1081
1079
  - containerWidth / 2;
1082
1080
  if (containerLeft < 0) {
1083
- this.container.css({
1084
- top: containerTop,
1081
+ Object.assign(this.container.style, {
1082
+ top: containerTop + 'px',
1085
1083
  right: 'auto',
1086
1084
  left: 9
1087
1085
  });
1088
- } else if (containerLeft + containerWidth > $(window).width()) {
1089
- this.container.css({
1090
- top: containerTop,
1086
+ } else if (containerLeft + containerWidth > window.innerWidth) {
1087
+ Object.assign(this.container.style, {
1088
+ top: containerTop + 'px',
1091
1089
  left: 'auto',
1092
1090
  right: 0
1093
1091
  });
1094
1092
  } else {
1095
- this.container.css({
1096
- top: containerTop,
1097
- left: containerLeft,
1093
+ Object.assign(this.container.style, {
1094
+ top: containerTop + 'px',
1095
+ left: containerLeft + 'px',
1098
1096
  right: 'auto'
1099
1097
  });
1100
1098
  }
1101
1099
  } else {
1102
- var containerLeft = this.element.offset().left - parentOffset.left;
1103
- if (containerLeft + containerWidth > $(window).width()) {
1104
- this.container.css({
1105
- top: containerTop,
1100
+ var containerLeft = this.element.getBoundingClientRect().left - parentOffset.left;
1101
+ if (containerLeft + containerWidth > window.innerWidth) {
1102
+ Object.assign(this.container.style, {
1103
+ top: containerTop + 'px',
1106
1104
  left: 'auto',
1107
1105
  right: 0
1108
1106
  });
1109
1107
  } else {
1110
- this.container.css({
1111
- top: containerTop,
1112
- left: containerLeft,
1108
+ Object.assign(this.container.style, {
1109
+ top: containerTop + 'px',
1110
+ left: containerLeft + 'px',
1113
1111
  right: 'auto'
1114
1112
  });
1115
1113
  }
@@ -1120,29 +1118,28 @@
1120
1118
  if (this.isShowing) return;
1121
1119
 
1122
1120
  // Create a click proxy that is private to this instance of datepicker, for unbinding
1123
- this._outsideClickProxy = $.proxy(function(e) { this.outsideClick(e); }, this);
1121
+ this._outsideClickProxy = e => this.outsideClick(e);
1124
1122
 
1125
1123
  // Bind global datepicker mousedown for hiding and
1126
- $(document)
1127
- .on('mousedown.daterangepicker', this._outsideClickProxy)
1128
- // also support mobile devices
1129
- .on('touchend.daterangepicker', this._outsideClickProxy)
1130
- // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
1131
- .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)
1132
- // and also close when focus changes to outside the picker (eg. tabbing between controls)
1133
- .on('focusin.daterangepicker', this._outsideClickProxy);
1124
+ document.addEventListener('mousedown', this._outsideClickProxy);
1125
+ // also support mobile devices
1126
+ document.addEventListener('touchend', this._outsideClickProxy);
1127
+ // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
1128
+ document.addEventListener('click', e => e.target.closest('[data-toggle=dropdown]') && this._outsideClickProxy(e));
1129
+ // and also close when focus changes to outside the picker (eg. tabbing between controls)
1130
+ document.addEventListener('focusin', this._outsideClickProxy);
1134
1131
 
1135
1132
  // Reposition the picker if the window is resized while it's open
1136
- $(window).on('resize.daterangepicker', $.proxy(function(e) { this.move(e); }, this));
1133
+ window.addEventListener('resize', e => this.move(e));
1137
1134
 
1138
1135
  this.oldStartDate = this.startDate.clone();
1139
1136
  this.oldEndDate = this.endDate.clone();
1140
1137
  this.previousRightTime = this.endDate.clone();
1141
1138
 
1142
1139
  this.updateView();
1143
- this.container.show();
1140
+ this.container.style.display = 'block';
1144
1141
  this.move();
1145
- this.element.trigger('show.daterangepicker', this);
1142
+ // this.element.trigger('show.daterangepicker', this);
1146
1143
  this.isShowing = true;
1147
1144
  },
1148
1145
 
@@ -1162,10 +1159,10 @@
1162
1159
  //if picker is attached to a text input, update it
1163
1160
  this.updateElement();
1164
1161
 
1165
- $(document).off('.daterangepicker');
1166
- $(window).off('.daterangepicker');
1167
- this.container.hide();
1168
- this.element.trigger('hide.daterangepicker', this);
1162
+ // $(document).off('.daterangepicker');
1163
+ // $(window).off('.daterangepicker');
1164
+ this.container.style.display = 'none';
1165
+ // this.element.trigger('hide.daterangepicker', this);
1169
1166
  this.isShowing = false;
1170
1167
  },
1171
1168
 
@@ -1178,28 +1175,28 @@
1178
1175
  },
1179
1176
 
1180
1177
  outsideClick: function(e) {
1181
- var target = $(e.target);
1178
+ var target = e.target;
1182
1179
  // if the page is clicked anywhere except within the daterangerpicker/button
1183
1180
  // itself then call this.hide()
1184
1181
  if (
1185
1182
  // ie modal dialog fix
1186
1183
  e.type == "focusin" ||
1187
- target.closest(this.element).length ||
1188
- target.closest(this.container).length ||
1189
- target.closest('.calendar-table').length
1184
+ this.element.contains(target) ||
1185
+ this.container.contains(target) ||
1186
+ target.closest('.calendar-table')
1190
1187
  ) return;
1191
1188
  this.hide();
1192
- this.element.trigger('outsideClick.daterangepicker', this);
1189
+ // this.element.trigger('outsideClick.daterangepicker', this);
1193
1190
  },
1194
1191
 
1195
1192
  showCalendars: function() {
1196
- this.container.addClass('show-calendar');
1193
+ this.container.classList.add('show-calendar');
1197
1194
  this.move();
1198
- this.element.trigger('showCalendar.daterangepicker', this);
1195
+ // this.element.trigger('showCalendar.daterangepicker', this);
1199
1196
  },
1200
1197
 
1201
1198
  hideCalendars: function() {
1202
- this.container.removeClass('show-calendar');
1199
+ this.container.classList.remove('show-calendar');
1203
1200
  this.element.trigger('hideCalendar.daterangepicker', this);
1204
1201
  },
1205
1202
 
@@ -1225,8 +1222,8 @@
1225
1222
  },
1226
1223
 
1227
1224
  clickPrev: function(e) {
1228
- var cal = $(e.target).parents('.drp-calendar');
1229
- if (cal.hasClass('left')) {
1225
+ var cal = e.target.closest('.drp-calendar');
1226
+ if (cal.classList.contains('left')) {
1230
1227
  this.leftCalendar.month.subtract(1, 'month');
1231
1228
  if (this.linkedCalendars)
1232
1229
  this.rightCalendar.month.subtract(1, 'month');
@@ -1237,8 +1234,8 @@
1237
1234
  },
1238
1235
 
1239
1236
  clickNext: function(e) {
1240
- var cal = $(e.target).parents('.drp-calendar');
1241
- if (cal.hasClass('left')) {
1237
+ var cal = e.target.closest('.drp-calendar');
1238
+ if (cal.classList.contains('left')) {
1242
1239
  this.leftCalendar.month.add(1, 'month');
1243
1240
  } else {
1244
1241
  this.rightCalendar.month.add(1, 'month');
@@ -1251,34 +1248,34 @@
1251
1248
  hoverDate: function(e) {
1252
1249
 
1253
1250
  //ignore dates that can't be selected
1254
- if (!$(e.target).hasClass('available')) return;
1251
+ if (!e.target.classList.contains('available')) return;
1255
1252
 
1256
- var title = $(e.target).attr('data-title');
1253
+ var title = e.target.getAttribute('data-title');
1257
1254
  var row = title.substr(1, 1);
1258
1255
  var col = title.substr(3, 1);
1259
- var cal = $(e.target).parents('.drp-calendar');
1260
- var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1256
+ var cal = e.target.closest('.drp-calendar');
1257
+ var date = cal.classList.contains('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1261
1258
 
1262
1259
  //highlight the dates between the start date and the date being hovered as a potential end date
1263
1260
  var leftCalendar = this.leftCalendar;
1264
1261
  var rightCalendar = this.rightCalendar;
1265
1262
  var startDate = this.startDate;
1266
1263
  if (!this.endDate) {
1267
- this.container.find('.drp-calendar tbody td').each(function(index, el) {
1264
+ this.container.querySelectorAll('.drp-calendar tbody td').forEach(function(el, index) {
1268
1265
 
1269
1266
  //skip week numbers, only look at dates
1270
- if ($(el).hasClass('week')) return;
1267
+ if (el.classList.contains('week')) return;
1271
1268
 
1272
- var title = $(el).attr('data-title');
1269
+ var title = el.getAttribute('data-title');
1273
1270
  var row = title.substr(1, 1);
1274
1271
  var col = title.substr(3, 1);
1275
- var cal = $(el).parents('.drp-calendar');
1276
- var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
1272
+ var cal = el.closest('.drp-calendar');
1273
+ var dt = cal.classList.contains('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
1277
1274
 
1278
1275
  if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) {
1279
- $(el).addClass('in-range');
1276
+ el.classList.add('in-range');
1280
1277
  } else {
1281
- $(el).removeClass('in-range');
1278
+ el.classList.remove('in-range');
1282
1279
  }
1283
1280
 
1284
1281
  });
@@ -1288,13 +1285,13 @@
1288
1285
 
1289
1286
  clickDate: function(e) {
1290
1287
 
1291
- if (!$(e.target).hasClass('available')) return;
1288
+ if (!e.target.classList.contains('available')) return;
1292
1289
 
1293
- var title = $(e.target).attr('data-title');
1290
+ var title = e.target.getAttribute('data-title');
1294
1291
  var row = title.substr(1, 1);
1295
1292
  var col = title.substr(3, 1);
1296
- var cal = $(e.target).parents('.drp-calendar');
1297
- var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1293
+ var cal = e.target.closest('.drp-calendar');
1294
+ var date = cal.classList.contains('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1298
1295
 
1299
1296
  //
1300
1297
  // this function needs to do a few things:
@@ -1307,19 +1304,19 @@
1307
1304
 
1308
1305
  if (this.endDate || date.isBefore(this.startDate, 'day')) { //picking start
1309
1306
  if (this.timePicker) {
1310
- var hour = parseInt(this.container.find('.left .hourselect').val(), 10);
1307
+ var hour = parseInt(this.container.querySelector('.left .hourselect').value, 10);
1311
1308
  if (!this.timePicker24Hour) {
1312
- var ampm = this.container.find('.left .ampmselect').val();
1309
+ var ampm = this.container.querySelector('.left .ampmselect').value;
1313
1310
  if (ampm === 'PM' && hour < 12)
1314
1311
  hour += 12;
1315
1312
  if (ampm === 'AM' && hour === 12)
1316
1313
  hour = 0;
1317
1314
  }
1318
- var minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
1315
+ var minute = parseInt(this.container.querySelector('.left .minuteselect').value, 10);
1319
1316
  if (isNaN(minute)) {
1320
- minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10);
1317
+ minute = parseInt(this.container.querySelector('.left .minuteselect option:last').value, 10);
1321
1318
  }
1322
- var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
1319
+ var second = this.timePickerSeconds ? parseInt(this.container.querySelector('.left .secondselect').value, 10) : 0;
1323
1320
  date = date.clone().hour(hour).minute(minute).second(second);
1324
1321
  }
1325
1322
  this.endDate = null;
@@ -1330,19 +1327,19 @@
1330
1327
  this.setEndDate(this.startDate.clone());
1331
1328
  } else { // picking end
1332
1329
  if (this.timePicker) {
1333
- var hour = parseInt(this.container.find('.right .hourselect').val(), 10);
1330
+ var hour = parseInt(this.container.querySelector('.right .hourselect').value, 10);
1334
1331
  if (!this.timePicker24Hour) {
1335
- var ampm = this.container.find('.right .ampmselect').val();
1332
+ var ampm = this.container.querySelector('.right .ampmselect').value;
1336
1333
  if (ampm === 'PM' && hour < 12)
1337
1334
  hour += 12;
1338
1335
  if (ampm === 'AM' && hour === 12)
1339
1336
  hour = 0;
1340
1337
  }
1341
- var minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
1338
+ var minute = parseInt(this.container.querySelector('.right .minuteselect').value, 10);
1342
1339
  if (isNaN(minute)) {
1343
- minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10);
1340
+ minute = parseInt(this.container.querySelector('.right .minuteselect option:last').value, 10);
1344
1341
  }
1345
- var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
1342
+ var second = this.timePickerSeconds ? parseInt(this.container.querySelector('.right .secondselect').value, 10) : 0;
1346
1343
  date = date.clone().hour(hour).minute(minute).second(second);
1347
1344
  }
1348
1345
  this.setEndDate(date.clone());
@@ -1374,14 +1371,16 @@
1374
1371
  //ignore times when comparing dates if time picker seconds is not enabled
1375
1372
  if (this.startDate.format(format) == this.ranges[range][0].format(format) && this.endDate.format(format) == this.ranges[range][1].format(format)) {
1376
1373
  customRange = false;
1377
- this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key');
1374
+ this.chosenLabel = this.container.querySelector('.ranges li:eq(' + i + ')').classList.add('active').attr('data-range-key');
1378
1375
  break;
1379
1376
  }
1380
1377
  } else {
1381
1378
  //ignore times when comparing dates if time picker is not enabled
1382
1379
  if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) {
1383
1380
  customRange = false;
1384
- this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key');
1381
+ var li = this.container.querySelectorAll('.ranges li')[i];
1382
+ li.classList.add('active');
1383
+ this.chosenLabel = li.getAttribute('data-range-key');
1385
1384
  break;
1386
1385
  }
1387
1386
  }
@@ -1389,7 +1388,11 @@
1389
1388
  }
1390
1389
  if (customRange) {
1391
1390
  if (this.showCustomRangeLabel) {
1392
- this.chosenLabel = this.container.find('.ranges li:last').addClass('active').attr('data-range-key');
1391
+ var li = this.container.querySelector('.ranges li:last-child');
1392
+ if (li) {
1393
+ li.classList.add('active');
1394
+ this.chosenLabel = li.getAttribute('data-range-key');
1395
+ }
1393
1396
  } else {
1394
1397
  this.chosenLabel = null;
1395
1398
  }
@@ -1399,7 +1402,7 @@
1399
1402
 
1400
1403
  clickApply: function(e) {
1401
1404
  this.hide();
1402
- this.element.trigger('apply.daterangepicker', this);
1405
+ this.element.dispatchEvent(new Event('apply.daterangepicker'));
1403
1406
  },
1404
1407
 
1405
1408
  clickCancel: function(e) {
@@ -1410,13 +1413,13 @@
1410
1413
  },
1411
1414
 
1412
1415
  monthOrYearChanged: function(e) {
1413
- var isLeft = $(e.target).closest('.drp-calendar').hasClass('left'),
1416
+ var isLeft = e.target.closest('.drp-calendar').classList.contains('left'),
1414
1417
  leftOrRight = isLeft ? 'left' : 'right',
1415
- cal = this.container.find('.drp-calendar.'+leftOrRight);
1418
+ cal = this.container.querySelector('.drp-calendar.'+leftOrRight);
1416
1419
 
1417
1420
  // Month must be Number for new moment versions
1418
- var month = parseInt(cal.find('.monthselect').val(), 10);
1419
- var year = cal.find('.yearselect').val();
1421
+ var month = parseInt(cal.querySelector('.monthselect').value, 10);
1422
+ var year = cal.querySelector('.yearselect').value;
1420
1423
 
1421
1424
  if (!isLeft) {
1422
1425
  if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) {
@@ -1453,18 +1456,18 @@
1453
1456
 
1454
1457
  timeChanged: function(e) {
1455
1458
 
1456
- var cal = $(e.target).closest('.drp-calendar'),
1457
- isLeft = cal.hasClass('left');
1459
+ var cal = e.target.closest('.drp-calendar'),
1460
+ isLeft = cal.classList.contains('left');
1458
1461
 
1459
- var hour = parseInt(cal.find('.hourselect').val(), 10);
1460
- var minute = parseInt(cal.find('.minuteselect').val(), 10);
1462
+ var hour = parseInt(cal.querySelector('.hourselect').value, 10);
1463
+ var minute = parseInt(cal.querySelector('.minuteselect').value, 10);
1461
1464
  if (isNaN(minute)) {
1462
- minute = parseInt(cal.find('.minuteselect option:last').val(), 10);
1465
+ minute = parseInt(cal.querySelector('.minuteselect option:last').value, 10);
1463
1466
  }
1464
- var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0;
1467
+ var second = this.timePickerSeconds ? parseInt(cal.querySelector('.secondselect').value, 10) : 0;
1465
1468
 
1466
1469
  if (!this.timePicker24Hour) {
1467
- var ampm = cal.find('.ampmselect').val();
1470
+ var ampm = cal.querySelector('.ampmselect').value;
1468
1471
  if (ampm === 'PM' && hour < 12)
1469
1472
  hour += 12;
1470
1473
  if (ampm === 'AM' && hour === 12)
@@ -1503,10 +1506,10 @@
1503
1506
  },
1504
1507
 
1505
1508
  elementChanged: function() {
1506
- if (!this.element.is('input')) return;
1507
- if (!this.element.val().length) return;
1509
+ if (!this.element.matches('input')) return;
1510
+ if (!this.element.value.length) return;
1508
1511
 
1509
- var dateString = this.element.val().split(this.locale.separator),
1512
+ var dateString = this.element.value.split(this.locale.separator),
1510
1513
  start = null,
1511
1514
  end = null;
1512
1515
 
@@ -1516,7 +1519,7 @@
1516
1519
  }
1517
1520
 
1518
1521
  if (this.singleDatePicker || start === null || end === null) {
1519
- start = moment(this.element.val(), this.locale.format);
1522
+ start = moment(this.element.value, this.locale.format);
1520
1523
  end = start;
1521
1524
  }
1522
1525
 
@@ -1543,12 +1546,12 @@
1543
1546
  },
1544
1547
 
1545
1548
  updateElement: function() {
1546
- if (this.element.is('input') && this.autoUpdateInput) {
1549
+ if (this.element.matches('input') && this.autoUpdateInput) {
1547
1550
  var newValue = this.startDate.format(this.locale.format);
1548
1551
  if (!this.singleDatePicker) {
1549
1552
  newValue += this.locale.separator + this.endDate.format(this.locale.format);
1550
1553
  }
1551
- if (newValue !== this.element.val()) {
1554
+ if (newValue !== this.element.value) {
1552
1555
  this.element.val(newValue).trigger('change');
1553
1556
  }
1554
1557
  }
@@ -1562,16 +1565,7 @@
1562
1565
 
1563
1566
  };
1564
1567
 
1565
- $.fn.daterangepicker = function(options, callback) {
1566
- var implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options);
1567
- this.each(function() {
1568
- var el = $(this);
1569
- if (el.data('daterangepicker'))
1570
- el.data('daterangepicker').remove();
1571
- el.data('daterangepicker', new DateRangePicker(el, implementOptions, callback));
1572
- });
1573
- return this;
1574
- };
1568
+ this.DateRangePicker = DateRangePicker;
1575
1569
 
1576
1570
  return DateRangePicker;
1577
1571