fullcalendar-rails 3.0.0.0 → 3.1.0.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-rails/version.rb +1 -1
- data/vendor/assets/javascripts/fullcalendar.js +1588 -811
- data/vendor/assets/javascripts/fullcalendar/gcal.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/af.js +1 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ar-dz.js +1 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ar-ly.js +1 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ar-ma.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ar-sa.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/ar-tn.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ar.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/bg.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ca.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/cs.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/da.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/de-at.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/de.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/el.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/en-au.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/en-ca.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/en-gb.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/en-ie.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/en-nz.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/es-do.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/es.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/eu.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/fa.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/fi.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/fr-ca.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/fr-ch.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/fr.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/gl.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/he.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/hi.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/hr.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/hu.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/id.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/is.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/it.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ja.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/kk.js +1 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ko.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/lb.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/lt.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/lv.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/mk.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ms-my.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ms.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/nb.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/nl-be.js +1 -0
- data/vendor/assets/javascripts/fullcalendar/lang/nl.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/nn.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/pl.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/pt-br.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/pt.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ro.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/ru.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/sk.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/sl.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/sr-cyrl.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/sr.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/sv.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/th.js +1 -1
- data/vendor/assets/javascripts/fullcalendar/lang/tr.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/uk.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/vi.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/zh-cn.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/lang/zh-tw.js +0 -0
- data/vendor/assets/javascripts/fullcalendar/locale-all.js +5 -5
- data/vendor/assets/stylesheets/fullcalendar.css +9 -2
- data/vendor/assets/stylesheets/fullcalendar.print.css +6 -6
- metadata +8 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 101da80d21194928e277041d77169ca0c69db33c
|
|
4
|
+
data.tar.gz: b1d67a1680789432aff809f3323c9490fd29cbdb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9fed2cf5ce778966801097161c8b1cae067ea4eaf943df6dea06bf5ecba9ffe1ae25ca618c4dae0bb62321d52ee73c6f2c3300aaee91e00261b7184c605ad93a
|
|
7
|
+
data.tar.gz: 21a423f82fc784a1c6095e94e82f0ab06d415acb760b4138d069939b6766fe6f1003437917bfd4c15edaac10c4f8a30e0f311b6f0ee31e3129bd3d3ca71719c2
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* FullCalendar v3.
|
|
2
|
+
* FullCalendar v3.1.0
|
|
3
3
|
* Docs & License: http://fullcalendar.io/
|
|
4
4
|
* (c) 2016 Adam Shaw
|
|
5
5
|
*/
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
;;
|
|
20
20
|
|
|
21
21
|
var FC = $.fullCalendar = {
|
|
22
|
-
version: "3.
|
|
23
|
-
internalApiVersion:
|
|
22
|
+
version: "3.1.0",
|
|
23
|
+
internalApiVersion: 7
|
|
24
24
|
};
|
|
25
25
|
var fcViews = FC.views = {};
|
|
26
26
|
|
|
@@ -53,13 +53,14 @@ $.fn.fullCalendar = function(options) {
|
|
|
53
53
|
calendar.render();
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
return res;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
var complexOptions = [ // names of options that are objects whose properties should be combined
|
|
62
62
|
'header',
|
|
63
|
+
'footer',
|
|
63
64
|
'buttonText',
|
|
64
65
|
'buttonIcons',
|
|
65
66
|
'themeButtonIcons'
|
|
@@ -848,6 +849,7 @@ function createObject(proto) {
|
|
|
848
849
|
f.prototype = proto;
|
|
849
850
|
return new f();
|
|
850
851
|
}
|
|
852
|
+
FC.createObject = createObject;
|
|
851
853
|
|
|
852
854
|
|
|
853
855
|
function copyOwnProps(src, dest) {
|
|
@@ -1004,20 +1006,6 @@ function debounce(func, wait, immediate) {
|
|
|
1004
1006
|
};
|
|
1005
1007
|
}
|
|
1006
1008
|
|
|
1007
|
-
|
|
1008
|
-
// HACK around jQuery's now A+ promises: execute callback synchronously if already resolved.
|
|
1009
|
-
// thenFunc shouldn't accept args.
|
|
1010
|
-
// similar to whenResources in Scheduler plugin.
|
|
1011
|
-
function syncThen(promise, thenFunc) {
|
|
1012
|
-
// not a promise, or an already-resolved promise?
|
|
1013
|
-
if (!promise || !promise.then || promise.state() === 'resolved') {
|
|
1014
|
-
return $.when(thenFunc()); // resolve immediately
|
|
1015
|
-
}
|
|
1016
|
-
else if (thenFunc) {
|
|
1017
|
-
return promise.then(thenFunc);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
1009
|
;;
|
|
1022
1010
|
|
|
1023
1011
|
/*
|
|
@@ -1574,6 +1562,49 @@ function chunkFormatString(formatStr) {
|
|
|
1574
1562
|
return chunks;
|
|
1575
1563
|
}
|
|
1576
1564
|
|
|
1565
|
+
|
|
1566
|
+
// Misc Utils
|
|
1567
|
+
// -------------------------------------------------------------------------------------------------
|
|
1568
|
+
|
|
1569
|
+
|
|
1570
|
+
// granularity only goes up until day
|
|
1571
|
+
// TODO: unify with similarUnitMap
|
|
1572
|
+
var tokenGranularities = {
|
|
1573
|
+
Y: { value: 1, unit: 'year' },
|
|
1574
|
+
M: { value: 2, unit: 'month' },
|
|
1575
|
+
W: { value: 3, unit: 'week' },
|
|
1576
|
+
w: { value: 3, unit: 'week' },
|
|
1577
|
+
D: { value: 4, unit: 'day' }, // day of month
|
|
1578
|
+
d: { value: 4, unit: 'day' } // day of week
|
|
1579
|
+
};
|
|
1580
|
+
|
|
1581
|
+
// returns a unit string, either 'year', 'month', 'day', or null
|
|
1582
|
+
// for the most granular formatting token in the string.
|
|
1583
|
+
FC.queryMostGranularFormatUnit = function(formatStr) {
|
|
1584
|
+
var chunks = getFormatStringChunks(formatStr);
|
|
1585
|
+
var i, chunk;
|
|
1586
|
+
var candidate;
|
|
1587
|
+
var best;
|
|
1588
|
+
|
|
1589
|
+
for (i = 0; i < chunks.length; i++) {
|
|
1590
|
+
chunk = chunks[i];
|
|
1591
|
+
if (chunk.token) {
|
|
1592
|
+
candidate = tokenGranularities[chunk.token.charAt(0)];
|
|
1593
|
+
if (candidate) {
|
|
1594
|
+
if (!best || candidate.value > best.value) {
|
|
1595
|
+
best = candidate;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
if (best) {
|
|
1602
|
+
return best.unit;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
return null;
|
|
1606
|
+
};
|
|
1607
|
+
|
|
1577
1608
|
;;
|
|
1578
1609
|
|
|
1579
1610
|
FC.Class = Class; // export
|
|
@@ -1638,6 +1669,201 @@ function mixIntoClass(theClass, members) {
|
|
|
1638
1669
|
}
|
|
1639
1670
|
;;
|
|
1640
1671
|
|
|
1672
|
+
/*
|
|
1673
|
+
Wrap jQuery's Deferred Promise object to be slightly more Promise/A+ compliant.
|
|
1674
|
+
With the added non-standard feature of synchronously executing handlers on resolved promises,
|
|
1675
|
+
which doesn't always happen otherwise (esp with nested .then handlers!?),
|
|
1676
|
+
so, this makes things a lot easier, esp because jQuery 3 changed the synchronicity for Deferred objects.
|
|
1677
|
+
|
|
1678
|
+
TODO: write tests and more comments
|
|
1679
|
+
*/
|
|
1680
|
+
|
|
1681
|
+
function Promise(executor) {
|
|
1682
|
+
var deferred = $.Deferred();
|
|
1683
|
+
var promise = deferred.promise();
|
|
1684
|
+
|
|
1685
|
+
if (typeof executor === 'function') {
|
|
1686
|
+
executor(
|
|
1687
|
+
function(value) { // resolve
|
|
1688
|
+
if (Promise.immediate) {
|
|
1689
|
+
promise._value = value;
|
|
1690
|
+
}
|
|
1691
|
+
deferred.resolve(value);
|
|
1692
|
+
},
|
|
1693
|
+
function() { // reject
|
|
1694
|
+
deferred.reject();
|
|
1695
|
+
}
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
if (Promise.immediate) {
|
|
1700
|
+
var origThen = promise.then;
|
|
1701
|
+
|
|
1702
|
+
promise.then = function(onFulfilled, onRejected) {
|
|
1703
|
+
var state = promise.state();
|
|
1704
|
+
|
|
1705
|
+
if (state === 'resolved') {
|
|
1706
|
+
if (typeof onFulfilled === 'function') {
|
|
1707
|
+
return Promise.resolve(onFulfilled(promise._value));
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
else if (state === 'rejected') {
|
|
1711
|
+
if (typeof onRejected === 'function') {
|
|
1712
|
+
onRejected();
|
|
1713
|
+
return promise; // already rejected
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
return origThen.call(promise, onFulfilled, onRejected);
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
return promise; // instanceof Promise will break :( TODO: make Promise a real class
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
FC.Promise = Promise;
|
|
1725
|
+
|
|
1726
|
+
Promise.immediate = true;
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
Promise.resolve = function(value) {
|
|
1730
|
+
if (value && typeof value.resolve === 'function') {
|
|
1731
|
+
return value.promise();
|
|
1732
|
+
}
|
|
1733
|
+
if (value && typeof value.then === 'function') {
|
|
1734
|
+
return value;
|
|
1735
|
+
}
|
|
1736
|
+
else {
|
|
1737
|
+
var deferred = $.Deferred().resolve(value);
|
|
1738
|
+
var promise = deferred.promise();
|
|
1739
|
+
|
|
1740
|
+
if (Promise.immediate) {
|
|
1741
|
+
var origThen = promise.then;
|
|
1742
|
+
|
|
1743
|
+
promise._value = value;
|
|
1744
|
+
|
|
1745
|
+
promise.then = function(onFulfilled, onRejected) {
|
|
1746
|
+
if (typeof onFulfilled === 'function') {
|
|
1747
|
+
return Promise.resolve(onFulfilled(value));
|
|
1748
|
+
}
|
|
1749
|
+
return origThen.call(promise, onFulfilled, onRejected);
|
|
1750
|
+
};
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
return promise;
|
|
1754
|
+
}
|
|
1755
|
+
};
|
|
1756
|
+
|
|
1757
|
+
|
|
1758
|
+
Promise.reject = function() {
|
|
1759
|
+
return $.Deferred().reject().promise();
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
Promise.all = function(inputs) {
|
|
1764
|
+
var hasAllValues = false;
|
|
1765
|
+
var values;
|
|
1766
|
+
var i, input;
|
|
1767
|
+
|
|
1768
|
+
if (Promise.immediate) {
|
|
1769
|
+
hasAllValues = true;
|
|
1770
|
+
values = [];
|
|
1771
|
+
|
|
1772
|
+
for (i = 0; i < inputs.length; i++) {
|
|
1773
|
+
input = inputs[i];
|
|
1774
|
+
|
|
1775
|
+
if (input && typeof input.state === 'function' && input.state() === 'resolved' && ('_value' in input)) {
|
|
1776
|
+
values.push(input._value);
|
|
1777
|
+
}
|
|
1778
|
+
else if (input && typeof input.then === 'function') {
|
|
1779
|
+
hasAllValues = false;
|
|
1780
|
+
break;
|
|
1781
|
+
}
|
|
1782
|
+
else {
|
|
1783
|
+
values.push(input);
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
if (hasAllValues) {
|
|
1789
|
+
return Promise.resolve(values);
|
|
1790
|
+
}
|
|
1791
|
+
else {
|
|
1792
|
+
return $.when.apply($.when, inputs).then(function() {
|
|
1793
|
+
return $.when($.makeArray(arguments));
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
|
|
1798
|
+
;;
|
|
1799
|
+
|
|
1800
|
+
// TODO: write tests and clean up code
|
|
1801
|
+
|
|
1802
|
+
function TaskQueue(debounceWait) {
|
|
1803
|
+
var q = []; // array of runFuncs
|
|
1804
|
+
|
|
1805
|
+
function addTask(taskFunc) {
|
|
1806
|
+
return new Promise(function(resolve) {
|
|
1807
|
+
|
|
1808
|
+
// should run this function when it's taskFunc's turn to run.
|
|
1809
|
+
// responsible for popping itself off the queue.
|
|
1810
|
+
var runFunc = function() {
|
|
1811
|
+
Promise.resolve(taskFunc()) // result might be async, coerce to promise
|
|
1812
|
+
.then(resolve) // resolve TaskQueue::push's promise, for the caller. will receive result of taskFunc.
|
|
1813
|
+
.then(function() {
|
|
1814
|
+
q.shift(); // pop itself off
|
|
1815
|
+
|
|
1816
|
+
// run the next task, if any
|
|
1817
|
+
if (q.length) {
|
|
1818
|
+
q[0]();
|
|
1819
|
+
}
|
|
1820
|
+
});
|
|
1821
|
+
};
|
|
1822
|
+
|
|
1823
|
+
// always put the task at the end of the queue, BEFORE running the task
|
|
1824
|
+
q.push(runFunc);
|
|
1825
|
+
|
|
1826
|
+
// if it's the only task in the queue, run immediately
|
|
1827
|
+
if (q.length === 1) {
|
|
1828
|
+
runFunc();
|
|
1829
|
+
}
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
this.add = // potentially debounce, for the public method
|
|
1834
|
+
typeof debounceWait === 'number' ?
|
|
1835
|
+
debounce(addTask, debounceWait) :
|
|
1836
|
+
addTask; // if not a number (null/undefined/false), no debounce at all
|
|
1837
|
+
|
|
1838
|
+
this.addQuickly = addTask; // guaranteed no debounce
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
FC.TaskQueue = TaskQueue;
|
|
1842
|
+
|
|
1843
|
+
/*
|
|
1844
|
+
q = new TaskQueue();
|
|
1845
|
+
|
|
1846
|
+
function work(i) {
|
|
1847
|
+
return q.push(function() {
|
|
1848
|
+
trigger();
|
|
1849
|
+
console.log('work' + i);
|
|
1850
|
+
});
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
var cnt = 0;
|
|
1854
|
+
|
|
1855
|
+
function trigger() {
|
|
1856
|
+
if (cnt < 5) {
|
|
1857
|
+
cnt++;
|
|
1858
|
+
work(cnt);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
work(9);
|
|
1863
|
+
*/
|
|
1864
|
+
|
|
1865
|
+
;;
|
|
1866
|
+
|
|
1641
1867
|
var EmitterMixin = FC.EmitterMixin = {
|
|
1642
1868
|
|
|
1643
1869
|
// jQuery-ification via $(this) allows a non-DOM object to have
|
|
@@ -1645,7 +1871,18 @@ var EmitterMixin = FC.EmitterMixin = {
|
|
|
1645
1871
|
|
|
1646
1872
|
|
|
1647
1873
|
on: function(types, handler) {
|
|
1874
|
+
$(this).on(types, this._prepareIntercept(handler));
|
|
1875
|
+
return this; // for chaining
|
|
1876
|
+
},
|
|
1877
|
+
|
|
1878
|
+
|
|
1879
|
+
one: function(types, handler) {
|
|
1880
|
+
$(this).one(types, this._prepareIntercept(handler));
|
|
1881
|
+
return this; // for chaining
|
|
1882
|
+
},
|
|
1883
|
+
|
|
1648
1884
|
|
|
1885
|
+
_prepareIntercept: function(handler) {
|
|
1649
1886
|
// handlers are always called with an "event" object as their first param.
|
|
1650
1887
|
// sneak the `this` context and arguments into the extra parameter object
|
|
1651
1888
|
// and forward them on to the original handler.
|
|
@@ -1665,9 +1902,7 @@ var EmitterMixin = FC.EmitterMixin = {
|
|
|
1665
1902
|
}
|
|
1666
1903
|
intercept.guid = handler.guid;
|
|
1667
1904
|
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
return this; // for chaining
|
|
1905
|
+
return intercept;
|
|
1671
1906
|
},
|
|
1672
1907
|
|
|
1673
1908
|
|
|
@@ -1996,9 +2231,15 @@ var CoordCache = FC.CoordCache = Class.extend({
|
|
|
1996
2231
|
// Queries the els for coordinates and stores them.
|
|
1997
2232
|
// Call this method before using and of the get* methods below.
|
|
1998
2233
|
build: function() {
|
|
1999
|
-
var offsetParentEl = this.forcedOffsetParentEl
|
|
2234
|
+
var offsetParentEl = this.forcedOffsetParentEl;
|
|
2235
|
+
if (!offsetParentEl && this.els.length > 0) {
|
|
2236
|
+
offsetParentEl = this.els.eq(0).offsetParent();
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
this.origin = offsetParentEl ?
|
|
2240
|
+
offsetParentEl.offset() :
|
|
2241
|
+
null;
|
|
2000
2242
|
|
|
2001
|
-
this.origin = offsetParentEl.offset();
|
|
2002
2243
|
this.boundingRect = this.queryBoundingRect();
|
|
2003
2244
|
|
|
2004
2245
|
if (this.isHorizontal) {
|
|
@@ -2181,12 +2422,19 @@ var CoordCache = FC.CoordCache = Class.extend({
|
|
|
2181
2422
|
|
|
2182
2423
|
// Compute and return what the elements' bounding rectangle is, from the user's perspective.
|
|
2183
2424
|
// Right now, only returns a rectangle if constrained by an overflow:scroll element.
|
|
2425
|
+
// Returns null if there are no elements
|
|
2184
2426
|
queryBoundingRect: function() {
|
|
2185
|
-
var scrollParentEl
|
|
2427
|
+
var scrollParentEl;
|
|
2186
2428
|
|
|
2187
|
-
if (
|
|
2188
|
-
|
|
2429
|
+
if (this.els.length > 0) {
|
|
2430
|
+
scrollParentEl = getScrollParent(this.els.eq(0));
|
|
2431
|
+
|
|
2432
|
+
if (!scrollParentEl.is(document)) {
|
|
2433
|
+
return getClientRect(scrollParentEl);
|
|
2434
|
+
}
|
|
2189
2435
|
}
|
|
2436
|
+
|
|
2437
|
+
return null;
|
|
2190
2438
|
},
|
|
2191
2439
|
|
|
2192
2440
|
isPointInBounds: function(leftOffset, topOffset) {
|
|
@@ -3405,6 +3653,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
|
|
|
3405
3653
|
|
|
3406
3654
|
dayTouchStart: function(ev) {
|
|
3407
3655
|
var view = this.view;
|
|
3656
|
+
var selectLongPressDelay = view.opt('selectLongPressDelay');
|
|
3408
3657
|
|
|
3409
3658
|
// HACK to prevent a user's clickaway for unselecting a range or an event
|
|
3410
3659
|
// from causing a dayClick.
|
|
@@ -3412,8 +3661,12 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
|
|
|
3412
3661
|
this.tempIgnoreMouse();
|
|
3413
3662
|
}
|
|
3414
3663
|
|
|
3664
|
+
if (selectLongPressDelay == null) {
|
|
3665
|
+
selectLongPressDelay = view.opt('longPressDelay'); // fallback
|
|
3666
|
+
}
|
|
3667
|
+
|
|
3415
3668
|
this.dayDragListener.startInteraction(ev, {
|
|
3416
|
-
delay:
|
|
3669
|
+
delay: selectLongPressDelay
|
|
3417
3670
|
});
|
|
3418
3671
|
},
|
|
3419
3672
|
|
|
@@ -3750,7 +4003,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
|
|
|
3750
4003
|
|
|
3751
4004
|
|
|
3752
4005
|
// Computes HTML classNames for a single-day element
|
|
3753
|
-
getDayClasses: function(date) {
|
|
4006
|
+
getDayClasses: function(date, noThemeHighlight) {
|
|
3754
4007
|
var view = this.view;
|
|
3755
4008
|
var today = view.calendar.getNow();
|
|
3756
4009
|
var classes = [ 'fc-' + dayIDs[date.day()] ];
|
|
@@ -3763,10 +4016,11 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
|
|
|
3763
4016
|
}
|
|
3764
4017
|
|
|
3765
4018
|
if (date.isSame(today, 'day')) {
|
|
3766
|
-
classes.push(
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
4019
|
+
classes.push('fc-today');
|
|
4020
|
+
|
|
4021
|
+
if (noThemeHighlight !== true) {
|
|
4022
|
+
classes.push(view.highlightStateClass);
|
|
4023
|
+
}
|
|
3770
4024
|
}
|
|
3771
4025
|
else if (date < today) {
|
|
3772
4026
|
classes.push('fc-past');
|
|
@@ -3962,16 +4216,33 @@ Grid.mixin({
|
|
|
3962
4216
|
|
|
3963
4217
|
// Compute business hour segs for the grid's current date range.
|
|
3964
4218
|
// Caller must ask if whole-day business hours are needed.
|
|
3965
|
-
|
|
3966
|
-
|
|
4219
|
+
// If no `businessHours` configuration value is specified, assumes the calendar default.
|
|
4220
|
+
buildBusinessHourSegs: function(wholeDay, businessHours) {
|
|
4221
|
+
return this.eventsToSegs(
|
|
4222
|
+
this.buildBusinessHourEvents(wholeDay, businessHours)
|
|
4223
|
+
);
|
|
4224
|
+
},
|
|
4225
|
+
|
|
4226
|
+
|
|
4227
|
+
// Compute business hour *events* for the grid's current date range.
|
|
4228
|
+
// Caller must ask if whole-day business hours are needed.
|
|
4229
|
+
// If no `businessHours` configuration value is specified, assumes the calendar default.
|
|
4230
|
+
buildBusinessHourEvents: function(wholeDay, businessHours) {
|
|
4231
|
+
var calendar = this.view.calendar;
|
|
4232
|
+
var events;
|
|
4233
|
+
|
|
4234
|
+
if (businessHours == null) {
|
|
4235
|
+
// fallback
|
|
4236
|
+
// access from calendawr. don't access from view. doesn't update with dynamic options.
|
|
4237
|
+
businessHours = calendar.options.businessHours;
|
|
4238
|
+
}
|
|
4239
|
+
|
|
4240
|
+
events = calendar.computeBusinessHourEvents(wholeDay, businessHours);
|
|
3967
4241
|
|
|
3968
4242
|
// HACK. Eventually refactor business hours "events" system.
|
|
3969
4243
|
// If no events are given, but businessHours is activated, this means the entire visible range should be
|
|
3970
4244
|
// marked as *not* business-hours, via inverse-background rendering.
|
|
3971
|
-
if (
|
|
3972
|
-
!events.length &&
|
|
3973
|
-
this.view.calendar.options.businessHours // don't access view option. doesn't update with dynamic options
|
|
3974
|
-
) {
|
|
4245
|
+
if (!events.length && businessHours) {
|
|
3975
4246
|
events = [
|
|
3976
4247
|
$.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, {
|
|
3977
4248
|
start: this.view.end, // guaranteed out-of-range
|
|
@@ -3981,7 +4252,7 @@ Grid.mixin({
|
|
|
3981
4252
|
];
|
|
3982
4253
|
}
|
|
3983
4254
|
|
|
3984
|
-
return
|
|
4255
|
+
return events;
|
|
3985
4256
|
},
|
|
3986
4257
|
|
|
3987
4258
|
|
|
@@ -4023,7 +4294,7 @@ Grid.mixin({
|
|
|
4023
4294
|
|
|
4024
4295
|
|
|
4025
4296
|
handleSegClick: function(seg, ev) {
|
|
4026
|
-
var res = this.view.
|
|
4297
|
+
var res = this.view.publiclyTrigger('eventClick', seg.el[0], seg.event, ev); // can return `false` to cancel
|
|
4027
4298
|
if (res === false) {
|
|
4028
4299
|
ev.preventDefault();
|
|
4029
4300
|
}
|
|
@@ -4040,7 +4311,7 @@ Grid.mixin({
|
|
|
4040
4311
|
if (this.view.isEventResizable(seg.event)) {
|
|
4041
4312
|
seg.el.addClass('fc-allow-mouse-resize');
|
|
4042
4313
|
}
|
|
4043
|
-
this.view.
|
|
4314
|
+
this.view.publiclyTrigger('eventMouseover', seg.el[0], seg.event, ev);
|
|
4044
4315
|
}
|
|
4045
4316
|
},
|
|
4046
4317
|
|
|
@@ -4056,7 +4327,7 @@ Grid.mixin({
|
|
|
4056
4327
|
if (this.view.isEventResizable(seg.event)) {
|
|
4057
4328
|
seg.el.removeClass('fc-allow-mouse-resize');
|
|
4058
4329
|
}
|
|
4059
|
-
this.view.
|
|
4330
|
+
this.view.publiclyTrigger('eventMouseout', seg.el[0], seg.event, ev);
|
|
4060
4331
|
}
|
|
4061
4332
|
},
|
|
4062
4333
|
|
|
@@ -4081,6 +4352,7 @@ Grid.mixin({
|
|
|
4081
4352
|
var isResizable = view.isEventResizable(event);
|
|
4082
4353
|
var isResizing = false;
|
|
4083
4354
|
var dragListener;
|
|
4355
|
+
var eventLongPressDelay;
|
|
4084
4356
|
|
|
4085
4357
|
if (isSelected && isResizable) {
|
|
4086
4358
|
// only allow resizing of the event is selected
|
|
@@ -4089,12 +4361,17 @@ Grid.mixin({
|
|
|
4089
4361
|
|
|
4090
4362
|
if (!isResizing && (isDraggable || isResizable)) { // allowed to be selected?
|
|
4091
4363
|
|
|
4364
|
+
eventLongPressDelay = view.opt('eventLongPressDelay');
|
|
4365
|
+
if (eventLongPressDelay == null) {
|
|
4366
|
+
eventLongPressDelay = view.opt('longPressDelay'); // fallback
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4092
4369
|
dragListener = isDraggable ?
|
|
4093
4370
|
this.buildSegDragListener(seg) :
|
|
4094
4371
|
this.buildSegSelectListener(seg); // seg isn't draggable, but still needs to be selected
|
|
4095
4372
|
|
|
4096
4373
|
dragListener.startInteraction(ev, { // won't start if already started
|
|
4097
|
-
delay: isSelected ? 0 :
|
|
4374
|
+
delay: isSelected ? 0 : eventLongPressDelay // do delay if not already selected
|
|
4098
4375
|
});
|
|
4099
4376
|
}
|
|
4100
4377
|
|
|
@@ -4227,11 +4504,15 @@ Grid.mixin({
|
|
|
4227
4504
|
mouseFollower.stop(!dropLocation, function() {
|
|
4228
4505
|
if (isDragging) {
|
|
4229
4506
|
view.unrenderDrag();
|
|
4230
|
-
view.showEvent(event);
|
|
4231
4507
|
_this.segDragStop(seg, ev);
|
|
4232
4508
|
}
|
|
4509
|
+
|
|
4233
4510
|
if (dropLocation) {
|
|
4234
|
-
|
|
4511
|
+
// no need to re-show original, will rerender all anyways. esp important if eventRenderWait
|
|
4512
|
+
view.reportEventDrop(event, dropLocation, _this.largeUnit, el, ev);
|
|
4513
|
+
}
|
|
4514
|
+
else {
|
|
4515
|
+
view.showEvent(event);
|
|
4235
4516
|
}
|
|
4236
4517
|
});
|
|
4237
4518
|
_this.segDragListener = null;
|
|
@@ -4273,14 +4554,14 @@ Grid.mixin({
|
|
|
4273
4554
|
// Called before event segment dragging starts
|
|
4274
4555
|
segDragStart: function(seg, ev) {
|
|
4275
4556
|
this.isDraggingSeg = true;
|
|
4276
|
-
this.view.
|
|
4557
|
+
this.view.publiclyTrigger('eventDragStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
|
|
4277
4558
|
},
|
|
4278
4559
|
|
|
4279
4560
|
|
|
4280
4561
|
// Called after event segment dragging stops
|
|
4281
4562
|
segDragStop: function(seg, ev) {
|
|
4282
4563
|
this.isDraggingSeg = false;
|
|
4283
|
-
this.view.
|
|
4564
|
+
this.view.publiclyTrigger('eventDragStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
|
|
4284
4565
|
},
|
|
4285
4566
|
|
|
4286
4567
|
|
|
@@ -4518,18 +4799,23 @@ Grid.mixin({
|
|
|
4518
4799
|
},
|
|
4519
4800
|
hitOut: function() { // called before mouse moves to a different hit OR moved out of all hits
|
|
4520
4801
|
resizeLocation = null;
|
|
4802
|
+
view.showEvent(event); // for when out-of-bounds. show original
|
|
4521
4803
|
},
|
|
4522
4804
|
hitDone: function() { // resets the rendering to show the original event
|
|
4523
4805
|
_this.unrenderEventResize();
|
|
4524
|
-
view.showEvent(event);
|
|
4525
4806
|
enableCursor();
|
|
4526
4807
|
},
|
|
4527
4808
|
interactionEnd: function(ev) {
|
|
4528
4809
|
if (isDragging) {
|
|
4529
4810
|
_this.segResizeStop(seg, ev);
|
|
4530
4811
|
}
|
|
4812
|
+
|
|
4531
4813
|
if (resizeLocation) { // valid date to resize to?
|
|
4532
|
-
|
|
4814
|
+
// no need to re-show original, will rerender all anyways. esp important if eventRenderWait
|
|
4815
|
+
view.reportEventResize(event, resizeLocation, _this.largeUnit, el, ev);
|
|
4816
|
+
}
|
|
4817
|
+
else {
|
|
4818
|
+
view.showEvent(event);
|
|
4533
4819
|
}
|
|
4534
4820
|
_this.segResizeListener = null;
|
|
4535
4821
|
}
|
|
@@ -4542,14 +4828,14 @@ Grid.mixin({
|
|
|
4542
4828
|
// Called before event segment resizing starts
|
|
4543
4829
|
segResizeStart: function(seg, ev) {
|
|
4544
4830
|
this.isResizingSeg = true;
|
|
4545
|
-
this.view.
|
|
4831
|
+
this.view.publiclyTrigger('eventResizeStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
|
|
4546
4832
|
},
|
|
4547
4833
|
|
|
4548
4834
|
|
|
4549
4835
|
// Called after event segment resizing stops
|
|
4550
4836
|
segResizeStop: function(seg, ev) {
|
|
4551
4837
|
this.isResizingSeg = false;
|
|
4552
|
-
this.view.
|
|
4838
|
+
this.view.publiclyTrigger('eventResizeStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
|
|
4553
4839
|
},
|
|
4554
4840
|
|
|
4555
4841
|
|
|
@@ -5100,7 +5386,7 @@ var DayTableMixin = FC.DayTableMixin = {
|
|
|
5100
5386
|
this.dayIndices = dayIndices;
|
|
5101
5387
|
this.daysPerRow = daysPerRow;
|
|
5102
5388
|
this.rowCnt = rowCnt;
|
|
5103
|
-
|
|
5389
|
+
|
|
5104
5390
|
this.updateDayTableCols();
|
|
5105
5391
|
},
|
|
5106
5392
|
|
|
@@ -5338,9 +5624,25 @@ var DayTableMixin = FC.DayTableMixin = {
|
|
|
5338
5624
|
// (colspan should be no different)
|
|
5339
5625
|
renderHeadDateCellHtml: function(date, colspan, otherAttrs) {
|
|
5340
5626
|
var view = this.view;
|
|
5627
|
+
var classNames = [
|
|
5628
|
+
'fc-day-header',
|
|
5629
|
+
view.widgetHeaderClass
|
|
5630
|
+
];
|
|
5631
|
+
|
|
5632
|
+
// if only one row of days, the classNames on the header can represent the specific days beneath
|
|
5633
|
+
if (this.rowCnt === 1) {
|
|
5634
|
+
classNames = classNames.concat(
|
|
5635
|
+
// includes the day-of-week class
|
|
5636
|
+
// noThemeHighlight=true (don't highlight the header)
|
|
5637
|
+
this.getDayClasses(date, true)
|
|
5638
|
+
);
|
|
5639
|
+
}
|
|
5640
|
+
else {
|
|
5641
|
+
classNames.push('fc-' + dayIDs[date.day()]); // only add the day-of-week class
|
|
5642
|
+
}
|
|
5341
5643
|
|
|
5342
5644
|
return '' +
|
|
5343
|
-
|
|
5645
|
+
'<th class="' + classNames.join(' ') + '"' +
|
|
5344
5646
|
(this.rowCnt === 1 ?
|
|
5345
5647
|
' data-date="' + date.format('YYYY-MM-DD') + '"' :
|
|
5346
5648
|
'') +
|
|
@@ -5491,7 +5793,7 @@ var DayGrid = FC.DayGrid = Grid.extend(DayTableMixin, {
|
|
|
5491
5793
|
// trigger dayRender with each cell's element
|
|
5492
5794
|
for (row = 0; row < rowCnt; row++) {
|
|
5493
5795
|
for (col = 0; col < colCnt; col++) {
|
|
5494
|
-
view.
|
|
5796
|
+
view.publiclyTrigger(
|
|
5495
5797
|
'dayRender',
|
|
5496
5798
|
null,
|
|
5497
5799
|
this.getCellDate(row, col),
|
|
@@ -6426,7 +6728,7 @@ DayGrid.mixin({
|
|
|
6426
6728
|
|
|
6427
6729
|
if (typeof clickOption === 'function') {
|
|
6428
6730
|
// the returned value can be an atomic option
|
|
6429
|
-
clickOption = view.
|
|
6731
|
+
clickOption = view.publiclyTrigger('eventLimitClick', null, {
|
|
6430
6732
|
date: date,
|
|
6431
6733
|
dayEl: dayEl,
|
|
6432
6734
|
moreEl: moreEl,
|
|
@@ -6469,6 +6771,14 @@ DayGrid.mixin({
|
|
|
6469
6771
|
viewportConstrain: view.opt('popoverViewportConstrain'),
|
|
6470
6772
|
hide: function() {
|
|
6471
6773
|
// kill everything when the popover is hidden
|
|
6774
|
+
// notify events to be removed
|
|
6775
|
+
if (_this.popoverSegs) {
|
|
6776
|
+
var seg;
|
|
6777
|
+
for (var i = 0; i < _this.popoverSegs.length; ++i) {
|
|
6778
|
+
seg = _this.popoverSegs[i];
|
|
6779
|
+
view.publiclyTrigger('eventDestroy', seg.event, seg.event, seg.el);
|
|
6780
|
+
}
|
|
6781
|
+
}
|
|
6472
6782
|
_this.segPopover.removeElement();
|
|
6473
6783
|
_this.segPopover = null;
|
|
6474
6784
|
_this.popoverSegs = null;
|
|
@@ -7746,9 +8056,14 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
7746
8056
|
options: null, // hash containing all options. already merged with view-specific-options
|
|
7747
8057
|
el: null, // the view's containing element. set by Calendar
|
|
7748
8058
|
|
|
7749
|
-
|
|
7750
|
-
|
|
8059
|
+
isDateSet: false,
|
|
8060
|
+
isDateRendered: false,
|
|
8061
|
+
dateRenderQueue: null,
|
|
8062
|
+
|
|
8063
|
+
isEventsBound: false,
|
|
8064
|
+
isEventsSet: false,
|
|
7751
8065
|
isEventsRendered: false,
|
|
8066
|
+
eventRenderQueue: null,
|
|
7752
8067
|
|
|
7753
8068
|
// range the view is actually displaying (moments)
|
|
7754
8069
|
start: null,
|
|
@@ -7798,6 +8113,9 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
7798
8113
|
|
|
7799
8114
|
this.eventOrderSpecs = parseFieldSpecs(this.opt('eventOrder'));
|
|
7800
8115
|
|
|
8116
|
+
this.dateRenderQueue = new TaskQueue();
|
|
8117
|
+
this.eventRenderQueue = new TaskQueue(this.opt('eventRenderWait'));
|
|
8118
|
+
|
|
7801
8119
|
this.initialize();
|
|
7802
8120
|
},
|
|
7803
8121
|
|
|
@@ -7815,10 +8133,10 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
7815
8133
|
|
|
7816
8134
|
|
|
7817
8135
|
// Triggers handlers that are view-related. Modifies args before passing to calendar.
|
|
7818
|
-
|
|
8136
|
+
publiclyTrigger: function(name, thisObj) { // arguments beyond thisObj are passed along
|
|
7819
8137
|
var calendar = this.calendar;
|
|
7820
8138
|
|
|
7821
|
-
return calendar.
|
|
8139
|
+
return calendar.publiclyTrigger.apply(
|
|
7822
8140
|
calendar,
|
|
7823
8141
|
[name, thisObj || this].concat(
|
|
7824
8142
|
Array.prototype.slice.call(arguments, 2), // arguments beyond thisObj
|
|
@@ -7828,16 +8146,33 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
7828
8146
|
},
|
|
7829
8147
|
|
|
7830
8148
|
|
|
7831
|
-
|
|
7832
|
-
|
|
8149
|
+
// Returns a proxy of the given promise that will be rejected if the given event fires
|
|
8150
|
+
// before the promise resolves.
|
|
8151
|
+
rejectOn: function(eventName, promise) {
|
|
8152
|
+
var _this = this;
|
|
7833
8153
|
|
|
8154
|
+
return new Promise(function(resolve, reject) {
|
|
8155
|
+
_this.one(eventName, reject);
|
|
7834
8156
|
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
8157
|
+
function cleanup() {
|
|
8158
|
+
_this.off(eventName, reject);
|
|
8159
|
+
}
|
|
8160
|
+
|
|
8161
|
+
promise.then(function(res) { // success
|
|
8162
|
+
cleanup();
|
|
8163
|
+
resolve(res);
|
|
8164
|
+
}, function() { // failure
|
|
8165
|
+
cleanup();
|
|
8166
|
+
reject();
|
|
8167
|
+
});
|
|
8168
|
+
});
|
|
7838
8169
|
},
|
|
7839
8170
|
|
|
7840
8171
|
|
|
8172
|
+
/* Date Computation
|
|
8173
|
+
------------------------------------------------------------------------------------------------------------------*/
|
|
8174
|
+
|
|
8175
|
+
|
|
7841
8176
|
// Updates all internal dates for displaying the given unzoned range.
|
|
7842
8177
|
setRange: function(range) {
|
|
7843
8178
|
$.extend(this, range); // assigns every property to this object's member variables
|
|
@@ -7920,6 +8255,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
7920
8255
|
// Sets the view's title property to the most updated computed value
|
|
7921
8256
|
updateTitle: function() {
|
|
7922
8257
|
this.title = this.computeTitle();
|
|
8258
|
+
this.calendar.setToolbarsTitle(this.title);
|
|
7923
8259
|
},
|
|
7924
8260
|
|
|
7925
8261
|
|
|
@@ -8025,183 +8361,238 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8025
8361
|
},
|
|
8026
8362
|
|
|
8027
8363
|
|
|
8028
|
-
|
|
8029
|
-
|
|
8364
|
+
// Rendering Non-date-related Content
|
|
8365
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8030
8366
|
|
|
8031
8367
|
|
|
8032
|
-
// Sets the container element that the view should render inside of
|
|
8033
|
-
//
|
|
8368
|
+
// Sets the container element that the view should render inside of, does global DOM-related initializations,
|
|
8369
|
+
// and renders all the non-date-related content inside.
|
|
8034
8370
|
setElement: function(el) {
|
|
8035
8371
|
this.el = el;
|
|
8036
8372
|
this.bindGlobalHandlers();
|
|
8373
|
+
this.renderSkeleton();
|
|
8037
8374
|
},
|
|
8038
8375
|
|
|
8039
8376
|
|
|
8040
8377
|
// Removes the view's container element from the DOM, clearing any content beforehand.
|
|
8041
8378
|
// Undoes any other DOM-related attachments.
|
|
8042
8379
|
removeElement: function() {
|
|
8043
|
-
this.
|
|
8044
|
-
|
|
8045
|
-
// clean up the skeleton
|
|
8046
|
-
if (this.isSkeletonRendered) {
|
|
8047
|
-
this.unrenderSkeleton();
|
|
8048
|
-
this.isSkeletonRendered = false;
|
|
8049
|
-
}
|
|
8380
|
+
this.unsetDate();
|
|
8381
|
+
this.unrenderSkeleton();
|
|
8050
8382
|
|
|
8051
8383
|
this.unbindGlobalHandlers();
|
|
8052
8384
|
|
|
8053
8385
|
this.el.remove();
|
|
8054
|
-
|
|
8055
8386
|
// NOTE: don't null-out this.el in case the View was destroyed within an API callback.
|
|
8056
8387
|
// We don't null-out the View's other jQuery element references upon destroy,
|
|
8057
8388
|
// so we shouldn't kill this.el either.
|
|
8058
8389
|
},
|
|
8059
8390
|
|
|
8060
8391
|
|
|
8061
|
-
//
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
var _this = this;
|
|
8066
|
-
var prevScrollState = null;
|
|
8067
|
-
|
|
8068
|
-
if (explicitScrollState != null && this.displaying) { // don't need prevScrollState if explicitScrollState
|
|
8069
|
-
prevScrollState = this.queryScroll();
|
|
8070
|
-
}
|
|
8071
|
-
|
|
8072
|
-
this.calendar.freezeContentHeight();
|
|
8073
|
-
|
|
8074
|
-
return syncThen(this.clear(), function() { // clear the content first
|
|
8075
|
-
return (
|
|
8076
|
-
_this.displaying =
|
|
8077
|
-
syncThen(_this.displayView(date), function() { // displayView might return a promise
|
|
8392
|
+
// Renders the basic structure of the view before any content is rendered
|
|
8393
|
+
renderSkeleton: function() {
|
|
8394
|
+
// subclasses should implement
|
|
8395
|
+
},
|
|
8078
8396
|
|
|
8079
|
-
// caller of display() wants a specific scroll state?
|
|
8080
|
-
if (explicitScrollState != null) {
|
|
8081
|
-
// we make an assumption that this is NOT the initial render,
|
|
8082
|
-
// and thus don't need forceScroll (is inconveniently asynchronous)
|
|
8083
|
-
_this.setScroll(explicitScrollState);
|
|
8084
|
-
}
|
|
8085
|
-
else {
|
|
8086
|
-
_this.forceScroll(_this.computeInitialScroll(prevScrollState));
|
|
8087
|
-
}
|
|
8088
8397
|
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
);
|
|
8093
|
-
});
|
|
8398
|
+
// Unrenders the basic structure of the view
|
|
8399
|
+
unrenderSkeleton: function() {
|
|
8400
|
+
// subclasses should implement
|
|
8094
8401
|
},
|
|
8095
8402
|
|
|
8096
8403
|
|
|
8097
|
-
//
|
|
8098
|
-
//
|
|
8099
|
-
// Is asychronous and returns a promise.
|
|
8100
|
-
clear: function() {
|
|
8101
|
-
var _this = this;
|
|
8102
|
-
var displaying = this.displaying;
|
|
8404
|
+
// Date Setting/Unsetting
|
|
8405
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8103
8406
|
|
|
8104
|
-
if (displaying) { // previously displayed, or in the process of being displayed?
|
|
8105
|
-
return syncThen(displaying, function() { // wait for the display to finish
|
|
8106
|
-
_this.displaying = null;
|
|
8107
|
-
_this.clearEvents();
|
|
8108
|
-
return _this.clearView(); // might return a promise. chain it
|
|
8109
|
-
});
|
|
8110
|
-
}
|
|
8111
|
-
else {
|
|
8112
|
-
return $.when(); // an immediately-resolved promise
|
|
8113
|
-
}
|
|
8114
|
-
},
|
|
8115
8407
|
|
|
8408
|
+
setDate: function(date) {
|
|
8409
|
+
var isReset = this.isDateSet;
|
|
8116
8410
|
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
displayView: function(date) {
|
|
8121
|
-
if (!this.isSkeletonRendered) {
|
|
8122
|
-
this.renderSkeleton();
|
|
8123
|
-
this.isSkeletonRendered = true;
|
|
8124
|
-
}
|
|
8125
|
-
if (date) {
|
|
8126
|
-
this.setDate(date);
|
|
8127
|
-
}
|
|
8128
|
-
if (this.render) {
|
|
8129
|
-
this.render(); // TODO: deprecate
|
|
8130
|
-
}
|
|
8131
|
-
this.renderDates();
|
|
8132
|
-
this.updateSize();
|
|
8133
|
-
this.renderBusinessHours(); // might need coordinates, so should go after updateSize()
|
|
8134
|
-
this.startNowIndicator();
|
|
8411
|
+
this.isDateSet = true;
|
|
8412
|
+
this.handleDate(date, isReset);
|
|
8413
|
+
this.trigger(isReset ? 'dateReset' : 'dateSet', date);
|
|
8135
8414
|
},
|
|
8136
8415
|
|
|
8137
8416
|
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
this.triggerUnrender();
|
|
8144
|
-
this.unrenderBusinessHours();
|
|
8145
|
-
this.unrenderDates();
|
|
8146
|
-
if (this.destroy) {
|
|
8147
|
-
this.destroy(); // TODO: deprecate
|
|
8417
|
+
unsetDate: function() {
|
|
8418
|
+
if (this.isDateSet) {
|
|
8419
|
+
this.isDateSet = false;
|
|
8420
|
+
this.handleDateUnset();
|
|
8421
|
+
this.trigger('dateUnset');
|
|
8148
8422
|
}
|
|
8149
8423
|
},
|
|
8150
8424
|
|
|
8151
8425
|
|
|
8152
|
-
//
|
|
8153
|
-
|
|
8154
|
-
// subclasses should implement
|
|
8155
|
-
},
|
|
8156
|
-
|
|
8426
|
+
// Date Handling
|
|
8427
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8157
8428
|
|
|
8158
|
-
// Unrenders the basic structure of the view
|
|
8159
|
-
unrenderSkeleton: function() {
|
|
8160
|
-
// subclasses should implement
|
|
8161
|
-
},
|
|
8162
8429
|
|
|
8430
|
+
handleDate: function(date, isReset) {
|
|
8431
|
+
var _this = this;
|
|
8163
8432
|
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8433
|
+
this.unbindEvents(); // will do nothing if not already bound
|
|
8434
|
+
this.requestDateRender(date).then(function() {
|
|
8435
|
+
// wish we could start earlier, but setRange/computeRange needs to execute first
|
|
8436
|
+
_this.bindEvents(); // will request events
|
|
8437
|
+
});
|
|
8168
8438
|
},
|
|
8169
8439
|
|
|
8170
8440
|
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8441
|
+
handleDateUnset: function() {
|
|
8442
|
+
this.unbindEvents();
|
|
8443
|
+
this.requestDateUnrender();
|
|
8174
8444
|
},
|
|
8175
8445
|
|
|
8176
8446
|
|
|
8177
|
-
//
|
|
8178
|
-
|
|
8179
|
-
this.trigger('viewRender', this, this, this.el);
|
|
8180
|
-
},
|
|
8447
|
+
// Date Render Queuing
|
|
8448
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8181
8449
|
|
|
8182
8450
|
|
|
8183
|
-
//
|
|
8184
|
-
|
|
8185
|
-
|
|
8451
|
+
// if date not specified, uses current
|
|
8452
|
+
requestDateRender: function(date) {
|
|
8453
|
+
var _this = this;
|
|
8454
|
+
|
|
8455
|
+
return this.dateRenderQueue.add(function() {
|
|
8456
|
+
return _this.executeDateRender(date);
|
|
8457
|
+
});
|
|
8186
8458
|
},
|
|
8187
8459
|
|
|
8188
8460
|
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
this.
|
|
8461
|
+
requestDateUnrender: function() {
|
|
8462
|
+
var _this = this;
|
|
8463
|
+
|
|
8464
|
+
return this.dateRenderQueue.add(function() {
|
|
8465
|
+
return _this.executeDateUnrender();
|
|
8466
|
+
});
|
|
8193
8467
|
},
|
|
8194
8468
|
|
|
8195
8469
|
|
|
8196
|
-
//
|
|
8197
|
-
|
|
8198
|
-
this.stopListeningTo($(document));
|
|
8199
|
-
},
|
|
8470
|
+
// Date High-level Rendering
|
|
8471
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8200
8472
|
|
|
8201
8473
|
|
|
8202
|
-
//
|
|
8203
|
-
|
|
8204
|
-
var
|
|
8474
|
+
// if date not specified, uses current
|
|
8475
|
+
executeDateRender: function(date) {
|
|
8476
|
+
var _this = this;
|
|
8477
|
+
|
|
8478
|
+
// if rendering a new date, reset scroll to initial state (scrollTime)
|
|
8479
|
+
if (date) {
|
|
8480
|
+
this.captureInitialScroll();
|
|
8481
|
+
}
|
|
8482
|
+
else {
|
|
8483
|
+
this.captureScroll(); // a rerender of the current date
|
|
8484
|
+
}
|
|
8485
|
+
|
|
8486
|
+
this.freezeHeight();
|
|
8487
|
+
|
|
8488
|
+
return this.executeDateUnrender().then(function() {
|
|
8489
|
+
|
|
8490
|
+
if (date) {
|
|
8491
|
+
_this.setRange(_this.computeRange(date));
|
|
8492
|
+
}
|
|
8493
|
+
|
|
8494
|
+
if (_this.render) {
|
|
8495
|
+
_this.render(); // TODO: deprecate
|
|
8496
|
+
}
|
|
8497
|
+
|
|
8498
|
+
_this.renderDates();
|
|
8499
|
+
_this.updateSize();
|
|
8500
|
+
_this.renderBusinessHours(); // might need coordinates, so should go after updateSize()
|
|
8501
|
+
_this.startNowIndicator();
|
|
8502
|
+
|
|
8503
|
+
_this.thawHeight();
|
|
8504
|
+
_this.releaseScroll();
|
|
8505
|
+
|
|
8506
|
+
_this.isDateRendered = true;
|
|
8507
|
+
_this.onDateRender();
|
|
8508
|
+
_this.trigger('dateRender');
|
|
8509
|
+
});
|
|
8510
|
+
},
|
|
8511
|
+
|
|
8512
|
+
|
|
8513
|
+
executeDateUnrender: function() {
|
|
8514
|
+
var _this = this;
|
|
8515
|
+
|
|
8516
|
+
if (_this.isDateRendered) {
|
|
8517
|
+
return this.requestEventsUnrender().then(function() {
|
|
8518
|
+
|
|
8519
|
+
_this.unselect();
|
|
8520
|
+
_this.stopNowIndicator();
|
|
8521
|
+
_this.triggerUnrender();
|
|
8522
|
+
_this.unrenderBusinessHours();
|
|
8523
|
+
_this.unrenderDates();
|
|
8524
|
+
|
|
8525
|
+
if (_this.destroy) {
|
|
8526
|
+
_this.destroy(); // TODO: deprecate
|
|
8527
|
+
}
|
|
8528
|
+
|
|
8529
|
+
_this.isDateRendered = false;
|
|
8530
|
+
_this.trigger('dateUnrender');
|
|
8531
|
+
});
|
|
8532
|
+
}
|
|
8533
|
+
else {
|
|
8534
|
+
return Promise.resolve();
|
|
8535
|
+
}
|
|
8536
|
+
},
|
|
8537
|
+
|
|
8538
|
+
|
|
8539
|
+
// Date Rendering Triggers
|
|
8540
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8541
|
+
|
|
8542
|
+
|
|
8543
|
+
onDateRender: function() {
|
|
8544
|
+
this.triggerRender();
|
|
8545
|
+
},
|
|
8546
|
+
|
|
8547
|
+
|
|
8548
|
+
// Date Low-level Rendering
|
|
8549
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8550
|
+
|
|
8551
|
+
|
|
8552
|
+
// date-cell content only
|
|
8553
|
+
renderDates: function() {
|
|
8554
|
+
// subclasses should implement
|
|
8555
|
+
},
|
|
8556
|
+
|
|
8557
|
+
|
|
8558
|
+
// date-cell content only
|
|
8559
|
+
unrenderDates: function() {
|
|
8560
|
+
// subclasses should override
|
|
8561
|
+
},
|
|
8562
|
+
|
|
8563
|
+
|
|
8564
|
+
// Misc view rendering utils
|
|
8565
|
+
// -------------------------
|
|
8566
|
+
|
|
8567
|
+
|
|
8568
|
+
// Signals that the view's content has been rendered
|
|
8569
|
+
triggerRender: function() {
|
|
8570
|
+
this.publiclyTrigger('viewRender', this, this, this.el);
|
|
8571
|
+
},
|
|
8572
|
+
|
|
8573
|
+
|
|
8574
|
+
// Signals that the view's content is about to be unrendered
|
|
8575
|
+
triggerUnrender: function() {
|
|
8576
|
+
this.publiclyTrigger('viewDestroy', this, this, this.el);
|
|
8577
|
+
},
|
|
8578
|
+
|
|
8579
|
+
|
|
8580
|
+
// Binds DOM handlers to elements that reside outside the view container, such as the document
|
|
8581
|
+
bindGlobalHandlers: function() {
|
|
8582
|
+
this.listenTo($(document), 'mousedown', this.handleDocumentMousedown);
|
|
8583
|
+
this.listenTo($(document), 'touchstart', this.processUnselect);
|
|
8584
|
+
},
|
|
8585
|
+
|
|
8586
|
+
|
|
8587
|
+
// Unbinds DOM handlers from elements that reside outside the view container
|
|
8588
|
+
unbindGlobalHandlers: function() {
|
|
8589
|
+
this.stopListeningTo($(document));
|
|
8590
|
+
},
|
|
8591
|
+
|
|
8592
|
+
|
|
8593
|
+
// Initializes internal variables related to theming
|
|
8594
|
+
initThemingProps: function() {
|
|
8595
|
+
var tm = this.opt('theme') ? 'ui' : 'fc';
|
|
8205
8596
|
|
|
8206
8597
|
this.widgetHeaderClass = tm + '-widget-header';
|
|
8207
8598
|
this.widgetContentClass = tm + '-widget-content';
|
|
@@ -8319,10 +8710,9 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8319
8710
|
|
|
8320
8711
|
// Refreshes anything dependant upon sizing of the container element of the grid
|
|
8321
8712
|
updateSize: function(isResize) {
|
|
8322
|
-
var scrollState;
|
|
8323
8713
|
|
|
8324
8714
|
if (isResize) {
|
|
8325
|
-
|
|
8715
|
+
this.captureScroll();
|
|
8326
8716
|
}
|
|
8327
8717
|
|
|
8328
8718
|
this.updateHeight(isResize);
|
|
@@ -8330,7 +8720,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8330
8720
|
this.updateNowIndicator();
|
|
8331
8721
|
|
|
8332
8722
|
if (isResize) {
|
|
8333
|
-
this.
|
|
8723
|
+
this.releaseScroll();
|
|
8334
8724
|
}
|
|
8335
8725
|
},
|
|
8336
8726
|
|
|
@@ -8363,72 +8753,294 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8363
8753
|
------------------------------------------------------------------------------------------------------------------*/
|
|
8364
8754
|
|
|
8365
8755
|
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8756
|
+
capturedScroll: null,
|
|
8757
|
+
capturedScrollDepth: 0,
|
|
8758
|
+
|
|
8759
|
+
|
|
8760
|
+
captureScroll: function() {
|
|
8761
|
+
if (!(this.capturedScrollDepth++)) {
|
|
8762
|
+
this.capturedScroll = this.isDateRendered ? this.queryScroll() : {}; // require a render first
|
|
8763
|
+
return true; // root?
|
|
8764
|
+
}
|
|
8765
|
+
return false;
|
|
8370
8766
|
},
|
|
8371
8767
|
|
|
8372
8768
|
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8769
|
+
captureInitialScroll: function(forcedScroll) {
|
|
8770
|
+
if (this.captureScroll()) { // root?
|
|
8771
|
+
this.capturedScroll.isInitial = true;
|
|
8772
|
+
|
|
8773
|
+
if (forcedScroll) {
|
|
8774
|
+
$.extend(this.capturedScroll, forcedScroll);
|
|
8775
|
+
}
|
|
8776
|
+
else {
|
|
8777
|
+
this.capturedScroll.isComputed = true;
|
|
8778
|
+
}
|
|
8779
|
+
}
|
|
8376
8780
|
},
|
|
8377
8781
|
|
|
8378
8782
|
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8783
|
+
releaseScroll: function() {
|
|
8784
|
+
var scroll = this.capturedScroll;
|
|
8785
|
+
var isRoot = this.discardScroll();
|
|
8786
|
+
|
|
8787
|
+
if (scroll.isComputed) {
|
|
8788
|
+
if (isRoot) {
|
|
8789
|
+
// only compute initial scroll if it will actually be used (is the root capture)
|
|
8790
|
+
$.extend(scroll, this.computeInitialScroll());
|
|
8791
|
+
}
|
|
8792
|
+
else {
|
|
8793
|
+
scroll = null; // scroll couldn't be computed. don't apply it to the DOM
|
|
8794
|
+
}
|
|
8795
|
+
}
|
|
8796
|
+
|
|
8797
|
+
if (scroll) {
|
|
8798
|
+
// we act immediately on a releaseScroll operation, as opposed to captureScroll.
|
|
8799
|
+
// if capture/release wraps a render operation that screws up the scroll,
|
|
8800
|
+
// we still want to restore it a good state after, regardless of depth.
|
|
8801
|
+
|
|
8802
|
+
if (scroll.isInitial) {
|
|
8803
|
+
this.hardSetScroll(scroll); // outsmart how browsers set scroll on initial DOM
|
|
8804
|
+
}
|
|
8805
|
+
else {
|
|
8806
|
+
this.setScroll(scroll);
|
|
8807
|
+
}
|
|
8808
|
+
}
|
|
8809
|
+
},
|
|
8810
|
+
|
|
8811
|
+
|
|
8812
|
+
discardScroll: function() {
|
|
8813
|
+
if (!(--this.capturedScrollDepth)) {
|
|
8814
|
+
this.capturedScroll = null;
|
|
8815
|
+
return true; // root?
|
|
8816
|
+
}
|
|
8817
|
+
return false;
|
|
8818
|
+
},
|
|
8819
|
+
|
|
8820
|
+
|
|
8821
|
+
computeInitialScroll: function() {
|
|
8822
|
+
return {};
|
|
8823
|
+
},
|
|
8824
|
+
|
|
8825
|
+
|
|
8826
|
+
queryScroll: function() {
|
|
8827
|
+
return {};
|
|
8382
8828
|
},
|
|
8383
8829
|
|
|
8384
8830
|
|
|
8385
|
-
|
|
8386
|
-
forceScroll: function(scrollState) {
|
|
8831
|
+
hardSetScroll: function(scroll) {
|
|
8387
8832
|
var _this = this;
|
|
8833
|
+
var exec = function() { _this.setScroll(scroll); };
|
|
8834
|
+
exec();
|
|
8835
|
+
setTimeout(exec, 0); // to surely clear the browser's initial scroll for the DOM
|
|
8836
|
+
},
|
|
8388
8837
|
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
_this.setScroll(scrollState);
|
|
8392
|
-
}, 0);
|
|
8838
|
+
|
|
8839
|
+
setScroll: function(scroll) {
|
|
8393
8840
|
},
|
|
8394
8841
|
|
|
8395
8842
|
|
|
8396
|
-
/*
|
|
8843
|
+
/* Height Freezing
|
|
8397
8844
|
------------------------------------------------------------------------------------------------------------------*/
|
|
8398
8845
|
|
|
8399
8846
|
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8847
|
+
freezeHeight: function() {
|
|
8848
|
+
this.calendar.freezeContentHeight();
|
|
8849
|
+
},
|
|
8850
|
+
|
|
8851
|
+
|
|
8852
|
+
thawHeight: function() {
|
|
8853
|
+
this.calendar.thawContentHeight();
|
|
8854
|
+
},
|
|
8855
|
+
|
|
8856
|
+
|
|
8857
|
+
// Event Binding/Unbinding
|
|
8858
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8859
|
+
|
|
8860
|
+
|
|
8861
|
+
bindEvents: function() {
|
|
8862
|
+
var _this = this;
|
|
8863
|
+
|
|
8864
|
+
if (!this.isEventsBound) {
|
|
8865
|
+
this.isEventsBound = true;
|
|
8866
|
+
this.rejectOn('eventsUnbind', this.requestEvents()).then(function(events) { // TODO: test rejection
|
|
8867
|
+
_this.listenTo(_this.calendar, 'eventsReset', _this.setEvents);
|
|
8868
|
+
_this.setEvents(events);
|
|
8869
|
+
});
|
|
8870
|
+
}
|
|
8871
|
+
},
|
|
8872
|
+
|
|
8873
|
+
|
|
8874
|
+
unbindEvents: function() {
|
|
8875
|
+
if (this.isEventsBound) {
|
|
8876
|
+
this.isEventsBound = false;
|
|
8877
|
+
this.stopListeningTo(this.calendar, 'eventsReset');
|
|
8878
|
+
this.unsetEvents();
|
|
8879
|
+
this.trigger('eventsUnbind');
|
|
8880
|
+
}
|
|
8881
|
+
},
|
|
8882
|
+
|
|
8883
|
+
|
|
8884
|
+
// Event Setting/Unsetting
|
|
8885
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8886
|
+
|
|
8887
|
+
|
|
8888
|
+
setEvents: function(events) {
|
|
8889
|
+
var isReset = this.isEventSet;
|
|
8890
|
+
|
|
8891
|
+
this.isEventsSet = true;
|
|
8892
|
+
this.handleEvents(events, isReset);
|
|
8893
|
+
this.trigger(isReset ? 'eventsReset' : 'eventsSet', events);
|
|
8894
|
+
},
|
|
8895
|
+
|
|
8896
|
+
|
|
8897
|
+
unsetEvents: function() {
|
|
8898
|
+
if (this.isEventsSet) {
|
|
8899
|
+
this.isEventsSet = false;
|
|
8900
|
+
this.handleEventsUnset();
|
|
8901
|
+
this.trigger('eventsUnset');
|
|
8902
|
+
}
|
|
8903
|
+
},
|
|
8904
|
+
|
|
8905
|
+
|
|
8906
|
+
whenEventsSet: function() {
|
|
8907
|
+
var _this = this;
|
|
8908
|
+
|
|
8909
|
+
if (this.isEventsSet) {
|
|
8910
|
+
return Promise.resolve(this.getCurrentEvents());
|
|
8911
|
+
}
|
|
8912
|
+
else {
|
|
8913
|
+
return new Promise(function(resolve) {
|
|
8914
|
+
_this.one('eventsSet', resolve);
|
|
8915
|
+
});
|
|
8916
|
+
}
|
|
8917
|
+
},
|
|
8918
|
+
|
|
8919
|
+
|
|
8920
|
+
// Event Handling
|
|
8921
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8403
8922
|
|
|
8404
|
-
|
|
8405
|
-
|
|
8406
|
-
this.
|
|
8407
|
-
|
|
8408
|
-
|
|
8923
|
+
|
|
8924
|
+
handleEvents: function(events, isReset) {
|
|
8925
|
+
this.requestEventsRender(events);
|
|
8926
|
+
},
|
|
8927
|
+
|
|
8928
|
+
|
|
8929
|
+
handleEventsUnset: function() {
|
|
8930
|
+
this.requestEventsUnrender();
|
|
8931
|
+
},
|
|
8932
|
+
|
|
8933
|
+
|
|
8934
|
+
// Event Render Queuing
|
|
8935
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8936
|
+
|
|
8937
|
+
|
|
8938
|
+
// assumes any previous event renders have been cleared already
|
|
8939
|
+
requestEventsRender: function(events) {
|
|
8940
|
+
var _this = this;
|
|
8941
|
+
|
|
8942
|
+
return this.eventRenderQueue.add(function() { // might not return a promise if debounced!? bad
|
|
8943
|
+
return _this.executeEventsRender(events);
|
|
8944
|
+
});
|
|
8945
|
+
},
|
|
8946
|
+
|
|
8947
|
+
|
|
8948
|
+
requestEventsUnrender: function() {
|
|
8949
|
+
var _this = this;
|
|
8950
|
+
|
|
8951
|
+
if (this.isEventsRendered) {
|
|
8952
|
+
return this.eventRenderQueue.addQuickly(function() {
|
|
8953
|
+
return _this.executeEventsUnrender();
|
|
8954
|
+
});
|
|
8955
|
+
}
|
|
8956
|
+
else {
|
|
8957
|
+
return Promise.resolve();
|
|
8958
|
+
}
|
|
8959
|
+
},
|
|
8960
|
+
|
|
8961
|
+
|
|
8962
|
+
requestCurrentEventsRender: function() {
|
|
8963
|
+
if (this.isEventsSet) {
|
|
8964
|
+
this.requestEventsRender(this.getCurrentEvents());
|
|
8965
|
+
}
|
|
8966
|
+
else {
|
|
8967
|
+
return Promise.reject();
|
|
8968
|
+
}
|
|
8409
8969
|
},
|
|
8410
8970
|
|
|
8411
8971
|
|
|
8412
|
-
//
|
|
8413
|
-
|
|
8414
|
-
|
|
8972
|
+
// Event High-level Rendering
|
|
8973
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
8974
|
+
|
|
8975
|
+
|
|
8976
|
+
executeEventsRender: function(events) {
|
|
8977
|
+
var _this = this;
|
|
8978
|
+
|
|
8979
|
+
this.captureScroll();
|
|
8980
|
+
this.freezeHeight();
|
|
8981
|
+
|
|
8982
|
+
return this.executeEventsUnrender().then(function() {
|
|
8983
|
+
_this.renderEvents(events);
|
|
8984
|
+
|
|
8985
|
+
_this.thawHeight();
|
|
8986
|
+
_this.releaseScroll();
|
|
8987
|
+
|
|
8988
|
+
_this.isEventsRendered = true;
|
|
8989
|
+
_this.onEventsRender();
|
|
8990
|
+
_this.trigger('eventsRender');
|
|
8991
|
+
});
|
|
8992
|
+
},
|
|
8993
|
+
|
|
8415
8994
|
|
|
8995
|
+
executeEventsUnrender: function() {
|
|
8416
8996
|
if (this.isEventsRendered) {
|
|
8997
|
+
this.onBeforeEventsUnrender();
|
|
8417
8998
|
|
|
8418
|
-
|
|
8419
|
-
|
|
8999
|
+
this.captureScroll();
|
|
9000
|
+
this.freezeHeight();
|
|
8420
9001
|
|
|
8421
|
-
this.triggerEventUnrender();
|
|
8422
9002
|
if (this.destroyEvents) {
|
|
8423
9003
|
this.destroyEvents(); // TODO: deprecate
|
|
8424
9004
|
}
|
|
9005
|
+
|
|
8425
9006
|
this.unrenderEvents();
|
|
8426
|
-
|
|
9007
|
+
|
|
9008
|
+
this.thawHeight();
|
|
9009
|
+
this.releaseScroll();
|
|
9010
|
+
|
|
8427
9011
|
this.isEventsRendered = false;
|
|
9012
|
+
this.trigger('eventsUnrender');
|
|
8428
9013
|
}
|
|
9014
|
+
|
|
9015
|
+
return Promise.resolve(); // always synchronous
|
|
9016
|
+
},
|
|
9017
|
+
|
|
9018
|
+
|
|
9019
|
+
// Event Rendering Triggers
|
|
9020
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
9021
|
+
|
|
9022
|
+
|
|
9023
|
+
// Signals that all events have been rendered
|
|
9024
|
+
onEventsRender: function() {
|
|
9025
|
+
this.renderedEventSegEach(function(seg) {
|
|
9026
|
+
this.publiclyTrigger('eventAfterRender', seg.event, seg.event, seg.el);
|
|
9027
|
+
});
|
|
9028
|
+
this.publiclyTrigger('eventAfterAllRender');
|
|
9029
|
+
},
|
|
9030
|
+
|
|
9031
|
+
|
|
9032
|
+
// Signals that all event elements are about to be removed
|
|
9033
|
+
onBeforeEventsUnrender: function() {
|
|
9034
|
+
this.renderedEventSegEach(function(seg) {
|
|
9035
|
+
this.publiclyTrigger('eventDestroy', seg.event, seg.event, seg.el);
|
|
9036
|
+
});
|
|
8429
9037
|
},
|
|
8430
9038
|
|
|
8431
9039
|
|
|
9040
|
+
// Event Low-level Rendering
|
|
9041
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
9042
|
+
|
|
9043
|
+
|
|
8432
9044
|
// Renders the events onto the view.
|
|
8433
9045
|
renderEvents: function(events) {
|
|
8434
9046
|
// subclasses should implement
|
|
@@ -8441,27 +9053,28 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8441
9053
|
},
|
|
8442
9054
|
|
|
8443
9055
|
|
|
8444
|
-
//
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
this.
|
|
9056
|
+
// Event Data Access
|
|
9057
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
9058
|
+
|
|
9059
|
+
|
|
9060
|
+
requestEvents: function() {
|
|
9061
|
+
return this.calendar.requestEvents(this.start, this.end);
|
|
8450
9062
|
},
|
|
8451
9063
|
|
|
8452
9064
|
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
this.renderedEventSegEach(function(seg) {
|
|
8456
|
-
this.trigger('eventDestroy', seg.event, seg.event, seg.el);
|
|
8457
|
-
});
|
|
9065
|
+
getCurrentEvents: function() {
|
|
9066
|
+
return this.calendar.getPrunedEventCache();
|
|
8458
9067
|
},
|
|
8459
9068
|
|
|
8460
9069
|
|
|
9070
|
+
// Event Rendering Utils
|
|
9071
|
+
// -----------------------------------------------------------------------------------------------------------------
|
|
9072
|
+
|
|
9073
|
+
|
|
8461
9074
|
// Given an event and the default element used for rendering, returns the element that should actually be used.
|
|
8462
9075
|
// Basically runs events and elements through the eventRender hook.
|
|
8463
9076
|
resolveEventEl: function(event, el) {
|
|
8464
|
-
var custom = this.
|
|
9077
|
+
var custom = this.publiclyTrigger('eventRender', event, event, el);
|
|
8465
9078
|
|
|
8466
9079
|
if (custom === false) { // means don't render at all
|
|
8467
9080
|
el = null;
|
|
@@ -8560,7 +9173,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8560
9173
|
|
|
8561
9174
|
// Triggers event-drop handlers that have subscribed via the API
|
|
8562
9175
|
triggerEventDrop: function(event, dateDelta, undoFunc, el, ev) {
|
|
8563
|
-
this.
|
|
9176
|
+
this.publiclyTrigger('eventDrop', el[0], event, dateDelta, undoFunc, ev, {}); // {} = jqui dummy
|
|
8564
9177
|
},
|
|
8565
9178
|
|
|
8566
9179
|
|
|
@@ -8590,10 +9203,10 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8590
9203
|
triggerExternalDrop: function(event, dropLocation, el, ev, ui) {
|
|
8591
9204
|
|
|
8592
9205
|
// trigger 'drop' regardless of whether element represents an event
|
|
8593
|
-
this.
|
|
9206
|
+
this.publiclyTrigger('drop', el[0], dropLocation.start, ev, ui);
|
|
8594
9207
|
|
|
8595
9208
|
if (event) {
|
|
8596
|
-
this.
|
|
9209
|
+
this.publiclyTrigger('eventReceive', null, event); // signal an external event landed
|
|
8597
9210
|
}
|
|
8598
9211
|
},
|
|
8599
9212
|
|
|
@@ -8663,7 +9276,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8663
9276
|
|
|
8664
9277
|
// Triggers event-resize handlers that have subscribed via the API
|
|
8665
9278
|
triggerEventResize: function(event, durationDelta, undoFunc, el, ev) {
|
|
8666
|
-
this.
|
|
9279
|
+
this.publiclyTrigger('eventResize', el[0], event, durationDelta, undoFunc, ev, {}); // {} = jqui dummy
|
|
8667
9280
|
},
|
|
8668
9281
|
|
|
8669
9282
|
|
|
@@ -8695,7 +9308,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8695
9308
|
|
|
8696
9309
|
// Triggers handlers to 'select'
|
|
8697
9310
|
triggerSelect: function(span, ev) {
|
|
8698
|
-
this.
|
|
9311
|
+
this.publiclyTrigger(
|
|
8699
9312
|
'select',
|
|
8700
9313
|
null,
|
|
8701
9314
|
this.calendar.applyTimezone(span.start), // convert to calendar's tz for external API
|
|
@@ -8714,7 +9327,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8714
9327
|
this.destroySelection(); // TODO: deprecate
|
|
8715
9328
|
}
|
|
8716
9329
|
this.unrenderSelection();
|
|
8717
|
-
this.
|
|
9330
|
+
this.publiclyTrigger('unselect', null, ev);
|
|
8718
9331
|
}
|
|
8719
9332
|
},
|
|
8720
9333
|
|
|
@@ -8806,7 +9419,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
8806
9419
|
// Triggers handlers to 'dayClick'
|
|
8807
9420
|
// Span has start/end of the clicked area. Only the start is useful.
|
|
8808
9421
|
triggerDayClick: function(span, dayEl, ev) {
|
|
8809
|
-
this.
|
|
9422
|
+
this.publiclyTrigger(
|
|
8810
9423
|
'dayClick',
|
|
8811
9424
|
dayEl,
|
|
8812
9425
|
this.calendar.applyTimezone(span.start), // convert to calendar's timezone for external API
|
|
@@ -9033,31 +9646,321 @@ var Scroller = FC.Scroller = Class.extend({
|
|
|
9033
9646
|
});
|
|
9034
9647
|
|
|
9035
9648
|
;;
|
|
9649
|
+
function Iterator(items) {
|
|
9650
|
+
this.items = items || [];
|
|
9651
|
+
}
|
|
9036
9652
|
|
|
9037
|
-
var Calendar = FC.Calendar = Class.extend({
|
|
9038
9653
|
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
options: null, // all defaults combined with overrides
|
|
9044
|
-
viewSpecCache: null, // cache of view definitions
|
|
9045
|
-
view: null, // current View object
|
|
9046
|
-
header: null,
|
|
9047
|
-
loadingLevel: 0, // number of simultaneous loading tasks
|
|
9654
|
+
/* Calls a method on every item passing the arguments through */
|
|
9655
|
+
Iterator.prototype.proxyCall = function(methodName) {
|
|
9656
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
9657
|
+
var results = [];
|
|
9048
9658
|
|
|
9659
|
+
this.items.forEach(function(item) {
|
|
9660
|
+
results.push(item[methodName].apply(item, args));
|
|
9661
|
+
});
|
|
9049
9662
|
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
constructor: Calendar_constructor,
|
|
9663
|
+
return results;
|
|
9664
|
+
};
|
|
9053
9665
|
|
|
9666
|
+
;;
|
|
9054
9667
|
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
},
|
|
9668
|
+
/* Toolbar with buttons and title
|
|
9669
|
+
----------------------------------------------------------------------------------------------------------------------*/
|
|
9058
9670
|
|
|
9671
|
+
function Toolbar(calendar, toolbarOptions) {
|
|
9672
|
+
var t = this;
|
|
9059
9673
|
|
|
9060
|
-
//
|
|
9674
|
+
// exports
|
|
9675
|
+
t.setToolbarOptions = setToolbarOptions;
|
|
9676
|
+
t.render = render;
|
|
9677
|
+
t.removeElement = removeElement;
|
|
9678
|
+
t.updateTitle = updateTitle;
|
|
9679
|
+
t.activateButton = activateButton;
|
|
9680
|
+
t.deactivateButton = deactivateButton;
|
|
9681
|
+
t.disableButton = disableButton;
|
|
9682
|
+
t.enableButton = enableButton;
|
|
9683
|
+
t.getViewsWithButtons = getViewsWithButtons;
|
|
9684
|
+
t.el = null; // mirrors local `el`
|
|
9685
|
+
|
|
9686
|
+
// locals
|
|
9687
|
+
var el;
|
|
9688
|
+
var viewsWithButtons = [];
|
|
9689
|
+
var tm;
|
|
9690
|
+
|
|
9691
|
+
// method to update toolbar-specific options, not calendar-wide options
|
|
9692
|
+
function setToolbarOptions(newToolbarOptions) {
|
|
9693
|
+
toolbarOptions = newToolbarOptions;
|
|
9694
|
+
}
|
|
9695
|
+
|
|
9696
|
+
// can be called repeatedly and will rerender
|
|
9697
|
+
function render() {
|
|
9698
|
+
var sections = toolbarOptions.layout;
|
|
9699
|
+
|
|
9700
|
+
tm = calendar.options.theme ? 'ui' : 'fc';
|
|
9701
|
+
|
|
9702
|
+
if (sections) {
|
|
9703
|
+
if (!el) {
|
|
9704
|
+
el = this.el = $("<div class='fc-toolbar "+ toolbarOptions.extraClasses + "'/>");
|
|
9705
|
+
}
|
|
9706
|
+
else {
|
|
9707
|
+
el.empty();
|
|
9708
|
+
}
|
|
9709
|
+
el.append(renderSection('left'))
|
|
9710
|
+
.append(renderSection('right'))
|
|
9711
|
+
.append(renderSection('center'))
|
|
9712
|
+
.append('<div class="fc-clear"/>');
|
|
9713
|
+
}
|
|
9714
|
+
else {
|
|
9715
|
+
removeElement();
|
|
9716
|
+
}
|
|
9717
|
+
}
|
|
9718
|
+
|
|
9719
|
+
|
|
9720
|
+
function removeElement() {
|
|
9721
|
+
if (el) {
|
|
9722
|
+
el.remove();
|
|
9723
|
+
el = t.el = null;
|
|
9724
|
+
}
|
|
9725
|
+
}
|
|
9726
|
+
|
|
9727
|
+
|
|
9728
|
+
function renderSection(position) {
|
|
9729
|
+
var sectionEl = $('<div class="fc-' + position + '"/>');
|
|
9730
|
+
var buttonStr = toolbarOptions.layout[position];
|
|
9731
|
+
|
|
9732
|
+
if (buttonStr) {
|
|
9733
|
+
$.each(buttonStr.split(' '), function(i) {
|
|
9734
|
+
var groupChildren = $();
|
|
9735
|
+
var isOnlyButtons = true;
|
|
9736
|
+
var groupEl;
|
|
9737
|
+
|
|
9738
|
+
$.each(this.split(','), function(j, buttonName) {
|
|
9739
|
+
var customButtonProps;
|
|
9740
|
+
var viewSpec;
|
|
9741
|
+
var buttonClick;
|
|
9742
|
+
var overrideText; // text explicitly set by calendar's constructor options. overcomes icons
|
|
9743
|
+
var defaultText;
|
|
9744
|
+
var themeIcon;
|
|
9745
|
+
var normalIcon;
|
|
9746
|
+
var innerHtml;
|
|
9747
|
+
var classes;
|
|
9748
|
+
var button; // the element
|
|
9749
|
+
|
|
9750
|
+
if (buttonName == 'title') {
|
|
9751
|
+
groupChildren = groupChildren.add($('<h2> </h2>')); // we always want it to take up height
|
|
9752
|
+
isOnlyButtons = false;
|
|
9753
|
+
}
|
|
9754
|
+
else {
|
|
9755
|
+
if ((customButtonProps = (calendar.options.customButtons || {})[buttonName])) {
|
|
9756
|
+
buttonClick = function(ev) {
|
|
9757
|
+
if (customButtonProps.click) {
|
|
9758
|
+
customButtonProps.click.call(button[0], ev);
|
|
9759
|
+
}
|
|
9760
|
+
};
|
|
9761
|
+
overrideText = ''; // icons will override text
|
|
9762
|
+
defaultText = customButtonProps.text;
|
|
9763
|
+
}
|
|
9764
|
+
else if ((viewSpec = calendar.getViewSpec(buttonName))) {
|
|
9765
|
+
buttonClick = function() {
|
|
9766
|
+
calendar.changeView(buttonName);
|
|
9767
|
+
};
|
|
9768
|
+
viewsWithButtons.push(buttonName);
|
|
9769
|
+
overrideText = viewSpec.buttonTextOverride;
|
|
9770
|
+
defaultText = viewSpec.buttonTextDefault;
|
|
9771
|
+
}
|
|
9772
|
+
else if (calendar[buttonName]) { // a calendar method
|
|
9773
|
+
buttonClick = function() {
|
|
9774
|
+
calendar[buttonName]();
|
|
9775
|
+
};
|
|
9776
|
+
overrideText = (calendar.overrides.buttonText || {})[buttonName];
|
|
9777
|
+
defaultText = calendar.options.buttonText[buttonName]; // everything else is considered default
|
|
9778
|
+
}
|
|
9779
|
+
|
|
9780
|
+
if (buttonClick) {
|
|
9781
|
+
|
|
9782
|
+
themeIcon =
|
|
9783
|
+
customButtonProps ?
|
|
9784
|
+
customButtonProps.themeIcon :
|
|
9785
|
+
calendar.options.themeButtonIcons[buttonName];
|
|
9786
|
+
|
|
9787
|
+
normalIcon =
|
|
9788
|
+
customButtonProps ?
|
|
9789
|
+
customButtonProps.icon :
|
|
9790
|
+
calendar.options.buttonIcons[buttonName];
|
|
9791
|
+
|
|
9792
|
+
if (overrideText) {
|
|
9793
|
+
innerHtml = htmlEscape(overrideText);
|
|
9794
|
+
}
|
|
9795
|
+
else if (themeIcon && calendar.options.theme) {
|
|
9796
|
+
innerHtml = "<span class='ui-icon ui-icon-" + themeIcon + "'></span>";
|
|
9797
|
+
}
|
|
9798
|
+
else if (normalIcon && !calendar.options.theme) {
|
|
9799
|
+
innerHtml = "<span class='fc-icon fc-icon-" + normalIcon + "'></span>";
|
|
9800
|
+
}
|
|
9801
|
+
else {
|
|
9802
|
+
innerHtml = htmlEscape(defaultText);
|
|
9803
|
+
}
|
|
9804
|
+
|
|
9805
|
+
classes = [
|
|
9806
|
+
'fc-' + buttonName + '-button',
|
|
9807
|
+
tm + '-button',
|
|
9808
|
+
tm + '-state-default'
|
|
9809
|
+
];
|
|
9810
|
+
|
|
9811
|
+
button = $( // type="button" so that it doesn't submit a form
|
|
9812
|
+
'<button type="button" class="' + classes.join(' ') + '">' +
|
|
9813
|
+
innerHtml +
|
|
9814
|
+
'</button>'
|
|
9815
|
+
)
|
|
9816
|
+
.click(function(ev) {
|
|
9817
|
+
// don't process clicks for disabled buttons
|
|
9818
|
+
if (!button.hasClass(tm + '-state-disabled')) {
|
|
9819
|
+
|
|
9820
|
+
buttonClick(ev);
|
|
9821
|
+
|
|
9822
|
+
// after the click action, if the button becomes the "active" tab, or disabled,
|
|
9823
|
+
// it should never have a hover class, so remove it now.
|
|
9824
|
+
if (
|
|
9825
|
+
button.hasClass(tm + '-state-active') ||
|
|
9826
|
+
button.hasClass(tm + '-state-disabled')
|
|
9827
|
+
) {
|
|
9828
|
+
button.removeClass(tm + '-state-hover');
|
|
9829
|
+
}
|
|
9830
|
+
}
|
|
9831
|
+
})
|
|
9832
|
+
.mousedown(function() {
|
|
9833
|
+
// the *down* effect (mouse pressed in).
|
|
9834
|
+
// only on buttons that are not the "active" tab, or disabled
|
|
9835
|
+
button
|
|
9836
|
+
.not('.' + tm + '-state-active')
|
|
9837
|
+
.not('.' + tm + '-state-disabled')
|
|
9838
|
+
.addClass(tm + '-state-down');
|
|
9839
|
+
})
|
|
9840
|
+
.mouseup(function() {
|
|
9841
|
+
// undo the *down* effect
|
|
9842
|
+
button.removeClass(tm + '-state-down');
|
|
9843
|
+
})
|
|
9844
|
+
.hover(
|
|
9845
|
+
function() {
|
|
9846
|
+
// the *hover* effect.
|
|
9847
|
+
// only on buttons that are not the "active" tab, or disabled
|
|
9848
|
+
button
|
|
9849
|
+
.not('.' + tm + '-state-active')
|
|
9850
|
+
.not('.' + tm + '-state-disabled')
|
|
9851
|
+
.addClass(tm + '-state-hover');
|
|
9852
|
+
},
|
|
9853
|
+
function() {
|
|
9854
|
+
// undo the *hover* effect
|
|
9855
|
+
button
|
|
9856
|
+
.removeClass(tm + '-state-hover')
|
|
9857
|
+
.removeClass(tm + '-state-down'); // if mouseleave happens before mouseup
|
|
9858
|
+
}
|
|
9859
|
+
);
|
|
9860
|
+
|
|
9861
|
+
groupChildren = groupChildren.add(button);
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9864
|
+
});
|
|
9865
|
+
|
|
9866
|
+
if (isOnlyButtons) {
|
|
9867
|
+
groupChildren
|
|
9868
|
+
.first().addClass(tm + '-corner-left').end()
|
|
9869
|
+
.last().addClass(tm + '-corner-right').end();
|
|
9870
|
+
}
|
|
9871
|
+
|
|
9872
|
+
if (groupChildren.length > 1) {
|
|
9873
|
+
groupEl = $('<div/>');
|
|
9874
|
+
if (isOnlyButtons) {
|
|
9875
|
+
groupEl.addClass('fc-button-group');
|
|
9876
|
+
}
|
|
9877
|
+
groupEl.append(groupChildren);
|
|
9878
|
+
sectionEl.append(groupEl);
|
|
9879
|
+
}
|
|
9880
|
+
else {
|
|
9881
|
+
sectionEl.append(groupChildren); // 1 or 0 children
|
|
9882
|
+
}
|
|
9883
|
+
});
|
|
9884
|
+
}
|
|
9885
|
+
|
|
9886
|
+
return sectionEl;
|
|
9887
|
+
}
|
|
9888
|
+
|
|
9889
|
+
|
|
9890
|
+
function updateTitle(text) {
|
|
9891
|
+
if (el) {
|
|
9892
|
+
el.find('h2').text(text);
|
|
9893
|
+
}
|
|
9894
|
+
}
|
|
9895
|
+
|
|
9896
|
+
|
|
9897
|
+
function activateButton(buttonName) {
|
|
9898
|
+
if (el) {
|
|
9899
|
+
el.find('.fc-' + buttonName + '-button')
|
|
9900
|
+
.addClass(tm + '-state-active');
|
|
9901
|
+
}
|
|
9902
|
+
}
|
|
9903
|
+
|
|
9904
|
+
|
|
9905
|
+
function deactivateButton(buttonName) {
|
|
9906
|
+
if (el) {
|
|
9907
|
+
el.find('.fc-' + buttonName + '-button')
|
|
9908
|
+
.removeClass(tm + '-state-active');
|
|
9909
|
+
}
|
|
9910
|
+
}
|
|
9911
|
+
|
|
9912
|
+
|
|
9913
|
+
function disableButton(buttonName) {
|
|
9914
|
+
if (el) {
|
|
9915
|
+
el.find('.fc-' + buttonName + '-button')
|
|
9916
|
+
.prop('disabled', true)
|
|
9917
|
+
.addClass(tm + '-state-disabled');
|
|
9918
|
+
}
|
|
9919
|
+
}
|
|
9920
|
+
|
|
9921
|
+
|
|
9922
|
+
function enableButton(buttonName) {
|
|
9923
|
+
if (el) {
|
|
9924
|
+
el.find('.fc-' + buttonName + '-button')
|
|
9925
|
+
.prop('disabled', false)
|
|
9926
|
+
.removeClass(tm + '-state-disabled');
|
|
9927
|
+
}
|
|
9928
|
+
}
|
|
9929
|
+
|
|
9930
|
+
|
|
9931
|
+
function getViewsWithButtons() {
|
|
9932
|
+
return viewsWithButtons;
|
|
9933
|
+
}
|
|
9934
|
+
|
|
9935
|
+
}
|
|
9936
|
+
|
|
9937
|
+
;;
|
|
9938
|
+
|
|
9939
|
+
var Calendar = FC.Calendar = Class.extend({
|
|
9940
|
+
|
|
9941
|
+
dirDefaults: null, // option defaults related to LTR or RTL
|
|
9942
|
+
localeDefaults: null, // option defaults related to current locale
|
|
9943
|
+
overrides: null, // option overrides given to the fullCalendar constructor
|
|
9944
|
+
dynamicOverrides: null, // options set with dynamic setter method. higher precedence than view overrides.
|
|
9945
|
+
options: null, // all defaults combined with overrides
|
|
9946
|
+
viewSpecCache: null, // cache of view definitions
|
|
9947
|
+
view: null, // current View object
|
|
9948
|
+
header: null,
|
|
9949
|
+
footer: null,
|
|
9950
|
+
loadingLevel: 0, // number of simultaneous loading tasks
|
|
9951
|
+
|
|
9952
|
+
|
|
9953
|
+
// a lot of this class' OOP logic is scoped within this constructor function,
|
|
9954
|
+
// but in the future, write individual methods on the prototype.
|
|
9955
|
+
constructor: Calendar_constructor,
|
|
9956
|
+
|
|
9957
|
+
|
|
9958
|
+
// Subclasses can override this for initialization logic after the constructor has been called
|
|
9959
|
+
initialize: function() {
|
|
9960
|
+
},
|
|
9961
|
+
|
|
9962
|
+
|
|
9963
|
+
// Computes the flattened options hash for the calendar and assigns to `this.options`.
|
|
9061
9964
|
// Assumes this.overrides and this.dynamicOverrides have already been initialized.
|
|
9062
9965
|
populateOptionsHash: function() {
|
|
9063
9966
|
var locale, localeDefaults;
|
|
@@ -9112,7 +10015,7 @@ var Calendar = FC.Calendar = Class.extend({
|
|
|
9112
10015
|
if ($.inArray(unit, intervalUnits) != -1) {
|
|
9113
10016
|
|
|
9114
10017
|
// put views that have buttons first. there will be duplicates, but oh well
|
|
9115
|
-
viewTypes = this.header.getViewsWithButtons();
|
|
10018
|
+
viewTypes = this.header.getViewsWithButtons(); // TODO: include footer as well?
|
|
9116
10019
|
$.each(FC.views, function(viewType) { // all views
|
|
9117
10020
|
viewTypes.push(viewType);
|
|
9118
10021
|
});
|
|
@@ -9259,7 +10162,7 @@ var Calendar = FC.Calendar = Class.extend({
|
|
|
9259
10162
|
// Should be called when any type of async data fetching begins
|
|
9260
10163
|
pushLoading: function() {
|
|
9261
10164
|
if (!(this.loadingLevel++)) {
|
|
9262
|
-
this.
|
|
10165
|
+
this.publiclyTrigger('loading', null, true, this.view);
|
|
9263
10166
|
}
|
|
9264
10167
|
},
|
|
9265
10168
|
|
|
@@ -9267,7 +10170,7 @@ var Calendar = FC.Calendar = Class.extend({
|
|
|
9267
10170
|
// Should be called when any type of async data fetching completes
|
|
9268
10171
|
popLoading: function() {
|
|
9269
10172
|
if (!(--this.loadingLevel)) {
|
|
9270
|
-
this.
|
|
10173
|
+
this.publiclyTrigger('loading', null, false, this.view);
|
|
9271
10174
|
}
|
|
9272
10175
|
},
|
|
9273
10176
|
|
|
@@ -9305,11 +10208,7 @@ function Calendar_constructor(element, overrides) {
|
|
|
9305
10208
|
|
|
9306
10209
|
t.render = render;
|
|
9307
10210
|
t.destroy = destroy;
|
|
9308
|
-
t.
|
|
9309
|
-
t.refetchEventSources = refetchEventSources;
|
|
9310
|
-
t.reportEvents = reportEvents;
|
|
9311
|
-
t.reportEventChange = reportEventChange;
|
|
9312
|
-
t.rerenderEvents = renderEvents; // `renderEvents` serves as a rerender. an API method
|
|
10211
|
+
t.rerenderEvents = rerenderEvents;
|
|
9313
10212
|
t.changeView = renderView; // `renderView` will switch to another view
|
|
9314
10213
|
t.select = select;
|
|
9315
10214
|
t.unselect = unselect;
|
|
@@ -9325,7 +10224,7 @@ function Calendar_constructor(element, overrides) {
|
|
|
9325
10224
|
t.getCalendar = getCalendar;
|
|
9326
10225
|
t.getView = getView;
|
|
9327
10226
|
t.option = option; // getter/setter method
|
|
9328
|
-
t.
|
|
10227
|
+
t.publiclyTrigger = publiclyTrigger;
|
|
9329
10228
|
|
|
9330
10229
|
|
|
9331
10230
|
// Options
|
|
@@ -9518,15 +10417,12 @@ function Calendar_constructor(element, overrides) {
|
|
|
9518
10417
|
};
|
|
9519
10418
|
|
|
9520
10419
|
|
|
9521
|
-
|
|
10420
|
+
|
|
9522
10421
|
// Imports
|
|
9523
10422
|
// -----------------------------------------------------------------------------------
|
|
9524
10423
|
|
|
9525
10424
|
|
|
9526
10425
|
EventManager.call(t);
|
|
9527
|
-
var isFetchNeeded = t.isFetchNeeded;
|
|
9528
|
-
var fetchEvents = t.fetchEvents;
|
|
9529
|
-
var fetchEventSources = t.fetchEventSources;
|
|
9530
10426
|
|
|
9531
10427
|
|
|
9532
10428
|
|
|
@@ -9535,7 +10431,9 @@ function Calendar_constructor(element, overrides) {
|
|
|
9535
10431
|
|
|
9536
10432
|
|
|
9537
10433
|
var _element = element[0];
|
|
10434
|
+
var toolbarsManager;
|
|
9538
10435
|
var header;
|
|
10436
|
+
var footer;
|
|
9539
10437
|
var content;
|
|
9540
10438
|
var tm; // for making theme classes
|
|
9541
10439
|
var currentView; // NOTE: keep this in sync with this.view
|
|
@@ -9543,11 +10441,10 @@ function Calendar_constructor(element, overrides) {
|
|
|
9543
10441
|
var suggestedViewHeight;
|
|
9544
10442
|
var windowResizeProxy; // wraps the windowResize function
|
|
9545
10443
|
var ignoreWindowResize = 0;
|
|
9546
|
-
var events = [];
|
|
9547
10444
|
var date; // unzoned
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
10445
|
+
|
|
10446
|
+
|
|
10447
|
+
|
|
9551
10448
|
// Main Rendering
|
|
9552
10449
|
// -----------------------------------------------------------------------------------
|
|
9553
10450
|
|
|
@@ -9559,8 +10456,8 @@ function Calendar_constructor(element, overrides) {
|
|
|
9559
10456
|
else {
|
|
9560
10457
|
date = t.getNow(); // getNow already returns unzoned
|
|
9561
10458
|
}
|
|
9562
|
-
|
|
9563
|
-
|
|
10459
|
+
|
|
10460
|
+
|
|
9564
10461
|
function render() {
|
|
9565
10462
|
if (!content) {
|
|
9566
10463
|
initialRender();
|
|
@@ -9571,8 +10468,8 @@ function Calendar_constructor(element, overrides) {
|
|
|
9571
10468
|
renderView();
|
|
9572
10469
|
}
|
|
9573
10470
|
}
|
|
9574
|
-
|
|
9575
|
-
|
|
10471
|
+
|
|
10472
|
+
|
|
9576
10473
|
function initialRender() {
|
|
9577
10474
|
element.addClass('fc');
|
|
9578
10475
|
|
|
@@ -9613,9 +10510,14 @@ function Calendar_constructor(element, overrides) {
|
|
|
9613
10510
|
|
|
9614
10511
|
content = $("<div class='fc-view-container'/>").prependTo(element);
|
|
9615
10512
|
|
|
9616
|
-
|
|
9617
|
-
|
|
10513
|
+
var toolbars = buildToolbars();
|
|
10514
|
+
toolbarsManager = new Iterator(toolbars);
|
|
10515
|
+
|
|
10516
|
+
header = t.header = toolbars[0];
|
|
10517
|
+
footer = t.footer = toolbars[1];
|
|
9618
10518
|
|
|
10519
|
+
renderHeader();
|
|
10520
|
+
renderFooter();
|
|
9619
10521
|
renderView(t.options.defaultView);
|
|
9620
10522
|
|
|
9621
10523
|
if (t.options.handleWindowResize) {
|
|
@@ -9625,15 +10527,6 @@ function Calendar_constructor(element, overrides) {
|
|
|
9625
10527
|
}
|
|
9626
10528
|
|
|
9627
10529
|
|
|
9628
|
-
// can be called repeatedly and Header will rerender
|
|
9629
|
-
function renderHeader() {
|
|
9630
|
-
header.render();
|
|
9631
|
-
if (header.el) {
|
|
9632
|
-
element.prepend(header.el);
|
|
9633
|
-
}
|
|
9634
|
-
}
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
10530
|
function destroy() {
|
|
9638
10531
|
|
|
9639
10532
|
if (currentView) {
|
|
@@ -9643,7 +10536,7 @@ function Calendar_constructor(element, overrides) {
|
|
|
9643
10536
|
// It is still the "current" view, just not rendered.
|
|
9644
10537
|
}
|
|
9645
10538
|
|
|
9646
|
-
|
|
10539
|
+
toolbarsManager.proxyCall('removeElement');
|
|
9647
10540
|
content.remove();
|
|
9648
10541
|
element.removeClass('fc fc-ltr fc-rtl fc-unthemed ui-widget');
|
|
9649
10542
|
|
|
@@ -9653,13 +10546,13 @@ function Calendar_constructor(element, overrides) {
|
|
|
9653
10546
|
$(window).unbind('resize', windowResizeProxy);
|
|
9654
10547
|
}
|
|
9655
10548
|
}
|
|
9656
|
-
|
|
9657
|
-
|
|
10549
|
+
|
|
10550
|
+
|
|
9658
10551
|
function elementVisible() {
|
|
9659
10552
|
return element.is(':visible');
|
|
9660
10553
|
}
|
|
9661
|
-
|
|
9662
|
-
|
|
10554
|
+
|
|
10555
|
+
|
|
9663
10556
|
|
|
9664
10557
|
// View Rendering
|
|
9665
10558
|
// -----------------------------------------------------------------------------------
|
|
@@ -9668,11 +10561,13 @@ function Calendar_constructor(element, overrides) {
|
|
|
9668
10561
|
// Renders a view because of a date change, view-type change, or for the first time.
|
|
9669
10562
|
// If not given a viewType, keep the current view but render different dates.
|
|
9670
10563
|
// Accepts an optional scroll state to restore to.
|
|
9671
|
-
function renderView(viewType,
|
|
10564
|
+
function renderView(viewType, forcedScroll) {
|
|
9672
10565
|
ignoreWindowResize++;
|
|
9673
10566
|
|
|
10567
|
+
var needsClearView = currentView && viewType && currentView.type !== viewType;
|
|
10568
|
+
|
|
9674
10569
|
// if viewType is changing, remove the old view's rendering
|
|
9675
|
-
if (
|
|
10570
|
+
if (needsClearView) {
|
|
9676
10571
|
freezeContentHeight(); // prevent a scroll jump when view element is removed
|
|
9677
10572
|
clearView();
|
|
9678
10573
|
}
|
|
@@ -9686,7 +10581,7 @@ function Calendar_constructor(element, overrides) {
|
|
|
9686
10581
|
currentView.setElement(
|
|
9687
10582
|
$("<div class='fc-view fc-" + viewType + "-view' />").appendTo(content)
|
|
9688
10583
|
);
|
|
9689
|
-
|
|
10584
|
+
toolbarsManager.proxyCall('activateButton', viewType);
|
|
9690
10585
|
}
|
|
9691
10586
|
|
|
9692
10587
|
if (currentView) {
|
|
@@ -9696,7 +10591,7 @@ function Calendar_constructor(element, overrides) {
|
|
|
9696
10591
|
|
|
9697
10592
|
// render or rerender the view
|
|
9698
10593
|
if (
|
|
9699
|
-
!currentView.
|
|
10594
|
+
!currentView.isDateSet ||
|
|
9700
10595
|
!( // NOT within interval range signals an implicit date window change
|
|
9701
10596
|
date >= currentView.intervalStart &&
|
|
9702
10597
|
date < currentView.intervalEnd
|
|
@@ -9704,19 +10599,27 @@ function Calendar_constructor(element, overrides) {
|
|
|
9704
10599
|
) {
|
|
9705
10600
|
if (elementVisible()) {
|
|
9706
10601
|
|
|
9707
|
-
|
|
9708
|
-
|
|
10602
|
+
if (forcedScroll) {
|
|
10603
|
+
currentView.captureInitialScroll(forcedScroll);
|
|
10604
|
+
}
|
|
9709
10605
|
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
10606
|
+
currentView.setDate(date, forcedScroll);
|
|
10607
|
+
|
|
10608
|
+
if (forcedScroll) {
|
|
10609
|
+
currentView.releaseScroll();
|
|
10610
|
+
}
|
|
9713
10611
|
|
|
9714
|
-
|
|
10612
|
+
// need to do this after View::render, so dates are calculated
|
|
10613
|
+
// NOTE: view updates title text proactively
|
|
10614
|
+
updateToolbarsTodayButton();
|
|
9715
10615
|
}
|
|
9716
10616
|
}
|
|
9717
10617
|
}
|
|
9718
10618
|
|
|
9719
|
-
|
|
10619
|
+
if (needsClearView) {
|
|
10620
|
+
thawContentHeight();
|
|
10621
|
+
}
|
|
10622
|
+
|
|
9720
10623
|
ignoreWindowResize--;
|
|
9721
10624
|
}
|
|
9722
10625
|
|
|
@@ -9724,7 +10627,7 @@ function Calendar_constructor(element, overrides) {
|
|
|
9724
10627
|
// Unrenders the current view and reflects this change in the Header.
|
|
9725
10628
|
// Unregsiters the `currentView`, but does not remove from viewByType hash.
|
|
9726
10629
|
function clearView() {
|
|
9727
|
-
|
|
10630
|
+
toolbarsManager.proxyCall('deactivateButton', currentView.type);
|
|
9728
10631
|
currentView.removeElement();
|
|
9729
10632
|
currentView = t.view = null;
|
|
9730
10633
|
}
|
|
@@ -9740,13 +10643,14 @@ function Calendar_constructor(element, overrides) {
|
|
|
9740
10643
|
var viewType = currentView.type;
|
|
9741
10644
|
var scrollState = currentView.queryScroll();
|
|
9742
10645
|
clearView();
|
|
10646
|
+
calcSize();
|
|
9743
10647
|
renderView(viewType, scrollState);
|
|
9744
10648
|
|
|
9745
|
-
|
|
10649
|
+
thawContentHeight();
|
|
9746
10650
|
ignoreWindowResize--;
|
|
9747
10651
|
}
|
|
9748
10652
|
|
|
9749
|
-
|
|
10653
|
+
|
|
9750
10654
|
|
|
9751
10655
|
// Resizing
|
|
9752
10656
|
// -----------------------------------------------------------------------------------
|
|
@@ -9763,8 +10667,8 @@ function Calendar_constructor(element, overrides) {
|
|
|
9763
10667
|
t.isHeightAuto = function() {
|
|
9764
10668
|
return t.options.contentHeight === 'auto' || t.options.height === 'auto';
|
|
9765
10669
|
};
|
|
9766
|
-
|
|
9767
|
-
|
|
10670
|
+
|
|
10671
|
+
|
|
9768
10672
|
function updateSize(shouldRecalc) {
|
|
9769
10673
|
if (elementVisible()) {
|
|
9770
10674
|
|
|
@@ -9786,8 +10690,8 @@ function Calendar_constructor(element, overrides) {
|
|
|
9786
10690
|
_calcSize();
|
|
9787
10691
|
}
|
|
9788
10692
|
}
|
|
9789
|
-
|
|
9790
|
-
|
|
10693
|
+
|
|
10694
|
+
|
|
9791
10695
|
function _calcSize() { // assumes elementVisible
|
|
9792
10696
|
var contentHeightInput = t.options.contentHeight;
|
|
9793
10697
|
var heightInput = t.options.height;
|
|
@@ -9799,13 +10703,13 @@ function Calendar_constructor(element, overrides) {
|
|
|
9799
10703
|
suggestedViewHeight = contentHeightInput();
|
|
9800
10704
|
}
|
|
9801
10705
|
else if (typeof heightInput === 'number') { // exists and not 'auto'
|
|
9802
|
-
suggestedViewHeight = heightInput -
|
|
10706
|
+
suggestedViewHeight = heightInput - queryToolbarsHeight();
|
|
9803
10707
|
}
|
|
9804
10708
|
else if (typeof heightInput === 'function') { // exists and is a function
|
|
9805
|
-
suggestedViewHeight = heightInput() -
|
|
10709
|
+
suggestedViewHeight = heightInput() - queryToolbarsHeight();
|
|
9806
10710
|
}
|
|
9807
10711
|
else if (heightInput === 'parent') { // set to height of parent element
|
|
9808
|
-
suggestedViewHeight = element.parent().height() -
|
|
10712
|
+
suggestedViewHeight = element.parent().height() - queryToolbarsHeight();
|
|
9809
10713
|
}
|
|
9810
10714
|
else {
|
|
9811
10715
|
suggestedViewHeight = Math.round(content.width() / Math.max(t.options.aspectRatio, .5));
|
|
@@ -9813,11 +10717,14 @@ function Calendar_constructor(element, overrides) {
|
|
|
9813
10717
|
}
|
|
9814
10718
|
|
|
9815
10719
|
|
|
9816
|
-
function
|
|
9817
|
-
return
|
|
10720
|
+
function queryToolbarsHeight() {
|
|
10721
|
+
return toolbarsManager.items.reduce(function(accumulator, toolbar) {
|
|
10722
|
+
var toolbarHeight = toolbar.el ? toolbar.el.outerHeight(true) : 0; // includes margin
|
|
10723
|
+
return accumulator + toolbarHeight;
|
|
10724
|
+
}, 0);
|
|
9818
10725
|
}
|
|
9819
|
-
|
|
9820
|
-
|
|
10726
|
+
|
|
10727
|
+
|
|
9821
10728
|
function windowResize(ev) {
|
|
9822
10729
|
if (
|
|
9823
10730
|
!ignoreWindowResize &&
|
|
@@ -9825,94 +10732,93 @@ function Calendar_constructor(element, overrides) {
|
|
|
9825
10732
|
currentView.start // view has already been rendered
|
|
9826
10733
|
) {
|
|
9827
10734
|
if (updateSize(true)) {
|
|
9828
|
-
currentView.
|
|
10735
|
+
currentView.publiclyTrigger('windowResize', _element);
|
|
9829
10736
|
}
|
|
9830
10737
|
}
|
|
9831
10738
|
}
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
/* Event Fetching/Rendering
|
|
9836
|
-
-----------------------------------------------------------------------------*/
|
|
9837
|
-
// TODO: going forward, most of this stuff should be directly handled by the view
|
|
9838
|
-
|
|
9839
10739
|
|
|
9840
|
-
function refetchEvents() { // can be called as an API method
|
|
9841
|
-
fetchAndRenderEvents();
|
|
9842
|
-
}
|
|
9843
10740
|
|
|
9844
10741
|
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
fetchEventSources(t.getEventSourcesByMatchArray(matchInputs));
|
|
9848
|
-
}
|
|
10742
|
+
/* Event Rendering
|
|
10743
|
+
-----------------------------------------------------------------------------*/
|
|
9849
10744
|
|
|
9850
10745
|
|
|
9851
|
-
function
|
|
10746
|
+
function rerenderEvents() { // API method. destroys old events if previously rendered.
|
|
9852
10747
|
if (elementVisible()) {
|
|
9853
|
-
|
|
9854
|
-
currentView.displayEvents(events);
|
|
9855
|
-
unfreezeContentHeight();
|
|
10748
|
+
t.reportEventChange(); // will re-trasmit events to the view, causing a rerender
|
|
9856
10749
|
}
|
|
9857
10750
|
}
|
|
9858
|
-
|
|
9859
10751
|
|
|
9860
|
-
function getAndRenderEvents() {
|
|
9861
|
-
if (!t.options.lazyFetching || isFetchNeeded(currentView.start, currentView.end)) {
|
|
9862
|
-
fetchAndRenderEvents();
|
|
9863
|
-
}
|
|
9864
|
-
else {
|
|
9865
|
-
renderEvents();
|
|
9866
|
-
}
|
|
9867
|
-
}
|
|
9868
10752
|
|
|
9869
10753
|
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
// ... will call reportEvents
|
|
9873
|
-
// ... which will call renderEvents
|
|
9874
|
-
}
|
|
10754
|
+
/* Toolbars
|
|
10755
|
+
-----------------------------------------------------------------------------*/
|
|
9875
10756
|
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
10757
|
+
|
|
10758
|
+
function buildToolbars() {
|
|
10759
|
+
return [
|
|
10760
|
+
new Toolbar(t, computeHeaderOptions()),
|
|
10761
|
+
new Toolbar(t, computeFooterOptions())
|
|
10762
|
+
];
|
|
9881
10763
|
}
|
|
9882
10764
|
|
|
9883
10765
|
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
|
|
10766
|
+
function computeHeaderOptions() {
|
|
10767
|
+
return {
|
|
10768
|
+
extraClasses: 'fc-header-toolbar',
|
|
10769
|
+
layout: t.options.header
|
|
10770
|
+
};
|
|
9887
10771
|
}
|
|
9888
10772
|
|
|
9889
10773
|
|
|
10774
|
+
function computeFooterOptions() {
|
|
10775
|
+
return {
|
|
10776
|
+
extraClasses: 'fc-footer-toolbar',
|
|
10777
|
+
layout: t.options.footer
|
|
10778
|
+
};
|
|
10779
|
+
}
|
|
9890
10780
|
|
|
9891
|
-
|
|
9892
|
-
|
|
10781
|
+
|
|
10782
|
+
// can be called repeatedly and Header will rerender
|
|
10783
|
+
function renderHeader() {
|
|
10784
|
+
header.setToolbarOptions(computeHeaderOptions());
|
|
10785
|
+
header.render();
|
|
10786
|
+
if (header.el) {
|
|
10787
|
+
element.prepend(header.el);
|
|
10788
|
+
}
|
|
10789
|
+
}
|
|
9893
10790
|
|
|
9894
10791
|
|
|
9895
|
-
|
|
9896
|
-
|
|
10792
|
+
// can be called repeatedly and Footer will rerender
|
|
10793
|
+
function renderFooter() {
|
|
10794
|
+
footer.setToolbarOptions(computeFooterOptions());
|
|
10795
|
+
footer.render();
|
|
10796
|
+
if (footer.el) {
|
|
10797
|
+
element.append(footer.el);
|
|
10798
|
+
}
|
|
9897
10799
|
}
|
|
9898
10800
|
|
|
9899
10801
|
|
|
9900
|
-
function
|
|
9901
|
-
|
|
10802
|
+
t.setToolbarsTitle = function(title) {
|
|
10803
|
+
toolbarsManager.proxyCall('updateTitle', title);
|
|
10804
|
+
};
|
|
10805
|
+
|
|
9902
10806
|
|
|
10807
|
+
function updateToolbarsTodayButton() {
|
|
10808
|
+
var now = t.getNow();
|
|
9903
10809
|
if (now >= currentView.intervalStart && now < currentView.intervalEnd) {
|
|
9904
|
-
|
|
10810
|
+
toolbarsManager.proxyCall('disableButton', 'today');
|
|
9905
10811
|
}
|
|
9906
10812
|
else {
|
|
9907
|
-
|
|
10813
|
+
toolbarsManager.proxyCall('enableButton', 'today');
|
|
9908
10814
|
}
|
|
9909
10815
|
}
|
|
9910
|
-
|
|
10816
|
+
|
|
9911
10817
|
|
|
9912
10818
|
|
|
9913
10819
|
/* Selection
|
|
9914
10820
|
-----------------------------------------------------------------------------*/
|
|
9915
|
-
|
|
10821
|
+
|
|
9916
10822
|
|
|
9917
10823
|
// this public method receives start/end dates in any format, with any timezone
|
|
9918
10824
|
function select(zonedStartInput, zonedEndInput) {
|
|
@@ -9920,56 +10826,56 @@ function Calendar_constructor(element, overrides) {
|
|
|
9920
10826
|
t.buildSelectSpan.apply(t, arguments)
|
|
9921
10827
|
);
|
|
9922
10828
|
}
|
|
9923
|
-
|
|
10829
|
+
|
|
9924
10830
|
|
|
9925
10831
|
function unselect() { // safe to be called before renderView
|
|
9926
10832
|
if (currentView) {
|
|
9927
10833
|
currentView.unselect();
|
|
9928
10834
|
}
|
|
9929
10835
|
}
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
|
|
10836
|
+
|
|
10837
|
+
|
|
10838
|
+
|
|
9933
10839
|
/* Date
|
|
9934
10840
|
-----------------------------------------------------------------------------*/
|
|
9935
|
-
|
|
9936
|
-
|
|
10841
|
+
|
|
10842
|
+
|
|
9937
10843
|
function prev() {
|
|
9938
10844
|
date = currentView.computePrevDate(date);
|
|
9939
10845
|
renderView();
|
|
9940
10846
|
}
|
|
9941
|
-
|
|
9942
|
-
|
|
10847
|
+
|
|
10848
|
+
|
|
9943
10849
|
function next() {
|
|
9944
10850
|
date = currentView.computeNextDate(date);
|
|
9945
10851
|
renderView();
|
|
9946
10852
|
}
|
|
9947
|
-
|
|
9948
|
-
|
|
10853
|
+
|
|
10854
|
+
|
|
9949
10855
|
function prevYear() {
|
|
9950
10856
|
date.add(-1, 'years');
|
|
9951
10857
|
renderView();
|
|
9952
|
-
}
|
|
9953
|
-
|
|
9954
|
-
|
|
10858
|
+
}
|
|
10859
|
+
|
|
10860
|
+
|
|
9955
10861
|
function nextYear() {
|
|
9956
10862
|
date.add(1, 'years');
|
|
9957
10863
|
renderView();
|
|
9958
10864
|
}
|
|
9959
|
-
|
|
9960
|
-
|
|
10865
|
+
|
|
10866
|
+
|
|
9961
10867
|
function today() {
|
|
9962
10868
|
date = t.getNow();
|
|
9963
10869
|
renderView();
|
|
9964
10870
|
}
|
|
9965
|
-
|
|
9966
|
-
|
|
10871
|
+
|
|
10872
|
+
|
|
9967
10873
|
function gotoDate(zonedDateInput) {
|
|
9968
10874
|
date = t.moment(zonedDateInput).stripZone();
|
|
9969
10875
|
renderView();
|
|
9970
10876
|
}
|
|
9971
|
-
|
|
9972
|
-
|
|
10877
|
+
|
|
10878
|
+
|
|
9973
10879
|
function incrementDate(delta) {
|
|
9974
10880
|
date.add(moment.duration(delta));
|
|
9975
10881
|
renderView();
|
|
@@ -9987,8 +10893,8 @@ function Calendar_constructor(element, overrides) {
|
|
|
9987
10893
|
date = newDate.clone();
|
|
9988
10894
|
renderView(spec ? spec.type : null);
|
|
9989
10895
|
}
|
|
9990
|
-
|
|
9991
|
-
|
|
10896
|
+
|
|
10897
|
+
|
|
9992
10898
|
// for external API
|
|
9993
10899
|
function getDate() {
|
|
9994
10900
|
return t.applyTimezone(date); // infuse the calendar's timezone
|
|
@@ -9998,45 +10904,51 @@ function Calendar_constructor(element, overrides) {
|
|
|
9998
10904
|
|
|
9999
10905
|
/* Height "Freezing"
|
|
10000
10906
|
-----------------------------------------------------------------------------*/
|
|
10001
|
-
|
|
10907
|
+
|
|
10002
10908
|
|
|
10003
10909
|
t.freezeContentHeight = freezeContentHeight;
|
|
10004
|
-
t.
|
|
10910
|
+
t.thawContentHeight = thawContentHeight;
|
|
10911
|
+
|
|
10912
|
+
var freezeContentHeightDepth = 0;
|
|
10005
10913
|
|
|
10006
10914
|
|
|
10007
10915
|
function freezeContentHeight() {
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10916
|
+
if (!(freezeContentHeightDepth++)) {
|
|
10917
|
+
content.css({
|
|
10918
|
+
width: '100%',
|
|
10919
|
+
height: content.height(),
|
|
10920
|
+
overflow: 'hidden'
|
|
10921
|
+
});
|
|
10922
|
+
}
|
|
10013
10923
|
}
|
|
10014
10924
|
|
|
10015
10925
|
|
|
10016
|
-
function
|
|
10017
|
-
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10926
|
+
function thawContentHeight() {
|
|
10927
|
+
if (!(--freezeContentHeightDepth)) {
|
|
10928
|
+
content.css({
|
|
10929
|
+
width: '',
|
|
10930
|
+
height: '',
|
|
10931
|
+
overflow: ''
|
|
10932
|
+
});
|
|
10933
|
+
}
|
|
10022
10934
|
}
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10935
|
+
|
|
10936
|
+
|
|
10937
|
+
|
|
10026
10938
|
/* Misc
|
|
10027
10939
|
-----------------------------------------------------------------------------*/
|
|
10028
|
-
|
|
10940
|
+
|
|
10029
10941
|
|
|
10030
10942
|
function getCalendar() {
|
|
10031
10943
|
return t;
|
|
10032
10944
|
}
|
|
10033
10945
|
|
|
10034
|
-
|
|
10946
|
+
|
|
10035
10947
|
function getView() {
|
|
10036
10948
|
return currentView;
|
|
10037
10949
|
}
|
|
10038
|
-
|
|
10039
|
-
|
|
10950
|
+
|
|
10951
|
+
|
|
10040
10952
|
function option(name, value) {
|
|
10041
10953
|
var newOptionHash;
|
|
10042
10954
|
|
|
@@ -10092,19 +11004,20 @@ function Calendar_constructor(element, overrides) {
|
|
|
10092
11004
|
}
|
|
10093
11005
|
else if (optionName === 'timezone') {
|
|
10094
11006
|
t.rezoneArrayEventSources();
|
|
10095
|
-
refetchEvents();
|
|
11007
|
+
t.refetchEvents();
|
|
10096
11008
|
return;
|
|
10097
11009
|
}
|
|
10098
11010
|
}
|
|
10099
11011
|
|
|
10100
|
-
// catch-all. rerender the header and rebuild/rerender the current view
|
|
11012
|
+
// catch-all. rerender the header and footer and rebuild/rerender the current view
|
|
10101
11013
|
renderHeader();
|
|
11014
|
+
renderFooter();
|
|
10102
11015
|
viewsByType = {}; // even non-current views will be affected by this option change. do before rerender
|
|
10103
11016
|
reinitView();
|
|
10104
11017
|
}
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
function
|
|
11018
|
+
|
|
11019
|
+
|
|
11020
|
+
function publiclyTrigger(name, thisObj) {
|
|
10108
11021
|
var args = Array.prototype.slice.call(arguments, 2);
|
|
10109
11022
|
|
|
10110
11023
|
thisObj = thisObj || _element;
|
|
@@ -10267,6 +11180,7 @@ Calendar.defaults = {
|
|
|
10267
11180
|
dropAccept: '*',
|
|
10268
11181
|
|
|
10269
11182
|
eventOrder: 'title',
|
|
11183
|
+
//eventRenderWait: null,
|
|
10270
11184
|
|
|
10271
11185
|
eventLimit: false,
|
|
10272
11186
|
eventLimitText: 'more',
|
|
@@ -10470,308 +11384,39 @@ var instanceComputableOptions = {
|
|
|
10470
11384
|
},
|
|
10471
11385
|
|
|
10472
11386
|
// Produces format strings for results like "Wk 5"
|
|
10473
|
-
weekFormat: function(options) {
|
|
10474
|
-
return options.isRTL ?
|
|
10475
|
-
'w[ ' + options.weekNumberTitle + ']' :
|
|
10476
|
-
'[' + options.weekNumberTitle + ' ]w';
|
|
10477
|
-
},
|
|
10478
|
-
|
|
10479
|
-
// Produces format strings for results like "Wk5"
|
|
10480
|
-
smallWeekFormat: function(options) {
|
|
10481
|
-
return options.isRTL ?
|
|
10482
|
-
'w[' + options.weekNumberTitle + ']' :
|
|
10483
|
-
'[' + options.weekNumberTitle + ']w';
|
|
10484
|
-
}
|
|
10485
|
-
|
|
10486
|
-
};
|
|
10487
|
-
|
|
10488
|
-
function populateInstanceComputableOptions(options) {
|
|
10489
|
-
$.each(instanceComputableOptions, function(name, func) {
|
|
10490
|
-
if (options[name] == null) {
|
|
10491
|
-
options[name] = func(options);
|
|
10492
|
-
}
|
|
10493
|
-
});
|
|
10494
|
-
}
|
|
10495
|
-
|
|
10496
|
-
|
|
10497
|
-
// Returns moment's internal locale data. If doesn't exist, returns English.
|
|
10498
|
-
function getMomentLocaleData(localeCode) {
|
|
10499
|
-
return moment.localeData(localeCode) || moment.localeData('en');
|
|
10500
|
-
}
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
// Initialize English by forcing computation of moment-derived options.
|
|
10504
|
-
// Also, sets it as the default.
|
|
10505
|
-
FC.locale('en', Calendar.englishDefaults);
|
|
10506
|
-
|
|
10507
|
-
;;
|
|
10508
|
-
|
|
10509
|
-
/* Top toolbar area with buttons and title
|
|
10510
|
-
----------------------------------------------------------------------------------------------------------------------*/
|
|
10511
|
-
// TODO: rename all header-related things to "toolbar"
|
|
10512
|
-
|
|
10513
|
-
function Header(calendar) {
|
|
10514
|
-
var t = this;
|
|
10515
|
-
|
|
10516
|
-
// exports
|
|
10517
|
-
t.render = render;
|
|
10518
|
-
t.removeElement = removeElement;
|
|
10519
|
-
t.updateTitle = updateTitle;
|
|
10520
|
-
t.activateButton = activateButton;
|
|
10521
|
-
t.deactivateButton = deactivateButton;
|
|
10522
|
-
t.disableButton = disableButton;
|
|
10523
|
-
t.enableButton = enableButton;
|
|
10524
|
-
t.getViewsWithButtons = getViewsWithButtons;
|
|
10525
|
-
t.el = null; // mirrors local `el`
|
|
10526
|
-
|
|
10527
|
-
// locals
|
|
10528
|
-
var el;
|
|
10529
|
-
var viewsWithButtons = [];
|
|
10530
|
-
var tm;
|
|
10531
|
-
|
|
10532
|
-
|
|
10533
|
-
// can be called repeatedly and will rerender
|
|
10534
|
-
function render() {
|
|
10535
|
-
var options = calendar.options;
|
|
10536
|
-
var sections = options.header;
|
|
10537
|
-
|
|
10538
|
-
tm = options.theme ? 'ui' : 'fc';
|
|
10539
|
-
|
|
10540
|
-
if (sections) {
|
|
10541
|
-
if (!el) {
|
|
10542
|
-
el = this.el = $("<div class='fc-toolbar'/>");
|
|
10543
|
-
}
|
|
10544
|
-
else {
|
|
10545
|
-
el.empty();
|
|
10546
|
-
}
|
|
10547
|
-
el.append(renderSection('left'))
|
|
10548
|
-
.append(renderSection('right'))
|
|
10549
|
-
.append(renderSection('center'))
|
|
10550
|
-
.append('<div class="fc-clear"/>');
|
|
10551
|
-
}
|
|
10552
|
-
else {
|
|
10553
|
-
removeElement();
|
|
10554
|
-
}
|
|
10555
|
-
}
|
|
10556
|
-
|
|
10557
|
-
|
|
10558
|
-
function removeElement() {
|
|
10559
|
-
if (el) {
|
|
10560
|
-
el.remove();
|
|
10561
|
-
el = t.el = null;
|
|
10562
|
-
}
|
|
10563
|
-
}
|
|
10564
|
-
|
|
10565
|
-
|
|
10566
|
-
function renderSection(position) {
|
|
10567
|
-
var sectionEl = $('<div class="fc-' + position + '"/>');
|
|
10568
|
-
var options = calendar.options;
|
|
10569
|
-
var buttonStr = options.header[position];
|
|
10570
|
-
|
|
10571
|
-
if (buttonStr) {
|
|
10572
|
-
$.each(buttonStr.split(' '), function(i) {
|
|
10573
|
-
var groupChildren = $();
|
|
10574
|
-
var isOnlyButtons = true;
|
|
10575
|
-
var groupEl;
|
|
10576
|
-
|
|
10577
|
-
$.each(this.split(','), function(j, buttonName) {
|
|
10578
|
-
var customButtonProps;
|
|
10579
|
-
var viewSpec;
|
|
10580
|
-
var buttonClick;
|
|
10581
|
-
var overrideText; // text explicitly set by calendar's constructor options. overcomes icons
|
|
10582
|
-
var defaultText;
|
|
10583
|
-
var themeIcon;
|
|
10584
|
-
var normalIcon;
|
|
10585
|
-
var innerHtml;
|
|
10586
|
-
var classes;
|
|
10587
|
-
var button; // the element
|
|
10588
|
-
|
|
10589
|
-
if (buttonName == 'title') {
|
|
10590
|
-
groupChildren = groupChildren.add($('<h2> </h2>')); // we always want it to take up height
|
|
10591
|
-
isOnlyButtons = false;
|
|
10592
|
-
}
|
|
10593
|
-
else {
|
|
10594
|
-
if ((customButtonProps = (options.customButtons || {})[buttonName])) {
|
|
10595
|
-
buttonClick = function(ev) {
|
|
10596
|
-
if (customButtonProps.click) {
|
|
10597
|
-
customButtonProps.click.call(button[0], ev);
|
|
10598
|
-
}
|
|
10599
|
-
};
|
|
10600
|
-
overrideText = ''; // icons will override text
|
|
10601
|
-
defaultText = customButtonProps.text;
|
|
10602
|
-
}
|
|
10603
|
-
else if ((viewSpec = calendar.getViewSpec(buttonName))) {
|
|
10604
|
-
buttonClick = function() {
|
|
10605
|
-
calendar.changeView(buttonName);
|
|
10606
|
-
};
|
|
10607
|
-
viewsWithButtons.push(buttonName);
|
|
10608
|
-
overrideText = viewSpec.buttonTextOverride;
|
|
10609
|
-
defaultText = viewSpec.buttonTextDefault;
|
|
10610
|
-
}
|
|
10611
|
-
else if (calendar[buttonName]) { // a calendar method
|
|
10612
|
-
buttonClick = function() {
|
|
10613
|
-
calendar[buttonName]();
|
|
10614
|
-
};
|
|
10615
|
-
overrideText = (calendar.overrides.buttonText || {})[buttonName];
|
|
10616
|
-
defaultText = options.buttonText[buttonName]; // everything else is considered default
|
|
10617
|
-
}
|
|
10618
|
-
|
|
10619
|
-
if (buttonClick) {
|
|
10620
|
-
|
|
10621
|
-
themeIcon =
|
|
10622
|
-
customButtonProps ?
|
|
10623
|
-
customButtonProps.themeIcon :
|
|
10624
|
-
options.themeButtonIcons[buttonName];
|
|
10625
|
-
|
|
10626
|
-
normalIcon =
|
|
10627
|
-
customButtonProps ?
|
|
10628
|
-
customButtonProps.icon :
|
|
10629
|
-
options.buttonIcons[buttonName];
|
|
10630
|
-
|
|
10631
|
-
if (overrideText) {
|
|
10632
|
-
innerHtml = htmlEscape(overrideText);
|
|
10633
|
-
}
|
|
10634
|
-
else if (themeIcon && options.theme) {
|
|
10635
|
-
innerHtml = "<span class='ui-icon ui-icon-" + themeIcon + "'></span>";
|
|
10636
|
-
}
|
|
10637
|
-
else if (normalIcon && !options.theme) {
|
|
10638
|
-
innerHtml = "<span class='fc-icon fc-icon-" + normalIcon + "'></span>";
|
|
10639
|
-
}
|
|
10640
|
-
else {
|
|
10641
|
-
innerHtml = htmlEscape(defaultText);
|
|
10642
|
-
}
|
|
10643
|
-
|
|
10644
|
-
classes = [
|
|
10645
|
-
'fc-' + buttonName + '-button',
|
|
10646
|
-
tm + '-button',
|
|
10647
|
-
tm + '-state-default'
|
|
10648
|
-
];
|
|
10649
|
-
|
|
10650
|
-
button = $( // type="button" so that it doesn't submit a form
|
|
10651
|
-
'<button type="button" class="' + classes.join(' ') + '">' +
|
|
10652
|
-
innerHtml +
|
|
10653
|
-
'</button>'
|
|
10654
|
-
)
|
|
10655
|
-
.click(function(ev) {
|
|
10656
|
-
// don't process clicks for disabled buttons
|
|
10657
|
-
if (!button.hasClass(tm + '-state-disabled')) {
|
|
10658
|
-
|
|
10659
|
-
buttonClick(ev);
|
|
10660
|
-
|
|
10661
|
-
// after the click action, if the button becomes the "active" tab, or disabled,
|
|
10662
|
-
// it should never have a hover class, so remove it now.
|
|
10663
|
-
if (
|
|
10664
|
-
button.hasClass(tm + '-state-active') ||
|
|
10665
|
-
button.hasClass(tm + '-state-disabled')
|
|
10666
|
-
) {
|
|
10667
|
-
button.removeClass(tm + '-state-hover');
|
|
10668
|
-
}
|
|
10669
|
-
}
|
|
10670
|
-
})
|
|
10671
|
-
.mousedown(function() {
|
|
10672
|
-
// the *down* effect (mouse pressed in).
|
|
10673
|
-
// only on buttons that are not the "active" tab, or disabled
|
|
10674
|
-
button
|
|
10675
|
-
.not('.' + tm + '-state-active')
|
|
10676
|
-
.not('.' + tm + '-state-disabled')
|
|
10677
|
-
.addClass(tm + '-state-down');
|
|
10678
|
-
})
|
|
10679
|
-
.mouseup(function() {
|
|
10680
|
-
// undo the *down* effect
|
|
10681
|
-
button.removeClass(tm + '-state-down');
|
|
10682
|
-
})
|
|
10683
|
-
.hover(
|
|
10684
|
-
function() {
|
|
10685
|
-
// the *hover* effect.
|
|
10686
|
-
// only on buttons that are not the "active" tab, or disabled
|
|
10687
|
-
button
|
|
10688
|
-
.not('.' + tm + '-state-active')
|
|
10689
|
-
.not('.' + tm + '-state-disabled')
|
|
10690
|
-
.addClass(tm + '-state-hover');
|
|
10691
|
-
},
|
|
10692
|
-
function() {
|
|
10693
|
-
// undo the *hover* effect
|
|
10694
|
-
button
|
|
10695
|
-
.removeClass(tm + '-state-hover')
|
|
10696
|
-
.removeClass(tm + '-state-down'); // if mouseleave happens before mouseup
|
|
10697
|
-
}
|
|
10698
|
-
);
|
|
11387
|
+
weekFormat: function(options) {
|
|
11388
|
+
return options.isRTL ?
|
|
11389
|
+
'w[ ' + options.weekNumberTitle + ']' :
|
|
11390
|
+
'[' + options.weekNumberTitle + ' ]w';
|
|
11391
|
+
},
|
|
10699
11392
|
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
11393
|
+
// Produces format strings for results like "Wk5"
|
|
11394
|
+
smallWeekFormat: function(options) {
|
|
11395
|
+
return options.isRTL ?
|
|
11396
|
+
'w[' + options.weekNumberTitle + ']' :
|
|
11397
|
+
'[' + options.weekNumberTitle + ']w';
|
|
11398
|
+
}
|
|
10704
11399
|
|
|
10705
|
-
|
|
10706
|
-
groupChildren
|
|
10707
|
-
.first().addClass(tm + '-corner-left').end()
|
|
10708
|
-
.last().addClass(tm + '-corner-right').end();
|
|
10709
|
-
}
|
|
11400
|
+
};
|
|
10710
11401
|
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
}
|
|
10716
|
-
groupEl.append(groupChildren);
|
|
10717
|
-
sectionEl.append(groupEl);
|
|
10718
|
-
}
|
|
10719
|
-
else {
|
|
10720
|
-
sectionEl.append(groupChildren); // 1 or 0 children
|
|
10721
|
-
}
|
|
10722
|
-
});
|
|
11402
|
+
function populateInstanceComputableOptions(options) {
|
|
11403
|
+
$.each(instanceComputableOptions, function(name, func) {
|
|
11404
|
+
if (options[name] == null) {
|
|
11405
|
+
options[name] = func(options);
|
|
10723
11406
|
}
|
|
11407
|
+
});
|
|
11408
|
+
}
|
|
10724
11409
|
|
|
10725
|
-
return sectionEl;
|
|
10726
|
-
}
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
function updateTitle(text) {
|
|
10730
|
-
if (el) {
|
|
10731
|
-
el.find('h2').text(text);
|
|
10732
|
-
}
|
|
10733
|
-
}
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
function activateButton(buttonName) {
|
|
10737
|
-
if (el) {
|
|
10738
|
-
el.find('.fc-' + buttonName + '-button')
|
|
10739
|
-
.addClass(tm + '-state-active');
|
|
10740
|
-
}
|
|
10741
|
-
}
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
function deactivateButton(buttonName) {
|
|
10745
|
-
if (el) {
|
|
10746
|
-
el.find('.fc-' + buttonName + '-button')
|
|
10747
|
-
.removeClass(tm + '-state-active');
|
|
10748
|
-
}
|
|
10749
|
-
}
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
function disableButton(buttonName) {
|
|
10753
|
-
if (el) {
|
|
10754
|
-
el.find('.fc-' + buttonName + '-button')
|
|
10755
|
-
.prop('disabled', true)
|
|
10756
|
-
.addClass(tm + '-state-disabled');
|
|
10757
|
-
}
|
|
10758
|
-
}
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
function enableButton(buttonName) {
|
|
10762
|
-
if (el) {
|
|
10763
|
-
el.find('.fc-' + buttonName + '-button')
|
|
10764
|
-
.prop('disabled', false)
|
|
10765
|
-
.removeClass(tm + '-state-disabled');
|
|
10766
|
-
}
|
|
10767
|
-
}
|
|
10768
11410
|
|
|
11411
|
+
// Returns moment's internal locale data. If doesn't exist, returns English.
|
|
11412
|
+
function getMomentLocaleData(localeCode) {
|
|
11413
|
+
return moment.localeData(localeCode) || moment.localeData('en');
|
|
11414
|
+
}
|
|
10769
11415
|
|
|
10770
|
-
function getViewsWithButtons() {
|
|
10771
|
-
return viewsWithButtons;
|
|
10772
|
-
}
|
|
10773
11416
|
|
|
10774
|
-
|
|
11417
|
+
// Initialize English by forcing computation of moment-derived options.
|
|
11418
|
+
// Also, sets it as the default.
|
|
11419
|
+
FC.locale('en', Calendar.englishDefaults);
|
|
10775
11420
|
|
|
10776
11421
|
;;
|
|
10777
11422
|
|
|
@@ -10788,38 +11433,39 @@ var eventGUID = 1;
|
|
|
10788
11433
|
|
|
10789
11434
|
function EventManager() { // assumed to be a calendar
|
|
10790
11435
|
var t = this;
|
|
10791
|
-
|
|
10792
|
-
|
|
11436
|
+
|
|
11437
|
+
|
|
10793
11438
|
// exports
|
|
11439
|
+
t.requestEvents = requestEvents;
|
|
11440
|
+
t.reportEventChange = reportEventChange;
|
|
10794
11441
|
t.isFetchNeeded = isFetchNeeded;
|
|
10795
11442
|
t.fetchEvents = fetchEvents;
|
|
10796
11443
|
t.fetchEventSources = fetchEventSources;
|
|
11444
|
+
t.refetchEvents = refetchEvents;
|
|
11445
|
+
t.refetchEventSources = refetchEventSources;
|
|
10797
11446
|
t.getEventSources = getEventSources;
|
|
10798
11447
|
t.getEventSourceById = getEventSourceById;
|
|
10799
|
-
t.getEventSourcesByMatchArray = getEventSourcesByMatchArray;
|
|
10800
|
-
t.getEventSourcesByMatch = getEventSourcesByMatch;
|
|
10801
11448
|
t.addEventSource = addEventSource;
|
|
10802
11449
|
t.removeEventSource = removeEventSource;
|
|
10803
11450
|
t.removeEventSources = removeEventSources;
|
|
10804
11451
|
t.updateEvent = updateEvent;
|
|
11452
|
+
t.updateEvents = updateEvents;
|
|
10805
11453
|
t.renderEvent = renderEvent;
|
|
11454
|
+
t.renderEvents = renderEvents;
|
|
10806
11455
|
t.removeEvents = removeEvents;
|
|
10807
11456
|
t.clientEvents = clientEvents;
|
|
10808
11457
|
t.mutateEvent = mutateEvent;
|
|
10809
11458
|
t.normalizeEventDates = normalizeEventDates;
|
|
10810
11459
|
t.normalizeEventTimes = normalizeEventTimes;
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
// imports
|
|
10814
|
-
var reportEvents = t.reportEvents;
|
|
10815
|
-
|
|
10816
|
-
|
|
11460
|
+
|
|
11461
|
+
|
|
10817
11462
|
// locals
|
|
10818
11463
|
var stickySource = { events: [] };
|
|
10819
11464
|
var sources = [ stickySource ];
|
|
10820
11465
|
var rangeStart, rangeEnd;
|
|
10821
11466
|
var pendingSourceCnt = 0; // outstanding fetch requests, max one per source
|
|
10822
11467
|
var cache = []; // holds events that have already been expanded
|
|
11468
|
+
var prunedCache; // like cache, but only events that intersect with rangeStart/rangeEnd
|
|
10823
11469
|
|
|
10824
11470
|
|
|
10825
11471
|
$.each(
|
|
@@ -10831,9 +11477,55 @@ function EventManager() { // assumed to be a calendar
|
|
|
10831
11477
|
}
|
|
10832
11478
|
}
|
|
10833
11479
|
);
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
|
|
11480
|
+
|
|
11481
|
+
|
|
11482
|
+
|
|
11483
|
+
function requestEvents(start, end) {
|
|
11484
|
+
if (!t.options.lazyFetching || isFetchNeeded(start, end)) {
|
|
11485
|
+
return fetchEvents(start, end);
|
|
11486
|
+
}
|
|
11487
|
+
else {
|
|
11488
|
+
return Promise.resolve(prunedCache);
|
|
11489
|
+
}
|
|
11490
|
+
}
|
|
11491
|
+
|
|
11492
|
+
|
|
11493
|
+
function reportEventChange() {
|
|
11494
|
+
prunedCache = filterEventsWithinRange(cache);
|
|
11495
|
+
t.trigger('eventsReset', prunedCache);
|
|
11496
|
+
}
|
|
11497
|
+
|
|
11498
|
+
|
|
11499
|
+
function filterEventsWithinRange(events) {
|
|
11500
|
+
var filteredEvents = [];
|
|
11501
|
+
var i, event;
|
|
11502
|
+
|
|
11503
|
+
for (i = 0; i < events.length; i++) {
|
|
11504
|
+
event = events[i];
|
|
11505
|
+
|
|
11506
|
+
if (
|
|
11507
|
+
event.start.clone().stripZone() < rangeEnd &&
|
|
11508
|
+
t.getEventEnd(event).stripZone() > rangeStart
|
|
11509
|
+
) {
|
|
11510
|
+
filteredEvents.push(event);
|
|
11511
|
+
}
|
|
11512
|
+
}
|
|
11513
|
+
|
|
11514
|
+
return filteredEvents;
|
|
11515
|
+
}
|
|
11516
|
+
|
|
11517
|
+
|
|
11518
|
+
t.getEventCache = function() {
|
|
11519
|
+
return cache;
|
|
11520
|
+
};
|
|
11521
|
+
|
|
11522
|
+
|
|
11523
|
+
t.getPrunedEventCache = function() {
|
|
11524
|
+
return prunedCache;
|
|
11525
|
+
};
|
|
11526
|
+
|
|
11527
|
+
|
|
11528
|
+
|
|
10837
11529
|
/* Fetching
|
|
10838
11530
|
-----------------------------------------------------------------------------*/
|
|
10839
11531
|
|
|
@@ -10843,12 +11535,24 @@ function EventManager() { // assumed to be a calendar
|
|
|
10843
11535
|
return !rangeStart || // nothing has been fetched yet?
|
|
10844
11536
|
start < rangeStart || end > rangeEnd; // is part of the new range outside of the old range?
|
|
10845
11537
|
}
|
|
10846
|
-
|
|
10847
|
-
|
|
11538
|
+
|
|
11539
|
+
|
|
10848
11540
|
function fetchEvents(start, end) {
|
|
10849
11541
|
rangeStart = start;
|
|
10850
11542
|
rangeEnd = end;
|
|
10851
|
-
|
|
11543
|
+
return refetchEvents();
|
|
11544
|
+
}
|
|
11545
|
+
|
|
11546
|
+
|
|
11547
|
+
// poorly named. fetches all sources with current `rangeStart` and `rangeEnd`.
|
|
11548
|
+
function refetchEvents() {
|
|
11549
|
+
return fetchEventSources(sources, 'reset');
|
|
11550
|
+
}
|
|
11551
|
+
|
|
11552
|
+
|
|
11553
|
+
// poorly named. fetches a subset of event sources.
|
|
11554
|
+
function refetchEventSources(matchInputs) {
|
|
11555
|
+
return fetchEventSources(getEventSourcesByMatchArray(matchInputs));
|
|
10852
11556
|
}
|
|
10853
11557
|
|
|
10854
11558
|
|
|
@@ -10878,9 +11582,17 @@ function EventManager() { // assumed to be a calendar
|
|
|
10878
11582
|
|
|
10879
11583
|
for (i = 0; i < specificSources.length; i++) {
|
|
10880
11584
|
source = specificSources[i];
|
|
10881
|
-
|
|
10882
11585
|
tryFetchEventSource(source, source._fetchId);
|
|
10883
11586
|
}
|
|
11587
|
+
|
|
11588
|
+
if (pendingSourceCnt) {
|
|
11589
|
+
return new Promise(function(resolve) {
|
|
11590
|
+
t.one('eventsReceived', resolve); // will send prunedCache
|
|
11591
|
+
});
|
|
11592
|
+
}
|
|
11593
|
+
else { // executed all synchronously, or no sources at all
|
|
11594
|
+
return Promise.resolve(prunedCache);
|
|
11595
|
+
}
|
|
10884
11596
|
}
|
|
10885
11597
|
|
|
10886
11598
|
|
|
@@ -10913,7 +11625,7 @@ function EventManager() { // assumed to be a calendar
|
|
|
10913
11625
|
}
|
|
10914
11626
|
|
|
10915
11627
|
if (abstractEvent) { // not false (an invalid event)
|
|
10916
|
-
cache.push.apply(
|
|
11628
|
+
cache.push.apply( // append
|
|
10917
11629
|
cache,
|
|
10918
11630
|
expandEvent(abstractEvent) // add individual expanded events to the cache
|
|
10919
11631
|
);
|
|
@@ -10941,11 +11653,12 @@ function EventManager() { // assumed to be a calendar
|
|
|
10941
11653
|
function decrementPendingSourceCnt() {
|
|
10942
11654
|
pendingSourceCnt--;
|
|
10943
11655
|
if (!pendingSourceCnt) {
|
|
10944
|
-
|
|
11656
|
+
reportEventChange(cache); // updates prunedCache
|
|
11657
|
+
t.trigger('eventsReceived', prunedCache);
|
|
10945
11658
|
}
|
|
10946
11659
|
}
|
|
10947
|
-
|
|
10948
|
-
|
|
11660
|
+
|
|
11661
|
+
|
|
10949
11662
|
function _fetchEventSource(source, callback) {
|
|
10950
11663
|
var i;
|
|
10951
11664
|
var fetchers = FC.sourceFetchers;
|
|
@@ -11054,9 +11767,9 @@ function EventManager() { // assumed to be a calendar
|
|
|
11054
11767
|
}
|
|
11055
11768
|
}
|
|
11056
11769
|
}
|
|
11057
|
-
|
|
11058
|
-
|
|
11059
|
-
|
|
11770
|
+
|
|
11771
|
+
|
|
11772
|
+
|
|
11060
11773
|
/* Sources
|
|
11061
11774
|
-----------------------------------------------------------------------------*/
|
|
11062
11775
|
|
|
@@ -11065,7 +11778,7 @@ function EventManager() { // assumed to be a calendar
|
|
|
11065
11778
|
var source = buildEventSource(sourceInput);
|
|
11066
11779
|
if (source) {
|
|
11067
11780
|
sources.push(source);
|
|
11068
|
-
fetchEventSources([ source ], 'add'); // will eventually call
|
|
11781
|
+
fetchEventSources([ source ], 'add'); // will eventually call reportEventChange
|
|
11069
11782
|
}
|
|
11070
11783
|
}
|
|
11071
11784
|
|
|
@@ -11161,7 +11874,7 @@ function EventManager() { // assumed to be a calendar
|
|
|
11161
11874
|
cache = excludeEventsBySources(cache, targetSources);
|
|
11162
11875
|
}
|
|
11163
11876
|
|
|
11164
|
-
|
|
11877
|
+
reportEventChange();
|
|
11165
11878
|
}
|
|
11166
11879
|
|
|
11167
11880
|
|
|
@@ -11255,27 +11968,39 @@ function EventManager() { // assumed to be a calendar
|
|
|
11255
11968
|
return true; // keep
|
|
11256
11969
|
});
|
|
11257
11970
|
}
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11971
|
+
|
|
11972
|
+
|
|
11973
|
+
|
|
11261
11974
|
/* Manipulation
|
|
11262
11975
|
-----------------------------------------------------------------------------*/
|
|
11263
11976
|
|
|
11264
11977
|
|
|
11265
11978
|
// Only ever called from the externally-facing API
|
|
11266
11979
|
function updateEvent(event) {
|
|
11980
|
+
updateEvents([ event ]);
|
|
11981
|
+
}
|
|
11267
11982
|
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
event
|
|
11983
|
+
|
|
11984
|
+
// Only ever called from the externally-facing API
|
|
11985
|
+
function updateEvents(events) {
|
|
11986
|
+
var i, event;
|
|
11987
|
+
|
|
11988
|
+
for (i = 0; i < events.length; i++) {
|
|
11989
|
+
event = events[i];
|
|
11990
|
+
|
|
11991
|
+
// massage start/end values, even if date string values
|
|
11992
|
+
event.start = t.moment(event.start);
|
|
11993
|
+
if (event.end) {
|
|
11994
|
+
event.end = t.moment(event.end);
|
|
11995
|
+
}
|
|
11996
|
+
else {
|
|
11997
|
+
event.end = null;
|
|
11998
|
+
}
|
|
11999
|
+
|
|
12000
|
+
mutateEvent(event, getMiscEventProps(event)); // will handle start/end/allDay normalization
|
|
11275
12001
|
}
|
|
11276
12002
|
|
|
11277
|
-
|
|
11278
|
-
reportEvents(cache); // reports event modifications (so we can redraw)
|
|
12003
|
+
reportEventChange(); // reports event modifications (so we can redraw)
|
|
11279
12004
|
}
|
|
11280
12005
|
|
|
11281
12006
|
|
|
@@ -11299,37 +12024,50 @@ function EventManager() { // assumed to be a calendar
|
|
|
11299
12024
|
return !/^_|^(id|allDay|start|end)$/.test(name);
|
|
11300
12025
|
}
|
|
11301
12026
|
|
|
11302
|
-
|
|
12027
|
+
|
|
11303
12028
|
// returns the expanded events that were created
|
|
11304
12029
|
function renderEvent(eventInput, stick) {
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
var i, event;
|
|
12030
|
+
return renderEvents([ eventInput ], stick);
|
|
12031
|
+
}
|
|
11308
12032
|
|
|
11309
|
-
if (abstractEvent) { // not false (a valid input)
|
|
11310
|
-
events = expandEvent(abstractEvent);
|
|
11311
12033
|
|
|
11312
|
-
|
|
11313
|
-
|
|
12034
|
+
// returns the expanded events that were created
|
|
12035
|
+
function renderEvents(eventInputs, stick) {
|
|
12036
|
+
var renderedEvents = [];
|
|
12037
|
+
var renderableEvents;
|
|
12038
|
+
var abstractEvent;
|
|
12039
|
+
var i, j, event;
|
|
12040
|
+
|
|
12041
|
+
for (i = 0; i < eventInputs.length; i++) {
|
|
12042
|
+
abstractEvent = buildEventFromInput(eventInputs[i]);
|
|
12043
|
+
|
|
12044
|
+
if (abstractEvent) { // not false (a valid input)
|
|
12045
|
+
renderableEvents = expandEvent(abstractEvent);
|
|
11314
12046
|
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
12047
|
+
for (j = 0; j < renderableEvents.length; j++) {
|
|
12048
|
+
event = renderableEvents[j];
|
|
12049
|
+
|
|
12050
|
+
if (!event.source) {
|
|
12051
|
+
if (stick) {
|
|
12052
|
+
stickySource.events.push(event);
|
|
12053
|
+
event.source = stickySource;
|
|
12054
|
+
}
|
|
12055
|
+
cache.push(event);
|
|
11319
12056
|
}
|
|
11320
|
-
cache.push(event);
|
|
11321
12057
|
}
|
|
11322
|
-
}
|
|
11323
12058
|
|
|
11324
|
-
|
|
12059
|
+
renderedEvents = renderedEvents.concat(renderableEvents);
|
|
12060
|
+
}
|
|
12061
|
+
}
|
|
11325
12062
|
|
|
11326
|
-
|
|
12063
|
+
if (renderedEvents.length) { // any new events rendered?
|
|
12064
|
+
reportEventChange();
|
|
11327
12065
|
}
|
|
11328
12066
|
|
|
11329
|
-
return
|
|
12067
|
+
return renderedEvents;
|
|
11330
12068
|
}
|
|
11331
|
-
|
|
11332
|
-
|
|
12069
|
+
|
|
12070
|
+
|
|
11333
12071
|
function removeEvents(filter) {
|
|
11334
12072
|
var eventID;
|
|
11335
12073
|
var i;
|
|
@@ -11356,10 +12094,10 @@ function EventManager() { // assumed to be a calendar
|
|
|
11356
12094
|
}
|
|
11357
12095
|
}
|
|
11358
12096
|
|
|
11359
|
-
|
|
12097
|
+
reportEventChange();
|
|
11360
12098
|
}
|
|
11361
12099
|
|
|
11362
|
-
|
|
12100
|
+
|
|
11363
12101
|
function clientEvents(filter) {
|
|
11364
12102
|
if ($.isFunction(filter)) {
|
|
11365
12103
|
return $.grep(cache, filter);
|
|
@@ -11399,8 +12137,8 @@ function EventManager() { // assumed to be a calendar
|
|
|
11399
12137
|
}
|
|
11400
12138
|
backupEventDates(event);
|
|
11401
12139
|
}
|
|
11402
|
-
|
|
11403
|
-
|
|
12140
|
+
|
|
12141
|
+
|
|
11404
12142
|
/* Event Normalization
|
|
11405
12143
|
-----------------------------------------------------------------------------*/
|
|
11406
12144
|
|
|
@@ -11810,11 +12548,6 @@ function EventManager() { // assumed to be a calendar
|
|
|
11810
12548
|
};
|
|
11811
12549
|
}
|
|
11812
12550
|
|
|
11813
|
-
|
|
11814
|
-
t.getEventCache = function() {
|
|
11815
|
-
return cache;
|
|
11816
|
-
};
|
|
11817
|
-
|
|
11818
12551
|
}
|
|
11819
12552
|
|
|
11820
12553
|
|
|
@@ -12343,13 +13076,18 @@ var BasicView = FC.BasicView = View.extend({
|
|
|
12343
13076
|
------------------------------------------------------------------------------------------------------------------*/
|
|
12344
13077
|
|
|
12345
13078
|
|
|
13079
|
+
computeInitialScroll: function() {
|
|
13080
|
+
return { top: 0 };
|
|
13081
|
+
},
|
|
13082
|
+
|
|
13083
|
+
|
|
12346
13084
|
queryScroll: function() {
|
|
12347
|
-
return this.scroller.getScrollTop();
|
|
13085
|
+
return { top: this.scroller.getScrollTop() };
|
|
12348
13086
|
},
|
|
12349
13087
|
|
|
12350
13088
|
|
|
12351
|
-
setScroll: function(
|
|
12352
|
-
this.scroller.setScrollTop(top);
|
|
13089
|
+
setScroll: function(scroll) {
|
|
13090
|
+
this.scroller.setScrollTop(scroll.top);
|
|
12353
13091
|
},
|
|
12354
13092
|
|
|
12355
13093
|
|
|
@@ -12866,17 +13604,17 @@ var AgendaView = FC.AgendaView = View.extend({
|
|
|
12866
13604
|
top++; // to overcome top border that slots beyond the first have. looks better
|
|
12867
13605
|
}
|
|
12868
13606
|
|
|
12869
|
-
return top;
|
|
13607
|
+
return { top: top };
|
|
12870
13608
|
},
|
|
12871
13609
|
|
|
12872
13610
|
|
|
12873
13611
|
queryScroll: function() {
|
|
12874
|
-
return this.scroller.getScrollTop();
|
|
13612
|
+
return { top: this.scroller.getScrollTop() };
|
|
12875
13613
|
},
|
|
12876
13614
|
|
|
12877
13615
|
|
|
12878
|
-
setScroll: function(
|
|
12879
|
-
this.scroller.setScrollTop(top);
|
|
13616
|
+
setScroll: function(scroll) {
|
|
13617
|
+
this.scroller.setScrollTop(scroll.top);
|
|
12880
13618
|
},
|
|
12881
13619
|
|
|
12882
13620
|
|
|
@@ -13214,21 +13952,36 @@ var ListViewGrid = Grid.extend({
|
|
|
13214
13952
|
// slices by day
|
|
13215
13953
|
spanToSegs: function(span) {
|
|
13216
13954
|
var view = this.view;
|
|
13217
|
-
var dayStart = view.start.clone();
|
|
13218
|
-
var
|
|
13955
|
+
var dayStart = view.start.clone().time(0); // timed, so segs get times!
|
|
13956
|
+
var dayIndex = 0;
|
|
13219
13957
|
var seg;
|
|
13220
13958
|
var segs = [];
|
|
13221
13959
|
|
|
13222
13960
|
while (dayStart < view.end) {
|
|
13223
|
-
|
|
13961
|
+
|
|
13224
13962
|
seg = intersectRanges(span, {
|
|
13225
13963
|
start: dayStart,
|
|
13226
|
-
end:
|
|
13964
|
+
end: dayStart.clone().add(1, 'day')
|
|
13227
13965
|
});
|
|
13966
|
+
|
|
13228
13967
|
if (seg) {
|
|
13968
|
+
seg.dayIndex = dayIndex;
|
|
13229
13969
|
segs.push(seg);
|
|
13230
13970
|
}
|
|
13231
|
-
|
|
13971
|
+
|
|
13972
|
+
dayStart.add(1, 'day');
|
|
13973
|
+
dayIndex++;
|
|
13974
|
+
|
|
13975
|
+
// detect when span won't go fully into the next day,
|
|
13976
|
+
// and mutate the latest seg to the be the end.
|
|
13977
|
+
if (
|
|
13978
|
+
seg && !seg.isEnd && span.end.hasTime() &&
|
|
13979
|
+
span.end < dayStart.clone().add(this.view.nextDayThreshold)
|
|
13980
|
+
) {
|
|
13981
|
+
seg.end = span.end.clone();
|
|
13982
|
+
seg.isEnd = true;
|
|
13983
|
+
break;
|
|
13984
|
+
}
|
|
13232
13985
|
}
|
|
13233
13986
|
|
|
13234
13987
|
return segs;
|
|
@@ -13261,11 +14014,12 @@ var ListViewGrid = Grid.extend({
|
|
|
13261
14014
|
|
|
13262
14015
|
if (!segs.length) {
|
|
13263
14016
|
this.renderEmptyMessage();
|
|
13264
|
-
return segs;
|
|
13265
14017
|
}
|
|
13266
14018
|
else {
|
|
13267
|
-
|
|
14019
|
+
this.renderSegList(segs);
|
|
13268
14020
|
}
|
|
14021
|
+
|
|
14022
|
+
return segs;
|
|
13269
14023
|
},
|
|
13270
14024
|
|
|
13271
14025
|
renderEmptyMessage: function() {
|
|
@@ -13280,30 +14034,47 @@ var ListViewGrid = Grid.extend({
|
|
|
13280
14034
|
);
|
|
13281
14035
|
},
|
|
13282
14036
|
|
|
13283
|
-
// render the event segments in the view
|
|
13284
|
-
renderSegList: function(
|
|
14037
|
+
// render the event segments in the view
|
|
14038
|
+
renderSegList: function(allSegs) {
|
|
14039
|
+
var segsByDay = this.groupSegsByDay(allSegs); // sparse array
|
|
14040
|
+
var dayIndex;
|
|
14041
|
+
var daySegs;
|
|
14042
|
+
var i;
|
|
13285
14043
|
var tableEl = $('<table class="fc-list-table"><tbody/></table>');
|
|
13286
14044
|
var tbodyEl = tableEl.find('tbody');
|
|
13287
|
-
var i, seg;
|
|
13288
|
-
var dayDate;
|
|
13289
14045
|
|
|
13290
|
-
|
|
14046
|
+
for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
|
|
14047
|
+
daySegs = segsByDay[dayIndex];
|
|
14048
|
+
if (daySegs) { // sparse array, so might be undefined
|
|
13291
14049
|
|
|
13292
|
-
|
|
13293
|
-
|
|
14050
|
+
// append a day header
|
|
14051
|
+
tbodyEl.append(this.dayHeaderHtml(
|
|
14052
|
+
this.view.start.clone().add(dayIndex, 'days')
|
|
14053
|
+
));
|
|
13294
14054
|
|
|
13295
|
-
|
|
13296
|
-
if (!dayDate || !seg.start.isSame(dayDate, 'day')) {
|
|
13297
|
-
dayDate = seg.start.clone().stripTime();
|
|
13298
|
-
tbodyEl.append(this.dayHeaderHtml(dayDate));
|
|
13299
|
-
}
|
|
14055
|
+
this.sortEventSegs(daySegs);
|
|
13300
14056
|
|
|
13301
|
-
|
|
14057
|
+
for (i = 0; i < daySegs.length; i++) {
|
|
14058
|
+
tbodyEl.append(daySegs[i].el); // append event row
|
|
14059
|
+
}
|
|
14060
|
+
}
|
|
13302
14061
|
}
|
|
13303
14062
|
|
|
13304
14063
|
this.el.empty().append(tableEl);
|
|
14064
|
+
},
|
|
14065
|
+
|
|
14066
|
+
// Returns a sparse array of arrays, segs grouped by their dayIndex
|
|
14067
|
+
groupSegsByDay: function(segs) {
|
|
14068
|
+
var segsByDay = []; // sparse array
|
|
14069
|
+
var i, seg;
|
|
14070
|
+
|
|
14071
|
+
for (i = 0; i < segs.length; i++) {
|
|
14072
|
+
seg = segs[i];
|
|
14073
|
+
(segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
|
|
14074
|
+
.push(seg);
|
|
14075
|
+
}
|
|
13305
14076
|
|
|
13306
|
-
return
|
|
14077
|
+
return segsByDay;
|
|
13307
14078
|
},
|
|
13308
14079
|
|
|
13309
14080
|
// generates the HTML for the day headers that live amongst the event rows
|
|
@@ -13341,13 +14112,20 @@ var ListViewGrid = Grid.extend({
|
|
|
13341
14112
|
var url = event.url;
|
|
13342
14113
|
var timeHtml;
|
|
13343
14114
|
|
|
13344
|
-
if (
|
|
13345
|
-
|
|
14115
|
+
if (event.allDay) {
|
|
14116
|
+
timeHtml = view.getAllDayHtml();
|
|
14117
|
+
}
|
|
14118
|
+
else if (view.isMultiDayEvent(event)) { // if the event appears to span more than one day
|
|
14119
|
+
if (seg.isStart || seg.isEnd) { // outer segment that probably lasts part of the day
|
|
14120
|
+
timeHtml = htmlEscape(this.getEventTimeText(seg));
|
|
14121
|
+
}
|
|
14122
|
+
else { // inner segment that lasts the whole day
|
|
13346
14123
|
timeHtml = view.getAllDayHtml();
|
|
13347
14124
|
}
|
|
13348
14125
|
}
|
|
13349
14126
|
else {
|
|
13350
|
-
|
|
14127
|
+
// Display the normal time text for the *event's* times
|
|
14128
|
+
timeHtml = htmlEscape(this.getEventTimeText(event));
|
|
13351
14129
|
}
|
|
13352
14130
|
|
|
13353
14131
|
if (url) {
|
|
@@ -13355,9 +14133,9 @@ var ListViewGrid = Grid.extend({
|
|
|
13355
14133
|
}
|
|
13356
14134
|
|
|
13357
14135
|
return '<tr class="' + classes.join(' ') + '">' +
|
|
13358
|
-
(
|
|
14136
|
+
(this.displayEventTime ?
|
|
13359
14137
|
'<td class="fc-list-item-time ' + view.widgetContentClass + '">' +
|
|
13360
|
-
timeHtml +
|
|
14138
|
+
(timeHtml || '') +
|
|
13361
14139
|
'</td>' :
|
|
13362
14140
|
'') +
|
|
13363
14141
|
'<td class="fc-list-item-marker ' + view.widgetContentClass + '">' +
|
|
@@ -13369,7 +14147,7 @@ var ListViewGrid = Grid.extend({
|
|
|
13369
14147
|
'</td>' +
|
|
13370
14148
|
'<td class="fc-list-item-title ' + view.widgetContentClass + '">' +
|
|
13371
14149
|
'<a' + (url ? ' href="' + htmlEscape(url) + '"' : '') + '>' +
|
|
13372
|
-
htmlEscape(seg.event.title) +
|
|
14150
|
+
htmlEscape(seg.event.title || '') +
|
|
13373
14151
|
'</a>' +
|
|
13374
14152
|
'</td>' +
|
|
13375
14153
|
'</tr>';
|
|
@@ -13384,7 +14162,6 @@ fcViews.list = {
|
|
|
13384
14162
|
buttonTextKey: 'list', // what to lookup in locale files
|
|
13385
14163
|
defaults: {
|
|
13386
14164
|
buttonText: 'list', // text to display for English
|
|
13387
|
-
listTime: true, // show the time column?
|
|
13388
14165
|
listDayFormat: 'LL', // like "January 1, 2016"
|
|
13389
14166
|
noEventsMessage: 'No events to display'
|
|
13390
14167
|
}
|