OptionsManager.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import * as $ from 'jquery'
  2. import { firstDefined } from './util'
  3. import { globalDefaults, rtlDefaults, mergeOptions } from './options'
  4. import { localeOptionHash, populateInstanceComputableOptions } from './locale'
  5. import Model from './common/Model'
  6. export default class OptionsManager extends Model {
  7. _calendar: any // avoid
  8. dirDefaults: any // option defaults related to LTR or RTL
  9. localeDefaults: any // option defaults related to current locale
  10. overrides: any // option overrides given to the fullCalendar constructor
  11. dynamicOverrides: any // options set with dynamic setter method. higher precedence than view overrides.
  12. constructor(_calendar, overrides) {
  13. super()
  14. this._calendar = _calendar
  15. this.overrides = $.extend({}, overrides) // make a copy
  16. this.dynamicOverrides = {}
  17. this.compute()
  18. }
  19. add(newOptionHash) {
  20. let optionCnt = 0
  21. let optionName
  22. this.recordOverrides(newOptionHash) // will trigger this model's watchers
  23. for (optionName in newOptionHash) {
  24. optionCnt++
  25. }
  26. // special-case handling of single option change.
  27. // if only one option change, `optionName` will be its name.
  28. if (optionCnt === 1) {
  29. if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') {
  30. this._calendar.updateViewSize(true) // isResize=true
  31. return
  32. } else if (optionName === 'defaultDate') {
  33. return // can't change date this way. use gotoDate instead
  34. } else if (optionName === 'businessHours') {
  35. return // this model already reacts to this
  36. } else if (optionName === 'timezone') {
  37. this._calendar.view.flash('initialEvents')
  38. return
  39. }
  40. }
  41. // catch-all. rerender the header and footer and rebuild/rerender the current view
  42. this._calendar.renderHeader()
  43. this._calendar.renderFooter()
  44. // even non-current views will be affected by this option change. do before rerender
  45. // TODO: detangle
  46. this._calendar.viewsByType = {}
  47. this._calendar.reinitView()
  48. }
  49. // Computes the flattened options hash for the calendar and assigns to `this.options`.
  50. // Assumes this.overrides and this.dynamicOverrides have already been initialized.
  51. compute() {
  52. let locale, localeDefaults
  53. let isRTL, dirDefaults
  54. let rawOptions
  55. locale = firstDefined( // explicit locale option given?
  56. this.dynamicOverrides.locale,
  57. this.overrides.locale
  58. )
  59. localeDefaults = localeOptionHash[locale]
  60. if (!localeDefaults) { // explicit locale option not given or invalid?
  61. locale = globalDefaults.locale
  62. localeDefaults = localeOptionHash[locale] || {}
  63. }
  64. isRTL = firstDefined( // based on options computed so far, is direction RTL?
  65. this.dynamicOverrides.isRTL,
  66. this.overrides.isRTL,
  67. localeDefaults.isRTL,
  68. globalDefaults.isRTL
  69. )
  70. dirDefaults = isRTL ? rtlDefaults : {}
  71. this.dirDefaults = dirDefaults
  72. this.localeDefaults = localeDefaults
  73. rawOptions = mergeOptions([ // merge defaults and overrides. lowest to highest precedence
  74. globalDefaults, // global defaults
  75. dirDefaults,
  76. localeDefaults,
  77. this.overrides,
  78. this.dynamicOverrides
  79. ])
  80. populateInstanceComputableOptions(rawOptions) // fill in gaps with computed options
  81. this.reset(rawOptions)
  82. }
  83. // stores the new options internally, but does not rerender anything.
  84. recordOverrides(newOptionHash) {
  85. let optionName
  86. for (optionName in newOptionHash) {
  87. this.dynamicOverrides[optionName] = newOptionHash[optionName]
  88. }
  89. this._calendar.viewSpecManager.clearCache() // the dynamic override invalidates the options in this cache, so just clear it
  90. this.compute() // this.options needs to be recomputed after the dynamic override
  91. }
  92. }