@fullcalendar/core 7.0.0-rc.0 → 7.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +3 -42
  3. package/index.d.ts +0 -46
  4. package/index.js +1 -2066
  5. package/package.json +13 -42
  6. package/protected-api.d.ts +28 -0
  7. package/protected-api.js +39 -0
  8. package/index.cjs +0 -2077
  9. package/index.global.js +0 -9657
  10. package/index.global.min.js +0 -6
  11. package/internal-common.cjs +0 -7600
  12. package/internal-common.d.ts +0 -2729
  13. package/internal-common.js +0 -7374
  14. package/internal.cjs +0 -183
  15. package/internal.d.ts +0 -4
  16. package/internal.js +0 -3
  17. package/locales/af.cjs +0 -26
  18. package/locales/af.d.ts +0 -6
  19. package/locales/af.global.js +0 -32
  20. package/locales/af.global.min.js +0 -6
  21. package/locales/af.js +0 -22
  22. package/locales/ar-dz.cjs +0 -28
  23. package/locales/ar-dz.d.ts +0 -6
  24. package/locales/ar-dz.global.js +0 -34
  25. package/locales/ar-dz.global.min.js +0 -6
  26. package/locales/ar-dz.js +0 -24
  27. package/locales/ar-kw.cjs +0 -28
  28. package/locales/ar-kw.d.ts +0 -6
  29. package/locales/ar-kw.global.js +0 -34
  30. package/locales/ar-kw.global.min.js +0 -6
  31. package/locales/ar-kw.js +0 -24
  32. package/locales/ar-ly.cjs +0 -28
  33. package/locales/ar-ly.d.ts +0 -6
  34. package/locales/ar-ly.global.js +0 -34
  35. package/locales/ar-ly.global.min.js +0 -6
  36. package/locales/ar-ly.js +0 -24
  37. package/locales/ar-ma.cjs +0 -28
  38. package/locales/ar-ma.d.ts +0 -6
  39. package/locales/ar-ma.global.js +0 -34
  40. package/locales/ar-ma.global.min.js +0 -6
  41. package/locales/ar-ma.js +0 -24
  42. package/locales/ar-sa.cjs +0 -28
  43. package/locales/ar-sa.d.ts +0 -6
  44. package/locales/ar-sa.global.js +0 -34
  45. package/locales/ar-sa.global.min.js +0 -6
  46. package/locales/ar-sa.js +0 -24
  47. package/locales/ar-tn.cjs +0 -28
  48. package/locales/ar-tn.d.ts +0 -6
  49. package/locales/ar-tn.global.js +0 -34
  50. package/locales/ar-tn.global.min.js +0 -6
  51. package/locales/ar-tn.js +0 -24
  52. package/locales/ar.cjs +0 -28
  53. package/locales/ar.d.ts +0 -6
  54. package/locales/ar.global.js +0 -34
  55. package/locales/ar.global.min.js +0 -6
  56. package/locales/ar.js +0 -24
  57. package/locales/az.cjs +0 -29
  58. package/locales/az.d.ts +0 -6
  59. package/locales/az.global.js +0 -35
  60. package/locales/az.global.min.js +0 -6
  61. package/locales/az.js +0 -25
  62. package/locales/bg.cjs +0 -28
  63. package/locales/bg.d.ts +0 -6
  64. package/locales/bg.global.js +0 -34
  65. package/locales/bg.global.min.js +0 -6
  66. package/locales/bg.js +0 -24
  67. package/locales/bn.cjs +0 -29
  68. package/locales/bn.d.ts +0 -6
  69. package/locales/bn.global.js +0 -35
  70. package/locales/bn.global.min.js +0 -6
  71. package/locales/bn.js +0 -25
  72. package/locales/bs.cjs +0 -29
  73. package/locales/bs.d.ts +0 -6
  74. package/locales/bs.global.js +0 -35
  75. package/locales/bs.global.min.js +0 -6
  76. package/locales/bs.js +0 -25
  77. package/locales/ca.cjs +0 -27
  78. package/locales/ca.d.ts +0 -6
  79. package/locales/ca.global.js +0 -33
  80. package/locales/ca.global.min.js +0 -6
  81. package/locales/ca.js +0 -23
  82. package/locales/cs.cjs +0 -29
  83. package/locales/cs.d.ts +0 -6
  84. package/locales/cs.global.js +0 -35
  85. package/locales/cs.global.min.js +0 -6
  86. package/locales/cs.js +0 -25
  87. package/locales/cy.cjs +0 -27
  88. package/locales/cy.d.ts +0 -6
  89. package/locales/cy.global.js +0 -33
  90. package/locales/cy.global.min.js +0 -6
  91. package/locales/cy.js +0 -23
  92. package/locales/da.cjs +0 -27
  93. package/locales/da.d.ts +0 -6
  94. package/locales/da.global.js +0 -33
  95. package/locales/da.global.min.js +0 -6
  96. package/locales/da.js +0 -23
  97. package/locales/de-at.cjs +0 -62
  98. package/locales/de-at.d.ts +0 -6
  99. package/locales/de-at.global.js +0 -68
  100. package/locales/de-at.global.min.js +0 -6
  101. package/locales/de-at.js +0 -58
  102. package/locales/de.cjs +0 -62
  103. package/locales/de.d.ts +0 -6
  104. package/locales/de.global.js +0 -68
  105. package/locales/de.global.min.js +0 -6
  106. package/locales/de.js +0 -58
  107. package/locales/el.cjs +0 -27
  108. package/locales/el.d.ts +0 -6
  109. package/locales/el.global.js +0 -33
  110. package/locales/el.global.min.js +0 -6
  111. package/locales/el.js +0 -23
  112. package/locales/en-au.cjs +0 -23
  113. package/locales/en-au.d.ts +0 -6
  114. package/locales/en-au.global.js +0 -29
  115. package/locales/en-au.global.min.js +0 -6
  116. package/locales/en-au.js +0 -19
  117. package/locales/en-gb.cjs +0 -23
  118. package/locales/en-gb.d.ts +0 -6
  119. package/locales/en-gb.global.js +0 -29
  120. package/locales/en-gb.global.min.js +0 -6
  121. package/locales/en-gb.js +0 -19
  122. package/locales/en-nz.cjs +0 -23
  123. package/locales/en-nz.d.ts +0 -6
  124. package/locales/en-nz.global.js +0 -29
  125. package/locales/en-nz.global.min.js +0 -6
  126. package/locales/en-nz.js +0 -19
  127. package/locales/eo.cjs +0 -27
  128. package/locales/eo.d.ts +0 -6
  129. package/locales/eo.global.js +0 -33
  130. package/locales/eo.global.min.js +0 -6
  131. package/locales/eo.js +0 -23
  132. package/locales/es-us.cjs +0 -27
  133. package/locales/es-us.d.ts +0 -6
  134. package/locales/es-us.global.js +0 -33
  135. package/locales/es-us.global.min.js +0 -6
  136. package/locales/es-us.js +0 -23
  137. package/locales/es.cjs +0 -45
  138. package/locales/es.d.ts +0 -6
  139. package/locales/es.global.js +0 -51
  140. package/locales/es.global.min.js +0 -6
  141. package/locales/es.js +0 -41
  142. package/locales/et.cjs +0 -29
  143. package/locales/et.d.ts +0 -6
  144. package/locales/et.global.js +0 -35
  145. package/locales/et.global.min.js +0 -6
  146. package/locales/et.js +0 -25
  147. package/locales/eu.cjs +0 -27
  148. package/locales/eu.d.ts +0 -6
  149. package/locales/eu.global.js +0 -33
  150. package/locales/eu.global.min.js +0 -6
  151. package/locales/eu.js +0 -23
  152. package/locales/fa.cjs +0 -30
  153. package/locales/fa.d.ts +0 -6
  154. package/locales/fa.global.js +0 -36
  155. package/locales/fa.global.min.js +0 -6
  156. package/locales/fa.js +0 -26
  157. package/locales/fi.cjs +0 -27
  158. package/locales/fi.d.ts +0 -6
  159. package/locales/fi.global.js +0 -33
  160. package/locales/fi.global.min.js +0 -6
  161. package/locales/fi.js +0 -23
  162. package/locales/fr-ca.cjs +0 -23
  163. package/locales/fr-ca.d.ts +0 -6
  164. package/locales/fr-ca.global.js +0 -29
  165. package/locales/fr-ca.global.min.js +0 -6
  166. package/locales/fr-ca.js +0 -19
  167. package/locales/fr-ch.cjs +0 -27
  168. package/locales/fr-ch.d.ts +0 -6
  169. package/locales/fr-ch.global.js +0 -33
  170. package/locales/fr-ch.global.min.js +0 -6
  171. package/locales/fr-ch.js +0 -23
  172. package/locales/fr.cjs +0 -28
  173. package/locales/fr.d.ts +0 -6
  174. package/locales/fr.global.js +0 -34
  175. package/locales/fr.global.min.js +0 -6
  176. package/locales/fr.js +0 -24
  177. package/locales/gl.cjs +0 -45
  178. package/locales/gl.d.ts +0 -6
  179. package/locales/gl.global.js +0 -51
  180. package/locales/gl.global.min.js +0 -6
  181. package/locales/gl.js +0 -41
  182. package/locales/he.cjs +0 -24
  183. package/locales/he.d.ts +0 -6
  184. package/locales/he.global.js +0 -30
  185. package/locales/he.global.min.js +0 -6
  186. package/locales/he.js +0 -20
  187. package/locales/hi.cjs +0 -29
  188. package/locales/hi.d.ts +0 -6
  189. package/locales/hi.global.js +0 -35
  190. package/locales/hi.global.min.js +0 -6
  191. package/locales/hi.js +0 -25
  192. package/locales/hr.cjs +0 -29
  193. package/locales/hr.d.ts +0 -6
  194. package/locales/hr.global.js +0 -35
  195. package/locales/hr.global.min.js +0 -6
  196. package/locales/hr.js +0 -25
  197. package/locales/hu.cjs +0 -27
  198. package/locales/hu.d.ts +0 -6
  199. package/locales/hu.global.js +0 -33
  200. package/locales/hu.global.min.js +0 -6
  201. package/locales/hu.js +0 -23
  202. package/locales/hy-am.cjs +0 -29
  203. package/locales/hy-am.d.ts +0 -6
  204. package/locales/hy-am.global.js +0 -35
  205. package/locales/hy-am.global.min.js +0 -6
  206. package/locales/hy-am.js +0 -25
  207. package/locales/id.cjs +0 -27
  208. package/locales/id.d.ts +0 -6
  209. package/locales/id.global.js +0 -33
  210. package/locales/id.global.min.js +0 -6
  211. package/locales/id.js +0 -23
  212. package/locales/is.cjs +0 -27
  213. package/locales/is.d.ts +0 -6
  214. package/locales/is.global.js +0 -33
  215. package/locales/is.global.min.js +0 -6
  216. package/locales/is.js +0 -23
  217. package/locales/it.cjs +0 -29
  218. package/locales/it.d.ts +0 -6
  219. package/locales/it.global.js +0 -35
  220. package/locales/it.global.min.js +0 -6
  221. package/locales/it.js +0 -25
  222. package/locales/ja.cjs +0 -25
  223. package/locales/ja.d.ts +0 -6
  224. package/locales/ja.global.js +0 -31
  225. package/locales/ja.global.min.js +0 -6
  226. package/locales/ja.js +0 -21
  227. package/locales/ka.cjs +0 -29
  228. package/locales/ka.d.ts +0 -6
  229. package/locales/ka.global.js +0 -35
  230. package/locales/ka.global.min.js +0 -6
  231. package/locales/ka.js +0 -25
  232. package/locales/kk.cjs +0 -29
  233. package/locales/kk.d.ts +0 -6
  234. package/locales/kk.global.js +0 -35
  235. package/locales/kk.global.min.js +0 -6
  236. package/locales/kk.js +0 -25
  237. package/locales/km.cjs +0 -27
  238. package/locales/km.d.ts +0 -6
  239. package/locales/km.global.js +0 -33
  240. package/locales/km.global.min.js +0 -6
  241. package/locales/km.js +0 -23
  242. package/locales/ko.cjs +0 -23
  243. package/locales/ko.d.ts +0 -6
  244. package/locales/ko.global.js +0 -29
  245. package/locales/ko.global.min.js +0 -6
  246. package/locales/ko.js +0 -19
  247. package/locales/ku.cjs +0 -28
  248. package/locales/ku.d.ts +0 -6
  249. package/locales/ku.global.js +0 -34
  250. package/locales/ku.global.min.js +0 -6
  251. package/locales/ku.js +0 -24
  252. package/locales/lb.cjs +0 -27
  253. package/locales/lb.d.ts +0 -6
  254. package/locales/lb.global.js +0 -33
  255. package/locales/lb.global.min.js +0 -6
  256. package/locales/lb.js +0 -23
  257. package/locales/lt.cjs +0 -27
  258. package/locales/lt.d.ts +0 -6
  259. package/locales/lt.global.js +0 -33
  260. package/locales/lt.global.min.js +0 -6
  261. package/locales/lt.js +0 -23
  262. package/locales/lv.cjs +0 -29
  263. package/locales/lv.d.ts +0 -6
  264. package/locales/lv.global.js +0 -35
  265. package/locales/lv.global.min.js +0 -6
  266. package/locales/lv.js +0 -25
  267. package/locales/mk.cjs +0 -25
  268. package/locales/mk.d.ts +0 -6
  269. package/locales/mk.global.js +0 -31
  270. package/locales/mk.global.min.js +0 -6
  271. package/locales/mk.js +0 -21
  272. package/locales/ms.cjs +0 -29
  273. package/locales/ms.d.ts +0 -6
  274. package/locales/ms.global.js +0 -35
  275. package/locales/ms.global.min.js +0 -6
  276. package/locales/ms.js +0 -25
  277. package/locales/nb.cjs +0 -38
  278. package/locales/nb.d.ts +0 -6
  279. package/locales/nb.global.js +0 -44
  280. package/locales/nb.global.min.js +0 -6
  281. package/locales/nb.js +0 -34
  282. package/locales/ne.cjs +0 -27
  283. package/locales/ne.d.ts +0 -6
  284. package/locales/ne.global.js +0 -33
  285. package/locales/ne.global.min.js +0 -6
  286. package/locales/ne.js +0 -23
  287. package/locales/nl.cjs +0 -26
  288. package/locales/nl.d.ts +0 -6
  289. package/locales/nl.global.js +0 -32
  290. package/locales/nl.global.min.js +0 -6
  291. package/locales/nl.js +0 -22
  292. package/locales/nn.cjs +0 -27
  293. package/locales/nn.d.ts +0 -6
  294. package/locales/nn.global.js +0 -33
  295. package/locales/nn.global.min.js +0 -6
  296. package/locales/nn.js +0 -23
  297. package/locales/pl.cjs +0 -27
  298. package/locales/pl.d.ts +0 -6
  299. package/locales/pl.global.js +0 -33
  300. package/locales/pl.global.min.js +0 -6
  301. package/locales/pl.js +0 -23
  302. package/locales/pt-br.cjs +0 -45
  303. package/locales/pt-br.d.ts +0 -6
  304. package/locales/pt-br.global.js +0 -51
  305. package/locales/pt-br.global.min.js +0 -6
  306. package/locales/pt-br.js +0 -41
  307. package/locales/pt.cjs +0 -27
  308. package/locales/pt.d.ts +0 -6
  309. package/locales/pt.global.js +0 -33
  310. package/locales/pt.global.min.js +0 -6
  311. package/locales/pt.js +0 -23
  312. package/locales/ro.cjs +0 -29
  313. package/locales/ro.d.ts +0 -6
  314. package/locales/ro.global.js +0 -35
  315. package/locales/ro.global.min.js +0 -6
  316. package/locales/ro.js +0 -25
  317. package/locales/ru.cjs +0 -29
  318. package/locales/ru.d.ts +0 -6
  319. package/locales/ru.global.js +0 -35
  320. package/locales/ru.global.min.js +0 -6
  321. package/locales/ru.js +0 -25
  322. package/locales/si-lk.cjs +0 -27
  323. package/locales/si-lk.d.ts +0 -6
  324. package/locales/si-lk.global.js +0 -33
  325. package/locales/si-lk.global.min.js +0 -6
  326. package/locales/si-lk.js +0 -23
  327. package/locales/sk.cjs +0 -29
  328. package/locales/sk.d.ts +0 -6
  329. package/locales/sk.global.js +0 -35
  330. package/locales/sk.global.min.js +0 -6
  331. package/locales/sk.js +0 -25
  332. package/locales/sl.cjs +0 -27
  333. package/locales/sl.d.ts +0 -6
  334. package/locales/sl.global.js +0 -33
  335. package/locales/sl.global.min.js +0 -6
  336. package/locales/sl.js +0 -23
  337. package/locales/sm.cjs +0 -23
  338. package/locales/sm.d.ts +0 -6
  339. package/locales/sm.global.js +0 -29
  340. package/locales/sm.global.min.js +0 -6
  341. package/locales/sm.js +0 -19
  342. package/locales/sq.cjs +0 -29
  343. package/locales/sq.d.ts +0 -6
  344. package/locales/sq.global.js +0 -35
  345. package/locales/sq.global.min.js +0 -6
  346. package/locales/sq.js +0 -25
  347. package/locales/sr-cyrl.cjs +0 -29
  348. package/locales/sr-cyrl.d.ts +0 -6
  349. package/locales/sr-cyrl.global.js +0 -35
  350. package/locales/sr-cyrl.global.min.js +0 -6
  351. package/locales/sr-cyrl.js +0 -25
  352. package/locales/sr.cjs +0 -29
  353. package/locales/sr.d.ts +0 -6
  354. package/locales/sr.global.js +0 -35
  355. package/locales/sr.global.min.js +0 -6
  356. package/locales/sr.js +0 -25
  357. package/locales/sv.cjs +0 -46
  358. package/locales/sv.d.ts +0 -6
  359. package/locales/sv.global.js +0 -52
  360. package/locales/sv.global.min.js +0 -6
  361. package/locales/sv.js +0 -42
  362. package/locales/ta-in.cjs +0 -29
  363. package/locales/ta-in.d.ts +0 -6
  364. package/locales/ta-in.global.js +0 -35
  365. package/locales/ta-in.global.min.js +0 -6
  366. package/locales/ta-in.js +0 -25
  367. package/locales/th.cjs +0 -29
  368. package/locales/th.d.ts +0 -6
  369. package/locales/th.global.js +0 -35
  370. package/locales/th.global.min.js +0 -6
  371. package/locales/th.js +0 -25
  372. package/locales/tr.cjs +0 -27
  373. package/locales/tr.d.ts +0 -6
  374. package/locales/tr.global.js +0 -33
  375. package/locales/tr.global.min.js +0 -6
  376. package/locales/tr.js +0 -23
  377. package/locales/ug.cjs +0 -20
  378. package/locales/ug.d.ts +0 -6
  379. package/locales/ug.global.js +0 -26
  380. package/locales/ug.global.min.js +0 -6
  381. package/locales/ug.js +0 -16
  382. package/locales/uk.cjs +0 -29
  383. package/locales/uk.d.ts +0 -6
  384. package/locales/uk.global.js +0 -35
  385. package/locales/uk.global.min.js +0 -6
  386. package/locales/uk.js +0 -25
  387. package/locales/uz-cy.cjs +0 -28
  388. package/locales/uz-cy.d.ts +0 -6
  389. package/locales/uz-cy.global.js +0 -34
  390. package/locales/uz-cy.global.min.js +0 -6
  391. package/locales/uz-cy.js +0 -24
  392. package/locales/uz.cjs +0 -28
  393. package/locales/uz.d.ts +0 -6
  394. package/locales/uz.global.js +0 -34
  395. package/locales/uz.global.min.js +0 -6
  396. package/locales/uz.js +0 -24
  397. package/locales/vi.cjs +0 -29
  398. package/locales/vi.d.ts +0 -6
  399. package/locales/vi.global.js +0 -35
  400. package/locales/vi.global.min.js +0 -6
  401. package/locales/vi.js +0 -25
  402. package/locales/zh-cn.cjs +0 -30
  403. package/locales/zh-cn.d.ts +0 -6
  404. package/locales/zh-cn.global.js +0 -36
  405. package/locales/zh-cn.global.min.js +0 -6
  406. package/locales/zh-cn.js +0 -26
  407. package/locales/zh-tw.cjs +0 -23
  408. package/locales/zh-tw.d.ts +0 -6
  409. package/locales/zh-tw.global.js +0 -29
  410. package/locales/zh-tw.global.min.js +0 -6
  411. package/locales/zh-tw.js +0 -19
  412. package/locales-all.cjs +0 -89
  413. package/locales-all.d.ts +0 -6
  414. package/locales-all.global.js +0 -1927
  415. package/locales-all.global.min.js +0 -6
  416. package/locales-all.js +0 -85
  417. package/preact.cjs +0 -24
  418. package/preact.d.ts +0 -16
  419. package/preact.js +0 -3
