Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Tag.js

Zuletzt modifiziert: 09.10.2024, 12:57 - Dateigröße: 7.96 KiB


 001  /**
 002  * @constructor
 003  *
 004  * @param {!number} type     Tag's type
 005  * @param {!string} name     Name of the tag
 006  * @param {!number} pos      Position of the tag in the text
 007  * @param {!number} len      Length of text consumed by the tag
 008  * @param {number}  priority This tag's sorting tiebreaker
 009  */
 010  function Tag(type, name, pos, len, priority)
 011  {
 012      this.type = +type;
 013      this.name = name;
 014      this.pos  = +pos;
 015      this.len  = +len;
 016      if (typeof priority !== 'undefined')
 017      {
 018          this.sortPriority = +priority;
 019      }
 020   
 021      this.attributes = {};
 022      this.cascade    = [];
 023   
 024      // Invalidate this tag now if any value is not a number, they could wreck
 025      // havoc in other parts of the program
 026      if (isNaN(type + pos + len))
 027      {
 028          this.invalidate();
 029      }
 030  }
 031   
 032  /** @const */
 033  Tag.START_TAG = 1;
 034   
 035  /** @const */
 036  Tag.END_TAG = 2;
 037   
 038  /** @const */
 039  Tag.SELF_CLOSING_TAG = 3;
 040   
 041  /**
 042  * @type {!Object} Dictionary of attributes
 043  */
 044  Tag.prototype.attributes;
 045   
 046  /**
 047  * @type {!Array.<!Tag>} List of tags that are invalidated when this tag is invalidated
 048  */
 049  Tag.prototype.cascade;
 050   
 051  /**
 052  * @type {Tag} End tag that unconditionally ends this start tag
 053  */
 054  Tag.prototype.endTag;
 055   
 056  /**
 057  * @type {!boolean} Whether this tag is be invalid
 058  */
 059  Tag.prototype.invalid = false;
 060   
 061  /**
 062  * @type {!number} Length of text consumed by this tag
 063  */
 064  Tag.prototype.len;
 065   
 066  /**
 067  * @type {!string} Name of this tag
 068  */
 069  Tag.prototype.name;
 070   
 071  /**
 072  * @type {!number} Position of this tag in the text
 073  */
 074  Tag.prototype.pos;
 075   
 076  /**
 077  * @type {!number} Tiebreaker used when sorting identical tags
 078  */
 079  Tag.prototype.sortPriority;
 080   
 081  /**
 082  * @type {Tag} Start tag that is unconditionally closed this end tag
 083  */
 084  Tag.prototype.startTag;
 085   
 086  /**
 087  * @type {!number} Tag type
 088  */
 089  Tag.prototype.type;
 090   
 091  /**
 092  * Add a set of flags to this tag's
 093  *
 094  * @param {!number} flags
 095  */
 096  Tag.prototype.addFlags = function(flags)
 097  {
 098      this.flags |= flags;
 099  };
 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  }