3 namespace RemexHtml\TreeBuilder;
4 use RemexHtml\HTMLData;
5 use RemexHtml\PropGuard;
6 use RemexHtml\Tokenizer\Attributes;
9 * Storage for all the state that TreeBuilder needs to associate with each
10 * element. These objects should be freed once they fall out of TreeBuilder's
11 * data structures (the stack etc.).
13 * These objects are also used to communicate information about elements with
16 class Element implements FormattingElement {
18 * The namespace. This will be the HTML namespace for elements that are not
19 * in foreign content, even if there is a prefix.
25 * The tag name, usually exactly as it appeared in the source document.
26 * This is not strictly a local name, since it still contains a colon for
27 * prefixed elements. In foreign content, it is effectively a local name.
28 * It is suitable for use as a serialized tag name.
34 * This is an internal designation of the type of the element, which is
35 * equal to the tag name when the element is in the HTML namespace, and is
36 * some other string when the element is not in the HTML namespace.
47 * This is true if the element was created by the TreeBuilder either as a
48 * fragment context node, or as a synthetic <html> element to be used as
49 * the top-level element in fragment parsing.
55 * Internal to CachingStack. A link in the scope list.
60 * Internal to CachingStack and SimpleStack. The current stack index, or
61 * null if the element is not in the stack.
66 * Internal to ActiveFormattingElements.
68 public $prevAFE, $nextAFE, $nextNoah;
71 * The cache for getNoahKey()
76 * This member variable can be written to by the TreeHandler, to store any
77 * state associated with the element (such as a DOM node). It is not used
83 * The element types in the MathML namespace which are MathML text
87 private static $mathmlIntegration = [
96 * The element types in the SVG namespace which are SVG text integration
100 private static $svgHtmlIntegration = [
101 'foreignObject' => true,
109 * @param string $namespace
110 * @param string $name
111 * @param Attributes $attrs
113 public function __construct( $namespace, $name, Attributes $attrs ) {
114 $this->namespace = $namespace;
116 if ( $namespace === HTMLData::NS_HTML ) {
117 $this->htmlName = $name;
118 } elseif ( $namespace === HTMLData::NS_MATHML ) {
119 $this->htmlName = "mathml $name";
120 } elseif ( $namespace === HTMLData::NS_SVG ) {
121 $this->htmlName = "svg $name";
123 $this->htmlName = "$namespace $name";
125 $this->attrs = $attrs;
128 public function __set( $name, $value ) {
129 PropGuard::set( $this, $name, $value );
133 * Is the element a MathML text integration point?
137 public function isMathmlTextIntegration() {
138 return $this->namespace === HTMLData::NS_MATHML
139 && isset( self::$mathmlIntegration[$this->name] );
143 * Is the element an HTML integration point?
145 public function isHtmlIntegration() {
146 if ( $this->namespace === HTMLData::NS_MATHML ) {
147 if ( isset( $this->attrs['encoding'] ) ) {
148 $encoding = strtolower( $this->attrs['encoding'] );
149 return $encoding === 'text/html' || $encoding === 'application/xhtml+xml';
153 } elseif ( $this->namespace === HTMLData::NS_SVG ) {
154 return isset( self::$svgHtmlIntegration[$this->name] );
161 * Get a string key for the Noah's Ark algorithm
165 public function getNoahKey() {
166 if ( $this->noahKey === null ) {
167 $attrs = $this->attrs->getValues();
169 $this->noahKey = serialize( [ $this->htmlName, $attrs ] );
171 return $this->noahKey;
175 * Get a string identifying the element, for use in debugging.
177 public function getDebugTag() {
178 return $this->htmlName . '#' . substr( md5( spl_object_hash( $this ) ), 0, 8 );