Skip to content

Commit

Permalink
pluginify event recurrence
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Jan 29, 2019
1 parent 40bd4b3 commit 400797b
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 36 deletions.
5 changes: 1 addition & 4 deletions src/core/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@

// for intentional side-effects
import './structs/recurring-event-simple'

// exports
// --------------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -148,7 +145,7 @@ export { formatDate, formatRange } from './formatting-api'

export { globalDefaults, globalHooks } from './options'

export { registerRecurringType, ParsedRecurring } from './structs/recurring-event'
export { RecurringType, ParsedRecurring } from './structs/recurring-event'

export { DragMetaInput, DragMeta, parseDragMeta } from './structs/drag-meta'

Expand Down
4 changes: 3 additions & 1 deletion src/core/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PluginDef } from './plugin-system'
import ArrayEventSourcePlugin from './event-sources/array-event-source'
import FuncEventSourcePlugin from './event-sources/func-event-source'
import JsonFeedEventSourcePlugin from './event-sources/json-feed-event-source'
import SimpleRecurrencePlugin from './structs/recurring-event-simple'

export const globalHooks = {} as any // TODO: make these options

Expand Down Expand Up @@ -129,7 +130,8 @@ export function mergeOptions(optionObjs) {
const INTERNAL_PLUGINS: PluginDef[] = [
ArrayEventSourcePlugin,
FuncEventSourcePlugin,
JsonFeedEventSourcePlugin
JsonFeedEventSourcePlugin,
SimpleRecurrencePlugin
]

export function getDefaultPlugins(): PluginDef[] {
Expand Down
22 changes: 9 additions & 13 deletions src/core/plugin-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ThemeClass } from './theme/Theme'
import { __assign } from 'tslib'
import { EventSourceDef } from './structs/event-source'
import { CmdFormatterFunc } from './datelib/formatting-cmd'
import { RecurringType } from './structs/recurring-event'

// TODO: easier way to add new hooks? need to update a million things

Expand All @@ -41,6 +42,7 @@ export interface PluginDefInput {
themeClasses?: { [themeSystemName: string]: ThemeClass }
eventSourceDefs?: EventSourceDef[]
cmdFormatter?: CmdFormatterFunc
recurringTypes?: RecurringType[]
}

export interface PluginHooks {
Expand All @@ -64,6 +66,7 @@ export interface PluginHooks {
themeClasses: { [themeSystemName: string]: ThemeClass }
eventSourceDefs: EventSourceDef[]
cmdFormatter?: CmdFormatterFunc
recurringTypes: RecurringType[]
}

export interface PluginDef extends PluginHooks {
Expand Down Expand Up @@ -105,7 +108,8 @@ export function createPlugin(input: PluginDefInput): PluginDef {
calendarInteractions: input.calendarInteractions || [],
themeClasses: input.themeClasses || {},
eventSourceDefs: input.eventSourceDefs || [],
cmdFormatter: input.cmdFormatter
cmdFormatter: input.cmdFormatter,
recurringTypes: input.recurringTypes || []
}
}

Expand Down Expand Up @@ -135,22 +139,13 @@ export class PluginSystem {
calendarInteractions: [],
themeClasses: {},
eventSourceDefs: [],
cmdFormatter: null
cmdFormatter: null,
recurringTypes: []
}
this.addedHash = {}
}

add(plugin: PluginDef) {

// TODO: remove this
if ((plugin as any).warning) {
if (!(plugin as any).warned) {
console.warn((plugin as any).warning)
;(plugin as any).warned = true
}
return
}

if (!this.addedHash[plugin.id]) {
this.addedHash[plugin.id] = true

Expand Down Expand Up @@ -185,6 +180,7 @@ function combineHooks(hooks0: PluginHooks, hooks1: PluginHooks): PluginHooks {
componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
themeClasses: __assign({}, hooks0.themeClasses, hooks1.themeClasses),
eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter
cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes)
}
}
2 changes: 1 addition & 1 deletion src/core/structs/event-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function expandRecurring(eventStore: EventStore, framingRange: DateRange,
let def = defs[defId]

if (def.recurringDef) {
let starts = expandRecurringRanges(def, framingRange, calendar.dateEnv)
let starts = expandRecurringRanges(def, framingRange, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes)
let duration = def.recurringDef.duration

if (!duration) {
Expand Down
1 change: 1 addition & 0 deletions src/core/structs/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export function parseEvent(raw: EventInput, sourceId: string, calendar: Calendar
raw, // raw, but with single-event stuff stripped out
allDayDefault,
calendar.dateEnv,
calendar.pluginSystem.hooks.recurringTypes,
leftovers0 // will populate with non-recurring props
)

Expand Down
9 changes: 7 additions & 2 deletions src/core/structs/recurring-event-simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { startOfDay, addDays, DateMarker } from '../datelib/marker'
import { Duration, createDuration, subtractDurations } from '../datelib/duration'
import { arrayToHash } from '../util/object'
import { refineProps } from '../util/misc'
import { registerRecurringType, ParsedRecurring } from './recurring-event'
import { RecurringType, ParsedRecurring } from './recurring-event'
import { EventInput, EventDef } from './event'
import { DateRange, intersectRanges } from '../datelib/date-range'
import { DateEnv } from '../datelib/env'
import { createPlugin } from '../plugin-system'

/*
An implementation of recurring events that only supports every-day or weekly recurrences.
Expand All @@ -23,7 +24,7 @@ interface SimpleParsedRecurring extends ParsedRecurring {
typeData: SimpleRecurringData // the whole point is to make this more specific
}

registerRecurringType({
let recurring: RecurringType = {

parse(rawEvent: EventInput, allDayDefault: boolean | null, leftoverProps: any, dateEnv: DateEnv): SimpleParsedRecurring | null {
let createMarker = dateEnv.createMarker.bind(dateEnv)
Expand Down Expand Up @@ -86,6 +87,10 @@ registerRecurringType({
}
}

}

export default createPlugin({
recurringTypes: [ recurring ]
})

function expandRanges(
Expand Down
22 changes: 13 additions & 9 deletions src/core/structs/recurring-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@ export interface RecurringType {
}


let recurringTypes: RecurringType[] = []

export function registerRecurringType(recurringType: RecurringType) {
recurringTypes.push(recurringType)
}


/*
KNOWN BUG: will populate lefovers only up until a recurring type works
*/
export function parseRecurring(eventInput: EventInput, allDayDefault: boolean | null, dateEnv: DateEnv, leftovers: any) {
export function parseRecurring(
eventInput: EventInput,
allDayDefault: boolean | null,
dateEnv: DateEnv,
recurringTypes: RecurringType[],
leftovers: any
) {
for (let i = 0; i < recurringTypes.length; i++) {
let parsed = recurringTypes[i].parse(eventInput, allDayDefault, leftovers, dateEnv) as ParsedRecurring

Expand All @@ -51,7 +50,12 @@ export function parseRecurring(eventInput: EventInput, allDayDefault: boolean |
/*
Event MUST have a recurringDef
*/
export function expandRecurringRanges(eventDef: EventDef, framingRange: DateRange, dateEnv: DateEnv): DateMarker[] {
export function expandRecurringRanges(
eventDef: EventDef,
framingRange: DateRange,
dateEnv: DateEnv,
recurringTypes: RecurringType[],
): DateMarker[] {
let typeDef = recurringTypes[eventDef.recurringDef.typeId]
let markers = typeDef.expand(
eventDef.recurringDef.typeData,
Expand Down
23 changes: 17 additions & 6 deletions src/rrule/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import { RRule, rrulestr } from 'rrule'
import { registerRecurringType, ParsedRecurring, EventInput, refineProps, DateEnv, EventDef, DateRange, DateMarker, createDuration } from '@fullcalendar/core'
import {
RecurringType,
ParsedRecurring,
EventInput,
refineProps,
DateEnv,
EventDef,
DateRange,
DateMarker,
createDuration,
createPlugin
} from '@fullcalendar/core'

interface RRuleParsedRecurring extends ParsedRecurring {
typeData: RRule
Expand All @@ -10,7 +21,7 @@ const EVENT_DEF_PROPS = {
duration: createDuration
}

registerRecurringType({
let recurring: RecurringType = {

parse(rawEvent: EventInput, allDayDefault: boolean | null, leftoverProps: any, dateEnv: DateEnv): RRuleParsedRecurring | null {
if (rawEvent.rrule != null) {
Expand All @@ -33,6 +44,10 @@ registerRecurringType({
return rrule.between(framingRange.start, framingRange.end)
}

}

export default createPlugin({
recurringTypes: [ recurring ]
})

function parseRRule(input, allDayDefault: boolean | null, dateEnv: DateEnv) {
Expand Down Expand Up @@ -102,7 +117,3 @@ function convertConstant(input) {
}
return input
}

export default {
warning: 'TODO: convert fullcalendar-rrule to real plugin. will still work though.'
}

0 comments on commit 400797b

Please sign in to comment.