Compare commits

...

22 Commits

Author SHA1 Message Date
a5b4190d60 Declare this fork as a replacement of the original project 2021-07-10 00:26:10 +03:00
6d7736e222 Update build.properties 2021-07-09 23:24:20 +03:00
9f7340ec78 Fix code styling 2021-07-09 23:19:03 +03:00
7bdec8e106 Update composer info 2021-07-09 21:46:22 +03:00
a29ea00c29 Make the project compatible with PHP8 2021-07-09 21:34:54 +03:00
Matt Karl
91b4d067c9 Update build.properties 2014-12-26 09:10:30 -05:00
Matt Karl
3124421f7c Update composer.json 2014-12-26 09:10:15 -05:00
Matt Karl
19149925e6 Merge pull request #7 from JustBlackBird/add_iframe
Add iframe to specification
2014-12-26 09:07:53 -05:00
Dmitriy Simushev
9e874d95f6 Add iframe to specification 2014-12-25 14:26:27 +00:00
Matt Karl
76c68ac05e Update composer.json 2014-11-12 10:22:45 -05:00
Matt Karl
e9c28b5145 Merge pull request #6 from JustBlackBird/fix_add_child_at
Fix NodeContainer::addChildAt method
2014-11-12 10:21:58 -05:00
Dmitriy Simushev
72c2523ba7 Fix NodeContainer::addChildAt method 2014-11-12 12:17:23 +00:00
Matt Karl
c5d4f89045 Update composer.json 2014-11-11 09:44:49 -05:00
Matt Karl
3a5f8c49c5 Merge pull request #5 from JustBlackBird/fix_autoload
Fix autoload for "Canteen\HTML5\html" function
2014-11-11 09:44:33 -05:00
Dmitriy Simushev
f0d8f68c36 Fix autoload for "Canteen\HTML5\html" function 2014-11-11 11:14:37 +00:00
Matt Karl
48ded16c2f Fixed docs, bumped version 2014-11-10 17:42:23 -05:00
Matt Karl
9c3888aef3 Merge pull request #4 from JustBlackBird/untagged_container
Add untagged container
2014-11-10 17:40:49 -05:00
Dmitriy Simushev
c15142fdd8 Add untagged container 2014-11-10 10:57:01 +00:00
Matt Karl
047273e3b8 Added event attribute 2014-10-31 13:41:26 -04:00
Matt Karl
6c698ff9ee Update README.md 2014-10-31 12:39:38 -04:00
Matt Karl
946984b6e4 Fixed example, optional global function, added Specification 2014-10-31 12:34:20 -04:00
Matt Karl
497dc7140a Fixed docs version 2014-02-13 14:02:25 -05:00
19 changed files with 1971 additions and 1479 deletions

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013 Matt Karl Copyright (c) 2014 Matt Karl
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@ -29,6 +29,12 @@ require 'vendor/autoload.php';
To create an HTML node, simply call global `html` method, passing in the tag name and then any attributes. To create an HTML node, simply call global `html` method, passing in the tag name and then any attributes.
```php ```php
// Enable the global use of html()
Canteen\HTML5\HTML5::useGlobal();
// Turn on autoloading if not using composer's autoloading
Canteen\HTML5\HTML5::autoload();
echo html('img src=home.jpg'); echo html('img src=home.jpg');
echo html('img', 'src=home.jpg'); echo html('img', 'src=home.jpg');
echo html('img', array('src'=>'home.jpg')); echo html('img', array('src'=>'home.jpg'));

View File

@ -10,4 +10,4 @@ docs.helpers=${docs.themedir}/path.js
git=git git=git
git.docs=gh-pages git.docs=gh-pages
git.master=master git.master=master
version=1.0.0 version=1.1.5

View File

