Adam Shaw 8 anos atrás
pai
commit
365446eef3

+ 3 - 3
src/Calendar.ts

@@ -1,6 +1,6 @@
 import * as moment from 'moment'
 import { capitaliseFirstLetter, debounce } from './util'
-import { listenBySelector, toggleClassName, makeElement, removeElement, applyStyle, prependWithinEl, computeHeightAndMargins } from './util/dom'
+import { listenBySelector, makeElement, removeElement, applyStyle, prependWithinEl, computeHeightAndMargins } from './util/dom'
 import { globalDefaults, englishDefaults, rtlDefaults } from './options'
 import Iterator from './common/Iterator'
 import GlobalEmitter from './common/GlobalEmitter'
@@ -384,8 +384,8 @@ export default class Calendar {
     // called immediately, and upon option change.
     // HACK: locale often affects isRTL, so we explicitly listen to that too.
     this.optionsManager.watch('applyingDirClasses', [ '?isRTL', '?locale' ], (opts) => {
-      toggleClassName(el, 'fc-ltr', !opts.isRTL)
-      toggleClassName(el, 'fc-rtl', opts.isRTL)
+      el.classList.toggle('fc-ltr', !opts.isRTL)
+      el.classList.toggle('fc-rtl', opts.isRTL)
     })
 
     prependWithinEl(el, this.contentEl = makeElement('div', { className: 'fc-view-container' }))

+ 3 - 6
src/basic/DayGrid.ts

@@ -12,7 +12,7 @@ import { default as DayTableMixin, DayTableInterface } from '../component/DayTab
 import DayGridEventRenderer from './DayGridEventRenderer'
 import DayGridHelperRenderer from './DayGridHelperRenderer'
 import DayGridFillRenderer from './DayGridFillRenderer'
-import { makeElement, htmlToElements, findElsWithin, removeElement } from '../util/dom'
+import { makeElement, htmlToElements, findElsWithin, removeElement, queryChildren } from '../util/dom'
 
 
 /* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.
@@ -458,7 +458,7 @@ export default class DayGrid extends InteractiveDateComponent {
   computeRowLevelLimit(row): (number | false) {
     let rowEl = this.rowEls[row] // the containing "fake" row div
     let rowBottom = rowEl.getBoundingClientRect().bottom
-    let trEls: HTMLTableRowElement[] = this.eventRenderer.rowStructs[row].tbodyEl.childNodes
+    let trEls = queryChildren(this.eventRenderer.rowStructs[row].tbodyEl) as HTMLTableRowElement[]
     let i
     let trEl: HTMLTableRowElement
 
@@ -518,10 +518,7 @@ export default class DayGrid extends InteractiveDateComponent {
       levelSegs = rowStruct.segLevels[levelLimit - 1]
       cellMatrix = rowStruct.cellMatrix
 
-      limitedNodes = Array.prototype.slice.call( // get level <tr> elements past the limit
-        rowStruct.tbodyEl.childNodes,
-        levelLimit
-      )
+      limitedNodes = queryChildren(rowStruct.tbodyEl).slice(levelLimit) // get level <tr> elements past the limit
       limitedNodes.forEach(function(node) {
         node.classList.add('fc-limited') // hide elements and get a simple DOM-nodes array
       })

+ 2 - 2
src/common/Popover.ts

@@ -14,7 +14,7 @@ Options:
 */
 
 import { getScrollParent } from '../util'
-import { listenViaDelegation, ElementContent, removeElement, makeElement } from '../util/dom'
+import { listenBySelector, ElementContent, removeElement, makeElement } from '../util/dom'
 import { default as ListenerMixin, ListenerInterface } from './ListenerMixin'
 
 export interface PopoverOptions {
@@ -82,7 +82,7 @@ export default class Popover {
     options.parentEl.appendChild(el)
 
     // when a click happens on anything inside with a 'fc-close' className, hide the popover
-    listenViaDelegation(el, 'click', 'fc-close', (ev) => {
+    listenBySelector(el, 'click', '.fc-close', (ev) => {
       this.hide()
     })
 

+ 1 - 1
src/component/Component.ts

@@ -21,7 +21,7 @@ export default class Component extends Model {
 
     removeElement(this.el)
     // NOTE: don't null-out this.el in case the View was destroyed within an API callback.
-    // We don't null-out the View's other jQuery element references upon destroy,
+    // We don't null-out the View's other element references upon destroy,
     //  so we shouldn't kill this.el either.
   }
 

+ 1 - 1
src/component/DateComponent.ts

@@ -531,7 +531,7 @@ export default abstract class DateComponent extends Component {
 
 
   // Given position-level information about a date-related area within the grid,
-  // should return a jQuery element that best represents it. passed to dayClick callback.
+  // should return an element that best represents it. passed to dayClick callback.
   getHitEl(hit): HTMLElement | null {
     return null
   }

+ 2 - 2
src/exports.ts

@@ -49,10 +49,10 @@ export {
   insertAfterEl,
   prependWithinEl,
   removeElement,
-  listenViaDelegation,
+  listenBySelector,
   appendContentTo,
-  toggleClassName,
   applyStyle,
+  applyStyleProp,
   computeHeightAndMargins,
   elementMatches,
   queryChild,

+ 125 - 135
src/util/dom.ts

@@ -1,46 +1,11 @@
 
-
-// TODO: search for .childNodes
-export function queryChildren(parent: HTMLElement, selector?: string): HTMLElement[] {
-  let childNodes = parent.childNodes
-  let a = []
-
-  for (let i = 0; i < childNodes.length; i++) {
-    let childNode = childNodes[i]
-    if (
-      childNode.nodeType === 1 && // an element
-      (!selector || elementMatches(childNode as HTMLElement, selector))
-    ) {
-      a.push(childNode)
-    }
-  }
-
-  return a
-}
-
-export function queryChild(parent: HTMLElement, selector?: string): HTMLElement | null {
-  let childNodes = parent.childNodes
-
-  for (let i = 0; i < childNodes.length; i++) {
-    let childNode = childNodes[i]
-    if (
-      childNode.nodeType === 1 && // an element
-      (!selector || elementMatches(childNode as HTMLElement, selector))
-    ) {
-      return childNode as HTMLElement
-    }
-  }
-
-  return null
-}
-
-
-
-
-
 // TODO: util for animation end
 // TODO: get straight the distinction between HTMLElement and Element
 
+
+// Creating
+// ----------------------------------------------------------------------------------------------------------------
+
 // TODO: use in other places
 // TODO: rename to createElement
 export function makeElement(tagName, attrs, content?): HTMLElement {
@@ -67,39 +32,6 @@ export function makeElement(tagName, attrs, content?): HTMLElement {
   return el
 }
 
-const PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i
-
-// find other places to do this
-export function applyStyle(el: HTMLElement, props: object | string, propVal?: any) {
-  if (typeof props === 'object') {
-    for (let propName in props) {
-      applyStyleProp(el, propName, props[propName])
-    }
-  } else if (typeof props === 'string') {
-    applyStyleProp(el, props, propVal)
-  }
-}
-
-// TODO: just expose this?
-function applyStyleProp(el, name, val) {
-  if (val == null) {
-    el.style[name] = ''
-  } else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
-    el.style[name] = val + 'px'
-  } else {
-    el.style[name] = val
-  }
-}
-
-export type ElementContent = string | Node | NodeList | Node[]
-
-export function appendContentTo(el: HTMLElement, content: ElementContent) {
-  let childNodes = normalizeContent(content)
-  for (let i = 0; i < childNodes.length; i++) {
-    el.appendChild(childNodes[i])
-  }
-}
-
 export function htmlToElement(htmlString): HTMLElement {
   htmlString = htmlString.trim()
   let container = document.createElement(computeContainerTag(htmlString))
@@ -129,18 +61,58 @@ function computeContainerTag(html: string) {
 }
 
 
-// TODO: rename to listenByClassName
-export function listenViaDelegation(container: HTMLElement, eventType, childClassName, handler) {
-  container.addEventListener(eventType, function(ev: Event) {
-    for (let node = ev.target as HTMLElement; node !== container; node = node.parentNode as HTMLElement) {
-      if (node.classList.contains(childClassName)) {
-        handler.call(node, ev)
-        break
-      }
-    }
-  })
+// Inserting / Removing
+// ----------------------------------------------------------------------------------------------------------------
+
+export type ElementContent = string | Node | NodeList | Node[]
+
+export function appendContentTo(el: HTMLElement, content: ElementContent) {
+  let childNodes = normalizeContent(content)
+  for (let i = 0; i < childNodes.length; i++) {
+    el.appendChild(childNodes[i])
+  }
+}
+
+export function prependWithinEl(parent: HTMLElement, content: ElementContent) {
+  let newEls = normalizeContent(content)
+  let afterEl = parent.firstChild || null // if no firstChild, will append to end, but that's okay, b/c there were no children
+
+  for (let i = 0; i < newEls.length; i++) {
+    parent.insertBefore(newEls[i], afterEl)
+  }
+}
+
+export function insertAfterEl(refEl: HTMLElement, content: ElementContent) {
+  let newEls = normalizeContent(content)
+  let afterEl = refEl.nextSibling || null
+
+  for (let i = 0; i < newEls.length; i++) {
+    refEl.parentNode.insertBefore(newEls[i], afterEl)
+  }
+}
+
+function normalizeContent(content: ElementContent): NodeList | Node[] {
+  let els
+  if (typeof content === 'string') {
+    els = htmlToElements(content) // TODO: optimization, htmlToNodeList
+  } else if (content instanceof Node) {
+    els = [ content ]
+  } else { // assumed to be HTMLElement[]
+    els = content
+  }
+  return els
+}
+
+export function removeElement(el: HTMLElement) {
+  if (el.parentNode) {
+    el.parentNode.removeChild(el)
+  }
 }
 
+
+// Querying
+// ----------------------------------------------------------------------------------------------------------------
+
 // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
 const matchesMethod =
   Element.prototype.matches ||
@@ -172,6 +144,61 @@ export function elementMatches(el: HTMLElement, selector: string) {
   return matchesMethod.call(el, selector)
 }
 
+// TODO: user new signature in other places
+// this is only func that accepts array :(
+export function findElsWithin(containers: HTMLElement[] | HTMLElement, selector: string): HTMLElement[] {
+  if (containers instanceof HTMLElement) {
+    containers = [ containers ]
+  }
+  let allChildEls: HTMLElement[] = []
+
+  for (let i = 0; i < containers.length; i++) {
+    let childEls = containers[i].querySelectorAll(selector)
+    for (let j = 0; j < childEls.length; j++) {
+      allChildEls.push(childEls[j] as HTMLElement)
+    }
+  }
+
+  return allChildEls
+}
+
+export function queryChildren(parent: HTMLElement, selector?: string): HTMLElement[] {
+  let childNodes = parent.childNodes
+  let a = []
+
+  for (let i = 0; i < childNodes.length; i++) {
+    let childNode = childNodes[i]
+    if (
+      childNode.nodeType === 1 && // an element
+      (!selector || elementMatches(childNode as HTMLElement, selector))
+    ) {
+      a.push(childNode)
+    }
+  }
+
+  return a
+}
+
+export function queryChild(parent: HTMLElement, selector?: string): HTMLElement | null {
+  let childNodes = parent.childNodes
+
+  for (let i = 0; i < childNodes.length; i++) {
+    let childNode = childNodes[i]
+    if (
+      childNode.nodeType === 1 && // an element
+      (!selector || elementMatches(childNode as HTMLElement, selector))
+    ) {
+      return childNode as HTMLElement
+    }
+  }
+
+  return null
+}
+
+
+// Event Delegation
+// ----------------------------------------------------------------------------------------------------------------
+
 export function listenBySelector(
   container: HTMLElement,
   eventType: string,
@@ -217,68 +244,31 @@ export function listenToHoverBySelector(
 }
 
 
-// TODO: user new signature in other places
-// this is only func that accepts array :(
-export function findElsWithin(containers: HTMLElement[] | HTMLElement, selector: string): HTMLElement[] {
-  if (containers instanceof HTMLElement) {
-    containers = [ containers ]
-  }
-  let allChildEls: HTMLElement[] = []
-
-  for (let i = 0; i < containers.length; i++) {
-    let childEls = containers[i].querySelectorAll(selector)
-    for (let j = 0; j < childEls.length; j++) {
-      allChildEls.push(childEls[j] as HTMLElement)
-    }
-  }
-
-  return allChildEls
-}
-
-export function removeElement(el: HTMLElement) {
-  if (el.parentNode) {
-    el.parentNode.removeChild(el)
-  }
-}
+// Style
+// ----------------------------------------------------------------------------------------------------------------
 
-export function prependWithinEl(parent: HTMLElement, content: ElementContent) {
-  let newEls = normalizeContent(content)
-  let afterEl = parent.firstChild || null // if no firstChild, will append to end, but that's okay, b/c there were no children
+const PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i
 
-  for (let i = 0; i < newEls.length; i++) {
-    parent.insertBefore(newEls[i], afterEl)
+// find other places to do this
+export function applyStyle(el: HTMLElement, props: object, propVal?: any) {
+  for (let propName in props) {
+    applyStyleProp(el, propName, props[propName])
   }
 }
 
-export function insertAfterEl(refEl: HTMLElement, content: ElementContent) {
-  let newEls = normalizeContent(content)
-  let afterEl = refEl.nextSibling || null
-
-  for (let i = 0; i < newEls.length; i++) {
-    refEl.parentNode.insertBefore(newEls[i], afterEl)
+export function applyStyleProp(el: HTMLElement, name: string, val) {
+  if (val == null) {
+    el.style[name] = ''
+  } else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
+    el.style[name] = val + 'px'
+  } else {
+    el.style[name] = val
   }
 }
 
-function normalizeContent(content: ElementContent): NodeList | Node[] {
-  let els
-  if (typeof content === 'string') {
-    els = htmlToElements(content) // TODO: optimization, htmlToNodeList
-  } else if (content instanceof Node) {
-    els = [ content ]
-  } else { // assumed to be HTMLElement[]
-    els = content
-  }
-  return els
-}
 
-// TODO: switch to tokenList.toggle
-export function toggleClassName(el, className, bool) {
-  if (bool) {
-    el.classList.add(className)
-  } else {
-    el.classList.remove(className)
-  }
-}
+// Dimensions
+// ----------------------------------------------------------------------------------------------------------------
 
 export function computeHeightAndMargins(el: HTMLElement) {
   let computed = window.getComputedStyle(el)