package/index.cjs DELETED
@@ -1,2077 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var internalCommon = require('./internal-common.cjs');
6
- var preact = require('preact');
7
- require('preact/compat');
8
-
9
- const globalLocales = [];
10
-
11
- const MINIMAL_RAW_EN_LOCALE = {
12
- code: 'en',
13
- week: {
14
- dow: 0,
15
- doy: 4, // 4 days need to be within the year to be considered the first week
16
- },
17
- direction: 'ltr',
18
- buttonText: {
19
- prev: 'prev',
20
- next: 'next',
21
- prevYear: 'prev year',
22
- nextYear: 'next year',
23
- year: 'year',
24
- today: 'today',
25
- month: 'month',
26
- week: 'week',
27
- day: 'day',
28
- list: 'list',
29
- },
30
- weekText: 'W',
31
- weekTextLong: 'Week',
32
- closeHint: 'Close',
33
- eventsHint: 'Events',
34
- allDayText: 'all-day',
35
- timedText: 'timed',
36
- moreLinkText: 'more',
37
- noEventsText: 'No events to display',
38
- };
39
- const RAW_EN_LOCALE = Object.assign(Object.assign({}, MINIMAL_RAW_EN_LOCALE), {
40
- // Includes things we don't want other locales to inherit,
41
- // things that derive from other translatable strings.
42
- buttonHints: {
43
- prev: 'Previous $0',
44
- next: 'Next $0',
45
- today(buttonText, unit) {
46
- return (unit === 'day')
47
- ? 'Today'
48
- : `This ${buttonText}`;
49
- },
50
- }, viewHint: '$0 view', viewChangeHint: 'Change view', navLinkHint: 'Go to $0', moreLinkHint(eventCnt) {
51
- return `Show ${eventCnt} more event${eventCnt === 1 ? '' : 's'}`;
52
- } });
53
- function organizeRawLocales(explicitRawLocales) {
54
- let defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
55
- let allRawLocales = globalLocales.concat(explicitRawLocales);
56
- let rawLocaleMap = {
57
- en: RAW_EN_LOCALE,
58
- };
59
- for (let rawLocale of allRawLocales) {
60
- rawLocaleMap[rawLocale.code] = rawLocale;
61
- }
62
- return {
63
- map: rawLocaleMap,
64
- defaultCode,
65
- };
66
- }
67
- function buildLocale(inputSingular, available) {
68
- if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
69
- return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
70
- }
71
- return queryLocale(inputSingular, available);
72
- }
73
- function queryLocale(codeArg, available) {
74
- let codes = [].concat(codeArg || []); // will convert to array
75
- let raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
76
- return parseLocale(codeArg, codes, raw);
77
- }
78
- function queryRawLocale(codes, available) {
79
- for (let i = 0; i < codes.length; i += 1) {
80
- let parts = codes[i].toLocaleLowerCase().split('-');
81
- for (let j = parts.length; j > 0; j -= 1) {
82
- let simpleId = parts.slice(0, j).join('-');
83
- if (available[simpleId]) {
84
- return available[simpleId];
85
- }
86
- }
87
- }
88
- return null;
89
- }
90
- function parseLocale(codeArg, codes, raw) {
91
- let merged = internalCommon.mergeProps([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']);
92
- delete merged.code; // don't want this part of the options
93
- let { week } = merged;
94
- delete merged.week;
95
- return {
96
- codeArg,
97
- codes,
98
- week,
99
- simpleNumberFormat: new Intl.NumberFormat(codeArg),
100
- options: merged,
101
- };
102
- }
103
-
104
- // TODO: easier way to add new hooks? need to update a million things
105
- function createPlugin(input) {
106
- return {
107
- id: internalCommon.guid(),
108
- name: input.name,
109
- premiumReleaseDate: input.premiumReleaseDate ? new Date(input.premiumReleaseDate) : undefined,
110
- deps: input.deps || [],
111
- reducers: input.reducers || [],
112
- isLoadingFuncs: input.isLoadingFuncs || [],
113
- contextInit: [].concat(input.contextInit || []),
114
- eventRefiners: input.eventRefiners || {},
115
- eventDefMemberAdders: input.eventDefMemberAdders || [],
116
- eventSourceRefiners: input.eventSourceRefiners || {},
117
- isDraggableTransformers: input.isDraggableTransformers || [],
118
- eventDragMutationMassagers: input.eventDragMutationMassagers || [],
119
- eventDefMutationAppliers: input.eventDefMutationAppliers || [],
120
- dateSelectionTransformers: input.dateSelectionTransformers || [],
121
- datePointTransforms: input.datePointTransforms || [],
122
- dateSpanTransforms: input.dateSpanTransforms || [],
123
- views: input.views || {},
124
- viewPropsTransformers: input.viewPropsTransformers || [],
125
- isPropsValid: input.isPropsValid || null,
126
- externalDefTransforms: input.externalDefTransforms || [],
127
- viewContainerAppends: input.viewContainerAppends || [],
128
- eventDropTransformers: input.eventDropTransformers || [],
129
- componentInteractions: input.componentInteractions || [],
130
- calendarInteractions: input.calendarInteractions || [],
131
- themeClasses: input.themeClasses || {},
132
- eventSourceDefs: input.eventSourceDefs || [],
133
- cmdFormatter: input.cmdFormatter,
134
- recurringTypes: input.recurringTypes || [],
135
- namedTimeZonedImpl: input.namedTimeZonedImpl,
136
- initialView: input.initialView || '',
137
- elementDraggingImpl: input.elementDraggingImpl,
138
- optionChangeHandlers: input.optionChangeHandlers || {},
139
- scrollerSyncerClass: input.scrollerSyncerClass || null,
140
- listenerRefiners: input.listenerRefiners || {},
141
- optionRefiners: input.optionRefiners || {},
142
- propSetHandlers: input.propSetHandlers || {},
143
- };
144
- }
145
- function buildPluginHooks(pluginDefs, globalDefs) {
146
- let currentPluginIds = {};
147
- let hooks = {
148
- premiumReleaseDate: undefined,
149
- reducers: [],
150
- isLoadingFuncs: [],
151
- contextInit: [],
152
- eventRefiners: {},
153
- eventDefMemberAdders: [],
154
- eventSourceRefiners: {},
155
- isDraggableTransformers: [],
156
- eventDragMutationMassagers: [],
157
- eventDefMutationAppliers: [],
158
- dateSelectionTransformers: [],
159
- datePointTransforms: [],
160
- dateSpanTransforms: [],
161
- views: {},
162
- viewPropsTransformers: [],
163
- isPropsValid: null,
164
- externalDefTransforms: [],
165
- viewContainerAppends: [],
166
- eventDropTransformers: [],
167
- componentInteractions: [],
168
- calendarInteractions: [],
169
- themeClasses: {},
170
- eventSourceDefs: [],
171
- cmdFormatter: null,
172
- recurringTypes: [],
173
- namedTimeZonedImpl: null,
174
- initialView: '',
175
- elementDraggingImpl: null,
176
- optionChangeHandlers: {},
177
- scrollerSyncerClass: null,
178
- listenerRefiners: {},
179
- optionRefiners: {},
180
- propSetHandlers: {},
181
- };
182
- function addDefs(defs) {
183
- for (let def of defs) {
184
- const pluginName = def.name;
185
- const currentId = currentPluginIds[pluginName];
186
- if (currentId === undefined) {
187
- currentPluginIds[pluginName] = def.id;
188
- addDefs(def.deps);
189
- hooks = combineHooks(hooks, def);
190
- }
191
- else if (currentId !== def.id) {
192
- // different ID than the one already added
193
- console.warn(`Duplicate plugin '${pluginName}'`);
194
- }
195
- }
196
- }
197
- if (pluginDefs) {
198
- addDefs(pluginDefs);
199
- }
200
- addDefs(globalDefs);
201
- return hooks;
202
- }
203
- function buildBuildPluginHooks() {
204
- let currentOverrideDefs = [];
205
- let currentGlobalDefs = [];
206
- let currentHooks;
207
- return (overrideDefs, globalDefs) => {
208
- if (!currentHooks || !internalCommon.isArraysEqual(overrideDefs, currentOverrideDefs) || !internalCommon.isArraysEqual(globalDefs, currentGlobalDefs)) {
209
- currentHooks = buildPluginHooks(overrideDefs, globalDefs);
210
- }
211
- currentOverrideDefs = overrideDefs;
212
- currentGlobalDefs = globalDefs;
213
- return currentHooks;
214
- };
215
- }
216
- function combineHooks(hooks0, hooks1) {
217
- return {
218
- premiumReleaseDate: compareOptionalDates(hooks0.premiumReleaseDate, hooks1.premiumReleaseDate),
219
- reducers: hooks0.reducers.concat(hooks1.reducers),
220
- isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),
221
- contextInit: hooks0.contextInit.concat(hooks1.contextInit),
222
- eventRefiners: Object.assign(Object.assign({}, hooks0.eventRefiners), hooks1.eventRefiners),
223
- eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),
224
- eventSourceRefiners: Object.assign(Object.assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),
225
- isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
226
- eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
227
- eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
228
- dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
229
- datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
230
- dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
231
- views: Object.assign(Object.assign({}, hooks0.views), hooks1.views),
232
- viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
233
- isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
234
- externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
235
- viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),
236
- eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
237
- calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
238
- componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
239
- themeClasses: Object.assign(Object.assign({}, hooks0.themeClasses), hooks1.themeClasses),
240
- eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
241
- cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
242
- recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
243
- namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
244
- initialView: hooks0.initialView || hooks1.initialView,
245
- elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
246
- optionChangeHandlers: Object.assign(Object.assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),
247
- scrollerSyncerClass: hooks0.scrollerSyncerClass || hooks1.scrollerSyncerClass,
248
- listenerRefiners: Object.assign(Object.assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),
249
- optionRefiners: Object.assign(Object.assign({}, hooks0.optionRefiners), hooks1.optionRefiners),
250
- propSetHandlers: Object.assign(Object.assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers),
251
- };
252
- }
253
- function compareOptionalDates(date0, date1) {
254
- if (date0 === undefined) {
255
- return date1;
256
- }
257
- if (date1 === undefined) {
258
- return date0;
259
- }
260
- return new Date(Math.max(date0.valueOf(), date1.valueOf()));
261
- }
262
-
263
- class StandardTheme extends internalCommon.Theme {
264
- }
265
- StandardTheme.prototype.classes = {
266
- root: 'fc-theme-standard',
267
- buttonGroup: 'fc-button-group',
268
- button: 'fc-button fc-button-primary',
269
- buttonActive: 'fc-button-active',
270
- };
271
- StandardTheme.prototype.baseIconClass = 'fc-icon';
272
- StandardTheme.prototype.iconClasses = {
273
- close: 'fc-icon-x',
274
- prev: 'fc-icon-chevron-left',
275
- next: 'fc-icon-chevron-right',
276
- prevYear: 'fc-icon-chevrons-left',
277
- nextYear: 'fc-icon-chevrons-right',
278
- };
279
- StandardTheme.prototype.rtlIconClasses = {
280
- prev: 'fc-icon-chevron-right',
281
- next: 'fc-icon-chevron-left',
282
- prevYear: 'fc-icon-chevrons-right',
283
- nextYear: 'fc-icon-chevrons-left',
284
- };
285
- StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly
286
- StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
287
- StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
288
-
289
- function compileViewDefs(defaultConfigs, overrideConfigs) {
290
- let hash = {};
291
- let viewType;
292
- for (viewType in defaultConfigs) {
293
- ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
294
- }
295
- for (viewType in overrideConfigs) {
296
- ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
297
- }
298
- return hash;
299
- }
300
- function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
301
- if (hash[viewType]) {
302
- return hash[viewType];
303
- }
304
- let viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
305
- if (viewDef) {
306
- hash[viewType] = viewDef;
307
- }
308
- return viewDef;
309
- }
310
- function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
311
- let defaultConfig = defaultConfigs[viewType];
312
- let overrideConfig = overrideConfigs[viewType];
313
- let queryProp = (name) => ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
314
- ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null));
315
- let theComponent = queryProp('component');
316
- let superType = queryProp('superType');
317
- let superDef = null;
318
- if (superType) {
319
- if (superType === viewType) {
320
- throw new Error('Can\'t have a custom view type that references itself');
321
- }
322
- superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
323
- }
324
- if (!theComponent && superDef) {
325
- theComponent = superDef.component;
326
- }
327
- if (!theComponent) {
328
- return null; // don't throw a warning, might be settings for a single-unit view
329
- }
330
- return {
331
- type: viewType,
332
- component: theComponent,
333
- defaults: Object.assign(Object.assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),
334
- overrides: Object.assign(Object.assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})),
335
- };
336
- }
337
-
338
- function parseViewConfigs(inputs) {
339
- return internalCommon.mapHash(inputs, parseViewConfig);
340
- }
341
- function parseViewConfig(input) {
342
- let rawOptions = typeof input === 'function' ?
343
- { component: input } :
344
- input;
345
- let { component } = rawOptions;
346
- if (rawOptions.content) {
347
- // TODO: remove content/classNames/didMount/etc from options?
348
- component = createViewHookComponent(rawOptions);
349
- }
350
- else if (component && !(component.prototype instanceof internalCommon.BaseComponent)) {
351
- // WHY?: people were using `component` property for `content`
352
- // TODO: converge on one setting name
353
- component = createViewHookComponent(Object.assign(Object.assign({}, rawOptions), { content: component }));
354
- }
355
- return {
356
- superType: rawOptions.type,
357
- component: component,
358
- rawOptions, // includes type and component too :(
359
- };
360
- }
361
- function createViewHookComponent(options) {
362
- return (viewProps) => (preact.createElement(internalCommon.ViewContextType.Consumer, null, (context) => (preact.createElement(internalCommon.ContentContainer, { tag: "div", className: internalCommon.buildViewClassName(context.viewSpec), renderProps: Object.assign(Object.assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }), generatorName: undefined, customGenerator: options.content, classNameGenerator: options.classNames, didMount: options.didMount, willUnmount: options.willUnmount }))));
363
- }
364
-
365
- function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
366
- let defaultConfigs = parseViewConfigs(defaultInputs);
367
- let overrideConfigs = parseViewConfigs(optionOverrides.views);
368
- let viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
369
- return internalCommon.mapHash(viewDefs, (viewDef) => buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults));
370
- }
371
- function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
372
- let durationInput = viewDef.overrides.duration ||
373
- viewDef.defaults.duration ||
374
- dynamicOptionOverrides.duration ||
375
- optionOverrides.duration;
376
- let duration = null;
377
- let durationUnit = '';
378
- let singleUnit = '';
379
- let singleUnitOverrides = {};
380
- if (durationInput) {
381
- duration = createDurationCached(durationInput);
382
- if (duration) { // valid?
383
- let denom = internalCommon.greatestDurationDenominator(duration);
384
- durationUnit = denom.unit;
385
- if (denom.value === 1) {
386
- singleUnit = durationUnit;
387
- singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};
388
- }
389
- }
390
- }
391
- let queryButtonText = (optionsSubset) => {
392
- let buttonTextMap = optionsSubset.buttonText || {};
393
- let buttonTextKey = viewDef.defaults.buttonTextKey;
394
- if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
395
- return buttonTextMap[buttonTextKey];
396
- }
397
- if (buttonTextMap[viewDef.type] != null) {
398
- return buttonTextMap[viewDef.type];
399
- }
400
- if (buttonTextMap[singleUnit] != null) {
401
- return buttonTextMap[singleUnit];
402
- }
403
- return null;
404
- };
405
- let queryButtonTitle = (optionsSubset) => {
406
- let buttonHints = optionsSubset.buttonHints || {};
407
- let buttonKey = viewDef.defaults.buttonTextKey; // use same key as text
408
- if (buttonKey != null && buttonHints[buttonKey] != null) {
409
- return buttonHints[buttonKey];
410
- }
411
- if (buttonHints[viewDef.type] != null) {
412
- return buttonHints[viewDef.type];
413
- }
414
- if (buttonHints[singleUnit] != null) {
415
- return buttonHints[singleUnit];
416
- }
417
- return null;
418
- };
419
- return {
420
- type: viewDef.type,
421
- component: viewDef.component,
422
- duration,
423
- durationUnit,
424
- singleUnit,
425
- optionDefaults: viewDef.defaults,
426
- optionOverrides: Object.assign(Object.assign({}, singleUnitOverrides), viewDef.overrides),
427
- buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||
428
- queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence
429
- viewDef.overrides.buttonText,
430
- buttonTextDefault: queryButtonText(localeDefaults) ||
431
- viewDef.defaults.buttonText ||
432
- queryButtonText(internalCommon.BASE_OPTION_DEFAULTS) ||
433
- viewDef.type,
434
- // not DRY
435
- buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) ||
436
- queryButtonTitle(optionOverrides) ||
437
- viewDef.overrides.buttonHint,
438
- buttonTitleDefault: queryButtonTitle(localeDefaults) ||
439
- viewDef.defaults.buttonHint ||
440
- queryButtonTitle(internalCommon.BASE_OPTION_DEFAULTS),
441
- // will eventually fall back to buttonText
442
- };
443
- }
444
- // hack to get memoization working
445
- let durationInputMap = {};
446
- function createDurationCached(durationInput) {
447
- let json = JSON.stringify(durationInput);
448
- let res = durationInputMap[json];
449
- if (res === undefined) {
450
- res = internalCommon.createDuration(durationInput);
451
- durationInputMap[json] = res;
452
- }
453
- return res;
454
- }
455
-
456
- function reduceViewType(viewType, action) {
457
- switch (action.type) {
458
- case 'CHANGE_VIEW_TYPE':
459
- viewType = action.viewType;
460
- }
461
- return viewType;
462
- }
463
-
464
- function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {
465
- switch (action.type) {
466
- case 'SET_OPTION':
467
- return Object.assign(Object.assign({}, dynamicOptionOverrides), { [action.optionName]: action.rawOptionValue });
468
- default:
469
- return dynamicOptionOverrides;
470
- }
471
- }
472
-
473
- function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {
474
- let dp;
475
- switch (action.type) {
476
- case 'CHANGE_VIEW_TYPE':
477
- return dateProfileGenerator.build(action.dateMarker || currentDate);
478
- case 'CHANGE_DATE':
479
- return dateProfileGenerator.build(action.dateMarker);
480
- case 'PREV':
481
- dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);
482
- if (dp.isValid) {
483
- return dp;
484
- }
485
- break;
486
- case 'NEXT':
487
- dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);
488
- if (dp.isValid) {
489
- return dp;
490
- }
491
- break;
492
- }
493
- return currentDateProfile;
494
- }
495
-
496
- function initEventSources(calendarOptions, dateProfile, context) {
497
- let activeRange = dateProfile ? dateProfile.activeRange : null;
498
- return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);
499
- }
500
- function reduceEventSources(eventSources, action, dateProfile, context) {
501
- let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
502
- switch (action.type) {
503
- case 'ADD_EVENT_SOURCES': // already parsed
504
- return addSources(eventSources, action.sources, activeRange, context);
505
- case 'REMOVE_EVENT_SOURCE':
506
- return removeSource(eventSources, action.sourceId);
507
- case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
508
- case 'NEXT':
509
- case 'CHANGE_DATE':
510
- case 'CHANGE_VIEW_TYPE':
511
- if (dateProfile) {
512
- return fetchDirtySources(eventSources, activeRange, context);
513
- }
514
- return eventSources;
515
- case 'FETCH_EVENT_SOURCES':
516
- return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?
517
- internalCommon.arrayToHash(action.sourceIds) :
518
- excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context);
519
- case 'RECEIVE_EVENTS':
520
- case 'RECEIVE_EVENT_ERROR':
521
- return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
522
- case 'REMOVE_ALL_EVENT_SOURCES':
523
- return {};
524
- default:
525
- return eventSources;
526
- }
527
- }
528
- function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {
529
- let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
530
- return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context);
531
- }
532
- function computeEventSourcesLoading(eventSources) {
533
- for (let sourceId in eventSources) {
534
- if (eventSources[sourceId].isFetching) {
535
- return true;
536
- }
537
- }
538
- return false;
539
- }
540
- function addSources(eventSourceHash, sources, fetchRange, context) {
541
- let hash = {};
542
- for (let source of sources) {
543
- hash[source.sourceId] = source;
544
- }
545
- if (fetchRange) {
546
- hash = fetchDirtySources(hash, fetchRange, context);
547
- }
548
- return Object.assign(Object.assign({}, eventSourceHash), hash);
549
- }
550
- function removeSource(eventSourceHash, sourceId) {
551
- return internalCommon.filterHash(eventSourceHash, (eventSource) => eventSource.sourceId !== sourceId);
552
- }
553
- function fetchDirtySources(sourceHash, fetchRange, context) {
554
- return fetchSourcesByIds(sourceHash, internalCommon.filterHash(sourceHash, (eventSource) => isSourceDirty(eventSource, fetchRange, context)), fetchRange, false, context);
555
- }
556
- function isSourceDirty(eventSource, fetchRange, context) {
557
- if (!doesSourceNeedRange(eventSource, context)) {
558
- return !eventSource.latestFetchId;
559
- }
560
- return !context.options.lazyFetching ||
561
- !eventSource.fetchRange ||
562
- eventSource.isFetching || // always cancel outdated in-progress fetches
563
- fetchRange.start < eventSource.fetchRange.start ||
564
- fetchRange.end > eventSource.fetchRange.end;
565
- }
566
- function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) {
567
- let nextSources = {};
568
- for (let sourceId in prevSources) {
569
- let source = prevSources[sourceId];
570
- if (sourceIdHash[sourceId]) {
571
- nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context);
572
- }
573
- else {
574
- nextSources[sourceId] = source;
575
- }
576
- }
577
- return nextSources;
578
- }
579
- function fetchSource(eventSource, fetchRange, isRefetch, context) {
580
- let { options, calendarApi } = context;
581
- let sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];
582
- let fetchId = internalCommon.guid();
583
- sourceDef.fetch({
584
- eventSource,
585
- range: fetchRange,
586
- isRefetch,
587
- context,
588
- }, (res) => {
589
- let { rawEvents } = res;
590
- if (options.eventSourceSuccess) {
591
- rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.response) || rawEvents;
592
- }
593
- if (eventSource.success) {
594
- rawEvents = eventSource.success.call(calendarApi, rawEvents, res.response) || rawEvents;
595
- }
596
- context.dispatch({
597
- type: 'RECEIVE_EVENTS',
598
- sourceId: eventSource.sourceId,
599
- fetchId,
600
- fetchRange,
601
- rawEvents,
602
- });
603
- }, (error) => {
604
- let errorHandled = false;
605
- if (options.eventSourceFailure) {
606
- options.eventSourceFailure.call(calendarApi, error);
607
- errorHandled = true;
608
- }
609
- if (eventSource.failure) {
610
- eventSource.failure(error);
611
- errorHandled = true;
612
- }
613
- if (!errorHandled) {
614
- console.warn(error.message, error);
615
- }
616
- context.dispatch({
617
- type: 'RECEIVE_EVENT_ERROR',
618
- sourceId: eventSource.sourceId,
619
- fetchId,
620
- fetchRange,
621
- error,
622
- });
623
- });
624
- return Object.assign(Object.assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });
625
- }
626
- function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
627
- let eventSource = sourceHash[sourceId];
628
- if (eventSource && // not already removed
629
- fetchId === eventSource.latestFetchId) {
630
- return Object.assign(Object.assign({}, sourceHash), { [sourceId]: Object.assign(Object.assign({}, eventSource), { isFetching: false, fetchRange }) });
631
- }
632
- return sourceHash;
633
- }
634
- function excludeStaticSources(eventSources, context) {
635
- return internalCommon.filterHash(eventSources, (eventSource) => doesSourceNeedRange(eventSource, context));
636
- }
637
- function parseInitialSources(rawOptions, context) {
638
- let refiners = internalCommon.buildEventSourceRefiners(context);
639
- let rawSources = [].concat(rawOptions.eventSources || []);
640
- let sources = []; // parsed
641
- if (rawOptions.initialEvents) {
642
- rawSources.unshift(rawOptions.initialEvents);
643
- }
644
- if (rawOptions.events) {
645
- rawSources.unshift(rawOptions.events);
646
- }
647
- for (let rawSource of rawSources) {
648
- let source = internalCommon.parseEventSource(rawSource, context, refiners);
649
- if (source) {
650
- sources.push(source);
651
- }
652
- }
653
- return sources;
654
- }
655
- function doesSourceNeedRange(eventSource, context) {
656
- let defs = context.pluginHooks.eventSourceDefs;
657
- return !defs[eventSource.sourceDefId].ignoreRange;
658
- }
659
-
660
- function reduceDateSelection(currentSelection, action) {
661
- switch (action.type) {
662
- case 'UNSELECT_DATES':
663
- return null;
664
- case 'SELECT_DATES':
665
- return action.selection;
666
- default:
667
- return currentSelection;
668
- }
669
- }
670
-
671
- function reduceSelectedEvent(currentInstanceId, action) {
672
- switch (action.type) {
673
- case 'UNSELECT_EVENT':
674
- return '';
675
- case 'SELECT_EVENT':
676
- return action.eventInstanceId;
677
- default:
678
- return currentInstanceId;
679
- }
680
- }
681
-
682
- function reduceEventDrag(currentDrag, action) {
683
- let newDrag;
684
- switch (action.type) {
685
- case 'UNSET_EVENT_DRAG':
686
- return null;
687
- case 'SET_EVENT_DRAG':
688
- newDrag = action.state;
689
- return {
690
- affectedEvents: newDrag.affectedEvents,
691
- mutatedEvents: newDrag.mutatedEvents,
692
- isEvent: newDrag.isEvent,
693
- };
694
- default:
695
- return currentDrag;
696
- }
697
- }
698
-
699
- function reduceEventResize(currentResize, action) {
700
- let newResize;
701
- switch (action.type) {
702
- case 'UNSET_EVENT_RESIZE':
703
- return null;
704
- case 'SET_EVENT_RESIZE':
705
- newResize = action.state;
706
- return {
707
- affectedEvents: newResize.affectedEvents,
708
- mutatedEvents: newResize.mutatedEvents,
709
- isEvent: newResize.isEvent,
710
- };
711
- default:
712
- return currentResize;
713
- }
714
- }
715
-
716
- function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
717
- let header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;
718
- let footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;
719
- return { header, footer };
720
- }
721
- function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
722
- let isRtl = calendarOptions.direction === 'rtl';
723
- let viewsWithButtons = [];
724
- let hasTitle = false;
725
- function processSectionStr(sectionStr) {
726
- let sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi);
727
- viewsWithButtons.push(...sectionRes.viewsWithButtons);
728
- hasTitle = hasTitle || sectionRes.hasTitle;
729
- return sectionRes.widgets;
730
- }
731
- const sectionWidgets = {
732
- start: processSectionStr(sectionStrHash[isRtl ? 'right' : 'left'] || sectionStrHash.start || ''),
733
- center: processSectionStr(sectionStrHash.center || ''),
734
- end: processSectionStr(sectionStrHash[isRtl ? 'left' : 'right'] || sectionStrHash.end || ''),
735
- };
736
- return {
737
- sectionWidgets,
738
- viewsWithButtons,
739
- hasTitle,
740
- };
741
- }
742
- /*
743
- BAD: querying icons and text here. should be done at render time
744
- */
745
- function parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined
746
- calendarOptionOverrides, // overrides only!, unrefined :(
747
- theme, viewSpecs, calendarApi) {
748
- let isRtl = calendarOptions.direction === 'rtl';
749
- let calendarCustomButtons = calendarOptions.customButtons || {};
750
- let calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};
751
- let calendarButtonText = calendarOptions.buttonText || {};
752
- let calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {};
753
- let calendarButtonHints = calendarOptions.buttonHints || {};
754
- let sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];
755
- let viewsWithButtons = [];
756
- let hasTitle = false;
757
- let widgets = sectionSubstrs.map((buttonGroupStr) => (buttonGroupStr.split(',').map((buttonName) => {
758
- if (buttonName === 'title') {
759
- hasTitle = true;
760
- return { buttonName };
761
- }
762
- let customButtonProps;
763
- let viewSpec;
764
- let buttonClick;
765
- let buttonIcon; // only one of these will be set
766
- let buttonText; // "
767
- let buttonHint;
768
- let isView = false;
769
- // ^ for the title="" attribute, for accessibility
770
- if ((customButtonProps = calendarCustomButtons[buttonName])) {
771
- buttonClick = (ev) => {
772
- if (customButtonProps.click) {
773
- customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context?
774
- }
775
- };
776
- (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
777
- (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
778
- (buttonText = customButtonProps.text);
779
- buttonHint = customButtonProps.hint || customButtonProps.text;
780
- }
781
- else if ((viewSpec = viewSpecs[buttonName])) {
782
- isView = true;
783
- viewsWithButtons.push(buttonName);
784
- buttonClick = () => {
785
- calendarApi.changeView(buttonName);
786
- };
787
- (buttonText = viewSpec.buttonTextOverride) ||
788
- (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
789
- (buttonText = viewSpec.buttonTextDefault);
790
- let textFallback = viewSpec.buttonTextOverride ||
791
- viewSpec.buttonTextDefault;
792
- buttonHint = internalCommon.formatWithOrdinals(viewSpec.buttonTitleOverride ||
793
- viewSpec.buttonTitleDefault ||
794
- calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName
795
- textFallback);
796
- }
797
- else if (calendarApi[buttonName]) { // a calendarApi method
798
- buttonClick = () => {
799
- calendarApi[buttonName]();
800
- };
801
- (buttonText = calendarButtonTextOverrides[buttonName]) ||
802
- (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
803
- (buttonText = calendarButtonText[buttonName]); // everything else is considered default
804
- if (buttonName === 'prevYear' || buttonName === 'nextYear') {
805
- let prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next';
806
- buttonHint = internalCommon.formatWithOrdinals(calendarButtonHintOverrides[prevOrNext] ||
807
- calendarButtonHints[prevOrNext], [
808
- calendarButtonText.year || 'year',
809
- 'year',
810
- ], calendarButtonText[buttonName]);
811
- }
812
- else {
813
- buttonHint = (navUnit) => internalCommon.formatWithOrdinals(calendarButtonHintOverrides[buttonName] ||
814
- calendarButtonHints[buttonName], [
815
- calendarButtonText[navUnit] || navUnit,
816
- navUnit,
817
- ], calendarButtonText[buttonName]);
818
- }
819
- }
820
- return { buttonName, buttonClick, buttonIcon, buttonText, buttonHint, isView };
821
- })));
822
- return { widgets, viewsWithButtons, hasTitle };
823
- }
824
-
825
- // always represents the current view. otherwise, it'd need to change value every time date changes
826
- class ViewImpl {
827
- constructor(type, getCurrentData, dateEnv) {
828
- this.type = type;
829
- this.getCurrentData = getCurrentData;
830
- this.dateEnv = dateEnv;
831
- }
832
- get calendar() {
833
- return this.getCurrentData().calendarApi;
834
- }
835
- get title() {
836
- return this.getCurrentData().viewTitle;
837
- }
838
- get activeStart() {
839
- return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);
840
- }
841
- get activeEnd() {
842
- return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);
843
- }
844
- get currentStart() {
845
- return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);
846
- }
847
- get currentEnd() {
848
- return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);
849
- }
850
- getOption(name) {
851
- return this.getCurrentData().options[name]; // are the view-specific options
852
- }
853
- }
854
-
855
- let eventSourceDef$2 = {
856
- ignoreRange: true,
857
- parseMeta(refined) {
858
- if (Array.isArray(refined.events)) {
859
- return refined.events;
860
- }
861
- return null;
862
- },
863
- fetch(arg, successCallback) {
864
- successCallback({
865
- rawEvents: arg.eventSource.meta,
866
- });
867
- },
868
- };
869
- const arrayEventSourcePlugin = createPlugin({
870
- name: 'array-event-source',
871
- eventSourceDefs: [eventSourceDef$2],
872
- });
873
-
874
- let eventSourceDef$1 = {
875
- parseMeta(refined) {
876
- if (typeof refined.events === 'function') {
877
- return refined.events;
878
- }
879
- return null;
880
- },
881
- fetch(arg, successCallback, errorCallback) {
882
- const { dateEnv } = arg.context;
883
- const func = arg.eventSource.meta;
884
- internalCommon.unpromisify(func.bind(null, internalCommon.buildRangeApiWithTimeZone(arg.range, dateEnv)), (rawEvents) => successCallback({ rawEvents }), errorCallback);
885
- },
886
- };
887
- const funcEventSourcePlugin = createPlugin({
888
- name: 'func-event-source',
889
- eventSourceDefs: [eventSourceDef$1],
890
- });
891
-
892
- const JSON_FEED_EVENT_SOURCE_REFINERS = {
893
- method: String,
894
- extraParams: internalCommon.identity,
895
- startParam: String,
896
- endParam: String,
897
- timeZoneParam: String,
898
- };
899
-
900
- let eventSourceDef = {
901
- parseMeta(refined) {
902
- if (refined.url && (refined.format === 'json' || !refined.format)) {
903
- return {
904
- url: refined.url,
905
- format: 'json',
906
- method: (refined.method || 'GET').toUpperCase(),
907
- extraParams: refined.extraParams,
908
- startParam: refined.startParam,
909
- endParam: refined.endParam,
910
- timeZoneParam: refined.timeZoneParam,
911
- };
912
- }
913
- return null;
914
- },
915
- fetch(arg, successCallback, errorCallback) {
916
- const { meta } = arg.eventSource;
917
- const requestParams = buildRequestParams(meta, arg.range, arg.context);
918
- internalCommon.requestJson(meta.method, meta.url, requestParams).then(([rawEvents, response]) => {
919
- successCallback({ rawEvents, response });
920
- }, errorCallback);
921
- },
922
- };
923
- const jsonFeedEventSourcePlugin = createPlugin({
924
- name: 'json-event-source',
925
- eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,
926
- eventSourceDefs: [eventSourceDef],
927
- });
928
- function buildRequestParams(meta, range, context) {
929
- let { dateEnv, options } = context;
930
- let startParam;
931
- let endParam;
932
- let timeZoneParam;
933
- let customRequestParams;
934
- let params = {};
935
- startParam = meta.startParam;
936
- if (startParam == null) {
937
- startParam = options.startParam;
938
- }
939
- endParam = meta.endParam;
940
- if (endParam == null) {
941
- endParam = options.endParam;
942
- }
943
- timeZoneParam = meta.timeZoneParam;
944
- if (timeZoneParam == null) {
945
- timeZoneParam = options.timeZoneParam;
946
- }
947
- // retrieve any outbound GET/POST data from the options
948
- if (typeof meta.extraParams === 'function') {
949
- // supplied as a function that returns a key/value object
950
- customRequestParams = meta.extraParams();
951
- }
952
- else {
953
- // probably supplied as a straight key/value object
954
- customRequestParams = meta.extraParams || {};
955
- }
956
- Object.assign(params, customRequestParams);
957
- params[startParam] = dateEnv.formatIso(range.start);
958
- params[endParam] = dateEnv.formatIso(range.end);
959
- if (dateEnv.timeZone !== 'local') {
960
- params[timeZoneParam] = dateEnv.timeZone;
961
- }
962
- return params;
963
- }
964
-
965
- const SIMPLE_RECURRING_REFINERS = {
966
- daysOfWeek: internalCommon.identity,
967
- startTime: internalCommon.createDuration,
968
- endTime: internalCommon.createDuration,
969
- duration: internalCommon.createDuration,
970
- startRecur: internalCommon.identity,
971
- endRecur: internalCommon.identity,
972
- };
973
-
974
- let recurring = {
975
- parse(refined, dateEnv) {
976
- if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {
977
- let recurringData = {
978
- daysOfWeek: refined.daysOfWeek || null,
979
- startTime: refined.startTime || null,
980
- endTime: refined.endTime || null,
981
- startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,
982
- endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,
983
- };
984
- let duration;
985
- if (refined.duration) {
986
- duration = refined.duration;
987
- }
988
- if (!duration && refined.startTime && refined.endTime) {
989
- duration = internalCommon.subtractDurations(refined.endTime, refined.startTime);
990
- }
991
- return {
992
- allDayGuess: Boolean(!refined.startTime && !refined.endTime),
993
- duration,
994
- typeData: recurringData, // doesn't need endTime anymore but oh well
995
- };
996
- }
997
- return null;
998
- },
999
- expand(typeData, framingRange, dateEnv) {
1000
- let clippedFramingRange = internalCommon.intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
1001
- if (clippedFramingRange) {
1002
- return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
1003
- }
1004
- return [];
1005
- },
1006
- };
1007
- const simpleRecurringEventsPlugin = createPlugin({
1008
- name: 'simple-recurring-event',
1009
- recurringTypes: [recurring],
1010
- eventRefiners: SIMPLE_RECURRING_REFINERS,
1011
- });
1012
- function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
1013
- let dowHash = daysOfWeek ? internalCommon.arrayToHash(daysOfWeek) : null;
1014
- let dayMarker = internalCommon.startOfDay(framingRange.start);
1015
- let endMarker = framingRange.end;
1016
- let instanceStarts = [];
1017
- while (dayMarker < endMarker) {
1018
- let instanceStart;
1019
- // if everyday, or this particular day-of-week
1020
- if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
1021
- if (startTime) {
1022
- instanceStart = dateEnv.add(dayMarker, startTime);
1023
- }
1024
- else {
1025
- instanceStart = dayMarker;
1026
- }
1027
- instanceStarts.push(instanceStart);
1028
- }
1029
- dayMarker = internalCommon.addDays(dayMarker, 1);
1030
- }
1031
- return instanceStarts;
1032
- }
1033
-
1034
- const changeHandlerPlugin = createPlugin({
1035
- name: 'change-handler',
1036
- optionChangeHandlers: {
1037
- events(events, context) {
1038
- handleEventSources([events], context);
1039
- },
1040
- eventSources: handleEventSources,
1041
- },
1042
- });
1043
- /*
1044
- BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out
1045
- */
1046
- function handleEventSources(inputs, context) {
1047
- let unfoundSources = internalCommon.hashValuesToArray(context.getCurrentData().eventSources);
1048
- if (unfoundSources.length === 1 &&
1049
- inputs.length === 1 &&
1050
- Array.isArray(unfoundSources[0]._raw) &&
1051
- Array.isArray(inputs[0])) {
1052
- context.dispatch({
1053
- type: 'RESET_RAW_EVENTS',
1054
- sourceId: unfoundSources[0].sourceId,
1055
- rawEvents: inputs[0],
1056
- });
1057
- return;
1058
- }
1059
- let newInputs = [];
1060
- for (let input of inputs) {
1061
- let inputFound = false;
1062
- for (let i = 0; i < unfoundSources.length; i += 1) {
1063
- if (unfoundSources[i]._raw === input) {
1064
- unfoundSources.splice(i, 1); // delete
1065
- inputFound = true;
1066
- break;
1067
- }
1068
- }
1069
- if (!inputFound) {
1070
- newInputs.push(input);
1071
- }
1072
- }
1073
- for (let unfoundSource of unfoundSources) {
1074
- context.dispatch({
1075
- type: 'REMOVE_EVENT_SOURCE',
1076
- sourceId: unfoundSource.sourceId,
1077
- });
1078
- }
1079
- for (let newInput of newInputs) {
1080
- context.calendarApi.addEventSource(newInput);
1081
- }
1082
- }
1083
-
1084
- function handleDateProfile(dateProfile, context) {
1085
- context.emitter.trigger('datesSet', Object.assign(Object.assign({}, internalCommon.buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));
1086
- }
1087
-
1088
- function handleEventStore(eventStore, context) {
1089
- let { emitter } = context;
1090
- if (emitter.hasHandlers('eventsSet')) {
1091
- emitter.trigger('eventsSet', internalCommon.buildEventApis(eventStore, context));
1092
- }
1093
- }
1094
-
1095
- /*
1096
- this array is exposed on the root namespace so that UMD plugins can add to it.
1097
- see the rollup-bundles script.
1098
- */
1099
- const globalPlugins = [
1100
- arrayEventSourcePlugin,
1101
- funcEventSourcePlugin,
1102
- jsonFeedEventSourcePlugin,
1103
- simpleRecurringEventsPlugin,
1104
- changeHandlerPlugin,
1105
- createPlugin({
1106
- name: 'misc',
1107
- isLoadingFuncs: [
1108
- (state) => computeEventSourcesLoading(state.eventSources),
1109
- ],
1110
- propSetHandlers: {
1111
- dateProfile: handleDateProfile,
1112
- eventStore: handleEventStore,
1113
- },
1114
- }),
1115
- ];
1116
-
1117
- class TaskRunner {
1118
- constructor(runTaskOption, drainedOption) {
1119
- this.runTaskOption = runTaskOption;
1120
- this.drainedOption = drainedOption;
1121
- this.queue = [];
1122
- this.delayedRunner = new internalCommon.DelayedRunner(this.drain.bind(this));
1123
- }
1124
- request(task, delay) {
1125
- this.queue.push(task);
1126
- this.delayedRunner.request(delay);
1127
- }
1128
- pause(scope) {
1129
- this.delayedRunner.pause(scope);
1130
- }
1131
- resume(scope, force) {
1132
- this.delayedRunner.resume(scope, force);
1133
- }
1134
- drain() {
1135
- let { queue } = this;
1136
- while (queue.length) {
1137
- let completedTasks = [];
1138
- let task;
1139
- while ((task = queue.shift())) {
1140
- this.runTask(task);
1141
- completedTasks.push(task);
1142
- }
1143
- this.drained(completedTasks);
1144
- } // keep going, in case new tasks were added in the drained handler
1145
- }
1146
- runTask(task) {
1147
- if (this.runTaskOption) {
1148
- this.runTaskOption(task);
1149
- }
1150
- }
1151
- drained(completedTasks) {
1152
- if (this.drainedOption) {
1153
- this.drainedOption(completedTasks);
1154
- }
1155
- }
1156
- }
1157
-
1158
- // Computes what the title at the top of the calendarApi should be for this view
1159
- function buildTitle(dateProfile, viewOptions, dateEnv) {
1160
- let range;
1161
- // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
1162
- if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
1163
- range = dateProfile.currentRange;
1164
- }
1165
- else { // for day units or smaller, use the actual day range
1166
- range = dateProfile.activeRange;
1167
- }
1168
- return dateEnv.formatRange(range.start, range.end, internalCommon.createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {
1169
- isEndExclusive: dateProfile.isRangeAllDay,
1170
- defaultSeparator: viewOptions.titleRangeSeparator,
1171
- });
1172
- }
1173
- // Generates the format string that should be used to generate the title for the current date range.
1174
- // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
1175
- function buildTitleFormat(dateProfile) {
1176
- let { currentRangeUnit } = dateProfile;
1177
- if (currentRangeUnit === 'year') {
1178
- return { year: 'numeric' };
1179
- }
1180
- if (currentRangeUnit === 'month') {
1181
- return { year: 'numeric', month: 'long' }; // like "September 2014"
1182
- }
1183
- let days = internalCommon.diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
1184
- if (days !== null && days > 1) {
1185
- // multi-day range. shorter, like "Sep 9 - 10 2014"
1186
- return { year: 'numeric', month: 'short', day: 'numeric' };
1187
- }
1188
- // one day. longer, like "September 9 2014"
1189
- return { year: 'numeric', month: 'long', day: 'numeric' };
1190
- }
1191
-
1192
- // in future refactor, do the redux-style function(state=initial) for initial-state
1193
- // also, whatever is happening in constructor, have it happen in action queue too
1194
- class CalendarDataManager {
1195
- constructor(props) {
1196
- this.computeCurrentViewData = internalCommon.memoize(this._computeCurrentViewData);
1197
- this.organizeRawLocales = internalCommon.memoize(organizeRawLocales);
1198
- this.buildLocale = internalCommon.memoize(buildLocale);
1199
- this.buildPluginHooks = buildBuildPluginHooks();
1200
- this.buildDateEnv = internalCommon.memoize(buildDateEnv$1);
1201
- this.buildTheme = internalCommon.memoize(buildTheme);
1202
- this.parseToolbars = internalCommon.memoize(parseToolbars);
1203
- this.buildViewSpecs = internalCommon.memoize(buildViewSpecs);
1204
- this.buildDateProfileGenerator = internalCommon.memoizeObjArg(buildDateProfileGenerator);
1205
- this.buildViewApi = internalCommon.memoize(buildViewApi);
1206
- this.buildViewUiProps = internalCommon.memoizeObjArg(buildViewUiProps);
1207
- this.buildEventUiBySource = internalCommon.memoize(buildEventUiBySource, internalCommon.isPropsEqual);
1208
- this.buildEventUiBases = internalCommon.memoize(buildEventUiBases);
1209
- this.parseContextBusinessHours = internalCommon.memoizeObjArg(parseContextBusinessHours);
1210
- this.buildTitle = internalCommon.memoize(buildTitle);
1211
- this.emitter = new internalCommon.Emitter();
1212
- this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));
1213
- this.currentCalendarOptionsInput = {};
1214
- this.currentCalendarOptionsRefined = {};
1215
- this.currentViewOptionsInput = {};
1216
- this.currentViewOptionsRefined = {};
1217
- this.currentCalendarOptionsRefiners = {};
1218
- this.optionsForRefining = [];
1219
- this.optionsForHandling = [];
1220
- this.getCurrentData = () => this.data;
1221
- this.dispatch = (action) => {
1222
- this.actionRunner.request(action); // protects against recursive calls to _handleAction
1223
- };
1224
- this.props = props;
1225
- this.actionRunner.pause();
1226
- let dynamicOptionOverrides = {};
1227
- let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
1228
- let currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;
1229
- let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
1230
- // wire things up
1231
- // TODO: not DRY
1232
- props.calendarApi.currentDataManager = this;
1233
- this.emitter.setThisContext(props.calendarApi);
1234
- this.emitter.setOptions(currentViewData.options);
1235
- let currentDate = internalCommon.getInitialDate(optionsData.calendarOptions, optionsData.dateEnv);
1236
- let dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
1237
- if (!internalCommon.rangeContainsMarker(dateProfile.activeRange, currentDate)) {
1238
- currentDate = dateProfile.currentRange.start;
1239
- }
1240
- let calendarContext = {
1241
- dateEnv: optionsData.dateEnv,
1242
- options: optionsData.calendarOptions,
1243
- pluginHooks: optionsData.pluginHooks,
1244
- calendarApi: props.calendarApi,
1245
- dispatch: this.dispatch,
1246
- emitter: this.emitter,
1247
- getCurrentData: this.getCurrentData,
1248
- };
1249
- // needs to be after setThisContext
1250
- for (let callback of optionsData.pluginHooks.contextInit) {
1251
- callback(calendarContext);
1252
- }
1253
- // NOT DRY
1254
- let eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);
1255
- let initialState = {
1256
- dynamicOptionOverrides,
1257
- currentViewType,
1258
- currentDate,
1259
- dateProfile,
1260
- businessHours: this.parseContextBusinessHours(calendarContext),
1261
- eventSources,
1262
- eventUiBases: {},
1263
- eventStore: internalCommon.createEmptyEventStore(),
1264
- renderableEventStore: internalCommon.createEmptyEventStore(),
1265
- dateSelection: null,
1266
- eventSelection: '',
1267
- eventDrag: null,
1268
- eventResize: null,
1269
- selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig,
1270
- };
1271
- let contextAndState = Object.assign(Object.assign({}, calendarContext), initialState);
1272
- for (let reducer of optionsData.pluginHooks.reducers) {
1273
- Object.assign(initialState, reducer(null, null, contextAndState));
1274
- }
1275
- if (computeIsLoading(initialState, calendarContext)) {
1276
- this.emitter.trigger('loading', true); // NOT DRY
1277
- }
1278
- this.state = initialState;
1279
- this.updateData();
1280
- this.actionRunner.resume();
1281
- }
1282
- resetOptions(optionOverrides, changedOptionNames) {
1283
- let { props } = this;
1284
- if (changedOptionNames === undefined) {
1285
- props.optionOverrides = optionOverrides;
1286
- }
1287
- else {
1288
- props.optionOverrides = Object.assign(Object.assign({}, (props.optionOverrides || {})), optionOverrides);
1289
- this.optionsForRefining.push(...changedOptionNames);
1290
- }
1291
- if (changedOptionNames === undefined || changedOptionNames.length) {
1292
- this.actionRunner.request({
1293
- type: 'NOTHING',
1294
- });
1295
- }
1296
- }
1297
- _handleAction(action) {
1298
- let { props, state, emitter } = this;
1299
- let dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);
1300
- let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
1301
- let currentViewType = reduceViewType(state.currentViewType, action);
1302
- let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
1303
- // wire things up
1304
- // TODO: not DRY
1305
- props.calendarApi.currentDataManager = this;
1306
- emitter.setThisContext(props.calendarApi);
1307
- emitter.setOptions(currentViewData.options);
1308
- let calendarContext = {
1309
- dateEnv: optionsData.dateEnv,
1310
- options: optionsData.calendarOptions,
1311
- pluginHooks: optionsData.pluginHooks,
1312
- calendarApi: props.calendarApi,
1313
- dispatch: this.dispatch,
1314
- emitter,
1315
- getCurrentData: this.getCurrentData,
1316
- };
1317
- let { currentDate, dateProfile } = state;
1318
- if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack
1319
- dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
1320
- }
1321
- currentDate = internalCommon.reduceCurrentDate(currentDate, action);
1322
- dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);
1323
- if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator
1324
- action.type === 'NEXT' || // "
1325
- !internalCommon.rangeContainsMarker(dateProfile.currentRange, currentDate)) {
1326
- currentDate = dateProfile.currentRange.start;
1327
- }
1328
- let eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);
1329
- let eventStore = internalCommon.reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext);
1330
- let isEventsLoading = computeEventSourcesLoading(eventSources); // BAD. also called in this func in computeIsLoading
1331
- let renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?
1332
- (state.renderableEventStore || eventStore) : // try from previous state
1333
- eventStore;
1334
- let { eventUiSingleBase, selectionConfig } = this.buildViewUiProps(calendarContext); // will memoize obj
1335
- let eventUiBySource = this.buildEventUiBySource(eventSources);
1336
- let eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
1337
- let newState = {
1338
- dynamicOptionOverrides,
1339
- currentViewType,
1340
- currentDate,
1341
- dateProfile,
1342
- eventSources,
1343
- eventStore,
1344
- renderableEventStore,
1345
- selectionConfig,
1346
- eventUiBases,
1347
- businessHours: this.parseContextBusinessHours(calendarContext),
1348
- dateSelection: reduceDateSelection(state.dateSelection, action),
1349
- eventSelection: reduceSelectedEvent(state.eventSelection, action),
1350
- eventDrag: reduceEventDrag(state.eventDrag, action),
1351
- eventResize: reduceEventResize(state.eventResize, action),
1352
- };
1353
- let contextAndState = Object.assign(Object.assign({}, calendarContext), newState);
1354
- for (let reducer of optionsData.pluginHooks.reducers) {
1355
- Object.assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value
1356
- }
1357
- let wasLoading = computeIsLoading(state, calendarContext);
1358
- let isLoading = computeIsLoading(newState, calendarContext);
1359
- // TODO: use propSetHandlers in plugin system
1360
- if (!wasLoading && isLoading) {
1361
- emitter.trigger('loading', true);
1362
- }
1363
- else if (wasLoading && !isLoading) {
1364
- emitter.trigger('loading', false);
1365
- }
1366
- this.state = newState;
1367
- if (props.onAction) {
1368
- props.onAction(action);
1369
- }
1370
- }
1371
- updateData() {
1372
- let { props, state } = this;
1373
- let oldData = this.data;
1374
- let optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);
1375
- let currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);
1376
- let data = this.data = Object.assign(Object.assign(Object.assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);
1377
- let changeHandlers = optionsData.pluginHooks.optionChangeHandlers;
1378
- let oldCalendarOptions = oldData && oldData.calendarOptions;
1379
- let newCalendarOptions = optionsData.calendarOptions;
1380
- if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {
1381
- if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {
1382
- // hack
1383
- state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);
1384
- state.eventStore = data.eventStore = internalCommon.rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv);
1385
- state.renderableEventStore = data.renderableEventStore = internalCommon.rezoneEventStoreDates(data.renderableEventStore, oldData.dateEnv, data.dateEnv);
1386
- }
1387
- for (let optionName in changeHandlers) {
1388
- if (this.optionsForHandling.indexOf(optionName) !== -1 ||
1389
- oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {
1390
- changeHandlers[optionName](newCalendarOptions[optionName], data);
1391
- }
1392
- }
1393
- }
1394
- this.optionsForHandling = [];
1395
- if (props.onData) {
1396
- props.onData(data);
1397
- }
1398
- }
1399
- computeOptionsData(optionOverrides, dynamicOptionOverrides, calendarApi) {
1400
- // TODO: blacklist options that are handled by optionChangeHandlers
1401
- if (!this.optionsForRefining.length &&
1402
- optionOverrides === this.stableOptionOverrides &&
1403
- dynamicOptionOverrides === this.stableDynamicOptionOverrides) {
1404
- return this.stableCalendarOptionsData;
1405
- }
1406
- let { refinedOptions, pluginHooks, localeDefaults, availableLocaleData, extra, } = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides);
1407
- warnUnknownOptions(extra);
1408
- let dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);
1409
- let viewSpecs = this.buildViewSpecs(pluginHooks.views, this.stableOptionOverrides, this.stableDynamicOptionOverrides, localeDefaults);
1410
- let theme = this.buildTheme(refinedOptions, pluginHooks);
1411
- let toolbarConfig = this.parseToolbars(refinedOptions, this.stableOptionOverrides, theme, viewSpecs, calendarApi);
1412
- return this.stableCalendarOptionsData = {
1413
- calendarOptions: refinedOptions,
1414
- pluginHooks,
1415
- dateEnv,
1416
- viewSpecs,
1417
- theme,
1418
- toolbarConfig,
1419
- localeDefaults,
1420
- availableRawLocales: availableLocaleData.map,
1421
- };
1422
- }
1423
- // always called from behind a memoizer
1424
- processRawCalendarOptions(optionOverrides, dynamicOptionOverrides) {
1425
- let { locales, locale } = internalCommon.mergeRawOptions([
1426
- internalCommon.BASE_OPTION_DEFAULTS,
1427
- optionOverrides,
1428
- dynamicOptionOverrides,
1429
- ]);
1430
- let availableLocaleData = this.organizeRawLocales(locales);
1431
- let availableRawLocales = availableLocaleData.map;
1432
- let localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;
1433
- let pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);
1434
- let refiners = this.currentCalendarOptionsRefiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, internalCommon.BASE_OPTION_REFINERS), internalCommon.CALENDAR_LISTENER_REFINERS), internalCommon.CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
1435
- let extra = {};
1436
- let raw = internalCommon.mergeRawOptions([
1437
- internalCommon.BASE_OPTION_DEFAULTS,
1438
- localeDefaults,
1439
- optionOverrides,
1440
- dynamicOptionOverrides,
1441
- ]);
1442
- let refined = {};
1443
- let currentRaw = this.currentCalendarOptionsInput;
1444
- let currentRefined = this.currentCalendarOptionsRefined;
1445
- let anyChanges = false;
1446
- for (let optionName in raw) {
1447
- if (this.optionsForRefining.indexOf(optionName) === -1 && (raw[optionName] === currentRaw[optionName] || (internalCommon.COMPLEX_OPTION_COMPARATORS[optionName] &&
1448
- (optionName in currentRaw) &&
1449
- internalCommon.COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName])))) {
1450
- refined[optionName] = currentRefined[optionName];
1451
- }
1452
- else if (refiners[optionName]) {
1453
- refined[optionName] = refiners[optionName](raw[optionName]);
1454
- anyChanges = true;
1455
- }
1456
- else {
1457
- extra[optionName] = currentRaw[optionName];
1458
- }
1459
- }
1460
- if (anyChanges) {
1461
- this.currentCalendarOptionsInput = raw;
1462
- this.currentCalendarOptionsRefined = refined;
1463
- this.stableOptionOverrides = optionOverrides;
1464
- this.stableDynamicOptionOverrides = dynamicOptionOverrides;
1465
- }
1466
- this.optionsForHandling.push(...this.optionsForRefining);
1467
- this.optionsForRefining = [];
1468
- return {
1469
- rawOptions: this.currentCalendarOptionsInput,
1470
- refinedOptions: this.currentCalendarOptionsRefined,
1471
- pluginHooks,
1472
- availableLocaleData,
1473
- localeDefaults,
1474
- extra,
1475
- };
1476
- }
1477
- _computeCurrentViewData(viewType, optionsData, optionOverrides, dynamicOptionOverrides) {
1478
- let viewSpec = optionsData.viewSpecs[viewType];
1479
- if (!viewSpec) {
1480
- throw new Error(`viewType "${viewType}" is not available. Please make sure you've loaded all neccessary plugins`);
1481
- }
1482
- let { refinedOptions, extra } = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides);
1483
- warnUnknownOptions(extra);
1484
- let dateProfileGenerator = this.buildDateProfileGenerator({
1485
- dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,
1486
- duration: viewSpec.duration,
1487
- durationUnit: viewSpec.durationUnit,
1488
- usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,
1489
- dateEnv: optionsData.dateEnv,
1490
- calendarApi: this.props.calendarApi,
1491
- slotMinTime: refinedOptions.slotMinTime,
1492
- slotMaxTime: refinedOptions.slotMaxTime,
1493
- showNonCurrentDates: refinedOptions.showNonCurrentDates,
1494
- dayCount: refinedOptions.dayCount,
1495
- dateAlignment: refinedOptions.dateAlignment,
1496
- dateIncrement: refinedOptions.dateIncrement,
1497
- hiddenDays: refinedOptions.hiddenDays,
1498
- weekends: refinedOptions.weekends,
1499
- nowInput: refinedOptions.now,
1500
- validRangeInput: refinedOptions.validRange,
1501
- visibleRangeInput: refinedOptions.visibleRange,
1502
- fixedWeekCount: refinedOptions.fixedWeekCount,
1503
- });
1504
- let viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);
1505
- return { viewSpec, options: refinedOptions, dateProfileGenerator, viewApi };
1506
- }
1507
- processRawViewOptions(viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {
1508
- let raw = internalCommon.mergeRawOptions([
1509
- internalCommon.BASE_OPTION_DEFAULTS,
1510
- viewSpec.optionDefaults,
1511
- localeDefaults,
1512
- optionOverrides,
1513
- viewSpec.optionOverrides,
1514
- dynamicOptionOverrides,
1515
- ]);
1516
- let refiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, internalCommon.BASE_OPTION_REFINERS), internalCommon.CALENDAR_LISTENER_REFINERS), internalCommon.CALENDAR_OPTION_REFINERS), internalCommon.VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
1517
- let refined = {};
1518
- let currentRaw = this.currentViewOptionsInput;
1519
- let currentRefined = this.currentViewOptionsRefined;
1520
- let anyChanges = false;
1521
- let extra = {};
1522
- for (let optionName in raw) {
1523
- if (raw[optionName] === currentRaw[optionName] ||
1524
- (internalCommon.COMPLEX_OPTION_COMPARATORS[optionName] &&
1525
- internalCommon.COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], currentRaw[optionName]))) {
1526
- refined[optionName] = currentRefined[optionName];
1527
- }
1528
- else {
1529
- if (raw[optionName] === this.currentCalendarOptionsInput[optionName] ||
1530
- (internalCommon.COMPLEX_OPTION_COMPARATORS[optionName] &&
1531
- internalCommon.COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName]))) {
1532
- if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop
1533
- refined[optionName] = this.currentCalendarOptionsRefined[optionName];
1534
- }
1535
- }
1536
- else if (refiners[optionName]) {
1537
- refined[optionName] = refiners[optionName](raw[optionName]);
1538
- }
1539
- else {
1540
- extra[optionName] = raw[optionName];
1541
- }
1542
- anyChanges = true;
1543
- }
1544
- }
1545
- if (anyChanges) {
1546
- this.currentViewOptionsInput = raw;
1547
- this.currentViewOptionsRefined = refined;
1548
- }
1549
- return {
1550
- rawOptions: this.currentViewOptionsInput,
1551
- refinedOptions: this.currentViewOptionsRefined,
1552
- extra,
1553
- };
1554
- }
1555
- }
1556
- function buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {
1557
- let locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);
1558
- return new internalCommon.DateEnv({
1559
- calendarSystem: 'gregory',
1560
- timeZone,
1561
- namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,
1562
- locale,
1563
- weekNumberCalculation,
1564
- firstDay,
1565
- weekText,
1566
- cmdFormatter: pluginHooks.cmdFormatter,
1567
- defaultSeparator,
1568
- });
1569
- }
1570
- function buildTheme(options, pluginHooks) {
1571
- let ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;
1572
- return new ThemeClass(options);
1573
- }
1574
- function buildDateProfileGenerator(props) {
1575
- let DateProfileGeneratorClass = props.dateProfileGeneratorClass || internalCommon.DateProfileGenerator;
1576
- return new DateProfileGeneratorClass(props);
1577
- }
1578
- function buildViewApi(type, getCurrentData, dateEnv) {
1579
- return new ViewImpl(type, getCurrentData, dateEnv);
1580
- }
1581
- function buildEventUiBySource(eventSources) {
1582
- return internalCommon.mapHash(eventSources, (eventSource) => eventSource.ui);
1583
- }
1584
- function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
1585
- let eventUiBases = { '': eventUiSingleBase };
1586
- for (let defId in eventDefs) {
1587
- let def = eventDefs[defId];
1588
- if (def.sourceId && eventUiBySource[def.sourceId]) {
1589
- eventUiBases[defId] = eventUiBySource[def.sourceId];
1590
- }
1591
- }
1592
- return eventUiBases;
1593
- }
1594
- function buildViewUiProps(calendarContext) {
1595
- let { options } = calendarContext;
1596
- return {
1597
- eventUiSingleBase: internalCommon.createEventUi({
1598
- display: options.eventDisplay,
1599
- editable: options.editable,
1600
- startEditable: options.eventStartEditable,
1601
- durationEditable: options.eventDurationEditable,
1602
- constraint: options.eventConstraint,
1603
- overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,
1604
- allow: options.eventAllow,
1605
- backgroundColor: options.eventBackgroundColor,
1606
- borderColor: options.eventBorderColor,
1607
- textColor: options.eventTextColor,
1608
- color: options.eventColor,
1609
- // classNames: options.eventClassNames // render hook will handle this
1610
- }, calendarContext),
1611
- selectionConfig: internalCommon.createEventUi({
1612
- constraint: options.selectConstraint,
1613
- overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,
1614
- allow: options.selectAllow,
1615
- }, calendarContext),
1616
- };
1617
- }
1618
- function computeIsLoading(state, context) {
1619
- for (let isLoadingFunc of context.pluginHooks.isLoadingFuncs) {
1620
- if (isLoadingFunc(state)) {
1621
- return true;
1622
- }
1623
- }
1624
- return false;
1625
- }
1626
- function parseContextBusinessHours(calendarContext) {
1627
- return internalCommon.parseBusinessHours(calendarContext.options.businessHours, calendarContext);
1628
- }
1629
- function warnUnknownOptions(options, viewName) {
1630
- for (let optionName in options) {
1631
- console.warn(`Unknown option '${optionName}'` +
1632
- (viewName ? ` for view '${viewName}'` : ''));
1633
- }
1634
- }
1635
-
1636
- class ToolbarSection extends internalCommon.BaseComponent {
1637
- render() {
1638
- let children = this.props.widgetGroups.map((widgetGroup) => this.renderWidgetGroup(widgetGroup));
1639
- return preact.createElement('div', {
1640
- className: 'fc-toolbar-section fc-toolbar-' + this.props.name
1641
- }, ...children);
1642
- }
1643
- renderWidgetGroup(widgetGroup) {
1644
- let { props, context } = this;
1645
- let { options, theme } = context;
1646
- let children = [];
1647
- let isOnlyButtons = true;
1648
- let isOnlyView = true;
1649
- for (const widget of widgetGroup) {
1650
- const { buttonName, isView } = widget;
1651
- if (buttonName === 'title') {
1652
- isOnlyButtons = false;
1653
- }
1654
- else if (!isView) {
1655
- isOnlyView = false;
1656
- }
1657
- }
1658
- for (let widget of widgetGroup) {
1659
- let { buttonName, buttonClick, buttonText, buttonIcon, buttonHint } = widget;
1660
- if (buttonName === 'title') {
1661
- children.push(preact.createElement("div", { role: 'heading', "aria-level": options.headingLevel, id: props.titleId, className: 'fc-toolbar-title' }, props.title));
1662
- }
1663
- else {
1664
- let isPressed = buttonName === props.activeButton;
1665
- let isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||
1666
- (!props.isPrevEnabled && buttonName === 'prev') ||
1667
- (!props.isNextEnabled && buttonName === 'next');
1668
- children.push(preact.createElement("button", Object.assign({ type: "button", disabled: isDisabled }, ((isOnlyButtons && isOnlyView)
1669
- ? { 'role': 'tab', 'aria-selected': isPressed }
1670
- : { 'aria-pressed': isPressed }), { "aria-label": typeof buttonHint === 'function' ? buttonHint(props.navUnit) : buttonHint, className: internalCommon.joinClassNames(`fc-${buttonName}-button`, theme.getClassName('button'), isPressed && theme.getClassName('buttonActive')), onClick: buttonClick }), buttonText || (buttonIcon ? preact.createElement("span", { className: buttonIcon, "aria-hidden": true }) : '')));
1671
- }
1672
- }
1673
- if (children.length > 1) {
1674
- return preact.createElement('div', {
1675
- role: (isOnlyButtons && isOnlyView) ? 'tablist' : undefined,
1676
- 'aria-label': (isOnlyButtons && isOnlyView) ? options.viewChangeHint : undefined,
1677
- className: isOnlyButtons ? theme.getClassName('buttonGroup') : undefined,
1678
- }, ...children);
1679
- }
1680
- return children[0];
1681
- }
1682
- }
1683
-
1684
- class Toolbar extends internalCommon.BaseComponent {
1685
- render() {
1686
- let { model, className } = this.props;
1687
- let { sectionWidgets } = model;
1688
- return (preact.createElement("div", { className: internalCommon.joinClassNames(className, 'fc-toolbar') },
1689
- this.renderSection('start', sectionWidgets.start),
1690
- this.renderSection('center', sectionWidgets.center),
1691
- this.renderSection('end', sectionWidgets.end)));
1692
- }
1693
- renderSection(key, widgetGroups) {
1694
- let { props } = this;
1695
- return (preact.createElement(ToolbarSection, { key: key, name: key, widgetGroups: widgetGroups, title: props.title, titleId: props.titleId, navUnit: props.navUnit, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled }));
1696
- }
1697
- }
1698
-
1699
- /*
1700
- Detects when the user clicks on an event within a DateComponent
1701
- */
1702
- class EventClicking extends internalCommon.Interaction {
1703
- constructor(settings) {
1704
- super(settings);
1705
- this.handleSegClick = (ev, segEl) => {
1706
- let { component } = this;
1707
- let { context } = component;
1708
- let eventRange = internalCommon.getElEventRange(segEl);
1709
- if (eventRange && // might be the <div> surrounding the more link
1710
- component.isValidSegDownEl(ev.target)) {
1711
- context.emitter.trigger('eventClick', {
1712
- el: segEl,
1713
- event: new internalCommon.EventImpl(component.context, eventRange.def, eventRange.instance),
1714
- jsEvent: ev,
1715
- view: context.viewApi,
1716
- });
1717
- }
1718
- };
1719
- this.destroy = internalCommon.listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events
1720
- this.handleSegClick);
1721
- }
1722
- }
1723
-
1724
- /*
1725
- Triggers events and adds/removes core classNames when the user's pointer
1726
- enters/leaves event-elements of a component.
1727
- */
1728
- class EventHovering extends internalCommon.Interaction {
1729
- constructor(settings) {
1730
- super(settings);
1731
- // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
1732
- this.handleEventElRemove = (el) => {
1733
- if (el === this.currentSegEl) {
1734
- this.handleSegLeave(null, this.currentSegEl);
1735
- }
1736
- };
1737
- this.handleSegEnter = (ev, segEl) => {
1738
- if (internalCommon.getElEventRange(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
1739
- this.currentSegEl = segEl;
1740
- this.triggerEvent('eventMouseEnter', ev, segEl);
1741
- }
1742
- };
1743
- this.handleSegLeave = (ev, segEl) => {
1744
- if (this.currentSegEl) {
1745
- this.currentSegEl = null;
1746
- this.triggerEvent('eventMouseLeave', ev, segEl);
1747
- }
1748
- };
1749
- this.removeHoverListeners = internalCommon.listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events
1750
- this.handleSegEnter, this.handleSegLeave);
1751
- }
1752
- destroy() {
1753
- this.removeHoverListeners();
1754
- }
1755
- triggerEvent(publicEvName, ev, segEl) {
1756
- let { component } = this;
1757
- let { context } = component;
1758
- let eventRange = internalCommon.getElEventRange(segEl);
1759
- if (!ev || component.isValidSegDownEl(ev.target)) {
1760
- context.emitter.trigger(publicEvName, {
1761
- el: segEl,
1762
- event: new internalCommon.EventImpl(context, eventRange.def, eventRange.instance),
1763
- jsEvent: ev,
1764
- view: context.viewApi,
1765
- });
1766
- }
1767
- }
1768
- }
1769
-
1770
- class ViewHarness extends preact.Component {
1771
- render() {
1772
- const { props } = this;
1773
- return (preact.createElement("div", { className: internalCommon.joinClassNames('fc-view-outer', props.height != null
1774
- ? 'fc-view-outer-static'
1775
- : props.heightLiquid
1776
- ? 'fc-view-outer-liquid'
1777
- : props.aspectRatio != null
1778
- && 'fc-view-outer-aspect-ratio'), style: {
1779
- height: props.height,
1780
- paddingBottom: props.aspectRatio != null
1781
- ? `${(1 / props.aspectRatio) * 100}%`
1782
- : undefined
1783
- } }, props.children));
1784
- }
1785
- }
1786
-
1787
- class CalendarContent extends internalCommon.PureComponent {
1788
- constructor() {
1789
- super(...arguments);
1790
- this.buildViewContext = internalCommon.memoize(internalCommon.buildViewContext);
1791
- this.buildViewPropTransformers = internalCommon.memoize(buildViewPropTransformers);
1792
- this.buildToolbarProps = internalCommon.memoize(buildToolbarProps);
1793
- this.interactionsStore = {};
1794
- this.viewTitleId = internalCommon.getUniqueDomId();
1795
- // Component Registration
1796
- // -----------------------------------------------------------------------------------------------------------------
1797
- this.registerInteractiveComponent = (component, settingsInput) => {
1798
- let settings = internalCommon.parseInteractionSettings(component, settingsInput);
1799
- let DEFAULT_INTERACTIONS = [
1800
- EventClicking,
1801
- EventHovering,
1802
- ];
1803
- let interactionClasses = DEFAULT_INTERACTIONS;
1804
- if (!settingsInput.disableHits) {
1805
- interactionClasses = interactionClasses.concat(this.props.pluginHooks.componentInteractions);
1806
- }
1807
- let interactions = interactionClasses.map((TheInteractionClass) => new TheInteractionClass(settings));
1808
- this.interactionsStore[component.uid] = interactions;
1809
- internalCommon.interactionSettingsStore[component.uid] = settings;
1810
- };
1811
- this.unregisterInteractiveComponent = (component) => {
1812
- let listeners = this.interactionsStore[component.uid];
1813
- if (listeners) {
1814
- for (let listener of listeners) {
1815
- listener.destroy();
1816
- }
1817
- delete this.interactionsStore[component.uid];
1818
- }
1819
- delete internalCommon.interactionSettingsStore[component.uid];
1820
- };
1821
- }
1822
- /*
1823
- renders INSIDE of an outer div
1824
- */
1825
- render() {
1826
- let { props } = this;
1827
- let { toolbarConfig, options } = props;
1828
- let toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, internalCommon.getNow(props.options.now, props.dateEnv), // TODO: use NowTimer????
1829
- props.viewTitle);
1830
- let viewHeight;
1831
- let viewHeightLiquid = false;
1832
- let viewAspectRatio;
1833
- if (props.forPrint || internalCommon.getIsHeightAuto(options)) ;
1834
- else if (options.height != null) {
1835
- viewHeightLiquid = true;
1836
- }
1837
- else if (options.contentHeight != null) {
1838
- viewHeight = options.contentHeight;
1839
- }
1840
- else {
1841
- viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall
1842
- }
1843
- let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);
1844
- return (preact.createElement(internalCommon.ViewContextType.Provider, { value: viewContext },
1845
- toolbarConfig.header && (preact.createElement(Toolbar, Object.assign({ className: "fc-header-toolbar", model: toolbarConfig.header, titleId: this.viewTitleId }, toolbarProps))),
1846
- preact.createElement(ViewHarness, { height: viewHeight, heightLiquid: viewHeightLiquid, aspectRatio: viewAspectRatio },
1847
- this.renderView(props, toolbarProps.title),
1848
- this.buildAppendContent()),
1849
- toolbarConfig.footer && (preact.createElement(Toolbar, Object.assign({ className: "fc-footer-toolbar", model: toolbarConfig.footer }, toolbarProps)))));
1850
- }
1851
- componentDidMount() {
1852
- let { props } = this;
1853
- this.calendarInteractions = props.pluginHooks.calendarInteractions
1854
- .map((CalendarInteractionClass) => new CalendarInteractionClass(props));
1855
- let { propSetHandlers } = props.pluginHooks;
1856
- for (let propName in propSetHandlers) {
1857
- propSetHandlers[propName](props[propName], props);
1858
- }
1859
- }
1860
- componentDidUpdate(prevProps) {
1861
- let { props } = this;
1862
- let { propSetHandlers } = props.pluginHooks;
1863
- for (let propName in propSetHandlers) {
1864
- if (props[propName] !== prevProps[propName]) {
1865
- propSetHandlers[propName](props[propName], props);
1866
- }
1867
- }
1868
- }
1869
- componentWillUnmount() {
1870
- for (let interaction of this.calendarInteractions) {
1871
- interaction.destroy();
1872
- }
1873
- this.props.emitter.trigger('_unmount');
1874
- }
1875
- buildAppendContent() {
1876
- let { props } = this;
1877
- let children = props.pluginHooks.viewContainerAppends.map((buildAppendContent) => buildAppendContent(props));
1878
- return preact.createElement(preact.Fragment, {}, ...children);
1879
- }
1880
- renderView(props, title) {
1881
- let { pluginHooks } = props;
1882
- let { viewSpec, toolbarConfig } = props;
1883
- let viewProps = {
1884
- dateProfile: props.dateProfile,
1885
- businessHours: props.businessHours,
1886
- eventStore: props.renderableEventStore,
1887
- eventUiBases: props.eventUiBases,
1888
- dateSelection: props.dateSelection,
1889
- eventSelection: props.eventSelection,
1890
- eventDrag: props.eventDrag,
1891
- eventResize: props.eventResize,
1892
- forPrint: props.forPrint,
1893
- labelId: toolbarConfig.header && toolbarConfig.header.hasTitle ? this.viewTitleId : undefined,
1894
- labelStr: toolbarConfig.header && toolbarConfig.header.hasTitle ? undefined : title,
1895
- };
1896
- let transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);
1897
- for (let transformer of transformers) {
1898
- Object.assign(viewProps, transformer.transform(viewProps, props));
1899
- }
1900
- let ViewComponent = viewSpec.component;
1901
- return (preact.createElement(ViewComponent, Object.assign({}, viewProps)));
1902
- }
1903
- }
1904
- function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {
1905
- // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid
1906
- let todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason
1907
- let prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);
1908
- let nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);
1909
- return {
1910
- title,
1911
- activeButton: viewSpec.type,
1912
- navUnit: viewSpec.singleUnit,
1913
- isTodayEnabled: todayInfo.isValid && !internalCommon.rangeContainsMarker(dateProfile.currentRange, now),
1914
- isPrevEnabled: prevInfo.isValid,
1915
- isNextEnabled: nextInfo.isValid,
1916
- };
1917
- }
1918
- // Plugin
1919
- // -----------------------------------------------------------------------------------------------------------------
1920
- function buildViewPropTransformers(theClasses) {
1921
- return theClasses.map((TheClass) => new TheClass());
1922
- }
1923
-
1924
- /*
1925
- Vanilla JS API
1926
- */
1927
- class Calendar extends internalCommon.CalendarImpl {
1928
- constructor(el, optionOverrides = {}) {
1929
- super();
1930
- this.isRendering = false;
1931
- this.isRendered = false;
1932
- this.currentClassNames = [];
1933
- this.customContentRenderId = 0;
1934
- this.handleAction = (action) => {
1935
- // actions we know we want to render immediately
1936
- switch (action.type) {
1937
- case 'SET_EVENT_DRAG':
1938
- case 'SET_EVENT_RESIZE':
1939
- this.renderRunner.tryDrain();
1940
- }
1941
- };
1942
- this.handleData = (data) => {
1943
- this.currentData = data;
1944
- this.renderRunner.request(data.calendarOptions.rerenderDelay);
1945
- };
1946
- this.handleRenderRequest = () => {
1947
- if (this.isRendering) {
1948
- this.isRendered = true;
1949
- let { currentData } = this;
1950
- internalCommon.flushSync(() => {
1951
- preact.render(preact.createElement(internalCommon.CalendarRoot, { options: currentData.calendarOptions, theme: currentData.theme, emitter: currentData.emitter }, (classNames, height, forPrint) => {
1952
- this.setClassNames(classNames);
1953
- this.setHeight(height);
1954
- return (preact.createElement(internalCommon.RenderId.Provider, { value: this.customContentRenderId },
1955
- preact.createElement(CalendarContent, Object.assign({ forPrint: forPrint }, currentData))));
1956
- }), this.el);
1957
- });
1958
- }
1959
- else if (this.isRendered) {
1960
- this.isRendered = false;
1961
- preact.render(null, this.el);
1962
- this.setClassNames([]);
1963
- this.setHeight('');
1964
- }
1965
- };
1966
- internalCommon.ensureElHasStyles(el);
1967
- this.el = el;
1968
- this.renderRunner = new internalCommon.DelayedRunner(this.handleRenderRequest);
1969
- new CalendarDataManager({
1970
- optionOverrides,
1971
- calendarApi: this,
1972
- onAction: this.handleAction,
1973
- onData: this.handleData,
1974
- });
1975
- }
1976
- render() {
1977
- let wasRendering = this.isRendering;
1978
- if (!wasRendering) {
1979
- this.isRendering = true;
1980
- }
1981
- else {
1982
- this.customContentRenderId += 1;
1983
- }
1984
- this.renderRunner.request();
1985
- if (wasRendering) {
1986
- this.updateSize();
1987
- }
1988
- }
1989
- destroy() {
1990
- if (this.isRendering) {
1991
- this.isRendering = false;
1992
- this.renderRunner.request();
1993
- }
1994
- }
1995
- batchRendering(func) {
1996
- this.renderRunner.pause('batchRendering');
1997
- func();
1998
- this.renderRunner.resume('batchRendering');
1999
- }
2000
- pauseRendering() {
2001
- this.renderRunner.pause('pauseRendering');
2002
- }
2003
- resumeRendering() {
2004
- this.renderRunner.resume('pauseRendering', true);
2005
- }
2006
- resetOptions(optionOverrides, changedOptionNames) {
2007
- this.currentDataManager.resetOptions(optionOverrides, changedOptionNames);
2008
- }
2009
- setClassNames(classNames) {
2010
- if (!internalCommon.isArraysEqual(classNames, this.currentClassNames)) {
2011
- let { classList } = this.el;
2012
- for (let className of this.currentClassNames) {
2013
- classList.remove(className);
2014
- }
2015
- for (let className of classNames) {
2016
- classList.add(className);
2017
- }
2018
- this.currentClassNames = classNames;
2019
- }
2020
- }
2021
- setHeight(height) {
2022
- internalCommon.applyStyleProp(this.el, 'height', height);
2023
- }
2024
- }
2025
-
2026
- function formatDate(dateInput, options = {}) {
2027
- let dateEnv = buildDateEnv(options);
2028
- let formatter = internalCommon.createFormatter(options);
2029
- let dateMeta = dateEnv.createMarkerMeta(dateInput);
2030
- if (!dateMeta) { // TODO: warning?
2031
- return '';
2032
- }
2033
- return dateEnv.format(dateMeta.marker, formatter, {
2034
- forcedTzo: dateMeta.forcedTzo,
2035
- });
2036
- }
2037
- function formatRange(startInput, endInput, options) {
2038
- let dateEnv = buildDateEnv(typeof options === 'object' && options ? options : {}); // pass in if non-null object
2039
- let formatter = internalCommon.createFormatter(options);
2040
- let startMeta = dateEnv.createMarkerMeta(startInput);
2041
- let endMeta = dateEnv.createMarkerMeta(endInput);
2042
- if (!startMeta || !endMeta) { // TODO: warning?
2043
- return '';
2044
- }
2045
- return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
2046
- forcedStartTzo: startMeta.forcedTzo,
2047
- forcedEndTzo: endMeta.forcedTzo,
2048
- isEndExclusive: options.isEndExclusive,
2049
- defaultSeparator: internalCommon.BASE_OPTION_DEFAULTS.defaultRangeSeparator,
2050
- });
2051
- }
2052
- // TODO: more DRY and optimized
2053
- function buildDateEnv(settings) {
2054
- let locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
2055
- return new internalCommon.DateEnv(Object.assign(Object.assign({ timeZone: internalCommon.BASE_OPTION_DEFAULTS.timeZone, calendarSystem: 'gregory' }, settings), { locale }));
2056
- }
2057
-
2058
- // HELPERS
2059
- /*
2060
- if nextDayThreshold is specified, slicing is done in an all-day fashion.
2061
- you can get nextDayThreshold from context.nextDayThreshold
2062
- */
2063
- function sliceEvents(props, allDay) {
2064
- return internalCommon.sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;
2065
- }
2066
-
2067
- const version = '7.0.0-rc.0';
2068
-
2069
- exports.JsonRequestError = internalCommon.JsonRequestError;
2070
- exports.Calendar = Calendar;
2071
- exports.createPlugin = createPlugin;
2072
- exports.formatDate = formatDate;
2073
- exports.formatRange = formatRange;
2074
- exports.globalLocales = globalLocales;
2075
- exports.globalPlugins = globalPlugins;
2076
- exports.sliceEvents = sliceEvents;
2077
- exports.version = version;