@ -1,32 +1,48 @@
{ {
"name": "canteen/html5", "name": "mibew/html5",
"description" : "Create dynamic, valid HTML5 markup with a simple an intuitive PHP API", "description" : "Create dynamic, valid HTML5 markup with a simple an intuitive PHP API",
"version" : "1.0.1", "version" : "1.1.5",
"type": "library", "type": "library",
"keywords": ["html5", "markup", "document", "html", "tags"], "keywords": [
"html5",
"markup",
"document",
"html",
"tags"
],
"license": "MIT", "license": "MIT",
"homepage" : "http://github.com/Canteen/CanteenHTML5", "homepage" : "http://github.com/Mibew/CanteenHTML5",
"time": "2013-10-12", "time": "2021-07-09",
"authors": [ "authors": [
{ {
"name": "Matt Karl", "name": "Matt Karl",
"email": "matt@mattkarl.com", "email": "matt@mattkarl.com",
"homepage": "http://github.com/bigtimebuddy", "homepage": "http://github.com/bigtimebuddy"
"role": "Developer" },
{
"name": "Mibew Messenger project",
"homepage": "https://mibew.org/"
} }
], ],
"autoload": { "autoload": {
"psr-4": {"Canteen\\HTML5\\": "src/"}, "psr-4": {
"files": ["src/html.php"] "Canteen\\HTML5\\": "src/"
},
"files": [
"src/HTML5.php"
]
}, },
"require": { "require": {
"php": ">=5.3.0" "php": ">=5.3.0"
}, },
"replace": {
"canteen/html5": "~1.1.4"
},
"minimum-stability": "dev", "minimum-stability": "dev",
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "vcs",
"url": "https://github.com/Canteen/CanteenHTML5" "url": "https://github.com/Mibew/CanteenHTML5"
} }
] ]
} }

View File

@ -1,6 +1,10 @@
<?php <?php
include '../lib/html.php'; include '../src/HTML5.php';
use Canteen\HTML5\HTML5;
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
use Canteen\HTML5\Document; use Canteen\HTML5\Document;
use Canteen\HTML5\SimpleList; use Canteen\HTML5\SimpleList;
@ -13,6 +17,7 @@
// Add a link to the page // Add a link to the page
$link = html('a#google.external rel=external', 'Link', 'class="test something" target=blank rel=test'); $link = html('a#google.external rel=external', 'Link', 'class="test something" target=blank rel=test');
$link->href = 'http://google.com'; $link->href = 'http://google.com';
$link->onclick = "return confirm('Navigate away?');";
$link->appendTo($doc->body); $link->appendTo($doc->body);
// Create an unordered list for an array of items // Create an unordered list for an array of items
@ -48,5 +53,3 @@
// Output the result formatted nice with indents // Output the result formatted nice with indents
echo $doc; echo $doc;
?>

View File

@ -113,7 +113,7 @@ namespace Canteen\HTML5
// Match the name=value in the attributes string // Match the name=value in the attributes string
preg_match_all('/([a-z]+[a-z\-]*)\=("[^\"]*"|\'[^\']*\'|[^\s\"\']*)/',$str, $arr); preg_match_all('/([a-z]+[a-z\-]*)\=("[^\"]*"|\'[^\']*\'|[^\s\"\']*)/',$str, $arr);
foreach($arr[1] as $i=>$name) foreach ($arr[1] as $i=>$name)
{ {
$value = $arr[2][$i]; $value = $arr[2][$i];
@ -135,10 +135,14 @@ namespace Canteen\HTML5
public function __get($name) public function __get($name)
{ {
if (method_exists($this , $method =('get' . ucfirst($name)))) if (method_exists($this , $method =('get' . ucfirst($name))))
{
return $this->$method(); return $this->$method();
}
else else
{
throw new HTML5Error(HTML5Error::INVALID_GETTER, $name); throw new HTML5Error(HTML5Error::INVALID_GETTER, $name);
} }
}
/** /**
* General purpose setter for setting attribute->name and attribute->value * General purpose setter for setting attribute->name and attribute->value
@ -149,10 +153,14 @@ namespace Canteen\HTML5
public function __set($name, $value) public function __set($name, $value)
{ {
if (method_exists($this , $method =('set' . ucfirst($name)))) if (method_exists($this , $method =('set' . ucfirst($name))))
{
return $this->$method($value); return $this->$method($value);
}
else else
{
throw new HTML5Error(HTML5Error::INVALID_SETTER, $name); throw new HTML5Error(HTML5Error::INVALID_SETTER, $name);
} }
}
/** /**
* See if a property exists * See if a property exists
@ -166,5 +174,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

View File

@ -30,9 +30,7 @@ namespace Canteen\HTML5
*/ */
public function __toString() public function __toString()
{ {
return '<!-- '.$this->_tag.' -->'; return '<!-- ' . $this->_tag . ' -->';
} }
} }
} }
?>

View File

@ -58,14 +58,19 @@ namespace Canteen\HTML5
*/ */
public function __construct($title='', $charset='utf-8', $beautify=false) public function __construct($title='', $charset='utf-8', $beautify=false)
{ {
parent::__construct('html', null, null, 'manifest'); parent::__construct('html', null, null,
array_merge(
array('manifest'),
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);
@ -81,7 +86,9 @@ namespace Canteen\HTML5
{ {
$result = $this->docType . parent::__toString(); $result = $this->docType . parent::__toString();
if ($this->beautify) if ($this->beautify)
{
$result = self::beautify($result); $result = self::beautify($result);
}
return $result; return $result;
} }
@ -108,5 +115,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

41
src/Fragment.php Normal file
View File

@ -0,0 +1,41 @@
<?php
/**
* @module Canteen\HTML5
*/
namespace Canteen\HTML5
{
/**
* Represents a set of HTML tags without a wrapper.
* Do not initiate this class directly, use the `html()` function:
*
* $div = html('fragment');
*
* @class Fragment
* @extends NodeContainer
* @constructor
* @param {Node|Array} [children=null] The collection of children or single child
*/
class Fragment extends NodeContainer
{
public function __construct($children = null)
{
parent::__construct('fragment', $children, null);
}
/**
* Write to HTML
* @method __toString
* @return {String} The string representation of this HTML node
*/
public function __toString()
{
$buffer = '';
foreach ($this->getChildren() as $child)
{
$buffer .= $child->__toString();
}
return $buffer;
}
}
}

175
src/HTML5.php Normal file
View File

@ -0,0 +1,175 @@
<?php
/**
* @module Canteen\HTML5
*/
namespace Canteen\HTML5
{
/**
* Main class of the library
* @class HTML5
*/
class HTML5
{
/**
* Turn on autoloading for the library
* @method autoload
* @static
*/
static public function autoload()
{
spl_autoload_register(function($name)
{
// Ignore class names not in the HTML5 namespace
if (!preg_match('/^Canteen\\\HTML5\\\/', $name))
{
return;
}
// Remove the HTML5 namespace
$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';
});
}
/**
* Use the global `html()` method
* @method {Boolean} useGlobal
*/
static public function useGlobal()
{
include __DIR__ . '/html.php';
}
}
/**
* 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
* 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
if ($tag == 'comment')
{
return new Comment($childrenOrAttributes);
}
// Document type declaration
else if ($tag == 'doctype')
{
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;
}
}

View File

@ -140,5 +140,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

View File

@ -12,12 +12,12 @@ namespace Canteen\HTML5
* echo html('br'); * echo html('br');
* *
* @class Node * @class Node
* @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
* @param {String} [validAttrs=null] The list of non-global valid attributes for the tag, comma separated
*/ */
class Node class Node extends Proto
{ {
/** /**
* The string name of the tag * The string name of the tag
@ -47,15 +47,7 @@ namespace Canteen\HTML5
*/ */
protected $_validAttrs; protected $_validAttrs;
/** public function __construct($tag = null, $attributes = null)
* The default valid attributes
* @property {String} GLOBAL_ATTRS
* @final
* @static
*/
const GLOBAL_ATTRS = 'accesskey,class,contenteditable,contextmenu,dir,draggable,dropzone,hidden,id,lang,spellcheck,style,tabindex,title,translate';
public function __construct($tag = null, $attributes = null, $validAttrs = null)
{ {
if ($this->isEmpty($tag)) if ($this->isEmpty($tag))
{ {
@ -65,12 +57,16 @@ namespace Canteen\HTML5
$this->_tag = $tag; $this->_tag = $tag;
$this->_attributes = array(); $this->_attributes = array();
$validAttrs = is_string($validAttrs) ? explode(',', $validAttrs) : $validAttrs; if (isset(Specification::$TAGS[$tag]))
$this->_validAttrs = explode(',', self::GLOBAL_ATTRS);
if ($validAttrs !== null)
{ {
$this->_validAttrs = array_merge($this->_validAttrs, $validAttrs); $this->_validAttrs = array_merge(
Specification::$TAGS[$tag],
Specification::$ATTRIBUTES
);
}
else
{
$this->_validAttrs = array();
} }
if ($attributes !== null) if ($attributes !== null)
@ -138,14 +134,18 @@ namespace Canteen\HTML5
{ {
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME); throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
} }
foreach($this->_attributes as $i=>$attribute) foreach ($this->_attributes as $i=>$attribute)
{ {
if ($attribute->name === $name) if ($attribute->name === $name)
{ {
if (!$this->isEmpty($value)) if (!$this->isEmpty($value))
{
$attribute->value = $value; $attribute->value = $value;
}
else else
{
unset($this->_attributes[$i]); unset($this->_attributes[$i]);
}
return $this; return $this;
} }
} }
@ -169,7 +169,7 @@ namespace Canteen\HTML5
{ {
throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME); throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME);
} }
foreach($this->_attributes as $attribute) foreach ($this->_attributes as $attribute)
{ {
if ($attribute->name === $name) if ($attribute->name === $name)
{ {
@ -190,7 +190,7 @@ namespace Canteen\HTML5
{ {
if (is_array($values)) if (is_array($values))
{ {
foreach($values as $name=>$value) foreach ($values as $name=>$value)
{ {
$this->setAttribute($name, $value); $this->setAttribute($name, $value);
} }
@ -241,7 +241,7 @@ namespace Canteen\HTML5
*/ */
public function getData($name) public function getData($name)
{ {
return $this->getAttribute('data-'.$name); return $this->getAttribute('data-' . $name);
} }
/** /**
@ -265,7 +265,7 @@ namespace Canteen\HTML5
{ {
$buffer = '<'; $buffer = '<';
$buffer .= $this->_tag; $buffer .= $this->_tag;
foreach($this->_attributes as $attribute) foreach ($this->_attributes as $attribute)
{ {
$buffer .= (string)$attribute; $buffer .= (string)$attribute;
} }
@ -299,7 +299,6 @@ namespace Canteen\HTML5
{ {
return $this->setAttribute($name, $value); return $this->setAttribute($name, $value);
} }
return parent::__set($name);
} }
/** /**
@ -342,5 +341,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

View File

@ -17,7 +17,6 @@ namespace Canteen\HTML5
* @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
* @param {String} [validAttrs=null] Valid attributes specific to the HTML5 element, comma separated
*/ */
class NodeContainer extends Node class NodeContainer extends Node
{ {
@ -28,13 +27,13 @@ namespace Canteen\HTML5
*/ */
private $_children; private $_children;
public function __construct($tag = null, $children = null, $attributes = null, $validAttrs=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, $validAttrs); parent::__construct($tag, $attributes);
$this->_children = array(); $this->_children = array();
@ -46,7 +45,7 @@ namespace Canteen\HTML5
} }
if (is_array($children)) if (is_array($children))
{ {
foreach($children as $child) foreach ($children as $child)
{ {
$this->addChild($child); $this->addChild($child);
} }
@ -84,7 +83,7 @@ namespace Canteen\HTML5
{ {
array_unshift($this->_children, $childNode); array_unshift($this->_children, $childNode);
} }
else if ($index > $len) else if ($index > (count($this->_children) - 1))
{ {
$this->addChild($childNode); $this->addChild($childNode);
} }
@ -142,7 +141,7 @@ namespace Canteen\HTML5
throw new HTML5Error(HTML5Error::EMPTY_CHILD); throw new HTML5Error(HTML5Error::EMPTY_CHILD);
} }
for($i = 0; $i < count($this->_children); $i++) for ($i = 0; $i < count($this->_children); $i++)
{ {
$child = $this->_children[$i]; $child = $this->_children[$i];
if ($child === $childNode) if ($child === $childNode)
@ -224,7 +223,7 @@ namespace Canteen\HTML5
public function __toString() public function __toString()
{ {
$buffer = $this->writeOpen(false); $buffer = $this->writeOpen(false);
foreach($this->_children as $child) foreach ($this->_children as $child)
{ {
$buffer .= $child->__toString(); $buffer .= $child->__toString();
} }
@ -234,5 +233,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

37
src/Proto.php Normal file
View File

@ -0,0 +1,37 @@
<?php
/**
* @module Canteen\HTML5
*/
namespace Canteen\HTML5
{
/**
* Prototype class for all Canteen\HTML5 entities
*
* @class Proto
* @constructor
* @param {String} text the plain text string
*/
class Proto
{
/**
* General purpose getter to get attribute values
* @method __get
* @param {String} name The name of the property to set
*/
public function __get($name)
{
return null;
}
/**
* See if a property exists
* @method __isset
* @param {String} name The name of the attribute
*/
public function __isset($name)
{
return null;
}
}
}

View File

@ -31,14 +31,13 @@ namespace Canteen\HTML5
{ {
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);
$type == 'ol' ? 'reversed,start,type' : null);
if ($elements != null) if ($elements != null)
{ {
assert(is_array($elements)); assert(is_array($elements));
foreach($elements as $child) foreach ($elements as $child)
{ {
$this->addChild($child); $this->addChild($child);
} }
@ -69,5 +68,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

429
src/Specification.php Normal file
View File

@ -0,0 +1,429 @@
<?php
/**
* @module Canteen\HTML5
*/
namespace Canteen\HTML5
{
/**
* The HTML5 Specification
*
* @class Specification
* @constructor
*/
class Specification
{
/**
* The list of all tags and their specific attributes
* @property {array} TAGS
* @final
* @readOnly
* @static
*/
public static $TAGS = array(
'a' => array(
'href',
'hreflang',
'media',
'rel',
'target',
'type'
),
'abbr' => array(),
'address' => array(),
'area' => array(
'alt',
'coords',
'href',
'hreflang',
'media',
'rel',
'shape',
'target',
'type'
),
'article' => array(),
'aside' => array(),
'audio' => array(
'autoplay',
'controls',
'loop',
'muted',
'preload',
'src'
),
'b' => array(),
'base' => array(
'href',
'target'
),
'bdo' => array(),
'blockquote' => array(
'cite'
),
'body' => array(),
'br' => array(),
'button' => array(
'autofocus',
'disabled',
'form',
'formaction',
'formenctype',
'formmethod',
'formnovalidate',
'formtarget',
'name',
'type',
'value'
),
'canvas' => array(
'height',
'width'
),
'caption' => array(),
'cite' => array(),
'code' => array(),
'col' => null,
'colgroup' => array(
'span'
),
'command' => array(
'checked',
'disabled',
'icon',
'label',
'radiogroup',
'type'
),
'datalist' => array(),
'dd' => array(),
'del' => array(
'cite',
'datetime'
),
'dfn' => array(),
'div' => array(),
'dl' => array(),
'dt' => array(),
'em' => array(),
'embed' => array(
'height',
'src',
'type',
'width'
),
'fieldset' => array(
'disabled',
'form_id',
'text'
),
'figcaption' => array(),
'figure' => array(),
'footer' => array(),
'form' => array(
'accept',
'accept-charset',
'action',
'autocomplete',
'enctype',
'method',
'name',
'novalidate',
'target'
),
'h1' => array(),
'h2' => array(),
'h3' => array(),
'h4' => array(),
'h5' => array(),
'h6' => array(),
'head' => array(),
'header' => array(),
'hgroup' => array(),
'hr' => array(),
'html' => array(
'manifest'
),
'img' => array(
'alt',
'crossorigin',
'height',
'src',
'usemap',
'width'
),
'i' => array(),
'iframe' => array(
'src',
'srcdoc',
'name',
'width',
'height'
),
'input' => array(
'accept',
'alt',
'autocomplete',
'autofocus',
'checked',
'disabled',
'form',
'formaction',
'formenctype',
'formmethod',
'formnovalidate',
'formtarget',
'height',
'list',
'max',
'maxlength',
'min',
'multiple',
'name',
'pattern',
'placeholder',
'readonly',
'required',
'size',
'src',
'step',
'type',
'value',
'width'
),
'keygen' => array(
'autofocus',
'challenge',
'disabled',
'form',
'keytype',
'name'
),
'label' => array(
'for',
'form'
),
'legend' => array(),
'li' => array(),
'link' => array(
'href',
'hreflang',
'media',
'rel',
'sizes',
'type'
),
'map' => array(
'name'
),
'mark' => array(),
'menu' => array(),
'meta' => array(
'charset',
'content',
'http-equiv',
'name'
),
'meter' => array(
'form',
'heigh',
'low',
'max',
'min',
'optimum',
'value'
),
'nav' => array(),
'noscript' => array(),
'object' => array(
'data',
'form',
'height',
'name',
'type',
'usemap',
'width'
),
'ol' => array(
'reversed',
'start',
'type'
),
'optgroup' => array(
'disabled',
'label'
),
'option' => array(
'disabled',
'label',
'selected',
'value'
),
'output' => array(
'for',
'form',
'name'
),
'p' => array(),
'param' => array(
'name',
'value'
),
'pre' => array(),
'progress' => array(
'max',
'value'
),
'q' => array(
'cite'
),
'rp' => array(),
'rt' => array(),
'ruby' => array(),
's' => array(),
'sample' => array(),
'script' => array(
'async',
'charset',
'defer',
'src',
'type'
),
'section' => array(),
'select' => array(
'autofocus',
'disabled',
'form',
'multiple',
'name',
'required',
'size'
),
'small' => array(),
'source' => array(
'media',
'src',
'type'
),
'span' => array(),
'strong' => array(),
'style' => array(
'media',
'scoped',
'type'
),
'sub' => array(),
'table' => array(
'border'
),
'tbody' => array(),
'td' => array(
'colspan',
'headers',
'scope'
),
'textarea' => array(
'autofocus',
'cols',
'disabled',
'form',
'maxlength',
'name',
'placeholder',
'readonly',
'required',
'row',
'wrap'
),
'tfoot' => array(),
'th' => array(
'colspan',
'headers',
'rowspan',
'scope'
),
'thead' => array(),
'time' => array(
'datetime'
),
'title' => array(),
'tr' => array(),
'track' => array(
'default',
'kind',
'label',
'src',
'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
* @property {array} SELF_CLOSING
* @final
* @readOnly
* @static
*/
public static $SELF_CLOSING = array(
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'
);
/**
* Global valid attributes for all HTML5 tags
* See: http://www.w3.org/TR/html5/dom.html#global-attributes
* @property {Array} ATTRIBUTES
* @final
* @static
* @readOnly
*/
public static $ATTRIBUTES = array(
// Event handler context attributes
'onabort', 'onblur', 'oncancel', 'oncanplay', 'oncanplaythrough',
'onchange', 'onclick', 'oncuechange', 'ondblclick', 'ondurationchange',
'onemptied', 'onended', 'onerror', 'onfocus', 'oninput', 'oninvalid',
'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata',
'onloadedmetadata', 'onloadstart', 'onmousedown', 'onmouseenter',
'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup',
'onmousewheel', 'onpause', 'onplay', 'onplaying', 'onprogress',
'onratechange', 'onreset', 'onresize', 'onscroll', 'onseeked',
'onseeking', 'onselect', 'onshow', 'onstalled', 'onsubmit', 'onsuspend',
'ontimeupdate', 'ontoggle', 'onvolumechange', 'onwaiting',
// Allow-able on all tags
'accesskey', 'class', 'contenteditable', 'contextmenu', 'dir', 'draggable',
'dropzone', 'hidden', 'id', 'lang', 'spellcheck', 'style', 'tabindex',
'title', 'translate'
);
}
}

View File

@ -32,7 +32,7 @@ namespace Canteen\HTML5
{ {
public function __construct($data, $headers=null, $checkbox=null) public function __construct($data, $headers=null, $checkbox=null)
{ {
parent::__construct('table', null, null, 'border'); parent::__construct('table', null, null);
if ($headers != null && is_array($headers)) if ($headers != null && is_array($headers))
{ {
@ -46,7 +46,7 @@ namespace Canteen\HTML5
$row->addChild(html('th', html('span', $checkbox))); $row->addChild(html('th', html('span', $checkbox)));
} }
foreach($headers as $header) foreach ($headers as $header)
{ {
$row->addChild(html('th', $header)); $row->addChild(html('th', $header));
} }
@ -55,7 +55,7 @@ namespace Canteen\HTML5
$body = html('tbody'); $body = html('tbody');
foreach($data as $d) foreach ($data as $d)
{ {
$row = html('tr'); $row = html('tr');
@ -64,16 +64,19 @@ namespace Canteen\HTML5
$td = html('td', $td = html('td',
html( html(
'input', 'input',
'type=checkbox name='.$checkbox.'[] value='.$d[$checkbox] 'type=checkbox name=' . $checkbox . '[] value='.$d[$checkbox]
), ),
'class='.$checkbox 'class=' . $checkbox
); );
$row->addChild($td); $row->addChild($td);
} }
foreach($d as $name=>$value) foreach ($d as $name=>$value)
{ {
if ($name == $checkbox) continue; if ($name == $checkbox)
$td = html('td', $value, 'class='.$name); {
continue;
}
$td = html('td', $value, 'class=' . $name);
$row->addChild($td); $row->addChild($td);
} }
$body->addChild($row); $body->addChild($row);
@ -82,5 +85,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

View File

@ -35,5 +35,3 @@ namespace Canteen\HTML5
} }
} }
} }
?>

View File

@ -1,48 +1,13 @@
<?php <?php
/**
* @module global
*/
namespace
{
/** /**
* @module global * The global method which is an alias for Canteen\HTML5\html()
*/ * to use this method globally call Canteen\HTML5\HTML5::useGlobal()
/**
* Auto load the assets in this library
*/
spl_autoload_register(function($name)
{
// Ignore class names not in the HTML5 namespace
if (!preg_match('/^HTML5\\\/', $name)) return;
// Remove the HTML5 namespace
$name = preg_replace('/^HTML5\\\/', '', $name);
// Convert the rest to directories
$name = str_replace("\\", '/', $name);
// Include the class relative to here
include __DIR__.'/'.$name.'.php';
});
use Canteen\HTML5\NodeContainer;
use Canteen\HTML5\Node;
use Canteen\HTML5\Comment;
use Canteen\HTML5\HTML5Error;
use Canteen\HTML5\Text;
use Canteen\HTML5\Attribute;
/**
* 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
* 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'));
*
*
*
* @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
@ -55,183 +20,6 @@
*/ */
function html($tag, $childrenOrAttributes=null, $attributes=null) function html($tag, $childrenOrAttributes=null, $attributes=null)
{ {
// Get the tag ID from the tag string return Canteen\HTML5\html($tag, $childrenOrAttributes, $attributes);
// 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);
$s = false; // if the html is a single tag like <br>
$tag = strtolower($tagParts[1]); // the name of the tag
$a = ''; // Valid extra attributes for tags
switch($tag)
{
case 'a': $a = 'href,hreflang,media,rel,target,type'; break;
case 'abbr': break;
case 'address': break;
case 'area': $s = true; $a = 'alt,coords,href,hreflang,media,rel,shape,target,type'; break;
case 'article': break;
case 'aside': break;
case 'audio': $a = 'autoplay,controls,loop,muted,preload,src'; break;
case 'b': break;
case 'base': $s = true; $a = 'href,target'; break;
case 'bdo': break;
case 'blockquote': $a = 'cite'; break;
case 'body': break;
case 'br': $s = true; break;
case 'button': $a = 'autofocus,disabled,form,formaction,formenctype,formmethod,formnovalidate,formtarget,name,type,value'; break;
case 'canvas': $a = 'height,width'; break;
case 'caption': break;
case 'cite': break;
case 'code': break;
case 'col': $s = true; break;
case 'colgroup': $a = 'span'; break;
case 'command': $s = true; $a = 'checked,disabled,icon,label,radiogroup,type'; break;
case 'comment': return new Comment($childrenOrAttributes);
case 'doctype': return '<!DOCTYPE html>';
case 'datalist': break;
case 'dd': break;
case 'del': $a = 'cite,datetime'; break;
case 'dfn': break;
case 'div': break;
case 'dl': break;
case 'dt': break;
case 'em': break;
case 'embed': $s = true; $a = 'height,src,type,width'; break;
case 'fieldset': $a = 'disabled,form_id,text'; break;
case 'figcaption': break;
case 'figure': break;
case 'footer': break;
case 'form': $a = 'accept,accept-charset,action,autocomplete,enctype,method,name,novalidate,target'; break;
case 'h1': break;
case 'h2': break;
case 'h3': break;
case 'h4': break;
case 'h5': break;
case 'h6': break;
case 'head': break;
case 'header': break;
case 'hgroup': break;
case 'hr': $s = true; break;
case 'html': $a = 'manifest'; break;
case 'img': $s = true; $a = 'alt,crossorigin,height,src,usemap,width'; break;
case 'i': break;
case 'input': $s = true; $a = 'accept,alt,autocomplete,autofocus,checked,disabled,form,formaction,formenctype,formmethod,formnovalidate,formtarget,height,list,max,maxlength,min,multiple,name,pattern,placeholder,readonly,required,size,src,step,type,value,width'; break;
case 'keygen': $s = true; $a = 'autofocus,challenge,disabled,form,keytype,name'; break;
case 'label': $a = 'for,form'; break;
case 'legend': break;
case 'li': break;
case 'link': $s = true; $a = 'href,hreflang,media,rel,sizes,type'; break;
case 'map': $a = 'name'; break;
case 'mark': break;
case 'menu': break;
case 'meta': $s = true; $a = 'charset,content,http-equiv,name'; break;
case 'meter': $a = 'form,heigh,low,max,min,optimum,value'; break;
case 'nav': break;
case 'noscript': break;
case 'object': $a = 'data,form,height,name,type,usemap,width'; break;
case 'ol': $a = 'reversed,start,type'; break;
case 'optgroup': $a = 'disabled,label'; break;
case 'option': $a = 'disabled,label,selected,value'; break;
case 'output': $a = 'for,form,name'; break;
case 'p': break;
case 'param': $s = true; $a = 'name,value'; break;
case 'pre': break;
case 'progress': $a = 'max,value'; break;
case 'q': $a = 'cite'; break;
case 'rp': break;
case 'rt': break;
case 'ruby': break;
case 's': break;
case 'sample': break;
case 'script': $a = 'async,charset,defer,src,type'; break;
case 'section': break;
case 'select': $a = 'autofocus,disabled,form,multiple,name,required,size'; break;
case 'small': break;
case 'source': $s = true; $a = 'media,src,type'; break;
case 'span': break;
case 'strong': break;
case 'style': $a = 'media,scoped,type'; break;
case 'sub': break;
case 'table': $a = 'border'; break;
case 'tbody': break;
case 'td': $a = 'colspan,headers,scope'; break;
case 'text': return new Text($childrenOrAttributes);
case 'textarea': $a = 'autofocus,cols,disabled,form,maxlength,name,placeholder,readonly,required,row,wrap'; break;
case 'tfoot': break;
case 'th': $a = 'colspan,headers,rowspan,scope'; break;
case 'thead': break;
case 'time': $a = 'datetime'; break;
case 'title': break;
case 'tr': break;
case 'track': $s = true; $a = 'default,kind,label,src,srclang'; break;
case 'u': break;
case 'ul': break;
case 'var': break;
case 'video': $a = 'autoplay,controls,height,loop,muted,poster,preload,src,width'; break;
case 'wbr': $s = true; break;
default:
throw new HTML5Error(HTML5Error::INVALID_TAG, $tag);
break;
}
// Create the attributes collection, either string or array
$attributes = $s ? $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 = ($s) ?
new Node($tag, $attributes, $a) :
new NodeContainer($tag, $childrenOrAttributes, $attributes, $a);
// 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;
}
?>