mirror of
https://github.com/Mibew/CanteenHTML5.git
synced 2024-11-15 00:34:11 +03:00
Fix code styling
This commit is contained in:
parent
7bdec8e106
commit
9f7340ec78
@ -1,57 +1,55 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
include '../src/HTML5.php';
|
include '../src/HTML5.php';
|
||||||
use Canteen\HTML5\HTML5;
|
use Canteen\HTML5\HTML5;
|
||||||
|
|
||||||
HTML5::autoload(); // Autoload the classes, helpful if using outside composer
|
HTML5::autoload(); // Autoload the classes, helpful if using outside composer
|
||||||
HTML5::useGlobal(); // if you want to use the global html() method instead of namespaced one
|
HTML5::useGlobal(); // if you want to use the global html() method instead of namespaced one
|
||||||
|
|
||||||
use Canteen\HTML5\Document;
|
|
||||||
use Canteen\HTML5\SimpleList;
|
|
||||||
use Canteen\HTML5\Table;
|
|
||||||
|
|
||||||
// Create a new document
|
|
||||||
$doc = new Document('Test Document');
|
|
||||||
$doc->beautify = true;
|
|
||||||
|
|
||||||
// Add a link to the page
|
|
||||||
$link = html('a#google.external rel=external', 'Link', 'class="test something" target=blank rel=test');
|
|
||||||
$link->href = 'http://google.com';
|
|
||||||
$link->onclick = "return confirm('Navigate away?');";
|
|
||||||
$link->appendTo($doc->body);
|
|
||||||
|
|
||||||
// Create an unordered list for an array of items
|
|
||||||
// the array can be other html elements or text
|
|
||||||
$list = new SimpleList(
|
|
||||||
array(
|
|
||||||
html('b', 'first'),
|
|
||||||
'second',
|
|
||||||
'third',
|
|
||||||
array(
|
|
||||||
'sub-third',
|
|
||||||
'sub-forth'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$list->appendTo($doc->body);
|
|
||||||
|
|
||||||
// Create a sample table with some rows of dummy data
|
|
||||||
$table = new Table(
|
|
||||||
array(
|
|
||||||
array('id'=>1, 'first'=>'James', 'last'=>'Smith'),
|
|
||||||
array('id'=>2, 'first'=>'Mary', 'last'=>'Denver'),
|
|
||||||
array('id'=>3, 'first'=>'Charlie', 'last'=>'Rose')
|
|
||||||
),
|
|
||||||
array('ID', 'First Name', 'Last Name')
|
|
||||||
);
|
|
||||||
|
|
||||||
// We'll set some of the table properties
|
|
||||||
$table->style = 'border:1px solid black';
|
|
||||||
$table->border = 0;
|
|
||||||
$table->id = 'people';
|
|
||||||
$table->appendTo($doc->body);
|
|
||||||
|
|
||||||
// Output the result formatted nice with indents
|
|
||||||
echo $doc;
|
|
||||||
|
|
||||||
?>
|
use Canteen\HTML5\Document;
|
||||||
|
use Canteen\HTML5\SimpleList;
|
||||||
|
use Canteen\HTML5\Table;
|
||||||
|
|
||||||
|
// Create a new document
|
||||||
|
$doc = new Document('Test Document');
|
||||||
|
$doc->beautify = true;
|
||||||
|
|
||||||
|
// Add a link to the page
|
||||||
|
$link = html('a#google.external rel=external', 'Link', 'class="test something" target=blank rel=test');
|
||||||
|
$link->href = 'http://google.com';
|
||||||
|
$link->onclick = "return confirm('Navigate away?');";
|
||||||
|
$link->appendTo($doc->body);
|
||||||
|
|
||||||
|
// Create an unordered list for an array of items
|
||||||
|
// the array can be other html elements or text
|
||||||
|
$list = new SimpleList(
|
||||||
|
array(
|
||||||
|
html('b', 'first'),
|
||||||
|
'second',
|
||||||
|
'third',
|
||||||
|
array(
|
||||||
|
'sub-third',
|
||||||
|
'sub-forth'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$list->appendTo($doc->body);
|
||||||
|
|
||||||
|
// Create a sample table with some rows of dummy data
|
||||||
|
$table = new Table(
|
||||||
|
array(
|
||||||
|
array('id'=>1, 'first'=>'James', 'last'=>'Smith'),
|
||||||
|
array('id'=>2, 'first'=>'Mary', 'last'=>'Denver'),
|
||||||
|
array('id'=>3, 'first'=>'Charlie', 'last'=>'Rose')
|
||||||
|
),
|
||||||
|
array('ID', 'First Name', 'Last Name')
|
||||||
|
);
|
||||||
|
|
||||||
|
// We'll set some of the table properties
|
||||||
|
$table->style = 'border:1px solid black';
|
||||||
|
$table->border = 0;
|
||||||
|
$table->id = 'people';
|
||||||
|
$table->appendTo($doc->body);
|
||||||
|
|
||||||
|
// Output the result formatted nice with indents
|
||||||
|
echo $doc;
|
||||||
|
@ -1,170 +1,176 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* An HTML attribute used on the Node, this is used internally.
|
* An HTML attribute used on the Node, this is used internally.
|
||||||
* Do not initiate this class directly, use the `html()` function
|
* Do not initiate this class directly, use the `html()` function
|
||||||
* to create attributes on elements.
|
* to create attributes on elements.
|
||||||
*
|
*
|
||||||
* echo html('a', 'Link', 'class=button href="about.html"');
|
* echo html('a', 'Link', 'class=button href="about.html"');
|
||||||
*
|
*
|
||||||
* echo html('a', 'Link')
|
* echo html('a', 'Link')
|
||||||
* ->setAttribute('class', 'button')
|
* ->setAttribute('class', 'button')
|
||||||
* ->setAttribute('href', 'about.html');
|
* ->setAttribute('href', 'about.html');
|
||||||
*
|
*
|
||||||
* @class Attribute
|
* @class Attribute
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} [name=null] The name of the attribute
|
* @param {String} [name=null] The name of the attribute
|
||||||
* @param {String} [value=null] The value of the attribute
|
* @param {String} [value=null] The value of the attribute
|
||||||
*/
|
*/
|
||||||
class Attribute
|
class Attribute
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The name of the attribute
|
* The name of the attribute
|
||||||
* @property {String} _name
|
* @property {String} _name
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private $_name;
|
private $_name;
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the attribute
|
|
||||||
* @property {String} _value
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
private $_value;
|
|
||||||
|
|
||||||
public function __construct($name = null, $value = null)
|
/**
|
||||||
{
|
* The value of the attribute
|
||||||
$this->name = $name;
|
* @property {String} _value
|
||||||
$this->value = $value;
|
* @private
|
||||||
}
|
*/
|
||||||
|
private $_value;
|
||||||
|
|
||||||
/**
|
public function __construct($name = null, $value = null)
|
||||||
* Convert the attribute to an HTML tag attribute string
|
{
|
||||||
* @method __toString
|
$this->name = $name;
|
||||||
* @return {String} String representation of attribute
|
$this->value = $value;
|
||||||
*/
|
}
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return " " . $this->_name . "=\"" . $this->_value . "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of this attribute
|
* Convert the attribute to an HTML tag attribute string
|
||||||
* @method getName
|
* @method __toString
|
||||||
* @return {String} The attribute's name
|
* @return {String} String representation of attribute
|
||||||
*/
|
*/
|
||||||
public function getName()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return $this->_name;
|
return " " . $this->_name . "=\"" . $this->_value . "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of this attribute, cannot be empty
|
* Get the name of this attribute
|
||||||
* @method setName
|
* @method getName
|
||||||
* @param {String} [name=null] The name of the attribute
|
* @return {String} The attribute's name
|
||||||
*/
|
*/
|
||||||
public function setName($name = null)
|
public function getName()
|
||||||
{
|
{
|
||||||
if (is_null($name) || empty($name))
|
return $this->_name;
|
||||||
{
|
}
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
|
|
||||||
}
|
|
||||||
$this->_name = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of this attribute
|
|
||||||
* @method getValue
|
|
||||||
* @protected
|
|
||||||
* @return {String} The value of attribute
|
|
||||||
*/
|
|
||||||
protected function getValue()
|
|
||||||
{
|
|
||||||
return $this->_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of this attribute, this cannot be empty
|
* Set the name of this attribute, cannot be empty
|
||||||
* @method setValue
|
* @method setName
|
||||||
* @protected
|
* @param {String} [name=null] The name of the attribute
|
||||||
* @param {String} value The value to set
|
*/
|
||||||
*/
|
public function setName($name = null)
|
||||||
protected function setValue($value)
|
{
|
||||||
{
|
if (is_null($name) || empty($name))
|
||||||
$this->_value = $value;
|
{
|
||||||
}
|
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
/**
|
$this->_name = $name;
|
||||||
* Convert a string into an associative array
|
}
|
||||||
* @method shorthand
|
|
||||||
* @static
|
|
||||||
* @param {String} str The string, delineated by semicolons, and colons for attributes:values
|
|
||||||
* @return {Dictionary} The collection of attributes
|
|
||||||
*/
|
|
||||||
static public function shorthand($str)
|
|
||||||
{
|
|
||||||
$res = array();
|
|
||||||
|
|
||||||
// Match the name=value in the attributes string
|
|
||||||
preg_match_all('/([a-z]+[a-z\-]*)\=("[^\"]*"|\'[^\']*\'|[^\s\"\']*)/',$str, $arr);
|
|
||||||
|
|
||||||
foreach($arr[1] as $i=>$name)
|
|
||||||
{
|
|
||||||
$value = $arr[2][$i];
|
|
||||||
|
|
||||||
// Remove containing quotes if present
|
|
||||||
if (preg_match('/^[\'\"][^\n]*[\'\"]$/', $value))
|
|
||||||
{
|
|
||||||
$value = substr($value, 1, -1);
|
|
||||||
}
|
|
||||||
$res[$name] = $value;
|
|
||||||
}
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* General purpose getter for getting attribute->name and attribute->value
|
|
||||||
* @public __get
|
|
||||||
* @param {String} name The name of the property to get
|
|
||||||
*/
|
|
||||||
public function __get($name)
|
|
||||||
{
|
|
||||||
if (method_exists($this , $method =('get' . ucfirst($name))))
|
|
||||||
return $this->$method();
|
|
||||||
else
|
|
||||||
throw new HTML5Error(HTML5Error::INVALID_GETTER, $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General purpose setter for setting attribute->name and attribute->value
|
* Get the value of this attribute
|
||||||
* @public __set
|
* @method getValue
|
||||||
* @param {String} name The name of the attribute
|
* @protected
|
||||||
* @param {String} value The value of the attribute
|
* @return {String} The value of attribute
|
||||||
*/
|
*/
|
||||||
public function __set($name, $value)
|
protected function getValue()
|
||||||
{
|
{
|
||||||
if (method_exists($this , $method =('set' . ucfirst($name))))
|
return $this->_value;
|
||||||
return $this->$method($value);
|
}
|
||||||
else
|
|
||||||
throw new HTML5Error(HTML5Error::INVALID_SETTER, $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if a property exists
|
* Set the value of this attribute, this cannot be empty
|
||||||
* @method __isset
|
* @method setValue
|
||||||
* @param {String} name The name of the property
|
* @protected
|
||||||
*/
|
* @param {String} value The value to set
|
||||||
public function __isset($name)
|
*/
|
||||||
{
|
protected function setValue($value)
|
||||||
return method_exists($this , 'get' . ucfirst($name))
|
{
|
||||||
|| method_exists($this , 'set' . ucfirst($name));
|
$this->_value = $value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Convert a string into an associative array
|
||||||
|
* @method shorthand
|
||||||
|
* @static
|
||||||
|
* @param {String} str The string, delineated by semicolons, and colons for attributes:values
|
||||||
|
* @return {Dictionary} The collection of attributes
|
||||||
|
*/
|
||||||
|
static public function shorthand($str)
|
||||||
|
{
|
||||||
|
$res = array();
|
||||||
|
|
||||||
|
// Match the name=value in the attributes string
|
||||||
|
preg_match_all('/([a-z]+[a-z\-]*)\=("[^\"]*"|\'[^\']*\'|[^\s\"\']*)/',$str, $arr);
|
||||||
|
|
||||||
|
foreach ($arr[1] as $i=>$name)
|
||||||
|
{
|
||||||
|
$value = $arr[2][$i];
|
||||||
|
|
||||||
|
// Remove containing quotes if present
|
||||||
|
if (preg_match('/^[\'\"][^\n]*[\'\"]$/', $value))
|
||||||
|
{
|
||||||
|
$value = substr($value, 1, -1);
|
||||||
|
}
|
||||||
|
$res[$name] = $value;
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose getter for getting attribute->name and attribute->value
|
||||||
|
* @public __get
|
||||||
|
* @param {String} name The name of the property to get
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
if (method_exists($this , $method =('get' . ucfirst($name))))
|
||||||
|
{
|
||||||
|
return $this->$method();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::INVALID_GETTER, $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose setter for setting attribute->name and attribute->value
|
||||||
|
* @public __set
|
||||||
|
* @param {String} name The name of the attribute
|
||||||
|
* @param {String} value The value of the attribute
|
||||||
|
*/
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
if (method_exists($this , $method =('set' . ucfirst($name))))
|
||||||
|
{
|
||||||
|
return $this->$method($value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::INVALID_SETTER, $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if a property exists
|
||||||
|
* @method __isset
|
||||||
|
* @param {String} name The name of the property
|
||||||
|
*/
|
||||||
|
public function __isset($name)
|
||||||
|
{
|
||||||
|
return method_exists($this , 'get' . ucfirst($name))
|
||||||
|
|| method_exists($this , 'set' . ucfirst($name));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
@ -1,38 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Special node type representing an HTML5 inline comment.
|
* Special node type representing an HTML5 inline comment.
|
||||||
* Do not initiate this class directly, use the `html('comment')` function:
|
* Do not initiate this class directly, use the `html('comment')` function:
|
||||||
*
|
*
|
||||||
* echo html('comment', 'Hidden HTML comment here');
|
* echo html('comment', 'Hidden HTML comment here');
|
||||||
*
|
*
|
||||||
* @class Comment
|
* @class Comment
|
||||||
* @extends NodeContainer
|
* @extends NodeContainer
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} text the plain text string
|
* @param {String} text the plain text string
|
||||||
*/
|
*/
|
||||||
class Comment extends NodeContainer
|
class Comment extends NodeContainer
|
||||||
{
|
{
|
||||||
public function __construct($text)
|
public function __construct($text)
|
||||||
{
|
{
|
||||||
parent::__construct($text);
|
parent::__construct($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Write to HTML
|
|
||||||
* @method __toString
|
|
||||||
* @return {String} The string representation of this HTML node
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return '<!-- '.$this->_tag.' -->';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
/**
|
||||||
|
* Write to HTML
|
||||||
|
* @method __toString
|
||||||
|
* @return {String} The string representation of this HTML node
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return '<!-- ' . $this->_tag . ' -->';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
220
src/Document.php
220
src/Document.php
@ -1,117 +1,117 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Create an HTML document. Basic barebones structure.
|
* Create an HTML document. Basic barebones structure.
|
||||||
* Located in the namespace __Canteen\HTML5__.
|
* Located in the namespace __Canteen\HTML5__.
|
||||||
*
|
*
|
||||||
* $doc = new HTML5\Document('Untitled');
|
* $doc = new HTML5\Document('Untitled');
|
||||||
* $doc->head->addChild(html('script src=main.js'));
|
* $doc->head->addChild(html('script src=main.js'));
|
||||||
* $doc->body->addChild(html('div#frame'));
|
* $doc->body->addChild(html('div#frame'));
|
||||||
* echo $doc;
|
* echo $doc;
|
||||||
*
|
*
|
||||||
* @class Document
|
* @class Document
|
||||||
* @extends NodeContainer
|
* @extends NodeContainer
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} [title=''] The title of the document
|
* @param {String} [title=''] The title of the document
|
||||||
* @param {String} [charset='utf-8'] The character encoding set of this HTML document
|
* @param {String} [charset='utf-8'] The character encoding set of this HTML document
|
||||||
* @param {Boolean} [beautify=false] If we should add whitespace to the output to make it look nice markup.
|
* @param {Boolean} [beautify=false] If we should add whitespace to the output to make it look nice markup.
|
||||||
*/
|
*/
|
||||||
class Document extends NodeContainer
|
class Document extends NodeContainer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The document type
|
* The document type
|
||||||
* @property {NodeContainer} docType
|
* @property {NodeContainer} docType
|
||||||
*/
|
*/
|
||||||
private $docType;
|
private $docType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The head node
|
* The head node
|
||||||
* @property {NodeContainer} head
|
* @property {NodeContainer} head
|
||||||
*/
|
*/
|
||||||
public $head;
|
public $head;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The body node
|
* The body node
|
||||||
* @property {NodeContainer} body
|
* @property {NodeContainer} body
|
||||||
*/
|
*/
|
||||||
public $body;
|
public $body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The title node
|
* The title node
|
||||||
* @property {NodeContainer} title
|
* @property {NodeContainer} title
|
||||||
*/
|
*/
|
||||||
public $title;
|
public $title;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Beautify the output
|
* Beautify the output
|
||||||
* @property {Boolean} beautify
|
* @property {Boolean} beautify
|
||||||
*/
|
*/
|
||||||
public $beautify = false;
|
public $beautify = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for Docs
|
* Constructor for Docs
|
||||||
*/
|
*/
|
||||||
public function __construct($title='', $charset='utf-8', $beautify=false)
|
public function __construct($title='', $charset='utf-8', $beautify=false)
|
||||||
{
|
{
|
||||||
parent::__construct('html', null, null,
|
parent::__construct('html', null, null,
|
||||||
array_merge(
|
array_merge(
|
||||||
array('manifest'),
|
array('manifest'),
|
||||||
Specification::$ATTRIBUTES
|
Specification::$ATTRIBUTES
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->docType = html('doctype');
|
$this->docType = html('doctype');
|
||||||
$this->head = html('head');
|
$this->head = html('head');
|
||||||
$this->body = html('body');
|
$this->body = html('body');
|
||||||
$this->title = html('title', $title);
|
$this->title = html('title', $title);
|
||||||
|
|
||||||
$this->head->addChild(html('meta', 'charset='.$charset));
|
$this->head->addChild(html('meta', 'charset=' . $charset));
|
||||||
$this->head->addChild($this->title);
|
$this->head->addChild($this->title);
|
||||||
|
|
||||||
$this->addChild($this->head);
|
$this->addChild($this->head);
|
||||||
$this->addChild($this->body);
|
$this->addChild($this->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to HTML
|
* Write to HTML
|
||||||
* @method __toString
|
* @method __toString
|
||||||
* @return {String} The string representation of this HTML node
|
* @return {String} The string representation of this HTML node
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
$result = $this->docType . parent::__toString();
|
$result = $this->docType . parent::__toString();
|
||||||
if ($this->beautify)
|
if ($this->beautify)
|
||||||
$result = self::beautify($result);
|
{
|
||||||
return $result;
|
$result = self::beautify($result);
|
||||||
}
|
}
|
||||||
|
return $result;
|
||||||
/**
|
}
|
||||||
* Beautifies an HTML string into a human-readable and indented work of art.
|
|
||||||
* @method beautify
|
/**
|
||||||
* @static
|
* Beautifies an HTML string into a human-readable and indented work of art.
|
||||||
* @param {String} html The XML-compatible HTML as a string
|
* @method beautify
|
||||||
* @return {String} The formatted string
|
* @static
|
||||||
*/
|
* @param {String} html The XML-compatible HTML as a string
|
||||||
public static function beautify($html)
|
* @return {String} The formatted string
|
||||||
{
|
*/
|
||||||
// Conver the HTML -> SimpleXML -> DOMDocument
|
public static function beautify($html)
|
||||||
$dom = dom_import_simplexml(new \SimpleXMLElement($html))->ownerDocument;
|
{
|
||||||
|
// Conver the HTML -> SimpleXML -> DOMDocument
|
||||||
// Format the DOMDocument
|
$dom = dom_import_simplexml(new \SimpleXMLElement($html))->ownerDocument;
|
||||||
$dom->formatOutput = true;
|
|
||||||
|
// Format the DOMDocument
|
||||||
// Save the output as XML
|
$dom->formatOutput = true;
|
||||||
$buffer = $dom->saveXML();
|
|
||||||
|
// Save the output as XML
|
||||||
// Remove the first line which has the XML declaration
|
$buffer = $dom->saveXML();
|
||||||
return substr($buffer, strpos($buffer, "\n")+1);
|
|
||||||
}
|
// Remove the first line which has the XML declaration
|
||||||
}
|
return substr($buffer, strpos($buffer, "\n")+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
@ -5,39 +5,37 @@
|
|||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Represents a set of HTML tags without a wrapper.
|
* Represents a set of HTML tags without a wrapper.
|
||||||
* Do not initiate this class directly, use the `html()` function:
|
* Do not initiate this class directly, use the `html()` function:
|
||||||
*
|
*
|
||||||
* $div = html('fragment');
|
* $div = html('fragment');
|
||||||
*
|
*
|
||||||
* @class Fragment
|
* @class Fragment
|
||||||
* @extends NodeContainer
|
* @extends NodeContainer
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Node|Array} [children=null] The collection of children or single child
|
* @param {Node|Array} [children=null] The collection of children or single child
|
||||||
*/
|
*/
|
||||||
class Fragment extends NodeContainer
|
class Fragment extends NodeContainer
|
||||||
{
|
{
|
||||||
public function __construct($children = null)
|
public function __construct($children = null)
|
||||||
{
|
{
|
||||||
parent::__construct('fragment', $children, null);
|
parent::__construct('fragment', $children, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to HTML
|
* Write to HTML
|
||||||
* @method __toString
|
* @method __toString
|
||||||
* @return {String} The string representation of this HTML node
|
* @return {String} The string representation of this HTML node
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
$buffer = '';
|
$buffer = '';
|
||||||
foreach($this->getChildren() as $child)
|
foreach ($this->getChildren() as $child)
|
||||||
{
|
{
|
||||||
$buffer .= $child->__toString();
|
$buffer .= $child->__toString();
|
||||||
}
|
}
|
||||||
return $buffer;
|
return $buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
329
src/HTML5.php
329
src/HTML5.php
@ -1,170 +1,175 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Main class of the library
|
* Main class of the library
|
||||||
* @class HTML5
|
* @class HTML5
|
||||||
*/
|
*/
|
||||||
class HTML5
|
class HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Turn on autoloading for the library
|
* Turn on autoloading for the library
|
||||||
* @method autoload
|
* @method autoload
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
static public function autoload()
|
static public function autoload()
|
||||||
{
|
{
|
||||||
spl_autoload_register(function($name)
|
spl_autoload_register(function($name)
|
||||||
{
|
{
|
||||||
// Ignore class names not in the HTML5 namespace
|
// Ignore class names not in the HTML5 namespace
|
||||||
if (!preg_match('/^Canteen\\\HTML5\\\/', $name)) return;
|
if (!preg_match('/^Canteen\\\HTML5\\\/', $name))
|
||||||
|
{
|
||||||
// Remove the HTML5 namespace
|
return;
|
||||||
$name = preg_replace('/^Canteen\\\HTML5\\\/', '', $name);
|
}
|
||||||
|
|
||||||
// Convert the rest to directories
|
|
||||||
$name = str_replace("\\", '/', $name);
|
|
||||||
|
|
||||||
// Include the class relative to here
|
|
||||||
include __DIR__.'/'.$name.'.php';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Remove the HTML5 namespace
|
||||||
* Use the global `html()` method
|
$name = preg_replace('/^Canteen\\\HTML5\\\/', '', $name);
|
||||||
* @method {Boolean} useGlobal
|
|
||||||
*/
|
|
||||||
static public function useGlobal()
|
|
||||||
{
|
|
||||||
include __DIR__.'/html.php';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Convert the rest to directories
|
||||||
* This is the global function is the main entry for interacting with the HTML5 for PHP library.
|
$name = str_replace("\\", '/', $name);
|
||||||
* using `html()` global function you can create HTML5 quickly and easily. For more
|
|
||||||
* examples and instruction on how to use this library, please refer to the the
|
|
||||||
* <a href="https://github.com/Canteen/CanteenHTML5">GitHub project</a>.
|
|
||||||
* To install the library simply include `html.php`, this takes care of any autoloading that's needed
|
|
||||||
* for the rest of the library.
|
|
||||||
*
|
|
||||||
* echo html('img src=home.jpg');
|
|
||||||
* echo html('img', 'src=home.jpg');
|
|
||||||
* echo html('a', array('href'=>'about.html'));
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @method html
|
|
||||||
* @param {String} tag The name of the tag as a string for example 'tr', 'table', can be followed
|
|
||||||
* by CSS selector, e.g. 'a#backButton' or 'a.button'
|
|
||||||
* @param {Dictionary|Node|String|Array} [childrenOrAttributes=null] If the tag is a NodeContainer, this can be an array
|
|
||||||
* of attributes, another html node or some text. If the tag is a single node, this can
|
|
||||||
* be an array or chain of attributes
|
|
||||||
* @param {Dictionary|String} [attributes=null] The attributes list for container tags (e.g., 'class:selected')
|
|
||||||
* @return {Node} Return the html node
|
|
||||||
*/
|
|
||||||
function html($tag, $childrenOrAttributes=null, $attributes=null)
|
|
||||||
{
|
|
||||||
// Get the tag ID from the tag string
|
|
||||||
// for instance 'a.button rel=external', a.button is the tagId, the rest are the attributes
|
|
||||||
$endPos = strpos(trim($tag), ' ');
|
|
||||||
|
|
||||||
// The tag attributes
|
|
||||||
$tagAttributes = array();
|
|
||||||
|
|
||||||
// If the tag also has some attributes
|
|
||||||
if ($endPos !== false)
|
|
||||||
{
|
|
||||||
$tagOriginal = $tag;
|
|
||||||
$tag = substr($tag, 0, $endPos);
|
|
||||||
$tagAttributes = Attribute::shorthand(substr($tagOriginal, $endPos + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match the tag name without the CSS selectors
|
|
||||||
preg_match('/^([a-z1-6]{1,10})(.*)/', $tag, $tagParts);
|
|
||||||
|
|
||||||
// Valid class ane id names must begin with a -, _, or a-z letter
|
|
||||||
preg_match_all('/(\.|\#)\-?[\_a-zA-Z]+[\_a-zA-Z0-9\-]*/', $tagParts[2], $selectors);
|
|
||||||
|
|
||||||
$tag = strtolower($tagParts[1]); // the name of the tag
|
|
||||||
$selfClosing = false;
|
|
||||||
|
|
||||||
// Comment tags are special
|
// Include the class relative to here
|
||||||
if ($tag == 'comment')
|
include __DIR__ . '/' . $name . '.php';
|
||||||
{
|
});
|
||||||
return new Comment($childrenOrAttributes);
|
}
|
||||||
}
|
|
||||||
// Document type declaration
|
/**
|
||||||
else if ($tag == 'doctype')
|
* Use the global `html()` method
|
||||||
{
|
* @method {Boolean} useGlobal
|
||||||
return '<!DOCTYPE html>';
|
*/
|
||||||
}
|
static public function useGlobal()
|
||||||
// Any normal text
|
{
|
||||||
else if ($tag == 'text')
|
include __DIR__ . '/html.php';
|
||||||
{
|
}
|
||||||
return new Text($childrenOrAttributes);
|
}
|
||||||
}
|
|
||||||
// Untagged container
|
/**
|
||||||
else if ($tag == 'fragment')
|
* This is the global function is the main entry for interacting with the HTML5 for PHP library.
|
||||||
{
|
* using `html()` global function you can create HTML5 quickly and easily. For more
|
||||||
return new Fragment($childrenOrAttributes);
|
* examples and instruction on how to use this library, please refer to the the
|
||||||
}
|
* <a href="https://github.com/Canteen/CanteenHTML5">GitHub project</a>.
|
||||||
// Check for task specification
|
* To install the library simply include `html.php`, this takes care of any autoloading that's needed
|
||||||
else if (isset(Specification::$TAGS[$tag]))
|
* for the rest of the library.
|
||||||
{
|
*
|
||||||
// Check to see if this is a self closing tag
|
* echo html('img src=home.jpg');
|
||||||
$selfClosing = in_array($tag, Specification::$SELF_CLOSING);
|
* echo html('img', 'src=home.jpg');
|
||||||
}
|
* echo html('a', array('href'=>'about.html'));
|
||||||
else
|
*
|
||||||
{
|
*
|
||||||
throw new HTML5Error(HTML5Error::INVALID_TAG, $tag);
|
*
|
||||||
}
|
* @method html
|
||||||
|
* @param {String} tag The name of the tag as a string for example 'tr', 'table', can be followed
|
||||||
// Create the attributes collection, either string or array
|
* by CSS selector, e.g. 'a#backButton' or 'a.button'
|
||||||
$attributes = $selfClosing ? $childrenOrAttributes : $attributes;
|
* @param {Dictionary|Node|String|Array} [childrenOrAttributes=null] If the tag is a NodeContainer, this can be an array
|
||||||
|
* of attributes, another html node or some text. If the tag is a single node, this can
|
||||||
// If there are attributes and they are in a string format
|
* be an array or chain of attributes
|
||||||
// convert to an attributes array
|
* @param {Dictionary|String} [attributes=null] The attributes list for container tags (e.g., 'class:selected')
|
||||||
if ($attributes !== null && is_string($attributes))
|
* @return {Node} Return the html node
|
||||||
{
|
*/
|
||||||
$attributes = Attribute::shorthand($attributes);
|
function html($tag, $childrenOrAttributes=null, $attributes=null)
|
||||||
}
|
{
|
||||||
|
// Get the tag ID from the tag string
|
||||||
// Combine the attributes and the tags
|
// for instance 'a.button rel=external', a.button is the tagId, the rest are the attributes
|
||||||
if (is_array($attributes))
|
$endPos = strpos(trim($tag), ' ');
|
||||||
{
|
|
||||||
$attributes = array_merge($tagAttributes, $attributes);
|
// The tag attributes
|
||||||
}
|
$tagAttributes = array();
|
||||||
// Or just add any tag attributes
|
|
||||||
else if (count($tagAttributes))
|
// If the tag also has some attributes
|
||||||
{
|
if ($endPos !== false)
|
||||||
$attributes = $tagAttributes;
|
{
|
||||||
}
|
$tagOriginal = $tag;
|
||||||
|
$tag = substr($tag, 0, $endPos);
|
||||||
// Create the node or container
|
$tagAttributes = Attribute::shorthand(substr($tagOriginal, $endPos + 1));
|
||||||
$node = $selfClosing ?
|
}
|
||||||
new Node($tag, $attributes) :
|
|
||||||
new NodeContainer($tag, $childrenOrAttributes, $attributes);
|
// Match the tag name without the CSS selectors
|
||||||
|
preg_match('/^([a-z1-6]{1,10})(.*)/', $tag, $tagParts);
|
||||||
// Take the selectors convert them into id or class
|
|
||||||
foreach($selectors[0] as $selector)
|
// Valid class ane id names must begin with a -, _, or a-z letter
|
||||||
{
|
preg_match_all('/(\.|\#)\-?[\_a-zA-Z]+[\_a-zA-Z0-9\-]*/', $tagParts[2], $selectors);
|
||||||
switch($selector[0])
|
|
||||||
{
|
$tag = strtolower($tagParts[1]); // the name of the tag
|
||||||
case '#' :
|
$selfClosing = false;
|
||||||
$node->id = substr($selector, 1);
|
|
||||||
break;
|
// Comment tags are special
|
||||||
case '.' :
|
if ($tag == 'comment')
|
||||||
if ($node->class) $node->class .= ' ';
|
{
|
||||||
$node->class .= substr($selector, 1);
|
return new Comment($childrenOrAttributes);
|
||||||
break;
|
}
|
||||||
}
|
// Document type declaration
|
||||||
}
|
else if ($tag == 'doctype')
|
||||||
return $node;
|
{
|
||||||
}
|
return '<!DOCTYPE html>';
|
||||||
}
|
}
|
||||||
|
// Any normal text
|
||||||
|
else if ($tag == 'text')
|
||||||
|
{
|
||||||
|
return new Text($childrenOrAttributes);
|
||||||
|
}
|
||||||
|
// Untagged container
|
||||||
|
else if ($tag == 'fragment')
|
||||||
|
{
|
||||||
|
return new Fragment($childrenOrAttributes);
|
||||||
|
}
|
||||||
|
// Check for task specification
|
||||||
|
else if (isset(Specification::$TAGS[$tag]))
|
||||||
|
{
|
||||||
|
// Check to see if this is a self closing tag
|
||||||
|
$selfClosing = in_array($tag, Specification::$SELF_CLOSING);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::INVALID_TAG, $tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the attributes collection, either string or array
|
||||||
|
$attributes = $selfClosing ? $childrenOrAttributes : $attributes;
|
||||||
|
|
||||||
|
// If there are attributes and they are in a string format
|
||||||
|
// convert to an attributes array
|
||||||
|
if ($attributes !== null && is_string($attributes))
|
||||||
|
{
|
||||||
|
$attributes = Attribute::shorthand($attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine the attributes and the tags
|
||||||
|
if (is_array($attributes))
|
||||||
|
{
|
||||||
|
$attributes = array_merge($tagAttributes, $attributes);
|
||||||
|
}
|
||||||
|
// Or just add any tag attributes
|
||||||
|
else if (count($tagAttributes))
|
||||||
|
{
|
||||||
|
$attributes = $tagAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the node or container
|
||||||
|
$node = $selfClosing ?
|
||||||
|
new Node($tag, $attributes) :
|
||||||
|
new NodeContainer($tag, $childrenOrAttributes, $attributes);
|
||||||
|
|
||||||
|
// Take the selectors convert them into id or class
|
||||||
|
foreach ($selectors[0] as $selector)
|
||||||
|
{
|
||||||
|
switch ($selector[0])
|
||||||
|
{
|
||||||
|
case '#' :
|
||||||
|
$node->id = substr($selector, 1);
|
||||||
|
break;
|
||||||
|
case '.' :
|
||||||
|
if ($node->class) {
|
||||||
|
$node->class .= ' ';
|
||||||
|
}
|
||||||
|
$node->class .= substr($selector, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,144 +1,142 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Exceptions with using the HTML5 API.
|
* Exceptions with using the HTML5 API.
|
||||||
*
|
*
|
||||||
* try
|
* try
|
||||||
* {
|
* {
|
||||||
* html('invalid', 'something');
|
* html('invalid', 'something');
|
||||||
* }
|
* }
|
||||||
* catch(Canteen\HTML5\HTML5Error $e)
|
* catch(Canteen\HTML5\HTML5Error $e)
|
||||||
* {
|
* {
|
||||||
* $e->getMessage();
|
* $e->getMessage();
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @class HTML5Error
|
* @class HTML5Error
|
||||||
* @extends Exception
|
* @extends Exception
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {int} code The code of the error
|
* @param {int} code The code of the error
|
||||||
* @param {String} [data=''] Additional data to associate with this error
|
* @param {String} [data=''] Additional data to associate with this error
|
||||||
*/
|
*/
|
||||||
class HTML5Error extends \Exception
|
class HTML5Error extends \Exception
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The database connection failed
|
* The database connection failed
|
||||||
* @property {int} EMPTY_ATTRIBUTE_NAME
|
* @property {int} EMPTY_ATTRIBUTE_NAME
|
||||||
* @static
|
* @static
|
||||||
* @final
|
* @final
|
||||||
*/
|
*/
|
||||||
const EMPTY_ATTRIBUTE_NAME = 500;
|
const EMPTY_ATTRIBUTE_NAME = 500;
|
||||||
|
|
||||||
/**
|
|
||||||
* The alias for a database is invalid
|
|
||||||
* @property {int} EMPTY_ATTRIBUTE_VALUE
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const EMPTY_ATTRIBUTE_VALUE = 501;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The database name we're trying to switch to is invalid
|
|
||||||
* @property {int} INVALID_SETTER
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const INVALID_SETTER = 502;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The mysql where trying to execute was a problem
|
|
||||||
* @property {int} INVALID_GETTER
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const INVALID_GETTER = 503;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The html tag name is invalid
|
|
||||||
* @property {int} INVALID_TAG
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const INVALID_TAG = 504;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When trying to create a node, the name is empty
|
|
||||||
* @property {int} EMPTY_NODE_TAG
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const EMPTY_NODE_TAG = 505;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parent cannot be empty
|
|
||||||
* @property {int} EMPTY_PARENT
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const EMPTY_PARENT = 506;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* THe addChildAt is out of bounds
|
|
||||||
* @property {int} OUT_OF_BOUNDS
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const OUT_OF_BOUNDS = 507;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The child node is empty
|
|
||||||
* @property {int} EMPTY_CHILD
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const EMPTY_CHILD = 508;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The node is not of instance type Node
|
|
||||||
* @property {int} INVALID_NODE
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const INVALID_NODE = 509;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look-up for error messages
|
|
||||||
* @property {Dictionary} messages
|
|
||||||
* @private
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
private static $messages = array(
|
|
||||||
self::EMPTY_ATTRIBUTE_NAME => 'Attribute names cannot be empty',
|
|
||||||
self::EMPTY_ATTRIBUTE_VALUE => 'Attribute values cannot be empty',
|
|
||||||
self::INVALID_SETTER => 'Cannot set the property because name is invalid',
|
|
||||||
self::INVALID_GETTER => 'Cannot get the property because name is invalid',
|
|
||||||
self::INVALID_TAG => 'Not a valid HTML5 tag name',
|
|
||||||
self::EMPTY_NODE_TAG => 'Node tag is empty',
|
|
||||||
self::EMPTY_PARENT => 'The parent cannot be empty',
|
|
||||||
self::OUT_OF_BOUNDS => 'The index is out of bounds',
|
|
||||||
self::EMPTY_CHILD => 'Cannot addChild an empty child node',
|
|
||||||
self::INVALID_NODE => 'Child node must be a valid tag'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The label for an error that is unknown or unfound in messages
|
|
||||||
* @property {String} UNKNOWN
|
|
||||||
* @static
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
const UNKNOWN = 'Unknown error';
|
|
||||||
|
|
||||||
public function __construct($code, $data='')
|
|
||||||
{
|
|
||||||
$message = (isset(self::$messages[$code]) ? self::$messages[$code]: self::UNKNOWN)
|
|
||||||
. ($data ? ' : ' . $data : $data);
|
|
||||||
parent::__construct($message, $code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
/**
|
||||||
|
* The alias for a database is invalid
|
||||||
|
* @property {int} EMPTY_ATTRIBUTE_VALUE
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const EMPTY_ATTRIBUTE_VALUE = 501;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The database name we're trying to switch to is invalid
|
||||||
|
* @property {int} INVALID_SETTER
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const INVALID_SETTER = 502;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mysql where trying to execute was a problem
|
||||||
|
* @property {int} INVALID_GETTER
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const INVALID_GETTER = 503;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The html tag name is invalid
|
||||||
|
* @property {int} INVALID_TAG
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const INVALID_TAG = 504;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When trying to create a node, the name is empty
|
||||||
|
* @property {int} EMPTY_NODE_TAG
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const EMPTY_NODE_TAG = 505;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parent cannot be empty
|
||||||
|
* @property {int} EMPTY_PARENT
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const EMPTY_PARENT = 506;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THe addChildAt is out of bounds
|
||||||
|
* @property {int} OUT_OF_BOUNDS
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const OUT_OF_BOUNDS = 507;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The child node is empty
|
||||||
|
* @property {int} EMPTY_CHILD
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const EMPTY_CHILD = 508;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The node is not of instance type Node
|
||||||
|
* @property {int} INVALID_NODE
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const INVALID_NODE = 509;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look-up for error messages
|
||||||
|
* @property {Dictionary} messages
|
||||||
|
* @private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
private static $messages = array(
|
||||||
|
self::EMPTY_ATTRIBUTE_NAME => 'Attribute names cannot be empty',
|
||||||
|
self::EMPTY_ATTRIBUTE_VALUE => 'Attribute values cannot be empty',
|
||||||
|
self::INVALID_SETTER => 'Cannot set the property because name is invalid',
|
||||||
|
self::INVALID_GETTER => 'Cannot get the property because name is invalid',
|
||||||
|
self::INVALID_TAG => 'Not a valid HTML5 tag name',
|
||||||
|
self::EMPTY_NODE_TAG => 'Node tag is empty',
|
||||||
|
self::EMPTY_PARENT => 'The parent cannot be empty',
|
||||||
|
self::OUT_OF_BOUNDS => 'The index is out of bounds',
|
||||||
|
self::EMPTY_CHILD => 'Cannot addChild an empty child node',
|
||||||
|
self::INVALID_NODE => 'Child node must be a valid tag'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The label for an error that is unknown or unfound in messages
|
||||||
|
* @property {String} UNKNOWN
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
const UNKNOWN = 'Unknown error';
|
||||||
|
|
||||||
|
public function __construct($code, $data='')
|
||||||
|
{
|
||||||
|
$message = (isset(self::$messages[$code]) ? self::$messages[$code]: self::UNKNOWN)
|
||||||
|
. ($data ? ' : ' . $data : $data);
|
||||||
|
parent::__construct($message, $code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
664
src/Node.php
664
src/Node.php
@ -1,341 +1,343 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* A generic html tag with any children or closing tag. (e.g., img, br, hr).
|
* A generic html tag with any children or closing tag. (e.g., img, br, hr).
|
||||||
* Do not initiate this class directly, use the `html()` function:
|
* Do not initiate this class directly, use the `html()` function:
|
||||||
*
|
*
|
||||||
* echo html('br');
|
* echo html('br');
|
||||||
*
|
*
|
||||||
* @class Node
|
* @class Node
|
||||||
* @extends Proto
|
* @extends Proto
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} [tag=null] The name of the tag
|
* @param {String} [tag=null] The name of the tag
|
||||||
* @param {Array|String} [attributes=null] The collection of tag attributes
|
* @param {Array|String} [attributes=null] The collection of tag attributes
|
||||||
*/
|
*/
|
||||||
class Node extends Proto
|
class Node extends Proto
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The string name of the tag
|
* The string name of the tag
|
||||||
* @property {String} _tag
|
* @property {String} _tag
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
protected $_tag;
|
protected $_tag;
|
||||||
|
|
||||||
/**
|
|
||||||
* The collection of Attributes objects
|
|
||||||
* @property {Array} _attributes
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
protected $_attributes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parent node, if any
|
|
||||||
* @property {NodeContainer} _parent
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
protected $_parent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The collection of valid attributes names for given tag
|
|
||||||
* @property {Array} _validAttrs
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
protected $_validAttrs;
|
|
||||||
|
|
||||||
public function __construct($tag = null, $attributes = null)
|
|
||||||
{
|
|
||||||
if ($this->isEmpty($tag))
|
|
||||||
{
|
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_NODE_TAG);
|
|
||||||
}
|
|
||||||
$this->_parent = null;
|
|
||||||
$this->_tag = $tag;
|
|
||||||
$this->_attributes = array();
|
|
||||||
|
|
||||||
if (isset(Specification::$TAGS[$tag]))
|
/**
|
||||||
{
|
* The collection of Attributes objects
|
||||||
$this->_validAttrs = array_merge(
|
* @property {Array} _attributes
|
||||||
Specification::$TAGS[$tag],
|
* @protected
|
||||||
Specification::$ATTRIBUTES
|
*/
|
||||||
);
|
protected $_attributes;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->_validAttrs = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($attributes !== null)
|
|
||||||
{
|
|
||||||
if (is_string($attributes))
|
|
||||||
{
|
|
||||||
$attributes = Attribute::shorthand($attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($attributes))
|
|
||||||
{
|
|
||||||
$this->setAttributes($attributes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the parent node of this node, if
|
|
||||||
* a parent exists. If no parent exists,
|
|
||||||
* this function returns null.
|
|
||||||
* @method getParent
|
|
||||||
* @private
|
|
||||||
* @return {NodeContainer} The parent node object
|
|
||||||
*/
|
|
||||||
private function getParent()
|
|
||||||
{
|
|
||||||
return $this->_parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the parent of this Node. Note that this
|
|
||||||
* function is protected and can only be called by
|
|
||||||
* classes that extend Node. The parent cannot
|
|
||||||
* be null; this function will throw an Exception
|
|
||||||
* if the parent node is empty.
|
|
||||||
* @method setParent
|
|
||||||
* @protected
|
|
||||||
* @param {NodeContainer} [parent=null] The parent container node
|
|
||||||
*/
|
|
||||||
protected function setParent(NodeContainer $parent = null)
|
|
||||||
{
|
|
||||||
if ($this->isEmpty($parent))
|
|
||||||
{
|
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_PARENT);
|
|
||||||
}
|
|
||||||
$this->_parent = $parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a name and value pair, sets an attribute on this Node.
|
|
||||||
* The name and value cannot be empty; if so, this function
|
|
||||||
* will throw an Exception. Note if the attribute already exists
|
|
||||||
* and the caller wants to set an attribute of the same name,
|
|
||||||
* this function will not create a new Attribute, but rather
|
|
||||||
* update the value of the existing named attribute.
|
|
||||||
*
|
|
||||||
* @method setAttribute
|
|
||||||
* @param {String} [name=null] The name of the attribute to add
|
|
||||||
* @param {String} [value=null] The value of the attribute
|
|
||||||
* @param {Node} The instance of this node
|
|
||||||
*/
|
|
||||||
public function setAttribute($name = null, $value = null)
|
|
||||||
{
|
|
||||||
if ($this->isEmpty($name))
|
|
||||||
{
|
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
|
|
||||||
}
|
|
||||||
foreach($this->_attributes as $i=>$attribute)
|
|
||||||
{
|
|
||||||
if ($attribute->name === $name)
|
|
||||||
{
|
|
||||||
if (!$this->isEmpty($value))
|
|
||||||
$attribute->value = $value;
|
|
||||||
else
|
|
||||||
unset($this->_attributes[$i]);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->_attributes[] = new Attribute($name, $value);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch and attribute by name from this Node. The attribute
|
|
||||||
* name cannot be null; if so, this function will throw an
|
|
||||||
* Exception.
|
|
||||||
* @method getAttribute
|
|
||||||
* @param {String} [name=null] The name of the attribute to fetch
|
|
||||||
* @return {String} The attribute's value, if any or null
|
|
||||||
*/
|
|
||||||
protected function getAttribute($name = null)
|
|
||||||
{
|
|
||||||
$returnAttr = null;
|
|
||||||
|
|
||||||
if ($this->isEmpty($name))
|
/**
|
||||||
{
|
* The parent node, if any
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
|
* @property {NodeContainer} _parent
|
||||||
}
|
* @protected
|
||||||
foreach($this->_attributes as $attribute)
|
*/
|
||||||
{
|
protected $_parent;
|
||||||
if ($attribute->name === $name)
|
|
||||||
{
|
|
||||||
$returnAttr = $attribute->value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $returnAttr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the list of all attributes.
|
|
||||||
* @method setAttributes
|
|
||||||
* @param {Dictionary} values An attributes array(name=>value, name=>value)
|
|
||||||
* @return {Node} The instance of this Node
|
|
||||||
*/
|
|
||||||
public function setAttributes($values)
|
|
||||||
{
|
|
||||||
if (is_array($values))
|
|
||||||
{
|
|
||||||
foreach($values as $name=>$value)
|
|
||||||
{
|
|
||||||
$this->setAttribute($name, $value);
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the a data-* HTML5 Attribute
|
|
||||||
* @param {String} name The name of the data, for instance "id" is an attribute "data-id"
|
|
||||||
* @param {String} value The value of the attribute
|
|
||||||
* @return {Node} The instance of this Node
|
|
||||||
*/
|
|
||||||
public function setData($name, $value)
|
|
||||||
{
|
|
||||||
return $this->setAttribute('data-'.$name, $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add this child to a node container at the end
|
|
||||||
* @method appendTo
|
|
||||||
* @param {NodeContainer} container The node container to add to
|
|
||||||
* @return {Node} The instance of this Node
|
|
||||||
*/
|
|
||||||
public function appendTo(NodeContainer $container)
|
|
||||||
{
|
|
||||||
$container->addChild($this);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add this child to the beginning of a node container
|
|
||||||
* @method prependTo
|
|
||||||
* @param {NodeContainer} container The node container to prepend to to
|
|
||||||
* @return {Node} The instance of this Node
|
|
||||||
*/
|
|
||||||
public function prependTo(NodeContainer $container)
|
|
||||||
{
|
|
||||||
$container->addChildAt($this, 0);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data-* HTML5 attribute value, if set
|
|
||||||
* @method getData
|
|
||||||
* @param {String} name The name of the data attribute
|
|
||||||
* @return {String} The value of the data
|
|
||||||
*/
|
|
||||||
public function getData($name)
|
|
||||||
{
|
|
||||||
return $this->getAttribute('data-'.$name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write to HTML
|
|
||||||
* @method __toString
|
|
||||||
* @return {String} The string representation of this HTML node
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return $this->writeOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the writing the tag
|
|
||||||
* @method writeOpen
|
|
||||||
* @protected
|
|
||||||
* @param {Boolean} [selfClose=true] If the tag is a self closing tag (e.g., br, img, hr)
|
|
||||||
* @return {String} The buffer of HTML
|
|
||||||
*/
|
|
||||||
protected function writeOpen($selfClose=true)
|
|
||||||
{
|
|
||||||
$buffer = '<';
|
|
||||||
$buffer .= $this->_tag;
|
|
||||||
foreach($this->_attributes as $attribute)
|
|
||||||
{
|
|
||||||
$buffer .= (string)$attribute;
|
|
||||||
}
|
|
||||||
$buffer .= ($selfClose ? ' />' : '>');
|
|
||||||
return $buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* General purpose getter to get attribute values
|
|
||||||
* @method __get
|
|
||||||
* @param {String} name The name of the property to set
|
|
||||||
*/
|
|
||||||
public function __get($name)
|
|
||||||
{
|
|
||||||
if (in_array($name, $this->_validAttrs) || strpos($name, 'data-') === 0)
|
|
||||||
{
|
|
||||||
return $this->getAttribute($name);
|
|
||||||
}
|
|
||||||
return parent::__get($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General purpose setter to set attribute values
|
* The collection of valid attributes names for given tag
|
||||||
* @method __set
|
* @property {Array} _validAttrs
|
||||||
* @param {String} name The name of the attribute
|
* @protected
|
||||||
* @param {String} value The value of the attribute
|
*/
|
||||||
*/
|
protected $_validAttrs;
|
||||||
public function __set($name, $value)
|
|
||||||
{
|
|
||||||
if (in_array($name, $this->_validAttrs) || strpos($name, 'data-') === 0)
|
|
||||||
{
|
|
||||||
return $this->setAttribute($name, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public function __construct($tag = null, $attributes = null)
|
||||||
* See if a property exists
|
{
|
||||||
* @method __isset
|
if ($this->isEmpty($tag))
|
||||||
* @param {String} name The name of the attribute
|
{
|
||||||
*/
|
throw new HTML5Error(HTML5Error::EMPTY_NODE_TAG);
|
||||||
public function __isset($name)
|
}
|
||||||
{
|
$this->_parent = null;
|
||||||
return in_array($name, $this->_validAttrs) || parent::__isset($name);
|
$this->_tag = $tag;
|
||||||
}
|
$this->_attributes = array();
|
||||||
|
|
||||||
/**
|
if (isset(Specification::$TAGS[$tag]))
|
||||||
* Checks if a variable is really "empty". Code borrowed from PHP.net at
|
{
|
||||||
* http://us3.php.net/manual/en/function.empty.php#90767 because we were
|
$this->_validAttrs = array_merge(
|
||||||
* previously using empty() to see if a variable is empty or not. But
|
Specification::$TAGS[$tag],
|
||||||
* empty() dosen't work for attributes that have a value of "0", so we need
|
Specification::$ATTRIBUTES
|
||||||
* something more robust here.
|
);
|
||||||
* <ul>
|
}
|
||||||
* <li>an unset variable -> empty</li>
|
else
|
||||||
* <li>null -> empty</li>
|
{
|
||||||
* <li>0 -> NOT empty</li>
|
$this->_validAttrs = array();
|
||||||
* <li>"0" -> NOT empty</li>
|
}
|
||||||
* <li>false -> empty</li>
|
|
||||||
* <li>true -> NOT empty</li>
|
if ($attributes !== null)
|
||||||
* <li>'string value' -> NOT empty</li>
|
{
|
||||||
* <li>" "(white space) -> empty</li>
|
if (is_string($attributes))
|
||||||
* <li>array()(empty array) -> empty</li>
|
{
|
||||||
* </ul>
|
$attributes = Attribute::shorthand($attributes);
|
||||||
* @method isEmpty
|
}
|
||||||
* @protected
|
|
||||||
* @param {mixed} var The variable to check for empty on
|
if (is_array($attributes))
|
||||||
*/
|
{
|
||||||
protected function isEmpty($var)
|
$this->setAttributes($attributes);
|
||||||
{
|
}
|
||||||
return (!isset($var) || is_null($var) ||
|
}
|
||||||
(!is_object($var) && is_string($var) && trim($var) == '' && !is_bool($var)) ||
|
}
|
||||||
(is_bool($var) && $var === false) ||
|
|
||||||
(is_array($var) && empty($var)));
|
/**
|
||||||
}
|
* Returns the parent node of this node, if
|
||||||
}
|
* a parent exists. If no parent exists,
|
||||||
|
* this function returns null.
|
||||||
|
* @method getParent
|
||||||
|
* @private
|
||||||
|
* @return {NodeContainer} The parent node object
|
||||||
|
*/
|
||||||
|
private function getParent()
|
||||||
|
{
|
||||||
|
return $this->_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the parent of this Node. Note that this
|
||||||
|
* function is protected and can only be called by
|
||||||
|
* classes that extend Node. The parent cannot
|
||||||
|
* be null; this function will throw an Exception
|
||||||
|
* if the parent node is empty.
|
||||||
|
* @method setParent
|
||||||
|
* @protected
|
||||||
|
* @param {NodeContainer} [parent=null] The parent container node
|
||||||
|
*/
|
||||||
|
protected function setParent(NodeContainer $parent = null)
|
||||||
|
{
|
||||||
|
if ($this->isEmpty($parent))
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::EMPTY_PARENT);
|
||||||
|
}
|
||||||
|
$this->_parent = $parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a name and value pair, sets an attribute on this Node.
|
||||||
|
* The name and value cannot be empty; if so, this function
|
||||||
|
* will throw an Exception. Note if the attribute already exists
|
||||||
|
* and the caller wants to set an attribute of the same name,
|
||||||
|
* this function will not create a new Attribute, but rather
|
||||||
|
* update the value of the existing named attribute.
|
||||||
|
*
|
||||||
|
* @method setAttribute
|
||||||
|
* @param {String} [name=null] The name of the attribute to add
|
||||||
|
* @param {String} [value=null] The value of the attribute
|
||||||
|
* @param {Node} The instance of this node
|
||||||
|
*/
|
||||||
|
public function setAttribute($name = null, $value = null)
|
||||||
|
{
|
||||||
|
if ($this->isEmpty($name))
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
foreach ($this->_attributes as $i=>$attribute)
|
||||||
|
{
|
||||||
|
if ($attribute->name === $name)
|
||||||
|
{
|
||||||
|
if (!$this->isEmpty($value))
|
||||||
|
{
|
||||||
|
$attribute->value = $value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($this->_attributes[$i]);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->_attributes[] = new Attribute($name, $value);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch and attribute by name from this Node. The attribute
|
||||||
|
* name cannot be null; if so, this function will throw an
|
||||||
|
* Exception.
|
||||||
|
* @method getAttribute
|
||||||
|
* @param {String} [name=null] The name of the attribute to fetch
|
||||||
|
* @return {String} The attribute's value, if any or null
|
||||||
|
*/
|
||||||
|
protected function getAttribute($name = null)
|
||||||
|
{
|
||||||
|
$returnAttr = null;
|
||||||
|
|
||||||
|
if ($this->isEmpty($name))
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
foreach ($this->_attributes as $attribute)
|
||||||
|
{
|
||||||
|
if ($attribute->name === $name)
|
||||||
|
{
|
||||||
|
$returnAttr = $attribute->value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $returnAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of all attributes.
|
||||||
|
* @method setAttributes
|
||||||
|
* @param {Dictionary} values An attributes array(name=>value, name=>value)
|
||||||
|
* @return {Node} The instance of this Node
|
||||||
|
*/
|
||||||
|
public function setAttributes($values)
|
||||||
|
{
|
||||||
|
if (is_array($values))
|
||||||
|
{
|
||||||
|
foreach ($values as $name=>$value)
|
||||||
|
{
|
||||||
|
$this->setAttribute($name, $value);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the a data-* HTML5 Attribute
|
||||||
|
* @param {String} name The name of the data, for instance "id" is an attribute "data-id"
|
||||||
|
* @param {String} value The value of the attribute
|
||||||
|
* @return {Node} The instance of this Node
|
||||||
|
*/
|
||||||
|
public function setData($name, $value)
|
||||||
|
{
|
||||||
|
return $this->setAttribute('data-'.$name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add this child to a node container at the end
|
||||||
|
* @method appendTo
|
||||||
|
* @param {NodeContainer} container The node container to add to
|
||||||
|
* @return {Node} The instance of this Node
|
||||||
|
*/
|
||||||
|
public function appendTo(NodeContainer $container)
|
||||||
|
{
|
||||||
|
$container->addChild($this);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add this child to the beginning of a node container
|
||||||
|
* @method prependTo
|
||||||
|
* @param {NodeContainer} container The node container to prepend to to
|
||||||
|
* @return {Node} The instance of this Node
|
||||||
|
*/
|
||||||
|
public function prependTo(NodeContainer $container)
|
||||||
|
{
|
||||||
|
$container->addChildAt($this, 0);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data-* HTML5 attribute value, if set
|
||||||
|
* @method getData
|
||||||
|
* @param {String} name The name of the data attribute
|
||||||
|
* @return {String} The value of the data
|
||||||
|
*/
|
||||||
|
public function getData($name)
|
||||||
|
{
|
||||||
|
return $this->getAttribute('data-' . $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to HTML
|
||||||
|
* @method __toString
|
||||||
|
* @return {String} The string representation of this HTML node
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->writeOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the writing the tag
|
||||||
|
* @method writeOpen
|
||||||
|
* @protected
|
||||||
|
* @param {Boolean} [selfClose=true] If the tag is a self closing tag (e.g., br, img, hr)
|
||||||
|
* @return {String} The buffer of HTML
|
||||||
|
*/
|
||||||
|
protected function writeOpen($selfClose=true)
|
||||||
|
{
|
||||||
|
$buffer = '<';
|
||||||
|
$buffer .= $this->_tag;
|
||||||
|
foreach ($this->_attributes as $attribute)
|
||||||
|
{
|
||||||
|
$buffer .= (string)$attribute;
|
||||||
|
}
|
||||||
|
$buffer .= ($selfClose ? ' />' : '>');
|
||||||
|
return $buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose getter to get attribute values
|
||||||
|
* @method __get
|
||||||
|
* @param {String} name The name of the property to set
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
if (in_array($name, $this->_validAttrs) || strpos($name, 'data-') === 0)
|
||||||
|
{
|
||||||
|
return $this->getAttribute($name);
|
||||||
|
}
|
||||||
|
return parent::__get($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose setter to set attribute values
|
||||||
|
* @method __set
|
||||||
|
* @param {String} name The name of the attribute
|
||||||
|
* @param {String} value The value of the attribute
|
||||||
|
*/
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
if (in_array($name, $this->_validAttrs) || strpos($name, 'data-') === 0)
|
||||||
|
{
|
||||||
|
return $this->setAttribute($name, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if a property exists
|
||||||
|
* @method __isset
|
||||||
|
* @param {String} name The name of the attribute
|
||||||
|
*/
|
||||||
|
public function __isset($name)
|
||||||
|
{
|
||||||
|
return in_array($name, $this->_validAttrs) || parent::__isset($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a variable is really "empty". Code borrowed from PHP.net at
|
||||||
|
* http://us3.php.net/manual/en/function.empty.php#90767 because we were
|
||||||
|
* previously using empty() to see if a variable is empty or not. But
|
||||||
|
* empty() dosen't work for attributes that have a value of "0", so we need
|
||||||
|
* something more robust here.
|
||||||
|
* <ul>
|
||||||
|
* <li>an unset variable -> empty</li>
|
||||||
|
* <li>null -> empty</li>
|
||||||
|
* <li>0 -> NOT empty</li>
|
||||||
|
* <li>"0" -> NOT empty</li>
|
||||||
|
* <li>false -> empty</li>
|
||||||
|
* <li>true -> NOT empty</li>
|
||||||
|
* <li>'string value' -> NOT empty</li>
|
||||||
|
* <li>" "(white space) -> empty</li>
|
||||||
|
* <li>array()(empty array) -> empty</li>
|
||||||
|
* </ul>
|
||||||
|
* @method isEmpty
|
||||||
|
* @protected
|
||||||
|
* @param {mixed} var The variable to check for empty on
|
||||||
|
*/
|
||||||
|
protected function isEmpty($var)
|
||||||
|
{
|
||||||
|
return (!isset($var) || is_null($var) ||
|
||||||
|
(!is_object($var) && is_string($var) && trim($var) == '' && !is_bool($var)) ||
|
||||||
|
(is_bool($var) && $var === false) ||
|
||||||
|
(is_array($var) && empty($var)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
@ -1,237 +1,235 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Represents an HTML that that can contain other tags (e.g., br, p, div).
|
* Represents an HTML that that can contain other tags (e.g., br, p, div).
|
||||||
* Do not initiate this class directly, use the `html()` function:
|
* Do not initiate this class directly, use the `html()` function:
|
||||||
*
|
*
|
||||||
* $div = html('div');
|
* $div = html('div');
|
||||||
*
|
*
|
||||||
* @class NodeContainer
|
* @class NodeContainer
|
||||||
* @extends Node
|
* @extends Node
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} [tag=null] The name of the tag element
|
* @param {String} [tag=null] The name of the tag element
|
||||||
* @param {Node|Array} [children=null] The collection of children or single child
|
* @param {Node|Array} [children=null] The collection of children or single child
|
||||||
* @param {String|Dictionary} [attributes=null] The tag attributes
|
* @param {String|Dictionary} [attributes=null] The tag attributes
|
||||||
*/
|
*/
|
||||||
class NodeContainer extends Node
|
class NodeContainer extends Node
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The collection of children nodes
|
* The collection of children nodes
|
||||||
* @property {Array} _children
|
* @property {Array} _children
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private $_children;
|
private $_children;
|
||||||
|
|
||||||
public function __construct($tag = null, $children = null, $attributes = null)
|
public function __construct($tag = null, $children = null, $attributes = null)
|
||||||
{
|
{
|
||||||
if ($this->isEmpty($tag))
|
if ($this->isEmpty($tag))
|
||||||
{
|
{
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_NODE_TAG);
|
throw new HTML5Error(HTML5Error::EMPTY_NODE_TAG);
|
||||||
}
|
}
|
||||||
parent::__construct($tag, $attributes);
|
parent::__construct($tag, $attributes);
|
||||||
|
|
||||||
$this->_children = array();
|
|
||||||
|
|
||||||
if (!$this->isEmpty($children))
|
|
||||||
{
|
|
||||||
if (!is_array($children))
|
|
||||||
{
|
|
||||||
$children = array($children);
|
|
||||||
}
|
|
||||||
if (is_array($children))
|
|
||||||
{
|
|
||||||
foreach($children as $child)
|
|
||||||
{
|
|
||||||
$this->addChild($child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
$this->_children = array();
|
||||||
* Add's a child to this NodeContainer. The child to add cannot be null.
|
|
||||||
* @method addChild
|
|
||||||
* @param {Node|String|Number|Boolean} childNode The child Node to add
|
|
||||||
* @return {NodeContainer} The instance of this container
|
|
||||||
*/
|
|
||||||
public function addChild($childNode)
|
|
||||||
{
|
|
||||||
array_push($this->_children, $this->prepareChild($childNode));
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a child at a specific index
|
|
||||||
* @method addChildAt
|
|
||||||
* @param {Node|String|Number|Boolean} childNode The child Node to add
|
|
||||||
* @param {int} index The index to add child at, 0 is top
|
|
||||||
* @return {NodeContainer} The instance of this container
|
|
||||||
*/
|
|
||||||
public function addChildAt($childNode, $index)
|
|
||||||
{
|
|
||||||
if ($index < 0)
|
|
||||||
{
|
|
||||||
throw new HTML5Error(HTML5Error::OUT_OF_BOUNDS, $index);
|
|
||||||
}
|
|
||||||
$childNode = $this->prepareChild($childNode);
|
|
||||||
if ($index == 0)
|
|
||||||
{
|
|
||||||
array_unshift($this->_children, $childNode);
|
|
||||||
}
|
|
||||||
else if ($index > (count($this->_children) - 1))
|
|
||||||
{
|
|
||||||
$this->addChild($childNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
array_splice($this->_children, $index , 0, array($childNode));
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Before adding a child, we should do some checking for basic types
|
|
||||||
* and convert it into a more useable Node object.
|
|
||||||
* @method prepareChild
|
|
||||||
* @protected
|
|
||||||
* @param {Node|String|Number|Boolean} childNode The child node to add
|
|
||||||
* @return {Node} The child node
|
|
||||||
*/
|
|
||||||
protected function prepareChild($childNode)
|
|
||||||
{
|
|
||||||
if ($this->isEmpty($childNode))
|
|
||||||
{
|
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_CHILD);
|
|
||||||
}
|
|
||||||
if (is_bool($childNode))
|
|
||||||
{
|
|
||||||
$childNode = new Text($childNode ? 'true' : 'false');
|
|
||||||
}
|
|
||||||
else if (is_string($childNode) || is_numeric($childNode))
|
|
||||||
{
|
|
||||||
$childNode = new Text($childNode);
|
|
||||||
}
|
|
||||||
if (!($childNode instanceof Node))
|
|
||||||
{
|
|
||||||
throw new HTML5Error(HTML5Error::INVALID_NODE);
|
|
||||||
}
|
|
||||||
$childNode->setParent($this);
|
|
||||||
return $childNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (!$this->isEmpty($children))
|
||||||
* Removes the first instance of child from this.
|
{
|
||||||
* Once the first instance of the child
|
if (!is_array($children))
|
||||||
* is removed, this function will return. It returns
|
{
|
||||||
* true if a child was removed and false if no child
|
$children = array($children);
|
||||||
* was removed.
|
}
|
||||||
* @method removeChild
|
if (is_array($children))
|
||||||
* @param {Node} [childNode=null] The node to remove
|
{
|
||||||
* @return {Boolean} If successfully removed
|
foreach ($children as $child)
|
||||||
*/
|
{
|
||||||
public function removeChild(Node $childNode = null)
|
$this->addChild($child);
|
||||||
{
|
}
|
||||||
if ($this->isEmpty($childNode))
|
}
|
||||||
{
|
}
|
||||||
throw new HTML5Error(HTML5Error::EMPTY_CHILD);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for($i = 0; $i < count($this->_children); $i++)
|
/**
|
||||||
{
|
* Add's a child to this NodeContainer. The child to add cannot be null.
|
||||||
$child = $this->_children[$i];
|
* @method addChild
|
||||||
if ($child === $childNode)
|
* @param {Node|String|Number|Boolean} childNode The child Node to add
|
||||||
{
|
* @return {NodeContainer} The instance of this container
|
||||||
unset($this->_children[$i]);
|
*/
|
||||||
return true;
|
public function addChild($childNode)
|
||||||
}
|
{
|
||||||
}
|
array_push($this->_children, $this->prepareChild($childNode));
|
||||||
return false;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a child as a specific index
|
|
||||||
* @method removeChildAt
|
|
||||||
* @param {int} index The index to remove child at
|
|
||||||
* @return {NodeContainer} The instance of the node container
|
|
||||||
*/
|
|
||||||
public function removeChildAt($index)
|
|
||||||
{
|
|
||||||
if ($index >= $this->_children || $index < 0)
|
|
||||||
{
|
|
||||||
throw new HTML5Error(HTML5Error::OUT_OF_BOUNDS, $index);
|
|
||||||
}
|
|
||||||
array_splice($this->_children, $index, 1);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all children attached to this Node container
|
* Add a child at a specific index
|
||||||
* @method removeChildren
|
* @method addChildAt
|
||||||
* @return {NodeContainer} The instance of the node container
|
* @param {Node|String|Number|Boolean} childNode The child Node to add
|
||||||
*/
|
* @param {int} index The index to add child at, 0 is top
|
||||||
public function removeChildren()
|
* @return {NodeContainer} The instance of this container
|
||||||
{
|
*/
|
||||||
unset($this->_children);
|
public function addChildAt($childNode, $index)
|
||||||
$this->_children = array();
|
{
|
||||||
return $this;
|
if ($index < 0)
|
||||||
}
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::OUT_OF_BOUNDS, $index);
|
||||||
|
}
|
||||||
|
$childNode = $this->prepareChild($childNode);
|
||||||
|
if ($index == 0)
|
||||||
|
{
|
||||||
|
array_unshift($this->_children, $childNode);
|
||||||
|
}
|
||||||
|
else if ($index > (count($this->_children) - 1))
|
||||||
|
{
|
||||||
|
$this->addChild($childNode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_splice($this->_children, $index , 0, array($childNode));
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of all children attached to this Node container.
|
* Before adding a child, we should do some checking for basic types
|
||||||
* @method getChildren
|
* and convert it into a more useable Node object.
|
||||||
* @return {Array} The collection of Node objects
|
* @method prepareChild
|
||||||
*/
|
* @protected
|
||||||
public function getChildren()
|
* @param {Node|String|Number|Boolean} childNode The child node to add
|
||||||
{
|
* @return {Node} The child node
|
||||||
return $this->_children;
|
*/
|
||||||
}
|
protected function prepareChild($childNode)
|
||||||
|
{
|
||||||
|
if ($this->isEmpty($childNode))
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::EMPTY_CHILD);
|
||||||
|
}
|
||||||
|
if (is_bool($childNode))
|
||||||
|
{
|
||||||
|
$childNode = new Text($childNode ? 'true' : 'false');
|
||||||
|
}
|
||||||
|
else if (is_string($childNode) || is_numeric($childNode))
|
||||||
|
{
|
||||||
|
$childNode = new Text($childNode);
|
||||||
|
}
|
||||||
|
if (!($childNode instanceof Node))
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::INVALID_NODE);
|
||||||
|
}
|
||||||
|
$childNode->setParent($this);
|
||||||
|
return $childNode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a child of this Node container at given
|
* Removes the first instance of child from this.
|
||||||
* index. If no index is passed in, getChild()
|
* Once the first instance of the child
|
||||||
* will return the child at index zero (0).
|
* is removed, this function will return. It returns
|
||||||
* @method getChildAt
|
* true if a child was removed and false if no child
|
||||||
* @param {int} [index=0] The index to fetch child Node at
|
* was removed.
|
||||||
* @return {Node} The child Node
|
* @method removeChild
|
||||||
*/
|
* @param {Node} [childNode=null] The node to remove
|
||||||
public function getChildAt($index = 0)
|
* @return {Boolean} If successfully removed
|
||||||
{
|
*/
|
||||||
return $this->_children[$index];
|
public function removeChild(Node $childNode = null)
|
||||||
}
|
{
|
||||||
|
if ($this->isEmpty($childNode))
|
||||||
/**
|
{
|
||||||
* Close the writing of this container as HTML
|
throw new HTML5Error(HTML5Error::EMPTY_CHILD);
|
||||||
* @method writeClose
|
}
|
||||||
* @protected
|
|
||||||
* @return {String} The closing HTML tag element
|
|
||||||
*/
|
|
||||||
protected function writeClose()
|
|
||||||
{
|
|
||||||
return "</" . $this->_tag . ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
for ($i = 0; $i < count($this->_children); $i++)
|
||||||
* Write to HTML
|
{
|
||||||
* @method __toString
|
$child = $this->_children[$i];
|
||||||
* @return {String} The string representation of this HTML node
|
if ($child === $childNode)
|
||||||
*/
|
{
|
||||||
public function __toString()
|
unset($this->_children[$i]);
|
||||||
{
|
return true;
|
||||||
$buffer = $this->writeOpen(false);
|
}
|
||||||
foreach($this->_children as $child)
|
}
|
||||||
{
|
return false;
|
||||||
$buffer .= $child->__toString();
|
}
|
||||||
}
|
|
||||||
$buffer .= $this->writeClose();
|
|
||||||
|
|
||||||
return $buffer;
|
/**
|
||||||
}
|
* Remove a child as a specific index
|
||||||
}
|
* @method removeChildAt
|
||||||
|
* @param {int} index The index to remove child at
|
||||||
|
* @return {NodeContainer} The instance of the node container
|
||||||
|
*/
|
||||||
|
public function removeChildAt($index)
|
||||||
|
{
|
||||||
|
if ($index >= $this->_children || $index < 0)
|
||||||
|
{
|
||||||
|
throw new HTML5Error(HTML5Error::OUT_OF_BOUNDS, $index);
|
||||||
|
}
|
||||||
|
array_splice($this->_children, $index, 1);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all children attached to this Node container
|
||||||
|
* @method removeChildren
|
||||||
|
* @return {NodeContainer} The instance of the node container
|
||||||
|
*/
|
||||||
|
public function removeChildren()
|
||||||
|
{
|
||||||
|
unset($this->_children);
|
||||||
|
$this->_children = array();
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of all children attached to this Node container.
|
||||||
|
* @method getChildren
|
||||||
|
* @return {Array} The collection of Node objects
|
||||||
|
*/
|
||||||
|
public function getChildren()
|
||||||
|
{
|
||||||
|
return $this->_children;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a child of this Node container at given
|
||||||
|
* index. If no index is passed in, getChild()
|
||||||
|
* will return the child at index zero (0).
|
||||||
|
* @method getChildAt
|
||||||
|
* @param {int} [index=0] The index to fetch child Node at
|
||||||
|
* @return {Node} The child Node
|
||||||
|
*/
|
||||||
|
public function getChildAt($index = 0)
|
||||||
|
{
|
||||||
|
return $this->_children[$index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the writing of this container as HTML
|
||||||
|
* @method writeClose
|
||||||
|
* @protected
|
||||||
|
* @return {String} The closing HTML tag element
|
||||||
|
*/
|
||||||
|
protected function writeClose()
|
||||||
|
{
|
||||||
|
return "</" . $this->_tag . ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to HTML
|
||||||
|
* @method __toString
|
||||||
|
* @return {String} The string representation of this HTML node
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
$buffer = $this->writeOpen(false);
|
||||||
|
foreach ($this->_children as $child)
|
||||||
|
{
|
||||||
|
$buffer .= $child->__toString();
|
||||||
|
}
|
||||||
|
$buffer .= $this->writeClose();
|
||||||
|
|
||||||
|
return $buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
@ -1,72 +1,70 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Convenience class for creating an ordered or un-ordered list.
|
* Convenience class for creating an ordered or un-ordered list.
|
||||||
*
|
*
|
||||||
* $list = new Canteen\HTML5\SimpleList(
|
* $list = new Canteen\HTML5\SimpleList(
|
||||||
* array(
|
* array(
|
||||||
* html('b', 'first'),
|
* html('b', 'first'),
|
||||||
* 'second',
|
* 'second',
|
||||||
* 'third',
|
* 'third',
|
||||||
* array(
|
* array(
|
||||||
* 'sub-third',
|
* 'sub-third',
|
||||||
* 'sub-forth'
|
* 'sub-forth'
|
||||||
* )
|
* )
|
||||||
* )
|
* )
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* @class SimpleList
|
* @class SimpleList
|
||||||
* @extends NodeContainer
|
* @extends NodeContainer
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Array} [elements=null] The array of child Nodes, Strings, etc.
|
* @param {Array} [elements=null] The array of child Nodes, Strings, etc.
|
||||||
* @param {String|Dictionary} [attributes=null] The optional attributes
|
* @param {String|Dictionary} [attributes=null] The optional attributes
|
||||||
* @param {String} [type='ul'] The type of list, either ul or ol
|
* @param {String} [type='ul'] The type of list, either ul or ol
|
||||||
*/
|
*/
|
||||||
class SimpleList extends NodeContainer
|
class SimpleList extends NodeContainer
|
||||||
{
|
{
|
||||||
public function __construct($elements=null, $attributes=null, $type='ul')
|
public function __construct($elements=null, $attributes=null, $type='ul')
|
||||||
{
|
{
|
||||||
parent::__construct($type, null, $attributes);
|
parent::__construct($type, null, $attributes);
|
||||||
|
|
||||||
if ($elements != null)
|
|
||||||
{
|
|
||||||
assert(is_array($elements));
|
|
||||||
|
|
||||||
foreach($elements as $child)
|
if ($elements != null)
|
||||||
{
|
{
|
||||||
$this->addChild($child);
|
assert(is_array($elements));
|
||||||
}
|
|
||||||
}
|
foreach ($elements as $child)
|
||||||
}
|
{
|
||||||
|
$this->addChild($child);
|
||||||
/**
|
}
|
||||||
* Override for the prepareChild method on NodeContainer which
|
}
|
||||||
* wraps each elements in a list item
|
}
|
||||||
* @method prepareChild
|
|
||||||
* @protected
|
/**
|
||||||
* @param {Node|String|Number|Boolean|Array} childNode The child node to add, an array will get converted into another list elements.
|
* Override for the prepareChild method on NodeContainer which
|
||||||
* @return {Node} The child node
|
* wraps each elements in a list item
|
||||||
*/
|
* @method prepareChild
|
||||||
protected function prepareChild($childNode)
|
* @protected
|
||||||
{
|
* @param {Node|String|Number|Boolean|Array} childNode The child node to add, an array will get converted into another list elements.
|
||||||
// Recursively create new lists for each array
|
* @return {Node} The child node
|
||||||
if (is_array($childNode))
|
*/
|
||||||
{
|
protected function prepareChild($childNode)
|
||||||
$list = new SimpleList($childNode, null, $this->_tag);
|
{
|
||||||
return $this->prepareChild($list);
|
// Recursively create new lists for each array
|
||||||
}
|
if (is_array($childNode))
|
||||||
else
|
{
|
||||||
{
|
$list = new SimpleList($childNode, null, $this->_tag);
|
||||||
$childNode = parent::prepareChild($childNode);
|
return $this->prepareChild($list);
|
||||||
return html('li', $childNode);
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
}
|
$childNode = parent::prepareChild($childNode);
|
||||||
|
return html('li', $childNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
@ -1,413 +1,429 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The HTML5 Specification
|
* The HTML5 Specification
|
||||||
*
|
*
|
||||||
* @class Specification
|
* @class Specification
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
class Specification
|
class Specification
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The list of all tags and their specific attributes
|
* The list of all tags and their specific attributes
|
||||||
* @property {array} TAGS
|
* @property {array} TAGS
|
||||||
* @final
|
* @final
|
||||||
* @readOnly
|
* @readOnly
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
public static $TAGS = array(
|
public static $TAGS = array(
|
||||||
'a' => array(
|
'a' => array(
|
||||||
'href',
|
'href',
|
||||||
'hreflang',
|
'hreflang',
|
||||||
'media',
|
'media',
|
||||||
'rel',
|
'rel',
|
||||||
'target',
|
'target',
|
||||||
'type'
|
'type'
|
||||||
),
|
),
|
||||||
'abbr' => array(),
|
'abbr' => array(),
|
||||||
'address' => array(),
|
'address' => array(),
|
||||||
'area' => array(
|
'area' => array(
|
||||||
'alt',
|
'alt',
|
||||||
'coords',
|
'coords',
|
||||||
'href',
|
'href',
|
||||||
'hreflang',
|
'hreflang',
|
||||||
'media',
|
'media',
|
||||||
'rel',
|
'rel',
|
||||||
'shape',
|
'shape',
|
||||||
'target',
|
'target',
|
||||||
'type'
|
'type'
|
||||||
),
|
),
|
||||||
'article' => array(),
|
'article' => array(),
|
||||||
'aside' => array(),
|
'aside' => array(),
|
||||||
'audio' => array(
|
'audio' => array(
|
||||||
'autoplay',
|
'autoplay',
|
||||||
'controls',
|
'controls',
|
||||||
'loop',
|
'loop',
|
||||||
'muted',
|
'muted',
|
||||||
'preload',
|
'preload',
|
||||||
'src'
|
'src'
|
||||||
),
|
),
|
||||||
'b' => array(),
|
'b' => array(),
|
||||||
'base' => array(
|
'base' => array(
|
||||||
'href',
|
'href',
|
||||||
'target'
|
'target'
|
||||||
),
|
),
|
||||||
'bdo' => array(),
|
'bdo' => array(),
|
||||||
'blockquote' => array('cite'),
|
'blockquote' => array(
|
||||||
'body' => array(),
|
'cite'
|
||||||
'br' => array(),
|
),
|
||||||
'button' => array(
|
'body' => array(),
|
||||||
'autofocus',
|
'br' => array(),
|
||||||
'disabled',
|
'button' => array(
|
||||||
'form',
|
'autofocus',
|
||||||
'formaction',
|
'disabled',
|
||||||
'formenctype',
|
'form',
|
||||||
'formmethod',
|
'formaction',
|
||||||
'formnovalidate',
|
'formenctype',
|
||||||
'formtarget',
|
'formmethod',
|
||||||
'name',
|
'formnovalidate',
|
||||||
'type',
|
'formtarget',
|
||||||
'value'
|
'name',
|
||||||
),
|
'type',
|
||||||
'canvas' => array(
|
'value'
|
||||||
'height',
|
),
|
||||||
'width'
|
'canvas' => array(
|
||||||
),
|
'height',
|
||||||
'caption' => array(),
|
'width'
|
||||||
'cite' => array(),
|
),
|
||||||
'code' => array(),
|
'caption' => array(),
|
||||||
'col' => null,
|
'cite' => array(),
|
||||||
'colgroup' => array('span'),
|
'code' => array(),
|
||||||
'command' => array(
|
'col' => null,
|
||||||
'checked',
|
'colgroup' => array(
|
||||||
'disabled',
|
'span'
|
||||||
'icon',
|
),
|
||||||
'label',
|
'command' => array(
|
||||||
'radiogroup',
|
'checked',
|
||||||
'type'
|
'disabled',
|
||||||
),
|
'icon',
|
||||||
'datalist' => array(),
|
'label',
|
||||||
'dd' => array(),
|
'radiogroup',
|
||||||
'del' => array(
|
'type'
|
||||||
'cite',
|
),
|
||||||
'datetime'
|
'datalist' => array(),
|
||||||
),
|
'dd' => array(),
|
||||||
'dfn' => array(),
|
'del' => array(
|
||||||
'div' => array(),
|
'cite',
|
||||||
'dl' => array(),
|
'datetime'
|
||||||
'dt' => array(),
|
),
|
||||||
'em' => array(),
|
'dfn' => array(),
|
||||||
'embed' => array(
|
'div' => array(),
|
||||||
'height',
|
'dl' => array(),
|
||||||
'src',
|
'dt' => array(),
|
||||||
'type',
|
'em' => array(),
|
||||||
'width'
|
'embed' => array(
|
||||||
),
|
'height',
|
||||||
'fieldset' => array(
|
'src',
|
||||||
'disabled',
|
'type',
|
||||||
'form_id',
|
'width'
|
||||||
'text'
|
),
|
||||||
),
|
'fieldset' => array(
|
||||||
'figcaption' => array(),
|
'disabled',
|
||||||
'figure' => array(),
|
'form_id',
|
||||||
'footer' => array(),
|
'text'
|
||||||
'form' => array(
|
),
|
||||||
'accept',
|
'figcaption' => array(),
|
||||||
'accept-charset',
|
'figure' => array(),
|
||||||
'action',
|
'footer' => array(),
|
||||||
'autocomplete',
|
'form' => array(
|
||||||
'enctype',
|
'accept',
|
||||||
'method',
|
'accept-charset',
|
||||||
'name',
|
'action',
|
||||||
'novalidate',
|
'autocomplete',
|
||||||
'target'
|
'enctype',
|
||||||
),
|
'method',
|
||||||
'h1' => array(),
|
'name',
|
||||||
'h2' => array(),
|
'novalidate',
|
||||||
'h3' => array(),
|
'target'
|
||||||
'h4' => array(),
|
),
|
||||||
'h5' => array(),
|
'h1' => array(),
|
||||||
'h6' => array(),
|
'h2' => array(),
|
||||||
'head' => array(),
|
'h3' => array(),
|
||||||
'header' => array(),
|
'h4' => array(),
|
||||||
'hgroup' => array(),
|
'h5' => array(),
|
||||||
'hr' => array(),
|
'h6' => array(),
|
||||||
'html' => array('manifest'),
|
'head' => array(),
|
||||||
'img' => array(
|
'header' => array(),
|
||||||
'alt',
|
'hgroup' => array(),
|
||||||
'crossorigin',
|
'hr' => array(),
|
||||||
'height',
|
'html' => array(
|
||||||
'src',
|
'manifest'
|
||||||
'usemap',
|
),
|
||||||
'width'
|
'img' => array(
|
||||||
),
|
'alt',
|
||||||
'i' => array(),
|
'crossorigin',
|
||||||
'iframe' => array(
|
'height',
|
||||||
'src',
|
'src',
|
||||||
'srcdoc',
|
'usemap',
|
||||||
'name',
|
'width'
|
||||||
'width',
|
),
|
||||||
'height'
|
'i' => array(),
|
||||||
),
|
'iframe' => array(
|
||||||
'input' => array(
|
'src',
|
||||||
'accept',
|
'srcdoc',
|
||||||
'alt',
|
'name',
|
||||||
'autocomplete',
|
'width',
|
||||||
'autofocus',
|
'height'
|
||||||
'checked',
|
),
|
||||||
'disabled',
|
'input' => array(
|
||||||
'form',
|
'accept',
|
||||||
'formaction',
|
'alt',
|
||||||
'formenctype',
|
'autocomplete',
|
||||||
'formmethod',
|
'autofocus',
|
||||||
'formnovalidate',
|
'checked',
|
||||||
'formtarget',
|
'disabled',
|
||||||
'height',
|
'form',
|
||||||
'list',
|
'formaction',
|
||||||
'max',
|
'formenctype',
|
||||||
'maxlength',
|
'formmethod',
|
||||||
'min',
|
'formnovalidate',
|
||||||
'multiple',
|
'formtarget',
|
||||||
'name',
|
'height',
|
||||||
'pattern',
|
'list',
|
||||||
'placeholder',
|
'max',
|
||||||
'readonly',
|
'maxlength',
|
||||||
'required',
|
'min',
|
||||||
'size',
|
'multiple',
|
||||||
'src',
|
'name',
|
||||||
'step',
|
'pattern',
|
||||||
'type',
|
'placeholder',
|
||||||
'value',
|
'readonly',
|
||||||
'width'
|
'required',
|
||||||
),
|
'size',
|
||||||
'keygen' => array(
|
'src',
|
||||||
'autofocus',
|
'step',
|
||||||
'challenge',
|
'type',
|
||||||
'disabled',
|
'value',
|
||||||
'form',
|
'width'
|
||||||
'keytype',
|
),
|
||||||
'name'
|
'keygen' => array(
|
||||||
),
|
'autofocus',
|
||||||
'label' => array(
|
'challenge',
|
||||||
'for',
|
'disabled',
|
||||||
'form'
|
'form',
|
||||||
),
|
'keytype',
|
||||||
'legend' => array(),
|
'name'
|
||||||
'li' => array(),
|
),
|
||||||
'link' => array(
|
'label' => array(
|
||||||
'href',
|
'for',
|
||||||
'hreflang',
|
'form'
|
||||||
'media',
|
),
|
||||||
'rel',
|
'legend' => array(),
|
||||||
'sizes',
|
'li' => array(),
|
||||||
'type'
|
'link' => array(
|
||||||
),
|
'href',
|
||||||
'map' => array('name'),
|
'hreflang',
|
||||||
'mark' => array(),
|
'media',
|
||||||
'menu' => array(),
|
'rel',
|
||||||
'meta' => array(
|
'sizes',
|
||||||
'charset',
|
'type'
|
||||||
'content',
|
),
|
||||||
'http-equiv',
|
'map' => array(
|
||||||
'name'
|
'name'
|
||||||
),
|
),
|
||||||
'meter' => array(
|
'mark' => array(),
|
||||||
'form',
|
'menu' => array(),
|
||||||
'heigh',
|
'meta' => array(
|
||||||
'low',
|
'charset',
|
||||||
'max',
|
'content',
|
||||||
'min',
|
'http-equiv',
|
||||||
'optimum',
|
'name'
|
||||||
'value'
|
),
|
||||||
),
|
'meter' => array(
|
||||||
'nav' => array(),
|
'form',
|
||||||
'noscript' => array(),
|
'heigh',
|
||||||
'object' => array(
|
'low',
|
||||||
'data',
|
'max',
|
||||||
'form',
|
'min',
|
||||||
'height',
|
'optimum',
|
||||||
'name',
|
'value'
|
||||||
'type',
|
),
|
||||||
'usemap',
|
'nav' => array(),
|
||||||
'width'
|
'noscript' => array(),
|
||||||
),
|
'object' => array(
|
||||||
'ol' => array(
|
'data',
|
||||||
'reversed',
|
'form',
|
||||||
'start',
|
'height',
|
||||||
'type'
|
'name',
|
||||||
),
|
'type',
|
||||||
'optgroup' => array(
|
'usemap',
|
||||||
'disabled',
|
'width'
|
||||||
'label'
|
),
|
||||||
),
|
'ol' => array(
|
||||||
'option' => array(
|
'reversed',
|
||||||
'disabled',
|
'start',
|
||||||
'label',
|
'type'
|
||||||
'selected',
|
),
|
||||||
'value'
|
'optgroup' => array(
|
||||||
),
|
'disabled',
|
||||||
'output' => array(
|
'label'
|
||||||
'for',
|
),
|
||||||
'form',
|
'option' => array(
|
||||||
'name'
|
'disabled',
|
||||||
),
|
'label',
|
||||||
'p' => array(),
|
'selected',
|
||||||
'param' => array(
|
'value'
|
||||||
'name',
|
),
|
||||||
'value'
|
'output' => array(
|
||||||
),
|
'for',
|
||||||
'pre' => array(),
|
'form',
|
||||||
'progress' => array(
|
'name'
|
||||||
'max',
|
),
|
||||||
'value'
|
'p' => array(),
|
||||||
),
|
'param' => array(
|
||||||
'q' => array('cite'),
|
'name',
|
||||||
'rp' => array(),
|
'value'
|
||||||
'rt' => array(),
|
),
|
||||||
'ruby' => array(),
|
'pre' => array(),
|
||||||
's' => array(),
|
'progress' => array(
|
||||||
'sample' => array(),
|
'max',
|
||||||
'script' => array(
|
'value'
|
||||||
'async',
|
),
|
||||||
'charset',
|
'q' => array(
|
||||||
'defer',
|
'cite'
|
||||||
'src',
|
),
|
||||||
'type'
|
'rp' => array(),
|
||||||
),
|
'rt' => array(),
|
||||||
'section' => array(),
|
'ruby' => array(),
|
||||||
'select' => array(
|
's' => array(),
|
||||||
'autofocus',
|
'sample' => array(),
|
||||||
'disabled',
|
'script' => array(
|
||||||
'form',
|
'async',
|
||||||
'multiple',
|
'charset',
|
||||||
'name',
|
'defer',
|
||||||
'required',
|
'src',
|
||||||
'size'
|
'type'
|
||||||
),
|
),
|
||||||
'small' => array(),
|
'section' => array(),
|
||||||
'source' => array('media',
|
'select' => array(
|
||||||
'src',
|
'autofocus',
|
||||||
'type'
|
'disabled',
|
||||||
),
|
'form',
|
||||||
'span' => array(),
|
'multiple',
|
||||||
'strong' => array(),
|
'name',
|
||||||
'style' => array('media',
|
'required',
|
||||||
'scoped',
|
'size'
|
||||||
'type'
|
),
|
||||||
),
|
'small' => array(),
|
||||||
'sub' => array(),
|
'source' => array(
|
||||||
'table' => array('border'),
|
'media',
|
||||||
'tbody' => array(),
|
'src',
|
||||||
'td' => array(
|
'type'
|
||||||
'colspan',
|
),
|
||||||
'headers',
|
'span' => array(),
|
||||||
'scope'
|
'strong' => array(),
|
||||||
),
|
'style' => array(
|
||||||
'textarea' => array(
|
'media',
|
||||||
'autofocus',
|
'scoped',
|
||||||
'cols',
|
'type'
|
||||||
'disabled',
|
),
|
||||||
'form',
|
'sub' => array(),
|
||||||
'maxlength',
|
'table' => array(
|
||||||
'name',
|
'border'
|
||||||
'placeholder',
|
),
|
||||||
'readonly',
|
'tbody' => array(),
|
||||||
'required',
|
'td' => array(
|
||||||
'row',
|
'colspan',
|
||||||
'wrap'
|
'headers',
|
||||||
),
|
'scope'
|
||||||
'tfoot' => array(),
|
),
|
||||||
'th' => array(
|
'textarea' => array(
|
||||||
'colspan',
|
'autofocus',
|
||||||
'headers',
|
'cols',
|
||||||
'rowspan',
|
'disabled',
|
||||||
'scope'
|
'form',
|
||||||
),
|
'maxlength',
|
||||||
'thead' => array(),
|
'name',
|
||||||
'time' => array('datetime'),
|
'placeholder',
|
||||||
'title' => array(),
|
'readonly',
|
||||||
'tr' => array(),
|
'required',
|
||||||
'track' => array(
|
'row',
|
||||||
'default',
|
'wrap'
|
||||||
'kind',
|
),
|
||||||
'label',
|
'tfoot' => array(),
|
||||||
'src',
|
'th' => array(
|
||||||
'srclang'
|
'colspan',
|
||||||
),
|
'headers',
|
||||||
'u' => array(),
|
'rowspan',
|
||||||
'ul' => array(),
|
'scope'
|
||||||
'var' => array(),
|
),
|
||||||
'video' => array(
|
'thead' => array(),
|
||||||
'autoplay',
|
'time' => array(
|
||||||
'controls',
|
'datetime'
|
||||||
'height',
|
),
|
||||||
'loop',
|
'title' => array(),
|
||||||
'muted',
|
'tr' => array(),
|
||||||
'poster',
|
'track' => array(
|
||||||
'preload',
|
'default',
|
||||||
'src',
|
'kind',
|
||||||
'width'
|
'label',
|
||||||
),
|
'src',
|
||||||
'wbr' => null
|
'srclang'
|
||||||
);
|
),
|
||||||
|
'u' => array(),
|
||||||
|
'ul' => array(),
|
||||||
|
'var' => array(),
|
||||||
|
'video' => array(
|
||||||
|
'autoplay',
|
||||||
|
'controls',
|
||||||
|
'height',
|
||||||
|
'loop',
|
||||||
|
'muted',
|
||||||
|
'poster',
|
||||||
|
'preload',
|
||||||
|
'src',
|
||||||
|
'width'
|
||||||
|
),
|
||||||
|
'wbr' => null
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of self-closing tags
|
* The list of self-closing tags
|
||||||
* @property {array} SELF_CLOSING
|
* @property {array} SELF_CLOSING
|
||||||
* @final
|
* @final
|
||||||
* @readOnly
|
* @readOnly
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
public static $SELF_CLOSING = array(
|
public static $SELF_CLOSING = array(
|
||||||
'area',
|
'area',
|
||||||
'base',
|
'base',
|
||||||
'br',
|
'br',
|
||||||
'col',
|
'col',
|
||||||
'command',
|
'command',
|
||||||
'embed',
|
'embed',
|
||||||
'hr',
|
'hr',
|
||||||
'img',
|
'img',
|
||||||
'input',
|
'input',
|
||||||
'keygen',
|
'keygen',
|
||||||
'link',
|
'link',
|
||||||
'meta',
|
'meta',
|
||||||
'param',
|
'param',
|
||||||
'source',
|
'source',
|
||||||
'track',
|
'track',
|
||||||
'wbr'
|
'wbr'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global valid attributes for all HTML5 tags
|
* Global valid attributes for all HTML5 tags
|
||||||
* See: http://www.w3.org/TR/html5/dom.html#global-attributes
|
* See: http://www.w3.org/TR/html5/dom.html#global-attributes
|
||||||
* @property {Array} ATTRIBUTES
|
* @property {Array} ATTRIBUTES
|
||||||
* @final
|
* @final
|
||||||
* @static
|
* @static
|
||||||
* @readOnly
|
* @readOnly
|
||||||
*/
|
*/
|
||||||
public static $ATTRIBUTES = array(
|
public static $ATTRIBUTES = array(
|
||||||
|
|
||||||
// Event handler context attributes
|
// Event handler context attributes
|
||||||
'onabort', 'onblur', 'oncancel', 'oncanplay', 'oncanplaythrough',
|
'onabort', 'onblur', 'oncancel', 'oncanplay', 'oncanplaythrough',
|
||||||
'onchange', 'onclick', 'oncuechange', 'ondblclick', 'ondurationchange',
|
'onchange', 'onclick', 'oncuechange', 'ondblclick', 'ondurationchange',
|
||||||
'onemptied', 'onended', 'onerror', 'onfocus', 'oninput', 'oninvalid',
|
'onemptied', 'onended', 'onerror', 'onfocus', 'oninput', 'oninvalid',
|
||||||
'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata',
|
'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata',
|
||||||
'onloadedmetadata', 'onloadstart', 'onmousedown', 'onmouseenter',
|
'onloadedmetadata', 'onloadstart', 'onmousedown', 'onmouseenter',
|
||||||
'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup',
|
'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup',
|
||||||
'onmousewheel', 'onpause', 'onplay', 'onplaying', 'onprogress',
|
'onmousewheel', 'onpause', 'onplay', 'onplaying', 'onprogress',
|
||||||
'onratechange', 'onreset', 'onresize', 'onscroll', 'onseeked',
|
'onratechange', 'onreset', 'onresize', 'onscroll', 'onseeked',
|
||||||
'onseeking', 'onselect', 'onshow', 'onstalled', 'onsubmit', 'onsuspend',
|
'onseeking', 'onselect', 'onshow', 'onstalled', 'onsubmit', 'onsuspend',
|
||||||
'ontimeupdate', 'ontoggle', 'onvolumechange', 'onwaiting',
|
'ontimeupdate', 'ontoggle', 'onvolumechange', 'onwaiting',
|
||||||
|
|
||||||
// Allow-able on all tags
|
// Allow-able on all tags
|
||||||
'accesskey', 'class', 'contenteditable', 'contextmenu', 'dir', 'draggable',
|
'accesskey', 'class', 'contenteditable', 'contextmenu', 'dir', 'draggable',
|
||||||
'dropzone', 'hidden', 'id', 'lang', 'spellcheck', 'style', 'tabindex',
|
'dropzone', 'hidden', 'id', 'lang', 'spellcheck', 'style', 'tabindex',
|
||||||
'title', 'translate'
|
'title', 'translate'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
161
src/Table.php
161
src/Table.php
@ -1,86 +1,87 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Canteen\HTML5
|
* @module Canteen\HTML5
|
||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Convenience class for building a Table. Useful for display
|
* Convenience class for building a Table. Useful for display
|
||||||
* rows of data from a database or another collection
|
* rows of data from a database or another collection
|
||||||
* of associative arrays.
|
* of associative arrays.
|
||||||
*
|
*
|
||||||
* $table = new Canteen\HTML5\Table(
|
* $table = new Canteen\HTML5\Table(
|
||||||
* array(
|
* array(
|
||||||
* array('id'=>1, 'first'=>'James', 'last'=>'Smith'),
|
* array('id'=>1, 'first'=>'James', 'last'=>'Smith'),
|
||||||
* array('id'=>2, 'first'=>'Mary', 'last'=>'Denver'),
|
* array('id'=>2, 'first'=>'Mary', 'last'=>'Denver'),
|
||||||
* array('id'=>3, 'first'=>'Charlie', 'last'=>'Rose')
|
* array('id'=>3, 'first'=>'Charlie', 'last'=>'Rose')
|
||||||
* ),
|
* ),
|
||||||
* array('ID', 'First Name', 'Last Name')
|
* array('ID', 'First Name', 'Last Name')
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* @class Table
|
* @class Table
|
||||||
* @extends NodeContainer
|
* @extends NodeContainer
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Array} data The collection of Dictionary objects
|
* @param {Array} data The collection of Dictionary objects
|
||||||
* @param {Array} [headers=null] An optional collection of header labels for each value
|
* @param {Array} [headers=null] An optional collection of header labels for each value
|
||||||
* @param {String} [checkbox=null] If we should add a checkbox to each row, this is the name
|
* @param {String} [checkbox=null] If we should add a checkbox to each row, this is the name
|
||||||
* of the attribute to use as a value. For instance `array('id'=>2)` is
|
* of the attribute to use as a value. For instance `array('id'=>2)` is
|
||||||
* `<input type="checkbox" name="id[]" value="2">`
|
* `<input type="checkbox" name="id[]" value="2">`
|
||||||
*/
|
*/
|
||||||
class Table extends NodeContainer
|
class Table extends NodeContainer
|
||||||
{
|
{
|
||||||
public function __construct($data, $headers=null, $checkbox=null)
|
public function __construct($data, $headers=null, $checkbox=null)
|
||||||
{
|
{
|
||||||
parent::__construct('table', null, null);
|
parent::__construct('table', null, null);
|
||||||
|
|
||||||
if ($headers != null && is_array($headers))
|
|
||||||
{
|
|
||||||
$head = html('thead');
|
|
||||||
$this->addChild($head);
|
|
||||||
|
|
||||||
$row = html('tr');
|
|
||||||
|
|
||||||
if ($checkbox != null)
|
|
||||||
{
|
|
||||||
$row->addChild(html('th', html('span', $checkbox)));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($headers as $header)
|
|
||||||
{
|
|
||||||
$row->addChild(html('th', $header));
|
|
||||||
}
|
|
||||||
$head->addChild($row);
|
|
||||||
}
|
|
||||||
|
|
||||||
$body = html('tbody');
|
|
||||||
|
|
||||||
foreach($data as $d)
|
|
||||||
{
|
|
||||||
$row = html('tr');
|
|
||||||
|
|
||||||
if ($checkbox != null)
|
|
||||||
{
|
|
||||||
$td = html('td',
|
|
||||||
html(
|
|
||||||
'input',
|
|
||||||
'type=checkbox name='.$checkbox.'[] value='.$d[$checkbox]
|
|
||||||
),
|
|
||||||
'class='.$checkbox
|
|
||||||
);
|
|
||||||
$row->addChild($td);
|
|
||||||
}
|
|
||||||
foreach($d as $name=>$value)
|
|
||||||
{
|
|
||||||
if ($name == $checkbox) continue;
|
|
||||||
$td = html('td', $value, 'class='.$name);
|
|
||||||
$row->addChild($td);
|
|
||||||
}
|
|
||||||
$body->addChild($row);
|
|
||||||
}
|
|
||||||
$this->addChild($body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
if ($headers != null && is_array($headers))
|
||||||
|
{
|
||||||
|
$head = html('thead');
|
||||||
|
$this->addChild($head);
|
||||||
|
|
||||||
|
$row = html('tr');
|
||||||
|
|
||||||
|
if ($checkbox != null)
|
||||||
|
{
|
||||||
|
$row->addChild(html('th', html('span', $checkbox)));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($headers as $header)
|
||||||
|
{
|
||||||
|
$row->addChild(html('th', $header));
|
||||||
|
}
|
||||||
|
$head->addChild($row);
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = html('tbody');
|
||||||
|
|
||||||
|
foreach ($data as $d)
|
||||||
|
{
|
||||||
|
$row = html('tr');
|
||||||
|
|
||||||
|
if ($checkbox != null)
|
||||||
|
{
|
||||||
|
$td = html('td',
|
||||||
|
html(
|
||||||
|
'input',
|
||||||
|
'type=checkbox name=' . $checkbox . '[] value='.$d[$checkbox]
|
||||||
|
),
|
||||||
|
'class=' . $checkbox
|
||||||
|
);
|
||||||
|
$row->addChild($td);
|
||||||
|
}
|
||||||
|
foreach ($d as $name=>$value)
|
||||||
|
{
|
||||||
|
if ($name == $checkbox)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$td = html('td', $value, 'class=' . $name);
|
||||||
|
$row->addChild($td);
|
||||||
|
}
|
||||||
|
$body->addChild($row);
|
||||||
|
}
|
||||||
|
$this->addChild($body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
60
src/Text.php
60
src/Text.php
@ -5,35 +5,33 @@
|
|||||||
*/
|
*/
|
||||||
namespace Canteen\HTML5
|
namespace Canteen\HTML5
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Special Node representing plain text. Do not initiate this
|
* Special Node representing plain text. Do not initiate this
|
||||||
* class directly, it is created whenever a text is passed into
|
* class directly, it is created whenever a text is passed into
|
||||||
* a container tag:
|
* a container tag:
|
||||||
*
|
*
|
||||||
* echo html('p', 'Some Text Here');
|
* echo html('p', 'Some Text Here');
|
||||||
*
|
*
|
||||||
* @class Text
|
* @class Text
|
||||||
* @extends Node
|
* @extends Node
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} text the plain text string
|
* @param {String} text the plain text string
|
||||||
*/
|
*/
|
||||||
class Text extends Node
|
class Text extends Node
|
||||||
{
|
{
|
||||||
public function __construct($text)
|
public function __construct($text)
|
||||||
{
|
{
|
||||||
parent::__construct($text);
|
parent::__construct($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Write to HTML
|
|
||||||
* @method __toString
|
|
||||||
* @return {String} The string representation of this HTML node
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return $this->_tag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
/**
|
||||||
|
* Write to HTML
|
||||||
|
* @method __toString
|
||||||
|
* @return {String} The string representation of this HTML node
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->_tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
38
src/html.php
38
src/html.php
@ -1,25 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module global
|
* @module global
|
||||||
*/
|
*/
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The global method which is an alias for Canteen\HTML5\html()
|
* The global method which is an alias for Canteen\HTML5\html()
|
||||||
* to use this method globally call Canteen\HTML5\HTML5::useGlobal()
|
* to use this method globally call Canteen\HTML5\HTML5::useGlobal()
|
||||||
* @class html
|
* @class html
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} tag The name of the tag as a string for example 'tr', 'table', can be followed
|
* @param {String} tag The name of the tag as a string for example 'tr', 'table', can be followed
|
||||||
* by CSS selector, e.g. 'a#backButton' or 'a.button'
|
* by CSS selector, e.g. 'a#backButton' or 'a.button'
|
||||||
* @param {Dictionary|Node|String|Array} [childrenOrAttributes=null] If the tag is a NodeContainer, this can be an array
|
* @param {Dictionary|Node|String|Array} [childrenOrAttributes=null] If the tag is a NodeContainer, this can be an array
|
||||||
* of attributes, another html node or some text. If the tag is a single node, this can
|
* of attributes, another html node or some text. If the tag is a single node, this can
|
||||||
* be an array or chain of attributes
|
* be an array or chain of attributes
|
||||||
* @param {Dictionary|String} [attributes=null] The attributes list for container tags (e.g., 'class:selected')
|
* @param {Dictionary|String} [attributes=null] The attributes list for container tags (e.g., 'class:selected')
|
||||||
* @return {Node} Return the html node
|
* @return {Node} Return the html node
|
||||||
*/
|
*/
|
||||||
function html($tag, $childrenOrAttributes=null, $attributes=null)
|
function html($tag, $childrenOrAttributes=null, $attributes=null)
|
||||||
{
|
{
|
||||||
return Canteen\HTML5\html($tag, $childrenOrAttributes, $attributes);
|
return Canteen\HTML5\html($tag, $childrenOrAttributes, $attributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user