Overview

Namespaces

  • Tokamak
    • Dom

Classes

  • Tokamak\Dom\Component
  • Tokamak\Dom\Document
  • Tokamak\Dom\Element
  • Tokamak\Dom\HTMLDocument
  • Tokamak\Dom\Node
  • Overview
  • Namespace
  • Class
 1: <?php
 2: namespace Tokamak\Dom;
 3: use DOMDocument;
 4: use DOMNode;
 5: use Closure;
 6: 
 7: /**
 8:  * Class Component
 9:  * @package Tokamak\Dom
10:  * A component is a reusable/composable template for a DOM subtree.
11:  * Could be used to define a widget, page partial, etc. It behaves
12:  * slightly differently from an Element in that it can have multiple
13:  * elements at its top level; i.e., it has no explicit root node.
14:  * When a component is appended to an element, its top-level elements
15:  * are all added to the parent element.
16:  * If a component is appended to another component,
17:  * its top-level elements become siblings to the other component's,
18:  * effectively merging the two components and appending them to a common parent.
19:  * @todo: add selectors to make it easy to access descendant nodes within a component.
20:  */
21: abstract class Component extends Node {
22: 
23:     /**
24:      * @var array the data that is passed into the component
25:      */
26:     protected $data;
27: 
28:     /**
29:      * @var DOMNode;
30:      */
31:     protected $parentNode;
32: 
33:     /**
34:      * Accepts array of data/state and builds the component's
35:      * DOM structure via the implemented render method.
36:      * @param DOMDocument $dom  The ancestor DOMDocument instance.
37:      * @param array $data       Array of arbitrarty data/state passed to the component.
38:      */
39:     public function __construct(DOMDocument $dom, array $data = null){
40:         $this->dom = $dom;
41:         $this->data = $data;
42: 
43:         $this->render();
44:     }
45: 
46:     /**
47:      * Since a Component can have multiple top-level elements,
48:      * the semantics of "appending" are ambiguous. In this implementation,
49:      * calling "append" on a component instance will append a node to
50:      * the parent element as a sibling after this component.
51:      * @param Node $child
52:      * @return Node
53:      */
54:     public function append(Node $child){
55:         while($child->hasDomNodes()){
56:             if(isset($this->parentNode)){
57:                 // Component has already rendered, and append is being called
58:                 // as part of a chained method call. Append node(s) directly
59:                 // to parent element's DOMNode.
60:                 $this->parentNode->appendChild($child->getDomNode());
61:             } else {
62:                 // Add the dom nodes to the queue for the parent element to append.
63:                 $this->addDomNode($child->getDomNode());
64:             }
65:             if(isset($callback)){
66:                 $child->renderCallback($callback);
67:             }
68:         }
69: 
70:         return $child;
71:     }
72: 
73:     /**
74:      * Set a parent DOMNode.
75:      * Once this instance has already been appended by its parent,
76:      * any subsequent chained method calls to append must be
77:      * appended directly to the parent's underlying DOMNode.
78:      * @param DOMNode $parent
79:      */
80:     public function setParentNode(DOMNode $parent){
81:         $this->parentNode = $parent;
82:     }
83: 
84: }
API documentation generated by ApiGen