Jelajahi Sumber

remove many jquery util methods

Adam Shaw 8 tahun lalu
induk
melakukan
45cc7dd463

+ 4 - 4
src/Calendar.ts

@@ -106,11 +106,11 @@ export default class Calendar {
     let context
     let context
     let args
     let args
 
 
-    if ($.isPlainObject(triggerInfo)) {
+    if (Array.isArray(triggerInfo)) {
+      args = triggerInfo
+    } else if (typeof triggerInfo === 'object') {
       context = triggerInfo.context
       context = triggerInfo.context
       args = triggerInfo.args
       args = triggerInfo.args
-    } else if ($.isArray(triggerInfo)) {
-      args = triggerInfo
     }
     }
 
 
     if (context == null) {
     if (context == null) {
@@ -1308,7 +1308,7 @@ ListenerMixin.mixInto(Calendar)
 function filterLegacyEventInstances(legacyEventInstances, legacyQuery) {
 function filterLegacyEventInstances(legacyEventInstances, legacyQuery) {
   if (legacyQuery == null) {
   if (legacyQuery == null) {
     return legacyEventInstances
     return legacyEventInstances
-  } else if ($.isFunction(legacyQuery)) {
+  } else if (typeof legacyQuery === 'function') {
     return legacyEventInstances.filter(legacyQuery)
     return legacyEventInstances.filter(legacyQuery)
   } else { // an event ID
   } else { // an event ID
     legacyQuery += '' // normalize to string
     legacyQuery += '' // normalize to string

+ 2 - 2
src/OptionsManager.ts

@@ -1,5 +1,5 @@
-import * as $ from 'jquery'
 import { firstDefined } from './util'
 import { firstDefined } from './util'
+import { assignTo } from './util/object'
 import { globalDefaults, rtlDefaults, mergeOptions } from './options'
 import { globalDefaults, rtlDefaults, mergeOptions } from './options'
 import { localeOptionHash, populateInstanceComputableOptions } from './locale'
 import { localeOptionHash, populateInstanceComputableOptions } from './locale'
 import Model from './common/Model'
 import Model from './common/Model'
@@ -17,7 +17,7 @@ export default class OptionsManager extends Model {
   constructor(_calendar, overrides) {
   constructor(_calendar, overrides) {
     super()
     super()
     this._calendar = _calendar
     this._calendar = _calendar
-    this.overrides = $.extend({}, overrides) // make a copy
+    this.overrides = assignTo({}, overrides) // make a copy
     this.dynamicOverrides = {}
     this.dynamicOverrides = {}
     this.compute()
     this.compute()
   }
   }

+ 2 - 2
src/Toolbar.ts

@@ -66,12 +66,12 @@ export default class Toolbar {
     let calendarButtonText = optionsManager.get('buttonText') || {}
     let calendarButtonText = optionsManager.get('buttonText') || {}
 
 
     if (buttonStr) {
     if (buttonStr) {
-      $.each(buttonStr.split(' '), (i, buttonGroupStr) => {
+      buttonStr.split(' ').forEach((buttonGroupStr, i) => {
         let groupChildren = $()
         let groupChildren = $()
         let isOnlyButtons = true
         let isOnlyButtons = true
         let groupEl
         let groupEl
 
 
-        $.each(buttonGroupStr.split(','), (j, buttonName) => {
+        buttonGroupStr.split(',').forEach((buttonName, j) => {
           let customButtonProps
           let customButtonProps
           let viewSpec
           let viewSpec
           let buttonClick
           let buttonClick

+ 5 - 4
src/View.ts

@@ -1,6 +1,7 @@
 import * as $ from 'jquery'
 import * as $ from 'jquery'
 import * as moment from 'moment'
 import * as moment from 'moment'
 import { parseFieldSpecs, proxy, isPrimaryMouseButton } from './util'
 import { parseFieldSpecs, proxy, isPrimaryMouseButton } from './util'
+import { assignTo } from './util/object'
 import RenderQueue from './common/RenderQueue'
 import RenderQueue from './common/RenderQueue'
 import Calendar from './Calendar'
 import Calendar from './Calendar'
 import DateProfileGenerator from './DateProfileGenerator'
 import DateProfileGenerator from './DateProfileGenerator'
@@ -498,7 +499,7 @@ export default abstract class View extends InteractiveDateComponent {
   addScroll(scroll) {
   addScroll(scroll) {
     let queuedScroll = this.queuedScroll || (this.queuedScroll = {})
     let queuedScroll = this.queuedScroll || (this.queuedScroll = {})
 
 
-    $.extend(queuedScroll, scroll)
+    assignTo(queuedScroll, scroll)
   }
   }
 
 
 
 
@@ -519,7 +520,7 @@ export default abstract class View extends InteractiveDateComponent {
     let scroll = {}
     let scroll = {}
 
 
     if (this.isDatesRendered) {
     if (this.isDatesRendered) {
-      $.extend(scroll, this.queryDateScroll())
+      assignTo(scroll, this.queryDateScroll())
     }
     }
 
 
     return scroll
     return scroll
@@ -528,7 +529,7 @@ export default abstract class View extends InteractiveDateComponent {
 
 
   applyScroll(scroll) {
   applyScroll(scroll) {
     if (scroll.isDateInit && this.isDatesRendered) {
     if (scroll.isDateInit && this.isDatesRendered) {
-      $.extend(scroll, this.computeInitialDateScroll())
+      assignTo(scroll, this.computeInitialDateScroll())
     }
     }
 
 
     if (this.isDatesRendered) {
     if (this.isDatesRendered) {
@@ -915,7 +916,7 @@ export default abstract class View extends InteractiveDateComponent {
 
 
     for (i = 0; i < 7; i++) {
     for (i = 0; i < 7; i++) {
       if (
       if (
-        !(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)
+        !(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)
       ) {
       ) {
         dayCnt++
         dayCnt++
       }
       }

+ 3 - 4
src/ViewSpecManager.ts

@@ -1,5 +1,4 @@
 import * as moment from 'moment'
 import * as moment from 'moment'
-import * as $ from 'jquery'
 import { viewHash } from './ViewRegistry'
 import { viewHash } from './ViewRegistry'
 import { mergeProps, unitsDesc, computeDurationGreatestUnit } from './util'
 import { mergeProps, unitsDesc, computeDurationGreatestUnit } from './util'
 import { mergeOptions, globalDefaults } from './options'
 import { mergeOptions, globalDefaults } from './options'
@@ -41,13 +40,13 @@ export default class ViewSpecManager {
     let i
     let i
     let spec
     let spec
 
 
-    if ($.inArray(unit, unitsDesc) !== -1) {
+    if (unitsDesc.indexOf(unit) !== -1) {
 
 
       // put views that have buttons first. there will be duplicates, but oh well
       // put views that have buttons first. there will be duplicates, but oh well
       viewTypes = this._calendar.header.getViewsWithButtons() // TODO: include footer as well?
       viewTypes = this._calendar.header.getViewsWithButtons() // TODO: include footer as well?
-      $.each(viewHash, function(viewType) { // all views
+      for (let viewType in viewHash) {
         viewTypes.push(viewType)
         viewTypes.push(viewType)
-      })
+      }
 
 
       for (i = 0; i < viewTypes.length; i++) {
       for (i = 0; i < viewTypes.length; i++) {
         spec = this.getViewSpec(viewTypes[i])
         spec = this.getViewSpec(viewTypes[i])

+ 1 - 1
src/agenda/TimeGrid.ts

@@ -144,7 +144,7 @@ export default class TimeGrid extends InteractiveDateComponent {
     // might be an array value (for TimelineView).
     // might be an array value (for TimelineView).
     // if so, getting the most granular entry (the last one probably).
     // if so, getting the most granular entry (the last one probably).
     input = this.opt('slotLabelFormat')
     input = this.opt('slotLabelFormat')
-    if ($.isArray(input)) {
+    if (Array.isArray(input)) {
       input = input[input.length - 1]
       input = input[input.length - 1]
     }
     }
 
 

+ 2 - 1
src/basic/DayGrid.ts

@@ -1,5 +1,6 @@
 import * as $ from 'jquery'
 import * as $ from 'jquery'
 import { htmlEscape } from '../util'
 import { htmlEscape } from '../util'
+import { assignTo } from '../util/object'
 import CoordCache from '../common/CoordCache'
 import CoordCache from '../common/CoordCache'
 import Popover from '../common/Popover'
 import Popover from '../common/Popover'
 import UnzonedRange from '../models/UnzonedRange'
 import UnzonedRange from '../models/UnzonedRange'
@@ -746,7 +747,7 @@ export default class DayGrid extends InteractiveDateComponent {
 
 
       if (slicedRange) {
       if (slicedRange) {
         newSegs.push(
         newSegs.push(
-          $.extend({}, seg, {
+          assignTo({}, seg, {
             footprint: new EventFootprint(
             footprint: new EventFootprint(
               new ComponentFootprint(
               new ComponentFootprint(
                 slicedRange,
                 slicedRange,

+ 1 - 1
src/basic/DayGridEventRenderer.ts

@@ -20,7 +20,7 @@ export default class DayGridEventRenderer extends EventRenderer {
 
 
   renderBgRanges(eventRanges) {
   renderBgRanges(eventRanges) {
     // don't render timed background events
     // don't render timed background events
-    eventRanges = $.grep(eventRanges, function(eventRange: any) {
+    eventRanges = eventRanges.filter(function(eventRange: any) {
       return eventRange.eventDef.isAllDay()
       return eventRange.eventDef.isAllDay()
     })
     })
 
 

+ 2 - 2
src/common/GlobalEmitter.ts

@@ -82,7 +82,7 @@ export default class GlobalEmitter {
     window.addEventListener(
     window.addEventListener(
       'touchmove',
       'touchmove',
       this.handleTouchMoveProxy = (ev) => {
       this.handleTouchMoveProxy = (ev) => {
-        this.handleTouchMove($.Event(ev as any))
+        this.handleTouchMove(ev)
       },
       },
       { passive: false } as any // allows preventDefault()
       { passive: false } as any // allows preventDefault()
     )
     )
@@ -93,7 +93,7 @@ export default class GlobalEmitter {
     window.addEventListener(
     window.addEventListener(
       'scroll',
       'scroll',
       this.handleScrollProxy = (ev) => {
       this.handleScrollProxy = (ev) => {
-        this.handleScroll($.Event(ev as any))
+        this.handleScroll(ev)
       },
       },
       true // useCapture
       true // useCapture
     )
     )

+ 1 - 4
src/common/ListenerMixin.ts

@@ -11,7 +11,6 @@ after class:
   ListenerMixin.mixInto(TheClass)
   ListenerMixin.mixInto(TheClass)
 */
 */
 
 
-import * as $ from 'jquery'
 import Mixin from './Mixin'
 import Mixin from './Mixin'
 
 
 export interface ListenerInterface {
 export interface ListenerInterface {
@@ -46,9 +45,7 @@ export default class ListenerMixin extends Mixin implements ListenerInterface {
     } else if (typeof arg === 'string') {
     } else if (typeof arg === 'string') {
       other.on(
       other.on(
         arg + '.' + this.getListenerNamespace(), // use event namespacing to identify this object
         arg + '.' + this.getListenerNamespace(), // use event namespacing to identify this object
-        $.proxy(callback, this) // always use `this` context
-          // the usually-undesired jQuery guid behavior doesn't matter,
-          // because we always unbind via namespace
+        callback.bind(this) // always use `this` context
       )
       )
     }
     }
   }
   }

+ 3 - 4
src/component/DateComponent.ts

@@ -1,4 +1,3 @@
-import * as $ from 'jquery'
 import * as moment from 'moment'
 import * as moment from 'moment'
 import { attrsToStr, htmlEscape, dayIDs } from '../util'
 import { attrsToStr, htmlEscape, dayIDs } from '../util'
 import momentExt from '../moment-ext'
 import momentExt from '../moment-ext'
@@ -663,12 +662,12 @@ export default abstract class DateComponent extends Component {
     let forceOff
     let forceOff
     let finalOptions
     let finalOptions
 
 
-    if ($.isPlainObject(gotoOptions)) {
+    if (moment.isMoment(gotoOptions) || typeof gotoOptions !== 'object') {
+      date = gotoOptions // a single moment input
+    } else {
       date = gotoOptions.date
       date = gotoOptions.date
       type = gotoOptions.type
       type = gotoOptions.type
       forceOff = gotoOptions.forceOff
       forceOff = gotoOptions.forceOff
-    } else {
-      date = gotoOptions // a single moment input
     }
     }
     date = momentExt(date) // if a string, parse it
     date = momentExt(date) // if a string, parse it
 
 

+ 4 - 3
src/component/interactions/ExternalDropping.ts

@@ -2,6 +2,7 @@ import * as $ from 'jquery'
 import * as moment from 'moment'
 import * as moment from 'moment'
 import * as exportHooks from '../../exports'
 import * as exportHooks from '../../exports'
 import { disableCursor, enableCursor } from '../../util'
 import { disableCursor, enableCursor } from '../../util'
+import { assignTo } from '../../util/object'
 import momentExt from '../../moment-ext'
 import momentExt from '../../moment-ext'
 import { default as ListenerMixin, ListenerInterface } from '../../common/ListenerMixin'
 import { default as ListenerMixin, ListenerInterface } from '../../common/ListenerMixin'
 import HitDragListener from '../../common/HitDragListener'
 import HitDragListener from '../../common/HitDragListener'
@@ -61,7 +62,7 @@ export default class ExternalDropping extends Interaction {
       // Test that the dragged element passes the dropAccept selector or filter function.
       // Test that the dragged element passes the dropAccept selector or filter function.
       // FYI, the default is "*" (matches all)
       // FYI, the default is "*" (matches all)
       accept = this.opt('dropAccept')
       accept = this.opt('dropAccept')
-      if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {
+      if (typeof accept === 'function' ? accept.call(el[0], el) : el.is(accept)) {
         if (!this.isDragging) { // prevent double-listening if fired twice
         if (!this.isDragging) { // prevent double-listening if fired twice
           this.listenToExternalDrag(el, ev, ui)
           this.listenToExternalDrag(el, ev, ui)
         }
         }
@@ -175,7 +176,7 @@ export default class ExternalDropping extends Interaction {
     }
     }
 
 
     eventDef = SingleEventDef.parse(
     eventDef = SingleEventDef.parse(
-      $.extend({}, meta.eventProps, {
+      assignTo({}, meta.eventProps, {
         start: start,
         start: start,
         end: end
         end: end
       }),
       }),
@@ -212,7 +213,7 @@ function getDraggedElMeta(el) {
 
 
   if (eventProps) {
   if (eventProps) {
     if (typeof eventProps === 'object') {
     if (typeof eventProps === 'object') {
-      eventProps = $.extend({}, eventProps) // make a copy
+      eventProps = assignTo({}, eventProps) // make a copy
     } else { // something like 1 or true. still signal event creation
     } else { // something like 1 or true. still signal event creation
       eventProps = {}
       eventProps = {}
     }
     }

+ 9 - 6
src/locale.ts

@@ -118,11 +118,12 @@ const instanceComputableOptions = {
 
 
 // TODO: make these computable properties in optionsManager
 // TODO: make these computable properties in optionsManager
 export function populateInstanceComputableOptions(options) {
 export function populateInstanceComputableOptions(options) {
-  $.each(instanceComputableOptions, function(name, func) {
+  for (let name in instanceComputableOptions) {
+    let func = instanceComputableOptions[name]
     if (options[name] == null) {
     if (options[name] == null) {
       options[name] = func(options)
       options[name] = func(options)
     }
     }
-  })
+  }
 }
 }
 
 
 
 
@@ -138,9 +139,10 @@ export function datepickerLocale(localeCode, dpLocaleCode, dpOptions) {
   fcOptions.weekNumberTitle = dpOptions.weekHeader
   fcOptions.weekNumberTitle = dpOptions.weekHeader
 
 
   // compute some more complex options from datepicker
   // compute some more complex options from datepicker
-  $.each(dpComputableOptions, function(name, func) {
+  for (let name in dpComputableOptions) {
+    let func = dpComputableOptions[name]
     fcOptions[name] = func(dpOptions)
     fcOptions[name] = func(dpOptions)
-  })
+  }
 
 
   let jqDatePicker = ($ as any).datepicker
   let jqDatePicker = ($ as any).datepicker
 
 
@@ -181,11 +183,12 @@ export function locale(localeCode, newFcOptions) {
   // always do this. newFcOptions can be undefined when initializing from i18n file,
   // always do this. newFcOptions can be undefined when initializing from i18n file,
   // so no way to tell if this is an initialization or a default-setting.
   // so no way to tell if this is an initialization or a default-setting.
   momOptions = getMomentLocaleData(localeCode) // will fall back to en
   momOptions = getMomentLocaleData(localeCode) // will fall back to en
-  $.each(momComputableOptions, function(name, func) {
+  for (let name in momComputableOptions) {
+    let func = momComputableOptions[name]
     if (fcOptions[name] == null) {
     if (fcOptions[name] == null) {
       fcOptions[name] = (func)(momOptions, fcOptions)
       fcOptions[name] = (func)(momOptions, fcOptions)
     }
     }
-  })
+  }
 
 
   // set it as the default locale for FullCalendar
   // set it as the default locale for FullCalendar
   globalDefaults.locale = localeCode
   globalDefaults.locale = localeCode

+ 1 - 1
src/main.ts

@@ -41,7 +41,7 @@ $.fn.fullCalendar = function(options?): (JQuery | any) {
         }
         }
       } else if (!calendar) {
       } else if (!calendar) {
         warn('Attempting to call a FullCalendar method on an element with no calendar.')
         warn('Attempting to call a FullCalendar method on an element with no calendar.')
-      } else if ($.isFunction(calendar[options])) {
+      } else if (typeof calendar[options] === 'function') {
         singleRes = calendar[options].apply(calendar, args)
         singleRes = calendar[options].apply(calendar, args)
 
 
         if (!i) {
         if (!i) {

+ 5 - 5
src/models/BusinessHourGenerator.ts

@@ -1,4 +1,4 @@
-import * as $ from 'jquery'
+import { assignTo } from '../util/object'
 import { eventDefsToEventInstances } from '../models/event/util'
 import { eventDefsToEventInstances } from '../models/event/util'
 import EventInstanceGroup from './event/EventInstanceGroup'
 import EventInstanceGroup from './event/EventInstanceGroup'
 import RecurringEventDef from './event/RecurringEventDef'
 import RecurringEventDef from './event/RecurringEventDef'
@@ -52,11 +52,11 @@ export default class BusinessHourGenerator {
 
 
     if (rawComplexDef === true) {
     if (rawComplexDef === true) {
       rawDefs = [ {} ] // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim
       rawDefs = [ {} ] // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim
-    } else if ($.isPlainObject(rawComplexDef)) {
-      rawDefs = [ rawComplexDef ]
-    } else if ($.isArray(rawComplexDef)) {
+    } else if (Array.isArray(rawComplexDef)) {
       rawDefs = rawComplexDef
       rawDefs = rawComplexDef
       requireDow = true // every sub-definition NEEDS a day-of-week
       requireDow = true // every sub-definition NEEDS a day-of-week
+    } else if (typeof rawComplexDef === 'object') {
+      rawDefs = [ rawComplexDef ]
     }
     }
 
 
     for (i = 0; i < rawDefs.length; i++) {
     for (i = 0; i < rawDefs.length; i++) {
@@ -72,7 +72,7 @@ export default class BusinessHourGenerator {
 
 
 
 
   buildEventDef(isAllDay, rawDef) {
   buildEventDef(isAllDay, rawDef) {
-    let fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef)
+    let fullRawDef = assignTo({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef)
 
 
     if (isAllDay) {
     if (isAllDay) {
       fullRawDef.start = null
       fullRawDef.start = null

+ 3 - 4
src/models/EventManager.ts

@@ -1,4 +1,3 @@
-import * as $ from 'jquery'
 import { removeExact } from '../util'
 import { removeExact } from '../util'
 import EventPeriod from './EventPeriod'
 import EventPeriod from './EventPeriod'
 import ArrayEventSource from './event-source/ArrayEventSource'
 import ArrayEventSource from './event-source/ArrayEventSource'
@@ -125,7 +124,7 @@ export default class EventManager {
     // coerce into an array
     // coerce into an array
     if (!matchInputs) {
     if (!matchInputs) {
       matchInputs = []
       matchInputs = []
-    } else if (!$.isArray(matchInputs)) {
+    } else if (!Array.isArray(matchInputs)) {
       matchInputs = [ matchInputs ]
       matchInputs = [ matchInputs ]
     }
     }
 
 
@@ -170,7 +169,7 @@ export default class EventManager {
     matchInput = EventSourceParser.parse(matchInput, this.calendar)
     matchInput = EventSourceParser.parse(matchInput, this.calendar)
     if (matchInput) {
     if (matchInput) {
 
 
-      return $.grep(sources, function(source) {
+      return sources.filter(function(source) {
         return isSourcesEquivalent(matchInput, source)
         return isSourcesEquivalent(matchInput, source)
       })
       })
     }
     }
@@ -181,7 +180,7 @@ export default class EventManager {
   ID assumed to already be normalized
   ID assumed to already be normalized
   */
   */
   getSourceById(id) {
   getSourceById(id) {
-    return $.grep(this.otherSources, function(source: any) {
+    return this.otherSources.filter(function(source: any) {
       return source.id && source.id === id
       return source.id && source.id === id
     })[0]
     })[0]
   }
   }

+ 3 - 3
src/models/EventPeriod.ts

@@ -1,6 +1,6 @@
-import * as $ from 'jquery'
 import * as moment from 'moment'
 import * as moment from 'moment'
 import { removeExact, removeMatching } from '../util'
 import { removeExact, removeMatching } from '../util'
+import { isEmpty } from '../util/object'
 import Promise from '../common/Promise'
 import Promise from '../common/Promise'
 import { default as EmitterMixin, EmitterInterface } from '../common/EmitterMixin'
 import { default as EmitterMixin, EmitterInterface } from '../common/EmitterMixin'
 import UnzonedRange from './UnzonedRange'
 import UnzonedRange from './UnzonedRange'
@@ -192,13 +192,13 @@ export default class EventPeriod {
 
 
 
 
   removeAllEventDefs() {
   removeAllEventDefs() {
-    let isEmpty = $.isEmptyObject(this.eventDefsByUid)
+    let hasEventDefs = !isEmpty(this.eventDefsByUid)
 
 
     this.eventDefsByUid = {}
     this.eventDefsByUid = {}
     this.eventDefsById = {}
     this.eventDefsById = {}
     this.eventInstanceGroupsById = {}
     this.eventInstanceGroupsById = {}
 
 
-    if (!isEmpty) {
+    if (hasEventDefs) {
       this.tryRelease()
       this.tryRelease()
     }
     }
   }
   }

+ 2 - 3
src/models/event-source/ArrayEventSource.ts

@@ -1,4 +1,3 @@
-import * as $ from 'jquery'
 import { removeMatching } from '../../util'
 import { removeMatching } from '../../util'
 import Promise from '../../common/Promise'
 import Promise from '../../common/Promise'
 import EventSource from './EventSource'
 import EventSource from './EventSource'
@@ -22,9 +21,9 @@ export default class ArrayEventSource extends EventSource {
     let rawProps
     let rawProps
 
 
     // normalize raw input
     // normalize raw input
-    if ($.isArray(rawInput.events)) { // extended form
+    if (Array.isArray(rawInput.events)) { // extended form
       rawProps = rawInput
       rawProps = rawInput
-    } else if ($.isArray(rawInput)) { // short form
+    } else if (Array.isArray(rawInput)) { // short form
       rawProps = { events: rawInput }
       rawProps = { events: rawInput }
     }
     }
 
 

+ 1 - 2
src/models/event-source/EventSource.ts

@@ -1,4 +1,3 @@
-import * as $ from 'jquery'
 import {
 import {
   default as ParsableModelMixin,
   default as ParsableModelMixin,
   ParsableModelInterface
   ParsableModelInterface
@@ -133,7 +132,7 @@ export default class EventSource extends Class {
     }
     }
 
 
     // TODO: converge with EventDef
     // TODO: converge with EventDef
-    if ($.isArray(rawProps.className)) {
+    if (Array.isArray(rawProps.className)) {
       this.className = rawProps.className
       this.className = rawProps.className
     } else if (typeof rawProps.className === 'string') {
     } else if (typeof rawProps.className === 'string') {
       this.className = rawProps.className.split(/\s+/)
       this.className = rawProps.className.split(/\s+/)

+ 2 - 3
src/models/event-source/FuncEventSource.ts

@@ -1,4 +1,3 @@
-import * as $ from 'jquery'
 import Promise from '../../common/Promise'
 import Promise from '../../common/Promise'
 import EventSource from './EventSource'
 import EventSource from './EventSource'
 
 
@@ -12,9 +11,9 @@ export default class FuncEventSource extends EventSource {
     let rawProps
     let rawProps
 
 
     // normalize raw input
     // normalize raw input
-    if ($.isFunction(rawInput.events)) { // extended form
+    if (typeof rawInput.events === 'function') { // extended form
       rawProps = rawInput
       rawProps = rawInput
-    } else if ($.isFunction(rawInput)) { // short form
+    } else if (typeof rawInput === 'function') { // short form
       rawProps = { events: rawInput }
       rawProps = { events: rawInput }
     }
     }
 
 

+ 5 - 4
src/models/event-source/JsonFeedEventSource.ts

@@ -1,5 +1,6 @@
 import * as $ from 'jquery'
 import * as $ from 'jquery'
 import { applyAll } from '../../util'
 import { applyAll } from '../../util'
+import { assignTo } from '../../util/object'
 import Promise from '../../common/Promise'
 import Promise from '../../common/Promise'
 import EventSource from './EventSource'
 import EventSource from './EventSource'
 
 
@@ -50,7 +51,7 @@ export default class JsonFeedEventSource extends EventSource {
     this.calendar.pushLoading()
     this.calendar.pushLoading()
 
 
     return Promise.construct((onResolve, onReject) => {
     return Promise.construct((onResolve, onReject) => {
-      $.ajax($.extend(
+      $.ajax(assignTo(
         {}, // destination
         {}, // destination
         JsonFeedEventSource.AJAX_DEFAULTS,
         JsonFeedEventSource.AJAX_DEFAULTS,
         ajaxSettings,
         ajaxSettings,
@@ -65,7 +66,7 @@ export default class JsonFeedEventSource extends EventSource {
             if (rawEventDefs) {
             if (rawEventDefs) {
               callbackRes = applyAll(onSuccess, this, [ rawEventDefs, status, xhr ]) // redirect `this`
               callbackRes = applyAll(onSuccess, this, [ rawEventDefs, status, xhr ]) // redirect `this`
 
 
-              if ($.isArray(callbackRes)) {
+              if (Array.isArray(callbackRes)) {
                 rawEventDefs = callbackRes
                 rawEventDefs = callbackRes
               }
               }
 
 
@@ -111,7 +112,7 @@ export default class JsonFeedEventSource extends EventSource {
     }
     }
 
 
     // retrieve any outbound GET/POST $.ajax data from the options
     // retrieve any outbound GET/POST $.ajax data from the options
-    if ($.isFunction(ajaxSettings.data)) {
+    if (typeof ajaxSettings.data === 'function') {
       // supplied as a function that returns a key/value object
       // supplied as a function that returns a key/value object
       customRequestParams = ajaxSettings.data()
       customRequestParams = ajaxSettings.data()
     } else {
     } else {
@@ -119,7 +120,7 @@ export default class JsonFeedEventSource extends EventSource {
       customRequestParams = ajaxSettings.data || {}
       customRequestParams = ajaxSettings.data || {}
     }
     }
 
 
-    $.extend(params, customRequestParams)
+    assignTo(params, customRequestParams)
 
 
     params[startParam] = start.format()
     params[startParam] = start.format()
     params[endParam] = end.format()
     params[endParam] = end.format()

+ 5 - 5
src/models/event/EventDef.ts

@@ -1,4 +1,4 @@
-import * as $ from 'jquery'
+import { assignTo } from '../../util/object'
 import {
 import {
   default as ParsableModelMixin,
   default as ParsableModelMixin,
   ParsableModelInterface
   ParsableModelInterface
@@ -81,7 +81,7 @@ export default abstract class EventDef {
     EventDef.copyVerbatimStandardProps(this, copy)
     EventDef.copyVerbatimStandardProps(this, copy)
 
 
     copy.className = this.className.slice() // copy
     copy.className = this.className.slice() // copy
-    copy.miscProps = $.extend({}, this.miscProps)
+    copy.miscProps = assignTo({}, this.miscProps)
 
 
     return copy
     return copy
   }
   }
@@ -162,7 +162,7 @@ export default abstract class EventDef {
 
 
 
 
   toLegacy() {
   toLegacy() {
-    let obj = $.extend({}, this.miscProps)
+    let obj = assignTo({}, this.miscProps)
 
 
     obj._id = this.uid
     obj._id = this.uid
     obj.source = this.source
     obj.source = this.source
@@ -194,7 +194,7 @@ export default abstract class EventDef {
     }
     }
 
 
     // TODO: converge with EventSource
     // TODO: converge with EventSource
-    if ($.isArray(rawProps.className)) {
+    if (Array.isArray(rawProps.className)) {
       this.className = rawProps.className
       this.className = rawProps.className
     }
     }
     if (typeof rawProps.className === 'string') {
     if (typeof rawProps.className === 'string') {
@@ -206,7 +206,7 @@ export default abstract class EventDef {
 
 
 
 
   applyMiscProps(rawProps) {
   applyMiscProps(rawProps) {
-    $.extend(this.miscProps, rawProps)
+    assignTo(this.miscProps, rawProps)
   }
   }
 
 
 }
 }

+ 2 - 2
src/models/event/RecurringEventDef.ts

@@ -1,5 +1,5 @@
-import * as $ from 'jquery'
 import * as moment from 'moment'
 import * as moment from 'moment'
+import { assignTo } from '../../util/object'
 import EventDef from './EventDef'
 import EventDef from './EventDef'
 import EventInstance from './EventInstance'
 import EventInstance from './EventInstance'
 import EventDateProfile from './EventDateProfile'
 import EventDateProfile from './EventDateProfile'
@@ -84,7 +84,7 @@ export default class RecurringEventDef extends EventDef {
     }
     }
 
 
     if (this.dowHash) {
     if (this.dowHash) {
-      def.dowHash = $.extend({}, this.dowHash)
+      def.dowHash = assignTo({}, this.dowHash)
     }
     }
 
 
     return def
     return def

+ 3 - 3
src/moment-ext.ts

@@ -1,6 +1,6 @@
 import * as moment from 'moment'
 import * as moment from 'moment'
-import * as $ from 'jquery'
 import { isNativeDate } from './util'
 import { isNativeDate } from './util'
+import { assignTo } from './util/object'
 
 
 /*
 /*
 GENERAL NOTE on moments throughout the *entire rest* of the codebase:
 GENERAL NOTE on moments throughout the *entire rest* of the codebase:
@@ -22,7 +22,7 @@ let ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/
 let ambigTimeOrZoneRegex =
 let ambigTimeOrZoneRegex =
   /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/
   /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/
 let newMomentProto: any = moment.fn // where we will attach our new methods
 let newMomentProto: any = moment.fn // where we will attach our new methods
-let oldMomentProto = $.extend({}, newMomentProto) // copy of original moment methods
+let oldMomentProto = assignTo({}, newMomentProto) // copy of original moment methods
 
 
 // tell momentjs to transfer these properties upon clone
 // tell momentjs to transfer these properties upon clone
 let momentProperties = (moment as any).momentProperties
 let momentProperties = (moment as any).momentProperties
@@ -102,7 +102,7 @@ function makeMoment(args, parseAsUTC= false, parseZone= false) {
         isAmbigTime = !ambigMatch[5] // no time part?
         isAmbigTime = !ambigMatch[5] // no time part?
         isAmbigZone = true
         isAmbigZone = true
       }
       }
-    } else if ($.isArray(input)) {
+    } else if (Array.isArray(input)) {
       // arrays have no timezone information, so assume ambiguous zone
       // arrays have no timezone information, so assume ambiguous zone
       isAmbigZone = true
       isAmbigZone = true
     }
     }

+ 3 - 3
src/theme/Theme.ts

@@ -1,4 +1,4 @@
-import * as $ from 'jquery'
+import { assignTo } from '../util/object'
 
 
 
 
 export default class Theme {
 export default class Theme {
@@ -33,8 +33,8 @@ export default class Theme {
     let iconClassesCopy
     let iconClassesCopy
     let buttonName
     let buttonName
 
 
-    if ($.isPlainObject(iconOverrideHash)) {
-      iconClassesCopy = $.extend({}, this.iconClasses)
+    if (typeof iconOverrideHash === 'object') {
+      iconClassesCopy = assignTo({}, this.iconClasses)
 
 
       for (buttonName in iconOverrideHash) {
       for (buttonName in iconOverrideHash) {
         iconClassesCopy[buttonName] = this.applyIconOverridePrefix(
         iconClassesCopy[buttonName] = this.applyIconOverridePrefix(

+ 11 - 9
src/util.ts

@@ -301,7 +301,7 @@ export function isPrimaryMouseButton(ev) {
 
 
 
 
 export function getEvX(ev) {
 export function getEvX(ev) {
-  let touches = ev.originalEvent.touches
+  let touches = ev.touches
 
 
   // on mobile FF, pageX for touch events is present, but incorrect,
   // on mobile FF, pageX for touch events is present, but incorrect,
   // so, look at touch coordinates first.
   // so, look at touch coordinates first.
@@ -314,7 +314,7 @@ export function getEvX(ev) {
 
 
 
 
 export function getEvY(ev) {
 export function getEvY(ev) {
-  let touches = ev.originalEvent.touches
+  let touches = ev.touches
 
 
   // on mobile FF, pageX for touch events is present, but incorrect,
   // on mobile FF, pageX for touch events is present, but incorrect,
   // so, look at touch coordinates first.
   // so, look at touch coordinates first.
@@ -409,7 +409,7 @@ export function parseFieldSpecs(input) {
     tokens = input.split(/\s*,\s*/)
     tokens = input.split(/\s*,\s*/)
   } else if (typeof input === 'function') {
   } else if (typeof input === 'function') {
     tokens = [ input ]
     tokens = [ input ]
-  } else if ($.isArray(input)) {
+  } else if (Array.isArray(input)) {
     tokens = input
     tokens = input
   }
   }
 
 
@@ -476,7 +476,7 @@ export function flexibleCompare(a, b) {
   if (a == null) {
   if (a == null) {
     return 1
     return 1
   }
   }
-  if ($.type(a) === 'string' || $.type(b) === 'string') {
+  if (typeof a === 'string' || typeof b === 'string') {
     return String(a).localeCompare(String(b))
     return String(a).localeCompare(String(b))
   }
   }
   return a - b
   return a - b
@@ -729,7 +729,7 @@ export function hasOwnProp(obj, name) {
 
 
 
 
 export function applyAll(functions, thisObj, args) {
 export function applyAll(functions, thisObj, args) {
-  if ($.isFunction(functions)) {
+  if (typeof functions === 'function') { // supplied a single function
     functions = [ functions ]
     functions = [ functions ]
   }
   }
   if (functions) {
   if (functions) {
@@ -825,11 +825,12 @@ export function stripHtmlEntities(text) {
 export function cssToStr(cssProps) {
 export function cssToStr(cssProps) {
   let statements = []
   let statements = []
 
 
-  $.each(cssProps, function(name, val) {
+  for (let name in cssProps) {
+    let val = cssProps[name]
     if (val != null) {
     if (val != null) {
       statements.push(name + ':' + val)
       statements.push(name + ':' + val)
     }
     }
-  })
+  }
 
 
   return statements.join(';')
   return statements.join(';')
 }
 }
@@ -840,11 +841,12 @@ export function cssToStr(cssProps) {
 export function attrsToStr(attrs) {
 export function attrsToStr(attrs) {
   let parts = []
   let parts = []
 
 
-  $.each(attrs, function(name, val) {
+  for (let name in attrs) {
+    let val = attrs[name]
     if (val != null) {
     if (val != null) {
       parts.push(name + '="' + htmlEscape(val) + '"')
       parts.push(name + '="' + htmlEscape(val) + '"')
     }
     }
-  })
+  }
 
 
   return parts.join(' ')
   return parts.join(' ')
 }
 }

+ 22 - 0
src/util/object.ts

@@ -0,0 +1,22 @@
+
+export function assignTo(target, ...sources) {
+  for (let i = 0; i < sources.length; i++) {
+    let source = sources[i]
+    if (source != null) { // skip over if undefined or null
+      for (let key in source) {
+        // avoid bugs when hasOwnProperty is shadowed
+        if (Object.prototype.hasOwnProperty.call(source, key)) {
+          target[key] = source[key]
+        }
+      }
+    }
+  }
+  return target
+}
+
+export function isEmpty(obj) {
+  for (let _key in obj) {
+    return false
+  }
+  return true
+}