Adam Shaw 8 лет назад
Родитель
Сommit
9278d8e91c
4 измененных файлов с 78 добавлено и 30 удалено
  1. 3 3
      src/basic/DayGrid.ts
  2. 8 11
      src/common/Popover.ts
  3. 8 1
      src/exports.ts
  4. 59 15
      src/util/dom.ts

+ 3 - 3
src/basic/DayGrid.ts

@@ -493,7 +493,7 @@ export default class DayGrid extends InteractiveDateComponent {
     let totalSegsBelow // total number of segments below `seg` in any of the columns `seg` occupies
     let colSegsBelow // array of segment arrays, below seg, one for each column (offset from segs's first column)
     let td: HTMLTableCellElement
-    let rowspan
+    let rowSpan
     let segMoreNodes // array of "more" <td> cells that will stand-in for the current seg's cell
     let j
     let moreTd: HTMLTableCellElement
@@ -544,12 +544,12 @@ export default class DayGrid extends InteractiveDateComponent {
 
         if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
           td = cellMatrix[levelLimit - 1][seg.leftCol] // the segment's parent cell
-          rowspan = td.rowSpan || 1
+          rowSpan = td.rowSpan || 1
           segMoreNodes = []
 
           // make a replacement <td> for each column the segment occupies. will be one for each colspan
           for (j = 0; j < colSegsBelow.length; j++) {
-            moreTd = makeElement('td', { className: 'fc-more-cell', rowSpan: rowspan }) as HTMLTableCellElement
+            moreTd = makeElement('td', { className: 'fc-more-cell', rowSpan }) as HTMLTableCellElement
             segsBelow = colSegsBelow[j]
             moreLink = this.renderMoreLink(
               row,

+ 8 - 11
src/common/Popover.ts

@@ -15,7 +15,7 @@ Options:
 
 import * as $ from 'jquery'
 import { getScrollParent } from '../util'
-import { listenViaDelegation, appendContentTo, ElementContent, removeElement } from '../util/dom'
+import { listenViaDelegation, ElementContent, removeElement, makeElement } from '../util/dom'
 import { default as ListenerMixin, ListenerInterface } from './ListenerMixin'
 
 export interface PopoverOptions {
@@ -72,16 +72,13 @@ export default class Popover {
   // Creates `this.el` and renders content inside of it
   render() {
     let options = this.options
-
-    let el = this.el = document.createElement('div')
-    el.classList.add('fc-popover')
-    if (options.className) {
-      el.classList.add(options.className)
-    }
-    el.style.top = '0'
-    el.style.left = '0'
-
-    appendContentTo(el, options.content)
+    let el = this.el = makeElement('div', {
+      className: 'fc-popover ' + (options.className || ''),
+      style: {
+        top: '0',
+        left: '0'
+      }
+    }, options.content)
 
     options.parentEl.appendChild(el)
 

+ 8 - 1
src/exports.ts

@@ -45,7 +45,14 @@ export {
 } from './util/object'
 
 export {
-  findElsWithin
+  findElsWithin,
+  htmlToElement,
+  makeElement,
+  insertAfterEl,
+  prependWithinEl,
+  removeElement,
+  listenViaDelegation,
+  appendContentTo
 } from './util/dom'
 
 export {

+ 59 - 15
src/util/dom.ts

@@ -1,11 +1,15 @@
+import { assignTo } from '../util/object'
 
 // TODO: use in other places
+// TODO: rename to createElement
 export function makeElement(tagName, attrs, content?): HTMLElement {
   let el: HTMLElement = document.createElement(tagName)
 
   if (attrs) {
     for (let attrName in attrs) {
-      if (attrName === 'className' || attrName === 'colSpan' || attrName === 'rowSpan') {
+      if (attrName === 'style') {
+        assignTo(el.style, attrs[attrName])
+      } else if (attrName === 'className' || attrName === 'colSpan' || attrName === 'rowSpan') { // TODO: do hash
         el[attrName] = attrs[attrName]
       } else {
         el.setAttribute(attrName, attrs[attrName])
@@ -13,22 +17,19 @@ export function makeElement(tagName, attrs, content?): HTMLElement {
     }
   }
 
-  appendContentTo(el, content)
+  if (content != null) {
+    appendContentTo(el, content)
+  }
 
   return el
 }
 
-export type ElementContent = string | Node | Node[]
+export type ElementContent = string | Node | NodeList | Node[]
 
 export function appendContentTo(el: HTMLElement, content: ElementContent) {
-  if (typeof content === 'string') {
-    el.innerHTML = content
-  } else if (content instanceof Node) {
-    el.appendChild(content)
-  } else if (content && content.length) {
-    for (let i = 0; i < content.length; i++) {
-      el.appendChild(content[i])
-    }
+  let childNodes = normalizeContent(content)
+  for (let i = 0; i < childNodes.length; i++) {
+    el.appendChild(childNodes[i])
   }
 }
 
@@ -44,6 +45,7 @@ export function htmlToElements(htmlString): HTMLElement {
   return Array.prototype.slice.call(div.childNodes)
 }
 
+// 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) {
@@ -55,10 +57,22 @@ export function listenViaDelegation(container: HTMLElement, eventType, childClas
   })
 }
 
-export function findElsWithin(container: HTMLElement, selector: string): HTMLElement[] {
-  return Array.prototype.slice.call(
-    container.querySelectorAll(selector)
-  )
+// TODO: user new signature in other places
+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) {
@@ -66,3 +80,33 @@ export function removeElement(el: HTMLElement) {
     el.parentNode.removeChild(el)
   }
 }
+
+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
+}