Last active
August 29, 2015 14:19
-
-
Save madx/c2d009d1d92be7bd38b7 to your computer and use it in GitHub Desktop.
Component class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {isObject} from "./utils" | |
import Dispatcher from "./dispatcher" | |
export default class Component { | |
constructor() { | |
this.rootNode = null | |
this.props = {} | |
// Add dispatcher observers | |
if (this.constructor.observers) { | |
const observers = this.constructor.observers | |
for (let eventName in observers) { | |
const methodName = observers[eventName] | |
Dispatcher.addObserver(eventName, this, methodName) | |
} | |
} | |
} | |
destroy() { | |
if (this.rootNode.parentNode) { | |
this.rootNode.parentNode.removeChild(this.rootNode) | |
} | |
// Remove dispatcher observers | |
const observers = this.constructor.observers | |
if (observers) { | |
for (let eventName in observers) { | |
Dispatcher.removeObserver(eventName, this) | |
} | |
} | |
} | |
// Define an updatable property of the component. | |
// Also updates the property if it's already set | |
prop(propName, propValue = "") { | |
let propNode = this.props[propName] | |
if (!propNode) { | |
propNode = this.props[propName] = document.createTextNode(propValue) | |
} | |
if (propValue !== propNode.textContent) { | |
propNode.textContent = propValue | |
} | |
return propNode | |
} | |
render() { | |
if (this.rootNode) { | |
throw new Error("already rendered component") | |
} | |
if (!this.build) { | |
throw new Error("unimplemented method build()") | |
} | |
this.rootNode = this.build() | |
// Add DOM event handlers | |
const eventHandlers = this.constructor.eventHandlers | |
if (eventHandlers) { | |
for (let eventName in eventHandlers) { | |
const handler = eventHandlers[eventName] | |
this.rootNode.addEventListener(eventName, handler.bind(this), true) | |
} | |
} | |
return this.rootNode | |
} | |
show() { | |
this.rootNode.classList.toggle("u-hidden", false) | |
} | |
hide() { | |
this.rootNode.classList.toggle("u-hidden", true) | |
} | |
toggle() { | |
console.warn("hello", this.rootNode) | |
this.rootNode.classList.toggle("u-hidden") | |
} | |
static tag(tagSpec, attributes, children) { | |
if (!tagSpec) { | |
throw new Error("No tagSpec given") | |
} | |
attributes = attributes || {} | |
children = children || [] | |
if (!isObject(attributes)) { | |
children = attributes | |
attributes = {} | |
} | |
const [tagName, className] = tagSpec.split(".") | |
const node = document.createElement(tagName) | |
if (className) { | |
node.classList.add(className) | |
} | |
if (!(children instanceof Array)) { | |
children = [children] | |
} | |
for (let attrName in attributes) { | |
node.setAttribute(attrName, attributes[attrName]) | |
} | |
for (let child of children) { | |
if (typeof child === "object" && "render" in child) { | |
// Component children | |
child.render() | |
node.appendChild(child.rootNode) | |
} else if (typeof child === "string") { | |
// Text children | |
node.appendChild(document.createTextNode(child)) | |
} else { | |
// DOM nodes children | |
node.appendChild(child) | |
} | |
} | |
return node | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment