for a detailed description, copyright and license information. */ /* @package xajax @version $Id: validate_HTML401TRANSITIONAL.inc.php 362 2007-05-29 15:32:24Z calltoconstruct $ @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson @copyright Copyright (c) 2008-2009 by Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson @license http://www.xajaxproject.org/bsd_license.txt BSD License */ /* Section: Description This file contains the validation rules for the HTML 4.01 Transitional standard as defined by the W3C */ $aAttributes = array( '%bodycolors' => array( 'bgcolor', 'text', 'link', 'vlink', 'alink' ), '%coreattrs' => array( 'id', 'class', 'style', 'title' ), '%i18n' => array( 'lang', 'dir' ), '%events' => array( 'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onkeypress', 'onkeydown', 'onkeyup' ), '%attrs' => array( '%coreattrs', '%i18n', '%events' ), '%align' => array( 'left', 'center', 'right', 'justify' ), '%cellhalign' => array( 'align' ), '%cellvalign' => array( 'valign' ), 'TT' => array('%attrs'), 'I' => array('%attrs'), 'B' => array('%attrs'), 'U' => array('%attrs'), 'S' => array('%attrs'), 'STRIKE' => array('%attrs'), 'BIG' => array('%attrs'), 'SMALL' => array('%attrs'), 'EM' => array('%attrs'), 'STRONG' => array('%attrs'), 'DFN' => array('%attrs'), 'CODE' => array('%attrs'), 'SAMP' => array('%attrs'), 'KBD' => array('%attrs'), 'VAR' => array('%attrs'), 'CITE' => array('%attrs'), 'ABBR' => array('%attrs'), 'ACRONYM' => array('%attrs'), 'SUB' => array('%attrs'), 'SUP' => array('%attrs'), 'SPAN' => array( '%attrs' // , // '%reserved' ), 'BDO' => array( '%coreattrs', 'lang', 'dir' ), 'BASEFONT' => array( 'id', 'size', 'color', 'face' ), 'FONT' => array( '%coreattrs', '%i18n', 'size', 'color', 'face' ), 'BR' => array( '%coreattrs', 'clear' ), 'BODY' => array( '%attrs', 'onload', 'onunload', 'background', '%bodycolors' ), 'ADDRESS' => array('%attrs'), 'DIV' => array( '%attrs', '%align' // , // '%reserved' ), 'CENTER' => array('%attrs'), 'A' => array( '%attrs', 'charset', 'type', 'name', 'href', 'hreflang', 'target', 'rel', 'rev', 'accesskey', 'shape', 'coords', 'tabindex', 'onfocus', 'onblur' ), 'MAP' => array( '%attrs', 'name' ), 'AREA' => array( '%attrs', 'shape', 'coords', 'href', 'target', 'nohref', 'alt', 'tabindex', 'accesskey', 'onfocus', 'onblur' ), 'LINK' => array( '%attrs', 'charset', 'href', 'hreflang', 'type', 'rel', 'rev', 'media', 'target' ), 'IMG' => array( '%attrs', 'src', 'alt', 'longdesc', 'name', 'height', 'width', 'usemap', 'ismap', 'align', 'border', 'hspace', 'vspace' ), 'OBJECT' => array( '%attrs', 'declare', 'classid', 'codebase', 'data', 'type', 'codetype', 'archive', 'standby', 'height', 'width', 'usemap', 'name', 'tabindex', 'align', 'border', 'hspace', 'vspace' // , // '%reserved' ), 'PARAM' => array( 'id', 'name', 'value', 'valuetype', 'type' ), 'APPLET' => array( '%coreattrs', 'codebase', 'archive', 'code', 'object', 'alt', 'name', 'width', 'height', 'align', 'hspace', 'vspace' ), 'HR' => array( '%attrs', 'align', 'noshade', 'size', 'width' ), 'P' => array( '%attrs', '%align' ), 'H1' => array( '%attrs', '%align' ), 'H2' => array( '%attrs', '%align' ), 'H3' => array( '%attrs', '%align' ), 'H4' => array( '%attrs', '%align' ), 'H5' => array( '%attrs', '%align' ), 'H6' => array( '%attrs', '%align' ), 'PRE' => array( '%attrs', 'width' ), 'Q' => array( '%attrs', 'cite' ), 'BLOCKQUOTE' => array( '%attrs', 'cite' ), 'INS' => array( '%attrs', 'cite', 'datetime' ), 'DEL' => array( '%attrs', 'cite', 'datetime' ), 'DL' => array( '%attrs', 'compact' ), 'DT' => array('%attrs'), 'DD' => array('%attrs'), 'OL' => array( '%attrs', 'type', 'compact', 'start' ), 'UL' => array( '%attrs', 'type', 'compact' ), 'DIR' => array( '%attrs', 'compact' ), 'MENU' => array( '%attrs', 'compact' ), 'LI' => array( '%attrs', 'type', 'value' ), 'FORM' => array( '%attrs', 'action', 'method', 'enctype', 'accept', 'name', 'onsubmit', 'onreset', 'target', 'accept-charset' ), 'LABEL' => array( '%attrs', 'for', 'accesskey', 'onfocus', 'onblur' ), 'INPUT' => array( '%attrs', 'type', 'name', 'value', 'checked', 'disabled', 'readonly', 'size', 'maxlength', 'src', 'alt', 'usemap', 'ismap', 'tabindex', 'accesskey', 'onfocus', 'onblur', 'onselect', 'onchange', 'accept', 'align' // , // '%reserved' ), 'SELECT' => array( '%attrs', 'name', 'size', 'multiple', 'disabled', 'tabindex', 'onfocus', 'onblur', 'onchange' // , // '%reserved' ), 'OPTGROUP' => array( '%attrs', 'disabled', 'label' ), 'OPTION' => array( '%attrs', 'selected', 'disabled', 'label', 'value' ), 'TEXTAREA' => array( '%attrs', 'name', 'rows', 'cols', 'disabled', 'readonly', 'tabindex', 'accesskey', 'onfocus', 'onblur', 'onselect', 'onchange' // , // '%reserved' ), 'FIELDSET' => array('%attrs'), 'LEGEND' => array( '%attrs', 'accesskey', 'align' ), 'BUTTON' => array( '%attrs', 'name', 'value', 'type', 'disabled', 'tabindex', 'accesskey', 'onfocus', 'onblur' // , // '%reserved' ), 'TABLE' => array( '%attrs', 'summary', 'width', 'border', 'frame', 'rules', 'cellspacing', 'cellpadding', 'align', 'bgcolor', // '%reserved', 'datapagesize' ), 'CAPTION' => array('%attrs', 'align'), 'COLGROUP' => array( '%attrs', 'span', 'width', '%cellhalign', '%cellvalign' ), 'COL' => array( '%attrs', 'span', 'width', '%cellhalign', '%cellvalign' ), 'THEAD' => array( '%attrs', '%cellhalign', '%cellvalign' ), 'TBODY' => array( '%attrs', '%cellhalign', '%cellvalign' ), 'TFOOT' => array( '%attrs', '%cellhalign', '%cellvalign' ), 'TR' => array( '%attrs', '%cellhalign', '%cellvalign', 'bgcolor' ), 'TH' => array( '%attrs', 'abbr', 'axis', 'headers', 'scope', 'rowspan', 'colspan', '%cellhalign', '%cellvalign', 'nowrap', 'bgcolor', 'width', 'height' ), 'TD' => array( '%attrs', 'abbr', 'axis', 'headers', 'scope', 'rowspan', 'colspan', '%cellhalign', '%cellvalign', 'nowrap', 'bgcolor', 'width', 'height' ), 'IFRAME' => array( '%coreattrs', 'longdesc', 'name', 'src', 'frameborder', 'marginwidth', 'marginheight', 'scrolling', 'align', 'height', 'width' ), 'NOFRAMES' => array('%attrs'), 'HEAD' => array( '%i18n', 'profile' ), 'TITLE' => array('%i18n'), 'BASE' => array( 'href', 'target' ), 'META' => array( '%i18n', 'http-equiv', 'name', 'content', 'scheme' ), 'STYLE' => array( '%i18n', 'type', 'media', 'title' ), 'SCRIPT' => array( 'charset', 'type', 'language', 'src', 'defer', 'event', 'for' ), 'NOSCRIPT' => array('%attrs'), 'HTML' => array('%i18n') // , '%version') ); $aTags = array( '%heading' => array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), '%list' => array( 'UL', 'OL', 'DIR', 'MENU' ), '%preformatted' => array('PRE'), '%fontstyle' => array( 'TT', 'I', 'B', 'U', 'S', 'STRIKE', 'BIG', 'SMALL' ), '%phrase' => array( 'EM', 'STRONG', 'DFN', 'CODE', 'SAMP', 'KBD', 'VAR', 'CITE', 'ABBR', 'ACRONYM' ), '%special' => array( 'A', 'IMG', 'APPLET', 'OBJECT', 'FONT', 'BASEFONT', 'BR', 'SCRIPT', 'MAP', 'Q', 'SUB', 'SUP', 'SPAN', 'BDO', 'IFRAME' ), '%formctrl' => array( 'INPUT', 'SELECT', 'TEXTAREA', 'LABEL', 'BUTTON' ), '%inline' => array( 'CDATA', '%fontstyle', '%phrase', '%special', '%formctrl' ), '%block' => array( 'P', '%heading', '%list', '%preformatted', 'DL', 'DIV', 'CENTER', 'NOSCRIPT', 'NOFRAMES', 'BLOCKQUOTE', 'INS', 'DEL', 'FORM', 'ISINDEX', 'HR', 'TABLE', 'FIELDSET', 'ADDRESS' ), '%flow' => array( '%block', '%inline' ), 'TT' => array('%inline'), // fontstyle 'I' => array('%inline'), 'B' => array('%inline'), 'U' => array('%inline'), 'S' => array('%inline'), 'STRIKE' => array('%inline'), 'BIG' => array('%inline'), 'SMALL' => array('%inline'), 'EM' => array('%inline'), // phrase 'STRONG' => array('%inline'), 'DFN' => array('%inline'), 'CODE' => array('%inline'), 'SAMP' => array('%inline'), 'KBD' => array('%inline'), 'VAR' => array('%inline'), 'CITE' => array('%inline'), 'ABBR' => array('%inline'), 'ACRONYM' => array('%inline'), 'SUB' => array('%inline'), 'SUP' => array('%inline'), 'SPAN' => array('%inline'), 'BDO' => array('%inline'), 'BASEFONT' => array(), 'FONT' => array('%inline'), 'BR' => array(), 'BODY' => array( '%flow', 'INS', 'DEL' ), 'ADDRESS' => array( '%inline', 'P' ), 'DIV' => array('%flow'), 'CENTER' => array('%flow'), 'A' => array('%inline'), 'MAP' => array( '%block', 'AREA' ), 'AREA' => array(), 'LINK' => array(), 'IMG' => array(), 'OBJECT' => array( 'PARAM', '%flow' ), 'PARAM' => array(), 'HR' => array(), 'P' => array('%inline'), 'H1' => array('%inline'), 'H2' => array('%inline'), 'H3' => array('%inline'), 'H4' => array('%inline'), 'H5' => array('%inline'), 'H6' => array('%inline'), 'PRE' => array('%inline'), 'Q' => array('%inline'), 'BLOCKQUOTE' => array('%flow'), 'INS' => array('%flow'), 'DEL' => array('%flow'), 'DL' => array( 'DT', 'DD' ), 'DT' => array('%inline'), 'DD' => array('%flow'), 'OL' => array('LI'), 'UL' => array('LI'), 'DIR' => array('LI'), 'MENU' => array('LI'), 'LI' => array('%flow'), 'FORM' => array('%flow'), 'LABEL' => array('%inline'), 'INPUT' => array(), 'SELECT' => array( 'OPTGROUP', 'OPTION' ), 'OPTGROUP' => array('OPTION'), 'OPTION' => array('CDATA'), 'TEXTAREA' => array('CDATA'), 'FIELDSET' => array( 'CDATA', 'LEGEND', '%flow' ), 'LEGEND' => array('%inline'), 'BUTTON' => array('%flow'), 'TABLE' => array( 'CAPTION', 'COL', 'COLGROUP', 'THEAD', 'TFOOT', 'TBODY' ), 'CAPTION' => array('%inline'), 'THEAD' => array('TR'), 'TFOOT' => array('TR'), 'TBODY' => array('TR'), 'COLGROUP' => array('COL'), 'COL' => array(), 'TR' => array( 'TH', 'TD' ), 'TH' => array('%flow'), 'TD' => array('%flow'), 'IFRAME' => array('%flow'), 'NOFRAMES' => array('%flow'), 'HEAD' => array( 'TITLE', 'BASE', 'SCRIPT', 'STYLE', 'META', 'LINK', 'OBJECT' ), 'TITLE' => array('CDATA'), 'META' => array(), 'STYLE' => array('CDATA'), 'SCRIPT' => array('CDATA'), 'NOSCRIPT' => array('%flow'), 'BASE' => array(), 'HTML' => array( 'HEAD', 'BODY' ), 'DOCUMENT' => array( 'DOCTYPE', 'HTML' ) ); $aExclusions = array( 'A' => array('A'), 'PRE' => array( 'IMG', 'OBJECT', 'APPLET', 'BIG', 'SMALL', 'SUB', 'SUP', 'FONT', 'BASEFONT' ), 'DIR' => array('%block'), 'MENU' => array('%block'), 'FORM' => array('FORM'), 'LABEL' => array('LABEL'), 'BUTTON' => array( 'A', '%formctrl', 'FORM', 'ISINDEX', 'FIELDSET', 'IFRAME' ) ); $aRequiredAttributes = array( 'style' => array('type'), 'script' => array('type'), 'meta' => array('content'), 'optgroup' => array('label'), 'textarea' => array('rows', 'cols'), 'img' => array('src', 'alt') ); class clsValidator { var $aTags; var $aAttributes; var $aRequiredAttributes; function clsValidator() { global $aTags; global $aAttributes; global $aRequiredAttributes; $this->aTags = array(); $this->aAttributes = array(); $this->aRequiredAttributes = array(); foreach (array_keys($aTags) as $sTag) { $this->aTags[$sTag] = array(); $this->_expand($this->aTags[$sTag], $aTags[$sTag], $aTags); } foreach (array_keys($aAttributes) as $sAttribute) { $this->aAttributes[$sAttribute] = array(); $this->_expand($this->aAttributes[$sAttribute], $aAttributes[$sAttribute], $aAttributes); } foreach (array_keys($aRequiredAttributes) as $sElement) { $this->aRequiredAttributes[$sElement] = array(); $this->_expand($this->aRequiredAttributes[$sElement], $aRequiredAttributes[$sElement], $aRequiredAttributes); } } function &getInstance() { static $obj; if (!$obj) { $obj = new clsValidator(); } return $obj; } function _expand(&$aDestination, &$aSource, &$aDictionary) { foreach ($aSource as $sChild) { if ('%' == substr($sChild, 0, 1)) { $this->_expand($aDestination, $aDictionary[$sChild], $aDictionary); } else $aDestination[] = $sChild; } } function elementValid($sElement) { return isset($this->aTags[strtoupper($sElement)]); } function attributeValid($sElement, $sAttribute) { if (false == isset($this->aAttributes[strtoupper($sElement)])) return false; return in_array(strtolower($sAttribute), $this->aAttributes[strtoupper($sElement)]); } function childValid($sParent, $sElement) { if (false == isset($this->aTags[strtoupper($sParent)])) return false; return in_array(strtoupper($sElement), $this->aTags[strtoupper($sParent)]); } // verify that required attributes have been specified function checkRequiredAttributes($sElement, &$aAttributes, &$sMissing) { if (isset($this->aRequiredAttributes[strtolower($sElement)])) foreach ($this->aRequiredAttributes[strtolower($sElement)] as $sRequiredAttribute) if (false == isset($aAttributes[$sRequiredAttribute])) { $sMissing = $sRequiredAttribute; return false; } return true; } }