[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Parser/ -> Tag.js (source)

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


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1