[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package s9e\TextFormatter 5 * @copyright Copyright (c) 2010-2022 The s9e authors 6 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 7 */ 8 namespace s9e\TextFormatter\Parser; 9 10 class Tag 11 { 12 /** 13 * Tag type: start tag 14 */ 15 const START_TAG = 1; 16 17 /** 18 * Tag type: end tag 19 */ 20 const END_TAG = 2; 21 22 /** 23 * Tag type: self-closing tag 24 */ 25 const SELF_CLOSING_TAG = self::START_TAG | self::END_TAG; 26 27 /** 28 * @var array Dictionary of attributes 29 */ 30 protected $attributes = []; 31 32 /** 33 * @var array List of tags that are invalidated when this tag is invalidated 34 */ 35 protected $cascade = []; 36 37 /** 38 * @var Tag End tag that unconditionally ends this start tag 39 */ 40 protected $endTag = null; 41 42 /** 43 * @var integer Bitfield of boolean rules that apply to this tag 44 */ 45 protected $flags = 0; 46 47 /** 48 * @var bool Whether this tag is be invalid 49 */ 50 protected $invalid = false; 51 52 /** 53 * @var integer Length of text consumed by this tag 54 */ 55 protected $len; 56 57 /** 58 * @var string Name of this tag 59 */ 60 protected $name; 61 62 /** 63 * @var integer Position of this tag in the text 64 */ 65 protected $pos; 66 67 /** 68 * @var integer Tiebreaker used when sorting identical tags 69 */ 70 protected $sortPriority; 71 72 /** 73 * @var Tag Start tag that is unconditionally closed this end tag 74 */ 75 protected $startTag = null; 76 77 /** 78 * @var integer Tag type 79 */ 80 protected $type; 81 82 /** 83 * Constructor 84 * 85 * @param integer $type Tag's type 86 * @param string $name Name of the tag 87 * @param integer $pos Position of the tag in the text 88 * @param integer $len Length of text consumed by the tag 89 * @param integer $priority This tag's sorting tiebreaker 90 */ 91 public function __construct($type, $name, $pos, $len, $priority = 0) 92 { 93 $this->type = (int) $type; 94 $this->name = $name; 95 $this->pos = (int) $pos; 96 $this->len = (int) $len; 97 $this->sortPriority = (int) $priority; 98 } 99 100 //========================================================================== 101 // Actions 102 //========================================================================== 103 104 /** 105 * Add a set of flags to this tag's 106 * 107 * @param integer $flags 108 * @return void 109 */ 110 public function addFlags($flags) 111 { 112 $this->flags |= $flags; 113 } 114 115 /** 116 * Set given tag to be invalidated if this tag is invalidated 117 * 118 * @param Tag $tag 119 * @return void 120 */ 121 public function cascadeInvalidationTo(Tag $tag) 122 { 123 $this->cascade[] = $tag; 124 125 // If this tag is already invalid, cascade it now 126 if ($this->invalid) 127 { 128 $tag->invalidate(); 129 } 130 } 131 132 /** 133 * Invalidate this tag, as well as tags bound to this tag 134 * 135 * @return void 136 */ 137 public function invalidate() 138 { 139 // Only invalidate if this tag is valid to prevent infinite loops 140 if (!$this->invalid) 141 { 142 $this->invalid = true; 143 foreach ($this->cascade as $tag) 144 { 145 $tag->invalidate(); 146 } 147 } 148 } 149 150 /** 151 * Pair this tag with given tag 152 * 153 * @param Tag $tag 154 * @return void 155 */ 156 public function pairWith(Tag $tag) 157 { 158 if ($this->canBePaired($this, $tag)) 159 { 160 $this->endTag = $tag; 161 $tag->startTag = $this; 162 163 $this->cascadeInvalidationTo($tag); 164 } 165 elseif ($this->canBePaired($tag, $this)) 166 { 167 $this->startTag = $tag; 168 $tag->endTag = $this; 169 } 170 } 171 172 /** 173 * Test whether two tags can be paired 174 */ 175 protected function canBePaired(Tag $startTag, Tag $endTag): bool 176 { 177 return $startTag->name === $endTag->name && $startTag->type === self::START_TAG && $endTag->type === self::END_TAG && $startTag->pos <= $endTag->pos; 178 } 179 180 /** 181 * Remove a set of flags from this tag's 182 * 183 * @param integer $flags 184 * @return void 185 */ 186 public function removeFlags($flags) 187 { 188 $this->flags &= ~$flags; 189 } 190 191 /** 192 * Set the bitfield of boolean rules that apply to this tag 193 * 194 * @param integer $flags Bitfield of boolean rules that apply to this tag 195 * @return void 196 */ 197 public function setFlags($flags) 198 { 199 $this->flags = $flags; 200 } 201 202 //========================================================================== 203 // Getters 204 //========================================================================== 205 206 /** 207 * Return this tag's attributes 208 * 209 * @return array 210 */ 211 public function getAttributes() 212 { 213 return $this->attributes; 214 } 215 216 /** 217 * Return this tag's end tag 218 * 219 * @return Tag|null This tag's end tag, or NULL if none is set 220 */ 221 public function getEndTag() 222 { 223 return $this->endTag; 224 } 225 226 /** 227 * Return the bitfield of boolean rules that apply to this tag 228 * 229 * @return integer 230 */ 231 public function getFlags() 232 { 233 return $this->flags; 234 } 235 236 /** 237 * Return the length of text consumed by this tag 238 * 239 * @return integer 240 */ 241 public function getLen() 242 { 243 return $this->len; 244 } 245 246 /** 247 * Return this tag's name 248 * 249 * @return string 250 */ 251 public function getName() 252 { 253 return $this->name; 254 } 255 256 /** 257 * Return this tag's position 258 * 259 * @return integer 260 */ 261 public function getPos() 262 { 263 return $this->pos; 264 } 265 266 /** 267 * Return this tag's tiebreaker 268 * 269 * @return integer 270 */ 271 public function getSortPriority() 272 { 273 return $this->sortPriority; 274 } 275 276 /** 277 * Return this tag's start tag 278 * 279 * @return Tag|null This tag's start tag, or NULL if none is set 280 */ 281 public function getStartTag() 282 { 283 return $this->startTag; 284 } 285 286 /** 287 * Return this tag's type 288 * 289 * @return integer 290 */ 291 public function getType() 292 { 293 return $this->type; 294 } 295 296 //========================================================================== 297 // Tag's status 298 //========================================================================== 299 300 /** 301 * Test whether this tag can close given start tag 302 * 303 * @param Tag $startTag A start tag 304 * @return bool 305 */ 306 public function canClose(Tag $startTag) 307 { 308 if ($this->invalid 309 || !$this->canBePaired($startTag, $this) 310 || ($this->startTag && $this->startTag !== $startTag) 311 || ($startTag->endTag && $startTag->endTag !== $this)) 312 { 313 return false; 314 } 315 316 return true; 317 } 318 319 /** 320 * Test whether this tag is a br tag 321 * 322 * @return bool 323 */ 324 public function isBrTag() 325 { 326 return ($this->name === 'br'); 327 } 328 329 /** 330 * Test whether this tag is an end tag (self-closing tags inclusive) 331 * 332 * @return bool 333 */ 334 public function isEndTag() 335 { 336 return (bool) ($this->type & self::END_TAG); 337 } 338 339 /** 340 * Test whether this tag is an ignore tag 341 * 342 * @return bool 343 */ 344 public function isIgnoreTag() 345 { 346 return ($this->name === 'i'); 347 } 348 349 /** 350 * Test whether this tag is invalid 351 * 352 * @return bool 353 */ 354 public function isInvalid() 355 { 356 return $this->invalid; 357 } 358 359 /** 360 * Test whether this tag represents a paragraph break 361 * 362 * @return bool 363 */ 364 public function isParagraphBreak() 365 { 366 return ($this->name === 'pb'); 367 } 368 369 /** 370 * Test whether this tag is a self-closing tag 371 * 372 * @return bool 373 */ 374 public function isSelfClosingTag() 375 { 376 return ($this->type === self::SELF_CLOSING_TAG); 377 } 378 379 /** 380 * Test whether this tag is a special tag: "br", "i", "pb" or "v" 381 * 382 * @return bool 383 */ 384 public function isSystemTag() 385 { 386 return (strpos('br i pb v', $this->name) !== false); 387 } 388 389 /** 390 * Test whether this tag is a start tag (self-closing tags inclusive) 391 * 392 * @return bool 393 */ 394 public function isStartTag() 395 { 396 return (bool) ($this->type & self::START_TAG); 397 } 398 399 /** 400 * Test whether this tag represents verbatim text 401 * 402 * @return bool 403 */ 404 public function isVerbatim() 405 { 406 return ($this->name === 'v'); 407 } 408 409 //========================================================================== 410 // Attributes handling 411 //========================================================================== 412 413 /** 414 * Return the value of given attribute 415 * 416 * @param string $attrName 417 * @return mixed 418 */ 419 public function getAttribute($attrName) 420 { 421 return $this->attributes[$attrName]; 422 } 423 424 /** 425 * Return whether given attribute is set 426 * 427 * @param string $attrName 428 * @return bool 429 */ 430 public function hasAttribute($attrName) 431 { 432 return isset($this->attributes[$attrName]); 433 } 434 435 /** 436 * Remove given attribute 437 * 438 * @param string $attrName 439 * @return void 440 */ 441 public function removeAttribute($attrName) 442 { 443 unset($this->attributes[$attrName]); 444 } 445 446 /** 447 * Set the value of an attribute 448 * 449 * @param string $attrName Attribute's name 450 * @param string $attrValue Attribute's value 451 * @return void 452 */ 453 public function setAttribute($attrName, $attrValue) 454 { 455 $this->attributes[$attrName] = $attrValue; 456 } 457 458 /** 459 * Set all of this tag's attributes at once 460 * 461 * @param array $attributes 462 * @return void 463 */ 464 public function setAttributes(array $attributes) 465 { 466 $this->attributes = $attributes; 467 } 468 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |