You are here

Elements.php in Zircon Profile 8

Same filename and directory in other branches
  1. 8.0 vendor/masterminds/html5/src/HTML5/Elements.php

Namespace

Masterminds\HTML5

File

vendor/masterminds/html5/src/HTML5/Elements.php
View source
<?php

/**
 * Provide general element functions.
 */
namespace Masterminds\HTML5;


/**
 * This class provides general information about HTML5 elements,
 * including syntactic and semantic issues.
 * Parsers and serializers can
 * use this class as a reference point for information about the rules
 * of various HTML5 elements.
 *
 * @todo consider using a bitmask table lookup. There is enough overlap in
 *       naming that this could significantly shrink the size and maybe make it
 *       faster. See the Go teams implementation at https://code.google.com/p/go/source/browse/html/atom.
 */
class Elements {

  /**
   * Indicates an element is described in the specification.
   */
  const KNOWN_ELEMENT = 1;

  // From section 8.1.2: "script", "style"
  // From 8.2.5.4.7 ("in body" insertion mode): "noembed", "noscript"
  // From 8.4 "style", "xmp", "iframe", "noembed", "noframes"

  /**
   * Indicates the contained text should be processed as raw text.
   */
  const TEXT_RAW = 2;

  // From section 8.1.2: "textarea", "title"

  /**
   * Indicates the contained text should be processed as RCDATA.
   */
  const TEXT_RCDATA = 4;

  /**
   * Indicates the tag cannot have content.
   */
  const VOID_TAG = 8;

  // "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl",
  // "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "menu",
  // "nav", "ol", "p", "section", "summary", "ul"
  // "h1", "h2", "h3", "h4", "h5", "h6"
  // "pre", "listing"
  // "form"
  // "plaintext"

  /**
   * Indicates that if a previous event is for a P tag, that element
   * should be considered closed.
   */
  const AUTOCLOSE_P = 16;

  /**
   * Indicates that the text inside is plaintext (pre).
   */
  const TEXT_PLAINTEXT = 32;

  // See https://developer.mozilla.org/en-US/docs/HTML/Block-level_elements

  /**
   * Indicates that the tag is a block.
   */
  const BLOCK_TAG = 64;

  /**
   * Indicates that the tag allows only inline elements as child nodes.
   */
  const BLOCK_ONLY_INLINE = 128;

