fullcalendar.io-rails 2.3.2 → 2.4.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.
- checksums.yaml +4 -4
- data/lib/fullcalendar.io/rails/version.rb +1 -1
- data/vendor/assets/javascripts/fullcalendar.js +408 -116
- data/vendor/assets/javascripts/fullcalendar/gcal.js +2 -6
- data/vendor/assets/stylesheets/fullcalendar.css +1 -1
- data/vendor/assets/stylesheets/fullcalendar.print.css +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e95fa760c253b1bcbbdaacc80fd045d1126a39c
|
4
|
+
data.tar.gz: 44c65ae292b3c364da1454c5a7838185105f2a69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0aae9e839f7247dac108bb1b750543e22dc486f377ca34b70026670f2b7e103da8e57639158cab448d6ae6ddc9bfceccc469d43e07a6da7ee4b235fa1d2f2299
|
7
|
+
data.tar.gz: 28ae98115d58895d0f313f312194b4f9e293ba4e0ce6fab912d6df267ec9b7ab476b8dfffdf71ad44794a87dd9013b7787267dfcd829090812ad3ca07d5e6132
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* FullCalendar v2.
|
2
|
+
* FullCalendar v2.4.0
|
3
3
|
* Docs & License: http://fullcalendar.io/
|
4
4
|
* (c) 2015 Adam Shaw
|
5
5
|
*/
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
;;
|
20
20
|
|
21
|
-
var fc = $.fullCalendar = { version: "2.
|
21
|
+
var fc = $.fullCalendar = { version: "2.4.0" };
|
22
22
|
var fcViews = fc.views = {};
|
23
23
|
|
24
24
|
|
@@ -419,6 +419,7 @@ function isPrimaryMouseButton(ev) {
|
|
419
419
|
/* Geometry
|
420
420
|
----------------------------------------------------------------------------------------------------------------------*/
|
421
421
|
|
422
|
+
fc.intersectRects = intersectRects;
|
422
423
|
|
423
424
|
// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
|
424
425
|
function intersectRects(rect1, rect2) {
|
@@ -463,6 +464,90 @@ function diffPoints(point1, point2) {
|
|
463
464
|
}
|
464
465
|
|
465
466
|
|
467
|
+
/* Object Ordering by Field
|
468
|
+
----------------------------------------------------------------------------------------------------------------------*/
|
469
|
+
|
470
|
+
fc.parseFieldSpecs = parseFieldSpecs;
|
471
|
+
fc.compareByFieldSpecs = compareByFieldSpecs;
|
472
|
+
fc.compareByFieldSpec = compareByFieldSpec;
|
473
|
+
fc.flexibleCompare = flexibleCompare;
|
474
|
+
|
475
|
+
|
476
|
+
function parseFieldSpecs(input) {
|
477
|
+
var specs = [];
|
478
|
+
var tokens = [];
|
479
|
+
var i, token;
|
480
|
+
|
481
|
+
if (typeof input === 'string') {
|
482
|
+
tokens = input.split(/\s*,\s*/);
|
483
|
+
}
|
484
|
+
else if (typeof input === 'function') {
|
485
|
+
tokens = [ input ];
|
486
|
+
}
|
487
|
+
else if ($.isArray(input)) {
|
488
|
+
tokens = input;
|
489
|
+
}
|
490
|
+
|
491
|
+
for (i = 0; i < tokens.length; i++) {
|
492
|
+
token = tokens[i];
|
493
|
+
|
494
|
+
if (typeof token === 'string') {
|
495
|
+
specs.push(
|
496
|
+
token.charAt(0) == '-' ?
|
497
|
+
{ field: token.substring(1), order: -1 } :
|
498
|
+
{ field: token, order: 1 }
|
499
|
+
);
|
500
|
+
}
|
501
|
+
else if (typeof token === 'function') {
|
502
|
+
specs.push({ func: token });
|
503
|
+
}
|
504
|
+
}
|
505
|
+
|
506
|
+
return specs;
|
507
|
+
}
|
508
|
+
|
509
|
+
|
510
|
+
function compareByFieldSpecs(obj1, obj2, fieldSpecs) {
|
511
|
+
var i;
|
512
|
+
var cmp;
|
513
|
+
|
514
|
+
for (i = 0; i < fieldSpecs.length; i++) {
|
515
|
+
cmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i]);
|
516
|
+
if (cmp) {
|
517
|
+
return cmp;
|
518
|
+
}
|
519
|
+
}
|
520
|
+
|
521
|
+
return 0;
|
522
|
+
}
|
523
|
+
|
524
|
+
|
525
|
+
function compareByFieldSpec(obj1, obj2, fieldSpec) {
|
526
|
+
if (fieldSpec.func) {
|
527
|
+
return fieldSpec.func(obj1, obj2);
|
528
|
+
}
|
529
|
+
return flexibleCompare(obj1[fieldSpec.field], obj2[fieldSpec.field]) *
|
530
|
+
(fieldSpec.order || 1);
|
531
|
+
}
|
532
|
+
|
533
|
+
|
534
|
+
function flexibleCompare(a, b) {
|
535
|
+
if (!a && !b) {
|
536
|
+
return 0;
|
537
|
+
}
|
538
|
+
if (b == null) {
|
539
|
+
return -1;
|
540
|
+
}
|
541
|
+
if (a == null) {
|
542
|
+
return 1;
|
543
|
+
}
|
544
|
+
if ($.type(a) === 'string' || $.type(b) === 'string') {
|
545
|
+
return String(a).localeCompare(String(b));
|
546
|
+
}
|
547
|
+
return a - b;
|
548
|
+
}
|
549
|
+
|
550
|
+
|
466
551
|
/* FullCalendar-specific Misc Utilities
|
467
552
|
----------------------------------------------------------------------------------------------------------------------*/
|
468
553
|
|
@@ -512,6 +597,9 @@ function intersectionToSeg(subjectRange, constraintRange) {
|
|
512
597
|
----------------------------------------------------------------------------------------------------------------------*/
|
513
598
|
|
514
599
|
fc.computeIntervalUnit = computeIntervalUnit;
|
600
|
+
fc.divideRangeByDuration = divideRangeByDuration;
|
601
|
+
fc.divideDurationByDuration = divideDurationByDuration;
|
602
|
+
fc.multiplyDuration = multiplyDuration;
|
515
603
|
fc.durationHasTime = durationHasTime;
|
516
604
|
|
517
605
|
var dayIDs = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];
|
@@ -583,6 +671,55 @@ function computeRangeAs(unit, start, end) {
|
|
583
671
|
}
|
584
672
|
|
585
673
|
|
674
|
+
// Intelligently divides a range (specified by a start/end params) by a duration
|
675
|
+
function divideRangeByDuration(start, end, dur) {
|
676
|
+
var months;
|
677
|
+
|
678
|
+
if (durationHasTime(dur)) {
|
679
|
+
return (end - start) / dur;
|
680
|
+
}
|
681
|
+
months = dur.asMonths();
|
682
|
+
if (Math.abs(months) >= 1 && isInt(months)) {
|
683
|
+
return end.diff(start, 'months', true) / months;
|
684
|
+
}
|
685
|
+
return end.diff(start, 'days', true) / dur.asDays();
|
686
|
+
}
|
687
|
+
|
688
|
+
|
689
|
+
// Intelligently divides one duration by another
|
690
|
+
function divideDurationByDuration(dur1, dur2) {
|
691
|
+
var months1, months2;
|
692
|
+
|
693
|
+
if (durationHasTime(dur1) || durationHasTime(dur2)) {
|
694
|
+
return dur1 / dur2;
|
695
|
+
}
|
696
|
+
months1 = dur1.asMonths();
|
697
|
+
months2 = dur2.asMonths();
|
698
|
+
if (
|
699
|
+
Math.abs(months1) >= 1 && isInt(months1) &&
|
700
|
+
Math.abs(months2) >= 1 && isInt(months2)
|
701
|
+
) {
|
702
|
+
return months1 / months2;
|
703
|
+
}
|
704
|
+
return dur1.asDays() / dur2.asDays();
|
705
|
+
}
|
706
|
+
|
707
|
+
|
708
|
+
// Intelligently multiplies a duration by a number
|
709
|
+
function multiplyDuration(dur, n) {
|
710
|
+
var months;
|
711
|
+
|
712
|
+
if (durationHasTime(dur)) {
|
713
|
+
return moment.duration(dur * n);
|
714
|
+
}
|
715
|
+
months = dur.asMonths();
|
716
|
+
if (Math.abs(months) >= 1 && isInt(months)) {
|
717
|
+
return moment.duration({ months: months * n });
|
718
|
+
}
|
719
|
+
return moment.duration({ days: dur.asDays() * n });
|
720
|
+
}
|
721
|
+
|
722
|
+
|
586
723
|
// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms)
|
587
724
|
function durationHasTime(dur) {
|
588
725
|
return Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds());
|
@@ -600,6 +737,29 @@ function isTimeString(str) {
|
|
600
737
|
}
|
601
738
|
|
602
739
|
|
740
|
+
/* Logging and Debug
|
741
|
+
----------------------------------------------------------------------------------------------------------------------*/
|
742
|
+
|
743
|
+
fc.log = function() {
|
744
|
+
var console = window.console;
|
745
|
+
|
746
|
+
if (console && console.log) {
|
747
|
+
return console.log.apply(console, arguments);
|
748
|
+
}
|
749
|
+
};
|
750
|
+
|
751
|
+
fc.warn = function() {
|
752
|
+
var console = window.console;
|
753
|
+
|
754
|
+
if (console && console.warn) {
|
755
|
+
return console.warn.apply(console, arguments);
|
756
|
+
}
|
757
|
+
else {
|
758
|
+
return fc.log.apply(fc, arguments);
|
759
|
+
}
|
760
|
+
};
|
761
|
+
|
762
|
+
|
603
763
|
/* General Utilities
|
604
764
|
----------------------------------------------------------------------------------------------------------------------*/
|
605
765
|
|
@@ -1592,6 +1752,59 @@ Class.mixin = function(members) {
|
|
1592
1752
|
};
|
1593
1753
|
;;
|
1594
1754
|
|
1755
|
+
var Emitter = fc.Emitter = Class.extend({
|
1756
|
+
|
1757
|
+
callbackHash: null,
|
1758
|
+
|
1759
|
+
|
1760
|
+
on: function(name, callback) {
|
1761
|
+
this.getCallbacks(name).add(callback);
|
1762
|
+
return this; // for chaining
|
1763
|
+
},
|
1764
|
+
|
1765
|
+
|
1766
|
+
off: function(name, callback) {
|
1767
|
+
this.getCallbacks(name).remove(callback);
|
1768
|
+
return this; // for chaining
|
1769
|
+
},
|
1770
|
+
|
1771
|
+
|
1772
|
+
trigger: function(name) { // args...
|
1773
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
1774
|
+
|
1775
|
+
this.triggerWith(name, this, args);
|
1776
|
+
|
1777
|
+
return this; // for chaining
|
1778
|
+
},
|
1779
|
+
|
1780
|
+
|
1781
|
+
triggerWith: function(name, context, args) {
|
1782
|
+
var callbacks = this.getCallbacks(name);
|
1783
|
+
|
1784
|
+
callbacks.fireWith(context, args);
|
1785
|
+
|
1786
|
+
return this; // for chaining
|
1787
|
+
},
|
1788
|
+
|
1789
|
+
|
1790
|
+
getCallbacks: function(name) {
|
1791
|
+
var callbacks;
|
1792
|
+
|
1793
|
+
if (!this.callbackHash) {
|
1794
|
+
this.callbackHash = {};
|
1795
|
+
}
|
1796
|
+
|
1797
|
+
callbacks = this.callbackHash[name];
|
1798
|
+
if (!callbacks) {
|
1799
|
+
callbacks = this.callbackHash[name] = $.Callbacks();
|
1800
|
+
}
|
1801
|
+
|
1802
|
+
return callbacks;
|
1803
|
+
}
|
1804
|
+
|
1805
|
+
});
|
1806
|
+
;;
|
1807
|
+
|
1595
1808
|
/* A rectangular panel that is absolutely positioned over other content
|
1596
1809
|
------------------------------------------------------------------------------------------------------------------------
|
1597
1810
|
Options:
|
@@ -4389,6 +4602,21 @@ Grid.mixin({
|
|
4389
4602
|
}
|
4390
4603
|
|
4391
4604
|
return segs;
|
4605
|
+
},
|
4606
|
+
|
4607
|
+
|
4608
|
+
sortSegs: function(segs) {
|
4609
|
+
segs.sort(proxy(this, 'compareSegs'));
|
4610
|
+
},
|
4611
|
+
|
4612
|
+
|
4613
|
+
// A cmp function for determining which segments should take visual priority
|
4614
|
+
// DOES NOT WORK ON INVERTED BACKGROUND EVENTS because they have no eventStartMS/eventDurationMS
|
4615
|
+
compareSegs: function(seg1, seg2) {
|
4616
|
+
return seg1.eventStartMS - seg2.eventStartMS || // earlier events go first
|
4617
|
+
seg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first
|
4618
|
+
seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)
|
4619
|
+
compareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs);
|
4392
4620
|
}
|
4393
4621
|
|
4394
4622
|
});
|
@@ -4433,18 +4661,6 @@ function compareNormalRanges(range1, range2) {
|
|
4433
4661
|
}
|
4434
4662
|
|
4435
4663
|
|
4436
|
-
// A cmp function for determining which segments should take visual priority
|
4437
|
-
// DOES NOT WORK ON INVERTED BACKGROUND EVENTS because they have no eventStartMS/eventDurationMS
|
4438
|
-
function compareSegs(seg1, seg2) {
|
4439
|
-
return seg1.eventStartMS - seg2.eventStartMS || // earlier events go first
|
4440
|
-
seg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first
|
4441
|
-
seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)
|
4442
|
-
(seg1.event.title || '').localeCompare(seg2.event.title); // tie? alphabetically by title
|
4443
|
-
}
|
4444
|
-
|
4445
|
-
fc.compareSegs = compareSegs; // export
|
4446
|
-
|
4447
|
-
|
4448
4664
|
/* External-Dragging-Element Data
|
4449
4665
|
----------------------------------------------------------------------------------------------------------------------*/
|
4450
4666
|
|
@@ -5220,7 +5436,7 @@ DayGrid.mixin({
|
|
5220
5436
|
|
5221
5437
|
// Give preference to elements with certain criteria, so they have
|
5222
5438
|
// a chance to be closer to the top.
|
5223
|
-
|
5439
|
+
this.sortSegs(segs);
|
5224
5440
|
|
5225
5441
|
for (i = 0; i < segs.length; i++) {
|
5226
5442
|
seg = segs[i];
|
@@ -5621,7 +5837,7 @@ DayGrid.mixin({
|
|
5621
5837
|
);
|
5622
5838
|
|
5623
5839
|
// force an order because eventsToSegs doesn't guarantee one
|
5624
|
-
|
5840
|
+
this.sortSegs(segs);
|
5625
5841
|
|
5626
5842
|
return segs;
|
5627
5843
|
},
|
@@ -5673,7 +5889,8 @@ var TimeGrid = Grid.extend({
|
|
5673
5889
|
minTime: null, // Duration object that denotes the first visible time of any given day
|
5674
5890
|
maxTime: null, // Duration object that denotes the exclusive visible end time of any given day
|
5675
5891
|
colDates: null, // whole-day dates for each column. left to right
|
5676
|
-
|
5892
|
+
labelFormat: null, // formatting string for times running along vertical axis
|
5893
|
+
labelInterval: null, // duration of how often a label should be displayed for a slot
|
5677
5894
|
|
5678
5895
|
dayEls: null, // cells elements in the day-row background
|
5679
5896
|
slatEls: null, // elements running horizontally across all columns
|
@@ -5734,29 +5951,28 @@ var TimeGrid = Grid.extend({
|
|
5734
5951
|
var view = this.view;
|
5735
5952
|
var isRTL = this.isRTL;
|
5736
5953
|
var html = '';
|
5737
|
-
var slotNormal = this.slotDuration.asMinutes() % 15 === 0;
|
5738
5954
|
var slotTime = moment.duration(+this.minTime); // wish there was .clone() for durations
|
5739
5955
|
var slotDate; // will be on the view's first day, but we only care about its time
|
5740
|
-
var
|
5956
|
+
var isLabeled;
|
5741
5957
|
var axisHtml;
|
5742
5958
|
|
5743
5959
|
// Calculate the time for each slot
|
5744
5960
|
while (slotTime < this.maxTime) {
|
5745
|
-
slotDate = this.start.clone().time(slotTime); // will be in UTC but that's good
|
5746
|
-
|
5961
|
+
slotDate = this.start.clone().time(slotTime); // after .time() will be in UTC. but that's good, avoids DST issues
|
5962
|
+
isLabeled = isInt(divideDurationByDuration(slotTime, this.labelInterval));
|
5747
5963
|
|
5748
5964
|
axisHtml =
|
5749
5965
|
'<td class="fc-axis fc-time ' + view.widgetContentClass + '" ' + view.axisStyleAttr() + '>' +
|
5750
|
-
(
|
5966
|
+
(isLabeled ?
|
5751
5967
|
'<span>' + // for matchCellWidths
|
5752
|
-
htmlEscape(slotDate.format(this.
|
5968
|
+
htmlEscape(slotDate.format(this.labelFormat)) +
|
5753
5969
|
'</span>' :
|
5754
5970
|
''
|
5755
5971
|
) +
|
5756
5972
|
'</td>';
|
5757
5973
|
|
5758
5974
|
html +=
|
5759
|
-
'<tr ' + (
|
5975
|
+
'<tr ' + (isLabeled ? '' : 'class="fc-minor"') + '>' +
|
5760
5976
|
(!isRTL ? axisHtml : '') +
|
5761
5977
|
'<td class="' + view.widgetContentClass + '"/>' +
|
5762
5978
|
(isRTL ? axisHtml : '') +
|
@@ -5778,6 +5994,7 @@ var TimeGrid = Grid.extend({
|
|
5778
5994
|
var view = this.view;
|
5779
5995
|
var slotDuration = view.opt('slotDuration');
|
5780
5996
|
var snapDuration = view.opt('snapDuration');
|
5997
|
+
var input;
|
5781
5998
|
|
5782
5999
|
slotDuration = moment.duration(slotDuration);
|
5783
6000
|
snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;
|
@@ -5789,7 +6006,41 @@ var TimeGrid = Grid.extend({
|
|
5789
6006
|
this.minTime = moment.duration(view.opt('minTime'));
|
5790
6007
|
this.maxTime = moment.duration(view.opt('maxTime'));
|
5791
6008
|
|
5792
|
-
|
6009
|
+
// might be an array value (for TimelineView).
|
6010
|
+
// if so, getting the most granular entry (the last one probably).
|
6011
|
+
input = view.opt('slotLabelFormat');
|
6012
|
+
if ($.isArray(input)) {
|
6013
|
+
input = input[input.length - 1];
|
6014
|
+
}
|
6015
|
+
|
6016
|
+
this.labelFormat =
|
6017
|
+
input ||
|
6018
|
+
view.opt('axisFormat') || // deprecated
|
6019
|
+
view.opt('smallTimeFormat'); // the computed default
|
6020
|
+
|
6021
|
+
input = view.opt('slotLabelInterval');
|
6022
|
+
this.labelInterval = input ?
|
6023
|
+
moment.duration(input) :
|
6024
|
+
this.computeLabelInterval(slotDuration);
|
6025
|
+
},
|
6026
|
+
|
6027
|
+
|
6028
|
+
// Computes an automatic value for slotLabelInterval
|
6029
|
+
computeLabelInterval: function(slotDuration) {
|
6030
|
+
var i;
|
6031
|
+
var labelInterval;
|
6032
|
+
var slotsPerLabel;
|
6033
|
+
|
6034
|
+
// find the smallest stock label interval that results in more than one slots-per-label
|
6035
|
+
for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
|
6036
|
+
labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]);
|
6037
|
+
slotsPerLabel = divideDurationByDuration(labelInterval, slotDuration);
|
6038
|
+
if (isInt(slotsPerLabel) && slotsPerLabel > 1) {
|
6039
|
+
return labelInterval;
|
6040
|
+
}
|
6041
|
+
}
|
6042
|
+
|
6043
|
+
return moment.duration(slotDuration); // fall back. clone
|
5793
6044
|
},
|
5794
6045
|
|
5795
6046
|
|
@@ -6209,7 +6460,7 @@ TimeGrid.mixin({
|
|
6209
6460
|
|
6210
6461
|
for (col = 0; col < segCols.length; col++) { // iterate each column grouping
|
6211
6462
|
colSegs = segCols[col];
|
6212
|
-
placeSlotSegs(colSegs); // compute horizontal coordinates, z-index's, and reorder the array
|
6463
|
+
this.placeSlotSegs(colSegs); // compute horizontal coordinates, z-index's, and reorder the array
|
6213
6464
|
|
6214
6465
|
containerEl = $('<div class="fc-event-container"/>');
|
6215
6466
|
|
@@ -6235,6 +6486,74 @@ TimeGrid.mixin({
|
|
6235
6486
|
},
|
6236
6487
|
|
6237
6488
|
|
6489
|
+
// Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
|
6490
|
+
// NOTE: Also reorders the given array by date!
|
6491
|
+
placeSlotSegs: function(segs) {
|
6492
|
+
var levels;
|
6493
|
+
var level0;
|
6494
|
+
var i;
|
6495
|
+
|
6496
|
+
this.sortSegs(segs); // order by date
|
6497
|
+
levels = buildSlotSegLevels(segs);
|
6498
|
+
computeForwardSlotSegs(levels);
|
6499
|
+
|
6500
|
+
if ((level0 = levels[0])) {
|
6501
|
+
|
6502
|
+
for (i = 0; i < level0.length; i++) {
|
6503
|
+
computeSlotSegPressures(level0[i]);
|
6504
|
+
}
|
6505
|
+
|
6506
|
+
for (i = 0; i < level0.length; i++) {
|
6507
|
+
this.computeSlotSegCoords(level0[i], 0, 0);
|
6508
|
+
}
|
6509
|
+
}
|
6510
|
+
},
|
6511
|
+
|
6512
|
+
|
6513
|
+
// Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
|
6514
|
+
// from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
|
6515
|
+
// seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
|
6516
|
+
//
|
6517
|
+
// The segment might be part of a "series", which means consecutive segments with the same pressure
|
6518
|
+
// who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
|
6519
|
+
// segments behind this one in the current series, and `seriesBackwardCoord` is the starting
|
6520
|
+
// coordinate of the first segment in the series.
|
6521
|
+
computeSlotSegCoords: function(seg, seriesBackwardPressure, seriesBackwardCoord) {
|
6522
|
+
var forwardSegs = seg.forwardSegs;
|
6523
|
+
var i;
|
6524
|
+
|
6525
|
+
if (seg.forwardCoord === undefined) { // not already computed
|
6526
|
+
|
6527
|
+
if (!forwardSegs.length) {
|
6528
|
+
|
6529
|
+
// if there are no forward segments, this segment should butt up against the edge
|
6530
|
+
seg.forwardCoord = 1;
|
6531
|
+
}
|
6532
|
+
else {
|
6533
|
+
|
6534
|
+
// sort highest pressure first
|
6535
|
+
this.sortForwardSlotSegs(forwardSegs);
|
6536
|
+
|
6537
|
+
// this segment's forwardCoord will be calculated from the backwardCoord of the
|
6538
|
+
// highest-pressure forward segment.
|
6539
|
+
this.computeSlotSegCoords(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
|
6540
|
+
seg.forwardCoord = forwardSegs[0].backwardCoord;
|
6541
|
+
}
|
6542
|
+
|
6543
|
+
// calculate the backwardCoord from the forwardCoord. consider the series
|
6544
|
+
seg.backwardCoord = seg.forwardCoord -
|
6545
|
+
(seg.forwardCoord - seriesBackwardCoord) / // available width for series
|
6546
|
+
(seriesBackwardPressure + 1); // # of segments in the series
|
6547
|
+
|
6548
|
+
// use this segment's coordinates to computed the coordinates of the less-pressurized
|
6549
|
+
// forward segments
|
6550
|
+
for (i=0; i<forwardSegs.length; i++) {
|
6551
|
+
this.computeSlotSegCoords(forwardSegs[i], 0, seg.forwardCoord);
|
6552
|
+
}
|
6553
|
+
}
|
6554
|
+
},
|
6555
|
+
|
6556
|
+
|
6238
6557
|
// Refreshes the CSS top/bottom coordinates for each segment element. Probably after a window resize/zoom.
|
6239
6558
|
// Repositions business hours segs too, so not just for events. Maybe shouldn't be here.
|
6240
6559
|
updateSegVerticals: function() {
|
@@ -6396,33 +6715,25 @@ TimeGrid.mixin({
|
|
6396
6715
|
}
|
6397
6716
|
|
6398
6717
|
return segCols;
|
6399
|
-
}
|
6400
|
-
|
6401
|
-
});
|
6402
|
-
|
6403
|
-
|
6404
|
-
// Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
|
6405
|
-
// NOTE: Also reorders the given array by date!
|
6406
|
-
function placeSlotSegs(segs) {
|
6407
|
-
var levels;
|
6408
|
-
var level0;
|
6409
|
-
var i;
|
6718
|
+
},
|
6410
6719
|
|
6411
|
-
segs.sort(compareSegs); // order by date
|
6412
|
-
levels = buildSlotSegLevels(segs);
|
6413
|
-
computeForwardSlotSegs(levels);
|
6414
6720
|
|
6415
|
-
|
6721
|
+
sortForwardSlotSegs: function(forwardSegs) {
|
6722
|
+
forwardSegs.sort(proxy(this, 'compareForwardSlotSegs'));
|
6723
|
+
},
|
6416
6724
|
|
6417
|
-
for (i = 0; i < level0.length; i++) {
|
6418
|
-
computeSlotSegPressures(level0[i]);
|
6419
|
-
}
|
6420
6725
|
|
6421
|
-
|
6422
|
-
|
6423
|
-
|
6726
|
+
// A cmp function for determining which forward segment to rely on more when computing coordinates.
|
6727
|
+
compareForwardSlotSegs: function(seg1, seg2) {
|
6728
|
+
// put higher-pressure first
|
6729
|
+
return seg2.forwardPressure - seg1.forwardPressure ||
|
6730
|
+
// put segments that are closer to initial edge first (and favor ones with no coords yet)
|
6731
|
+
(seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
|
6732
|
+
// do normal sorting...
|
6733
|
+
this.compareSegs(seg1, seg2);
|
6424
6734
|
}
|
6425
|
-
|
6735
|
+
|
6736
|
+
});
|
6426
6737
|
|
6427
6738
|
|
6428
6739
|
// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
|
@@ -6501,50 +6812,6 @@ function computeSlotSegPressures(seg) {
|
|
6501
6812
|
}
|
6502
6813
|
|
6503
6814
|
|
6504
|
-
// Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
|
6505
|
-
// from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
|
6506
|
-
// seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
|
6507
|
-
//
|
6508
|
-
// The segment might be part of a "series", which means consecutive segments with the same pressure
|
6509
|
-
// who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
|
6510
|
-
// segments behind this one in the current series, and `seriesBackwardCoord` is the starting
|
6511
|
-
// coordinate of the first segment in the series.
|
6512
|
-
function computeSlotSegCoords(seg, seriesBackwardPressure, seriesBackwardCoord) {
|
6513
|
-
var forwardSegs = seg.forwardSegs;
|
6514
|
-
var i;
|
6515
|
-
|
6516
|
-
if (seg.forwardCoord === undefined) { // not already computed
|
6517
|
-
|
6518
|
-
if (!forwardSegs.length) {
|
6519
|
-
|
6520
|
-
// if there are no forward segments, this segment should butt up against the edge
|
6521
|
-
seg.forwardCoord = 1;
|
6522
|
-
}
|
6523
|
-
else {
|
6524
|
-
|
6525
|
-
// sort highest pressure first
|
6526
|
-
forwardSegs.sort(compareForwardSlotSegs);
|
6527
|
-
|
6528
|
-
// this segment's forwardCoord will be calculated from the backwardCoord of the
|
6529
|
-
// highest-pressure forward segment.
|
6530
|
-
computeSlotSegCoords(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
|
6531
|
-
seg.forwardCoord = forwardSegs[0].backwardCoord;
|
6532
|
-
}
|
6533
|
-
|
6534
|
-
// calculate the backwardCoord from the forwardCoord. consider the series
|
6535
|
-
seg.backwardCoord = seg.forwardCoord -
|
6536
|
-
(seg.forwardCoord - seriesBackwardCoord) / // available width for series
|
6537
|
-
(seriesBackwardPressure + 1); // # of segments in the series
|
6538
|
-
|
6539
|
-
// use this segment's coordinates to computed the coordinates of the less-pressurized
|
6540
|
-
// forward segments
|
6541
|
-
for (i=0; i<forwardSegs.length; i++) {
|
6542
|
-
computeSlotSegCoords(forwardSegs[i], 0, seg.forwardCoord);
|
6543
|
-
}
|
6544
|
-
}
|
6545
|
-
}
|
6546
|
-
|
6547
|
-
|
6548
6815
|
// Find all the segments in `otherSegs` that vertically collide with `seg`.
|
6549
6816
|
// Append into an optionally-supplied `results` array and return.
|
6550
6817
|
function computeSlotSegCollisions(seg, otherSegs, results) {
|
@@ -6565,17 +6832,6 @@ function isSlotSegCollision(seg1, seg2) {
|
|
6565
6832
|
return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
|
6566
6833
|
}
|
6567
6834
|
|
6568
|
-
|
6569
|
-
// A cmp function for determining which forward segment to rely on more when computing coordinates.
|
6570
|
-
function compareForwardSlotSegs(seg1, seg2) {
|
6571
|
-
// put higher-pressure first
|
6572
|
-
return seg2.forwardPressure - seg1.forwardPressure ||
|
6573
|
-
// put segments that are closer to initial edge first (and favor ones with no coords yet)
|
6574
|
-
(seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
|
6575
|
-
// do normal sorting...
|
6576
|
-
compareSegs(seg1, seg2);
|
6577
|
-
}
|
6578
|
-
|
6579
6835
|
;;
|
6580
6836
|
|
6581
6837
|
/* An abstract class from which other views inherit from
|
@@ -6610,6 +6866,8 @@ var View = fc.View = Class.extend({
|
|
6610
6866
|
isRTL: false,
|
6611
6867
|
isSelected: false, // boolean whether a range of time is user-selected or not
|
6612
6868
|
|
6869
|
+
eventOrderSpecs: null, // criteria for ordering events when they have same date/time
|
6870
|
+
|
6613
6871
|
// subclasses can optionally use a scroll container
|
6614
6872
|
scrollerEl: null, // the element that will most likely scroll when content is too tall
|
6615
6873
|
scrollTop: null, // cached vertical scroll value
|
@@ -6639,6 +6897,8 @@ var View = fc.View = Class.extend({
|
|
6639
6897
|
this.initHiddenDays();
|
6640
6898
|
this.isRTL = this.opt('isRTL');
|
6641
6899
|
|
6900
|
+
this.eventOrderSpecs = parseFieldSpecs(this.opt('eventOrder'));
|
6901
|
+
|
6642
6902
|
this.documentMousedownProxy = proxy(this, 'documentMousedown');
|
6643
6903
|
|
6644
6904
|
this.initialize();
|
@@ -7776,6 +8036,9 @@ var Calendar = fc.Calendar = Class.extend({
|
|
7776
8036
|
});
|
7777
8037
|
|
7778
8038
|
|
8039
|
+
Calendar.mixin(Emitter);
|
8040
|
+
|
8041
|
+
|
7779
8042
|
function Calendar_constructor(element, overrides) {
|
7780
8043
|
var t = this;
|
7781
8044
|
|
@@ -8409,12 +8672,14 @@ function Calendar_constructor(element, overrides) {
|
|
8409
8672
|
}
|
8410
8673
|
|
8411
8674
|
|
8412
|
-
function trigger(name, thisObj) {
|
8675
|
+
function trigger(name, thisObj) { // overrides the Emitter's trigger method :(
|
8676
|
+
var args = Array.prototype.slice.call(arguments, 2);
|
8677
|
+
|
8678
|
+
thisObj = thisObj || _element;
|
8679
|
+
this.triggerWith(name, thisObj, args); // Emitter's method
|
8680
|
+
|
8413
8681
|
if (options[name]) {
|
8414
|
-
return options[name].apply(
|
8415
|
-
thisObj || _element,
|
8416
|
-
Array.prototype.slice.call(arguments, 2)
|
8417
|
-
);
|
8682
|
+
return options[name].apply(thisObj, args);
|
8418
8683
|
}
|
8419
8684
|
}
|
8420
8685
|
|
@@ -8501,6 +8766,8 @@ Calendar.defaults = {
|
|
8501
8766
|
|
8502
8767
|
dropAccept: '*',
|
8503
8768
|
|
8769
|
+
eventOrder: 'title',
|
8770
|
+
|
8504
8771
|
eventLimit: false,
|
8505
8772
|
eventLimitText: 'more',
|
8506
8773
|
eventLimitClick: 'popover',
|
@@ -8796,6 +9063,7 @@ function Header(calendar, options) {
|
|
8796
9063
|
var groupEl;
|
8797
9064
|
|
8798
9065
|
$.each(this.split(','), function(j, buttonName) {
|
9066
|
+
var customButtonProps;
|
8799
9067
|
var viewSpec;
|
8800
9068
|
var buttonClick;
|
8801
9069
|
var overrideText; // text explicitly set by calendar's constructor options. overcomes icons
|
@@ -8804,16 +9072,23 @@ function Header(calendar, options) {
|
|
8804
9072
|
var normalIcon;
|
8805
9073
|
var innerHtml;
|
8806
9074
|
var classes;
|
8807
|
-
var button;
|
9075
|
+
var button; // the element
|
8808
9076
|
|
8809
9077
|
if (buttonName == 'title') {
|
8810
9078
|
groupChildren = groupChildren.add($('<h2> </h2>')); // we always want it to take up height
|
8811
9079
|
isOnlyButtons = false;
|
8812
9080
|
}
|
8813
9081
|
else {
|
8814
|
-
|
8815
|
-
|
8816
|
-
|
9082
|
+
if ((customButtonProps = (calendar.options.customButtons || {})[buttonName])) {
|
9083
|
+
buttonClick = function(ev) {
|
9084
|
+
if (customButtonProps.click) {
|
9085
|
+
customButtonProps.click.call(button[0], ev);
|
9086
|
+
}
|
9087
|
+
};
|
9088
|
+
overrideText = ''; // icons will override text
|
9089
|
+
defaultText = customButtonProps.text;
|
9090
|
+
}
|
9091
|
+
else if ((viewSpec = calendar.getViewSpec(buttonName))) {
|
8817
9092
|
buttonClick = function() {
|
8818
9093
|
calendar.changeView(buttonName);
|
8819
9094
|
};
|
@@ -8831,8 +9106,15 @@ function Header(calendar, options) {
|
|
8831
9106
|
|
8832
9107
|
if (buttonClick) {
|
8833
9108
|
|
8834
|
-
themeIcon =
|
8835
|
-
|
9109
|
+
themeIcon =
|
9110
|
+
customButtonProps ?
|
9111
|
+
customButtonProps.themeIcon :
|
9112
|
+
options.themeButtonIcons[buttonName];
|
9113
|
+
|
9114
|
+
normalIcon =
|
9115
|
+
customButtonProps ?
|
9116
|
+
customButtonProps.icon :
|
9117
|
+
options.buttonIcons[buttonName];
|
8836
9118
|
|
8837
9119
|
if (overrideText) {
|
8838
9120
|
innerHtml = htmlEscape(overrideText);
|
@@ -8858,11 +9140,11 @@ function Header(calendar, options) {
|
|
8858
9140
|
innerHtml +
|
8859
9141
|
'</button>'
|
8860
9142
|
)
|
8861
|
-
.click(function() {
|
9143
|
+
.click(function(ev) {
|
8862
9144
|
// don't process clicks for disabled buttons
|
8863
9145
|
if (!button.hasClass(tm + '-state-disabled')) {
|
8864
9146
|
|
8865
|
-
buttonClick();
|
9147
|
+
buttonClick(ev);
|
8866
9148
|
|
8867
9149
|
// after the click action, if the button becomes the "active" tab, or disabled,
|
8868
9150
|
// it should never have a hover class, so remove it now.
|
@@ -10851,6 +11133,16 @@ var AgendaView = View.extend({
|
|
10851
11133
|
|
10852
11134
|
var AGENDA_ALL_DAY_EVENT_LIMIT = 5;
|
10853
11135
|
|
11136
|
+
// potential nice values for the slot-duration and interval-duration
|
11137
|
+
// from largest to smallest
|
11138
|
+
var AGENDA_STOCK_SUB_DURATIONS = [
|
11139
|
+
{ hours: 1 },
|
11140
|
+
{ minutes: 30 },
|
11141
|
+
{ minutes: 15 },
|
11142
|
+
{ seconds: 30 },
|
11143
|
+
{ seconds: 15 }
|
11144
|
+
];
|
11145
|
+
|
10854
11146
|
fcViews.agenda = {
|
10855
11147
|
'class': AgendaView,
|
10856
11148
|
defaults: {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* FullCalendar v2.
|
2
|
+
* FullCalendar v2.4.0 Google Calendar Plugin
|
3
3
|
* Docs & License: http://fullcalendar.io/
|
4
4
|
* (c) 2015 Adam Shaw
|
5
5
|
*/
|
@@ -80,17 +80,13 @@ function transformOptions(sourceOptions, start, end, timezone, calendar) {
|
|
80
80
|
|
81
81
|
function reportError(message, apiErrorObjs) {
|
82
82
|
var errorObjs = apiErrorObjs || [ { message: message } ]; // to be passed into error handlers
|
83
|
-
var consoleObj = window.console;
|
84
|
-
var consoleWarnFunc = consoleObj ? (consoleObj.warn || consoleObj.log) : null;
|
85
83
|
|
86
84
|
// call error handlers
|
87
85
|
(sourceOptions.googleCalendarError || $.noop).apply(calendar, errorObjs);
|
88
86
|
(calendar.options.googleCalendarError || $.noop).apply(calendar, errorObjs);
|
89
87
|
|
90
88
|
// print error to debug console
|
91
|
-
|
92
|
-
consoleWarnFunc.apply(consoleObj, [ message ].concat(apiErrorObjs || []));
|
93
|
-
}
|
89
|
+
fc.warn.apply(null, [ message ].concat(apiErrorObjs || []));
|
94
90
|
}
|
95
91
|
|
96
92
|
if (!apiKey) {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fullcalendar.io-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dbackowski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jquery-rails
|