namespace DOM { export class Node { // DOM element this object controls Element: HTMLElement; // Optional DOM event handlers private _MouseDownEvent: DOMEvent; private _MouseUpEvent: DOMEvent; private _MouseMoveEvent: DOMEvent; private _ResizeEvent: DOMEvent; private _TouchStartEvent: DOMEvent; private _TouchEndEvent: DOMEvent; private _TouchCancelEvent: DOMEvent; private _TouchMoveEvent: DOMEvent; // ----- Constructor --------------------------------------------------------------- constructor(parameter: string | Element | Document | EventTarget) { // Take control of DOM objects if (parameter instanceof Element) { this.Element = parameter; } else if (parameter instanceof Document) { this.Element = parameter.documentElement; } else if (parameter instanceof EventTarget) { this.Element = parameter; } else if (typeof parameter === "string") { // Create a node from the provided HTML this.CreateFromHTML(parameter); } } // ----- Properties ---------------------------------------------------------------- // Absolute position of a HTML element on the page get AbsolutePosition() : int2 { // Recurse up through parents, summing offsets from their parents let pos = new int2(); for (let node = this.Element; node != null; node = node.offsetParent) { pos.x += node.offsetLeft; pos.y += node.offsetTop; } return pos; } set Position(position: int2) { this.Element.style.left = position.x.toString() + "px"; this.Element.style.top = position.y.toString() + "px"; } // HTML element size, including borders and padding get Size() : int2 { return new int2(this.Element.offsetWidth, this.Element.offsetHeight); } set Size(size: int2) { this.Element.style.width = size.x.toString() + "px"; this.Element.style.height = size.y.toString() + "px"; } // Rendering z-index, applied through CSS get ZIndex() : number { if (this.Element.style.zIndex.length) return parseInt(this.Element.style.zIndex); return null; } set ZIndex(z_index: number) { this.Element.style.zIndex = z_index.toString(); } // Set HTML element opacity through CSS style set Opacity(value: number) { this.Element.style.opacity = value.toString(); } // Set HTML element colour through CSS style set Colour(colour: string) { this.Element.style.color = colour; } set Cursor(cursor: string) { this.Element.style.cursor = cursor; } // Return the parent HTML node get Parent() : Node { if (this.Element.parentElement) return new Node(this.Element.parentElement); return null; } get ParentElement() : HTMLElement { return this.Element.parentElement; } // ----- Methods ------------------------------------------------------------------- // Check to see if a HTML element contains a class HasClass(class_name: string) : boolean { let regexp = new RegExp("\\b" + class_name + "\\b"); return regexp.test(this.Element.className); } // Remove a CSS class from a HTML element RemoveClass(class_name: string) { let regexp = new RegExp("\\b" + class_name + "\\b"); this.Element.className = this.Element.className.replace(regexp, ""); } // Add a CSS class to a HTML element, specified last AddClass(class_name: string) { if (!this.HasClass(class_name)) this.Element.className += " " + class_name; } Find(filter: string) : Node { var element = this.Element.querySelector(filter); if (element) return new DOM.Node(element); return null; } Append(node: Node) { this.Element.appendChild(node.Element); } Detach() { if (this.Element.parentNode) this.Element.parentNode.removeChild(this.Element); } Contains(node: Node) : boolean { while (node.Element != null && node.Element != this.Element) node = node.Parent; return node != null; } SetText(text: string) { this.Element.textContent = text; } // Create the HTML elements specified in the text parameter // Assumes there is only one root node in the text private CreateFromHTML(html: string) { // Prevent creation of superfluous text nodes html = html.trim(); // Create a temporary template to apply the HTML to let template = document.createElement("template"); template.innerHTML = html; this.Element = template.content.firstElementChild; } // ----- Events -------------------------------------------------------------------- // All event objects get created on-demand get MouseDownEvent() : DOMEvent { this._MouseDownEvent = this._MouseDownEvent || new DOMEvent(this.Element, "mousedown"); return this._MouseDownEvent; } get MouseUpEvent() : DOMEvent { this._MouseUpEvent = this._MouseUpEvent || new DOMEvent(this.Element, "mouseup"); return this._MouseUpEvent; } get MouseMoveEvent() : DOMEvent { this._MouseMoveEvent = this._MouseMoveEvent || new DOMEvent(this.Element, "mousemove"); return this._MouseMoveEvent; } get ResizeEvent() : DOMEvent { this._ResizeEvent = this._ResizeEvent || new DOMEvent(window, "resize"); return this._ResizeEvent; } get TouchStartEvent() : DOMEvent { this._TouchStartEvent = this._TouchStartEvent || new DOMEvent(this.Element, "touchstart"); return this._TouchStartEvent; } get TouchEndEvent() : DOMEvent { this._TouchEndEvent = this._TouchEndEvent || new DOMEvent(this.Element, "touchend"); return this._TouchEndEvent; } get TouchCancelEvent() : DOMEvent { this._TouchCancelEvent = this._TouchCancelEvent || new DOMEvent(this.Element, "touchcancel"); return this._TouchCancelEvent; } get TouchMoveEvent() : DOMEvent { this._TouchMoveEvent = this._TouchMoveEvent || new DOMEvent(this.Element, "touchmove"); return this._TouchMoveEvent; } }; } function $(parameter: string | Element | Document | EventTarget) { if (typeof parameter == "string") return new DOM.Node(document.querySelector(parameter)); return new DOM.Node(parameter); }