  /**
   * The HTML5 elements as defined in http://dev.w3.org/html5/markup/elements.html.
   *
   * @var array
   */
  public static $html5 = array(
    "a" => 1,
    "abbr" => 1,
    "address" => 89,
    // NORMAL | VOID_TAG | AUTOCLOSE_P | BLOCK_TAG
    "area" => 9,
    // NORMAL | VOID_TAG
    "article" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "aside" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "audio" => 65,
    // NORMAL | BLOCK_TAG
    "b" => 1,
    "base" => 9,
    // NORMAL | VOID_TAG
    "bdi" => 1,
    "bdo" => 1,
    "blockquote" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "body" => 1,
    "br" => 9,
    // NORMAL | VOID_TAG
    "button" => 1,
    "canvas" => 65,
    // NORMAL | BLOCK_TAG
    "caption" => 1,
    "cite" => 1,
    "code" => 1,
    "col" => 9,
    // NORMAL | VOID_TAG
    "colgroup" => 1,
    "command" => 9,
    // NORMAL | VOID_TAG
    // "data" => 1, // This is highly experimental and only part of the whatwg spec (not w3c). See https://developer.mozilla.org/en-US/docs/HTML/Element/data
    "datalist" => 1,
    "dd" => 65,
    // NORMAL | BLOCK_TAG
    "del" => 1,
    "details" => 17,
    // NORMAL | AUTOCLOSE_P,
    "dfn" => 1,
    "dialog" => 17,
    // NORMAL | AUTOCLOSE_P,
    "div" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "dl" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "dt" => 1,
    "em" => 1,
    "embed" => 9,
    // NORMAL | VOID_TAG
    "fieldset" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "figcaption" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "figure" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "footer" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "form" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "h1" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "h2" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "h3" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "h4" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "h5" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "h6" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "head" => 1,
    "header" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "hgroup" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "hr" => 73,
    // NORMAL | VOID_TAG
    "html" => 1,
    "i" => 1,
    "iframe" => 3,
    // NORMAL | TEXT_RAW
    "img" => 9,
    // NORMAL | VOID_TAG
    "input" => 9,
    // NORMAL | VOID_TAG
    "kbd" => 1,
    "ins" => 1,
    "keygen" => 9,
    // NORMAL | VOID_TAG
    "label" => 1,
    "legend" => 1,
    "li" => 1,
    "link" => 9,
    // NORMAL | VOID_TAG
    "map" => 1,
    "mark" => 1,
    "menu" => 17,
    // NORMAL | AUTOCLOSE_P,
    "meta" => 9,
    // NORMAL | VOID_TAG
    "meter" => 1,
    "nav" => 17,
    // NORMAL | AUTOCLOSE_P,
    "noscript" => 67,
    // NORMAL | TEXT_RAW | BLOCK_TAG
    "object" => 1,
    "ol" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "optgroup" => 1,
    "option" => 1,
    "output" => 65,
    // NORMAL | BLOCK_TAG
    "p" => 209,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG | BLOCK_ONLY_INLINE
    "param" => 9,
    // NORMAL | VOID_TAG
    "pre" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "progress" => 1,
    "q" => 1,
    "rp" => 1,
    "rt" => 1,
    "ruby" => 1,
    "s" => 1,
    "samp" => 1,
    "script" => 3,
    // NORMAL | TEXT_RAW
    "section" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "select" => 1,
    "small" => 1,
    "source" => 9,
    // NORMAL | VOID_TAG
    "span" => 1,
    "strong" => 1,
    "style" => 3,
    // NORMAL | TEXT_RAW
    "sub" => 1,
    "summary" => 17,
    // NORMAL | AUTOCLOSE_P,
    "sup" => 1,
    "table" => 65,
    // NORMAL | BLOCK_TAG
    "tbody" => 1,
    "td" => 1,
    "textarea" => 5,
    // NORMAL | TEXT_RCDATA
    "tfoot" => 65,
    // NORMAL | BLOCK_TAG
    "th" => 1,
    "thead" => 1,
    "time" => 1,
    "title" => 5,
    // NORMAL | TEXT_RCDATA
    "tr" => 1,
    "track" => 9,
    // NORMAL | VOID_TAG
    "u" => 1,
    "ul" => 81,
    // NORMAL | AUTOCLOSE_P | BLOCK_TAG
    "var" => 1,
    "video" => 65,
    // NORMAL | BLOCK_TAG
    "wbr" => 9,
    // NORMAL | VOID_TAG
    // Legacy?
    'basefont' => 8,
    // VOID_TAG
    'bgsound' => 8,
    // VOID_TAG
    'noframes' => 2,
    // RAW_TEXT
    'frame' => 9,
    // NORMAL | VOID_TAG
    'frameset' => 1,
    'center' => 16,
    'dir' => 16,
    'listing' => 16,
    // AUTOCLOSE_P
    'plaintext' => 48,
    // AUTOCLOSE_P | TEXT_PLAINTEXT
    'applet' => 0,
    'marquee' => 0,
    'isindex' => 8,
    // VOID_TAG
    'xmp' => 20,
    // AUTOCLOSE_P | VOID_TAG | RAW_TEXT
    'noembed' => 2,
  );

  /**
   * The MathML elements.
   * See http://www.w3.org/wiki/MathML/Elements.
   *
   * In our case we are only concerned with presentation MathML and not content
   * MathML. There is a nice list of this subset at https://developer.mozilla.org/en-US/docs/MathML/Element.
   *
   * @var array
   */
  public static $mathml = array(
    "maction" => 1,
    "maligngroup" => 1,
    "malignmark" => 1,
    "math" => 1,
    "menclose" => 1,
    "merror" => 1,
    "mfenced" => 1,
    "mfrac" => 1,
    "mglyph" => 1,
    "mi" => 1,
    "mlabeledtr" => 1,
    "mlongdiv" => 1,
    "mmultiscripts" => 1,
    "mn" => 1,
    "mo" => 1,
    "mover" => 1,
    "mpadded" => 1,
    "mphantom" => 1,
    "mroot" => 1,
    "mrow" => 1,
    "ms" => 1,
    "mscarries" => 1,
    "mscarry" => 1,
    "msgroup" => 1,
    "msline" => 1,
    "mspace" => 1,
    "msqrt" => 1,
    "msrow" => 1,
    "mstack" => 1,
    "mstyle" => 1,
    "msub" => 1,
    "msup" => 1,
    "msubsup" => 1,
    "mtable" => 1,
    "mtd" => 1,
    "mtext" => 1,
    "mtr" => 1,
    "munder" => 1,
    "munderover" => 1,
  );

  /**
   * The svg elements.
   *
   * The Mozilla documentation has a good list at https://developer.mozilla.org/en-US/docs/SVG/Element.
   * The w3c list appears to be lacking in some areas like filter effect elements.
   * That list can be found at http://www.w3.org/wiki/SVG/Elements.
   *
   * Note, FireFox appears to do a better job rendering filter effects than chrome.
   * While they are in the spec I'm not sure how widely implemented they are.
   *
   * @var array
   */
  public static $svg = array(
    "a" => 1,
    "altGlyph" => 1,
    "altGlyphDef" => 1,
    "altGlyphItem" => 1,
    "animate" => 1,
    "animateColor" => 1,
    "animateMotion" => 1,
    "animateTransform" => 1,
    "circle" => 1,
    "clipPath" => 1,
    "color-profile" => 1,
    "cursor" => 1,
    "defs" => 1,
    "desc" => 1,
    "ellipse" => 1,
    "feBlend" => 1,
    "feColorMatrix" => 1,
    "feComponentTransfer" => 1,
    "feComposite" => 1,
    "feConvolveMatrix" => 1,
    "feDiffuseLighting" => 1,
    "feDisplacementMap" => 1,
    "feDistantLight" => 1,
    "feFlood" => 1,
    "feFuncA" => 1,
    "feFuncB" => 1,
    "feFuncG" => 1,
    "feFuncR" => 1,
    "feGaussianBlur" => 1,
    "feImage" => 1,
    "feMerge" => 1,
    "feMergeNode" => 1,
    "feMorphology" => 1,
    "feOffset" => 1,
    "fePointLight" => 1,
    "feSpecularLighting" => 1,
    "feSpotLight" => 1,
    "feTile" => 1,
    "feTurbulence" => 1,
    "filter" => 1,
    "font" => 1,
    "font-face" => 1,
    "font-face-format" => 1,
    "font-face-name" => 1,
    "font-face-src" => 1,
    "font-face-uri" => 1,
    "foreignObject" => 1,
    "g" => 1,
    "glyph" => 1,
    "glyphRef" => 1,
    "hkern" => 1,
    "image" => 1,
    "line" => 1,
    "linearGradient" => 1,
    "marker" => 1,
    "mask" => 1,
    "metadata" => 1,
    "missing-glyph" => 1,
    "mpath" => 1,
    "path" => 1,
    "pattern" => 1,
    "polygon" => 1,
    "polyline" => 1,
    "radialGradient" => 1,
    "rect" => 1,
    "script" => 3,
    // NORMAL | RAW_TEXT
    "set" => 1,
    "stop" => 1,
    "style" => 3,
    // NORMAL | RAW_TEXT
    "svg" => 1,
    "switch" => 1,
    "symbol" => 1,
    "text" => 1,
    "textPath" => 1,
    "title" => 1,
    "tref" => 1,
    "tspan" => 1,
    "use" => 1,
    "view" => 1,
    "vkern" => 1,
  );

  /**
   * Some attributes in SVG are case sensetitive.
   *
   * This map contains key/value pairs with the key as the lowercase attribute
   * name and the value with the correct casing.
   */
  public static $svgCaseSensitiveAttributeMap = array(
    'attributename' => 'attributeName',
    'attributetype' => 'attributeType',
    'basefrequency' => 'baseFrequency',
    'baseprofile' => 'baseProfile',
    'calcmode' => 'calcMode',
    'clippathunits' => 'clipPathUnits',
    'contentscripttype' => 'contentScriptType',
    'contentstyletype' => 'contentStyleType',
    'diffuseconstant' => 'diffuseConstant',
    'edgemode' => 'edgeMode',
    'externalresourcesrequired' => 'externalResourcesRequired',
    'filterres' => 'filterRes',
    'filterunits' => 'filterUnits',
    'glyphref' => 'glyphRef',
    'gradienttransform' => 'gradientTransform',
    'gradientunits' => 'gradientUnits',
    'kernelmatrix' => 'kernelMatrix',
    'kernelunitlength' => 'kernelUnitLength',
    'keypoints' => 'keyPoints',
    'keysplines' => 'keySplines',
    'keytimes' => 'keyTimes',
    'lengthadjust' => 'lengthAdjust',
    'limitingconeangle' => 'limitingConeAngle',
    'markerheight' => 'markerHeight',
    'markerunits' => 'markerUnits',
    'markerwidth' => 'markerWidth',
    'maskcontentunits' => 'maskContentUnits',
    'maskunits' => 'maskUnits',
    'numoctaves' => 'numOctaves',
    'pathlength' => 'pathLength',
    'patterncontentunits' => 'patternContentUnits',
    'patterntransform' => 'patternTransform',
    'patternunits' => 'patternUnits',
    'pointsatx' => 'pointsAtX',
    'pointsaty' => 'pointsAtY',
    'pointsatz' => 'pointsAtZ',
    'preservealpha' => 'preserveAlpha',
    'preserveaspectratio' => 'preserveAspectRatio',
    'primitiveunits' => 'primitiveUnits',
    'refx' => 'refX',
    'refy' => 'refY',
    'repeatcount' => 'repeatCount',
    'repeatdur' => 'repeatDur',
    'requiredextensions' => 'requiredExtensions',
    'requiredfeatures' => 'requiredFeatures',
    'specularconstant' => 'specularConstant',
    'specularexponent' => 'specularExponent',
    'spreadmethod' => 'spreadMethod',
    'startoffset' => 'startOffset',
    'stddeviation' => 'stdDeviation',
    'stitchtiles' => 'stitchTiles',
    'surfacescale' => 'surfaceScale',
    'systemlanguage' => 'systemLanguage',
    'tablevalues' => 'tableValues',
    'targetx' => 'targetX',
    'targety' => 'targetY',
    'textlength' => 'textLength',
    'viewbox' => 'viewBox',
    'viewtarget' => 'viewTarget',
    'xchannelselector' => 'xChannelSelector',
    'ychannelselector' => 'yChannelSelector',
    'zoomandpan' => 'zoomAndPan',
  );

  /**
   * Some SVG elements are case sensetitive.
   * This map contains these.
   *
   * The map contains key/value store of the name is lowercase as the keys and
   * the correct casing as the value.
   */
  public static $svgCaseSensitiveElementMap = array(
    'altglyph' => 'altGlyph',
    'altglyphdef' => 'altGlyphDef',
    'altglyphitem' => 'altGlyphItem',
    'animatecolor' => 'animateColor',
    'animatemotion' => 'animateMotion',
    'animatetransform' => 'animateTransform',
    'clippath' => 'clipPath',
    'feblend' => 'feBlend',
    'fecolormatrix' => 'feColorMatrix',
    'fecomponenttransfer' => 'feComponentTransfer',
    'fecomposite' => 'feComposite',
    'feconvolvematrix' => 'feConvolveMatrix',
    'fediffuselighting' => 'feDiffuseLighting',
    'fedisplacementmap' => 'feDisplacementMap',
    'fedistantlight' => 'feDistantLight',
    'feflood' => 'feFlood',
    'fefunca' => 'feFuncA',
    'fefuncb' => 'feFuncB',
    'fefuncg' => 'feFuncG',
    'fefuncr' => 'feFuncR',
    'fegaussianblur' => 'feGaussianBlur',
    'feimage' => 'feImage',
    'femerge' => 'feMerge',
    'femergenode' => 'feMergeNode',
    'femorphology' => 'feMorphology',
    'feoffset' => 'feOffset',
    'fepointlight' => 'fePointLight',
    'fespecularlighting' => 'feSpecularLighting',
    'fespotlight' => 'feSpotLight',
    'fetile' => 'feTile',
    'feturbulence' => 'feTurbulence',
    'foreignobject' => 'foreignObject',
    'glyphref' => 'glyphRef',
    'lineargradient' => 'linearGradient',
    'radialgradient' => 'radialGradient',
    'textpath' => 'textPath',
  );

  /**
   * Check whether the given element meets the given criterion.
   *
   * Example:
   *
   * Elements::isA('script', Elements::TEXT_RAW); // Returns true.
   *
   * Elements::isA('script', Elements::TEXT_RCDATA); // Returns false.
   *
   * @param string $name
   *            The element name.
   * @param int $mask
   *            One of the constants on this class.
   * @return boolean true if the element matches the mask, false otherwise.
   */
  public static function isA($name, $mask) {
    if (!static::isElement($name)) {
      return false;
    }
    return (static::element($name) & $mask) == $mask;
  }

  /**
   * Test if an element is a valid html5 element.
   *
   * @param string $name
   *            The name of the element.
   *
   * @return bool True if a html5 element and false otherwise.
   */
  public static function isHtml5Element($name) {

    // html5 element names are case insensetitive. Forcing lowercase for the check.
    // Do we need this check or will all data passed here already be lowercase?
    return isset(static::$html5[strtolower($name)]);
  }

  /**
   * Test if an element name is a valid MathML presentation element.
   *
   * @param string $name
   *            The name of the element.
   *
   * @return bool True if a MathML name and false otherwise.
   */
  public static function isMathMLElement($name) {

    // MathML is case-sensetitive unlike html5 elements.
    return isset(static::$mathml[$name]);
  }

  /**
   * Test if an element is a valid SVG element.
   *
   * @param string $name
   *            The name of the element.
   *
   * @return boolean True if a SVG element and false otherise.
   */
  public static function isSvgElement($name) {

    // SVG is case-sensetitive unlike html5 elements.
    return isset(static::$svg[$name]);
  }

  /**
   * Is an element name valid in an html5 document.
   *
   * This includes html5 elements along with other allowed embedded content
   * such as svg and mathml.
   *
   * @param string $name
   *            The name of the element.
   *
   * @return bool True if valid and false otherwise.
   */
  public static function isElement($name) {
    return static::isHtml5Element($name) || static::isMathMLElement($name) || static::isSvgElement($name);
  }

  /**
   * Get the element mask for the given element name.
   *
   * @param string $name
   *            The name of the element.
   *
   * @return int The element mask.
   */
  public static function element($name) {
    if (isset(static::$html5[$name])) {
      return static::$html5[$name];
    }
    if (isset(static::$svg[$name])) {
      return static::$svg[$name];
    }
    if (isset(static::$mathml[$name])) {
      return static::$mathml[$name];
    }
    return false;
  }

  /**
   * Normalize a SVG element name to its proper case and form.
   *
   * @param string $name
   *            The name of the element.
   *
   * @return string The normalized form of the element name.
   */
  public static function normalizeSvgElement($name) {
    $name = strtolower($name);
    if (isset(static::$svgCaseSensitiveElementMap[$name])) {
      $name = static::$svgCaseSensitiveElementMap[$name];
    }
    return $name;
  }

  /**
   * Normalize a SVG attribute name to its proper case and form.
   *
   * @param string $name
   *            The name of the attribute.
   *
   * @return string The normalized form of the attribute name.
   */
  public static function normalizeSvgAttribute($name) {
    $name = strtolower($name);
    if (isset(static::$svgCaseSensitiveAttributeMap[$name])) {
      $name = static::$svgCaseSensitiveAttributeMap[$name];
    }
    return $name;
  }

  /**
   * Normalize a MathML attribute name to its proper case and form.
   *
   * Note, all MathML element names are lowercase.
   *
   * @param string $name
   *            The name of the attribute.
   *
   * @return string The normalized form of the attribute name.
   */
  public static function normalizeMathMlAttribute($name) {
    $name = strtolower($name);

    // Only one attribute has a mixed case form for MathML.
    if ($name == 'definitionurl') {
      $name = 'definitionURL';
    }
    return $name;
  }

}

Classes

Namesort descending Description
Elements This class provides general information about HTML5 elements, including syntactic and semantic issues. Parsers and serializers can use this class as a reference point for information about the rules of various HTML5 elements.