Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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: 02.04.2025, 15:03 - Dateigröße: 7.78 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      this.sortPriority = +priority || 0;
017   
018      this.attributes = {};
019      this.cascade    = [];
020   
021      // Invalidate this tag now if any value is not a number, they could wreck
022      // havoc in other parts of the program
023      if (isNaN(type + pos + len))
024      {
025          this.invalidate();
026      }
027  }
028   
029  /** @const */
030  Tag.START_TAG = 1;
031   
032  /** @const */
033  Tag.END_TAG = 2;
034   
035  /** @const */
036  Tag.SELF_CLOSING_TAG = 3;
037   
038  /**
039  * @type {!Object} Dictionary of attributes
040  */
041  Tag.prototype.attributes;
042   
043  /**
044  * @type {!Array.<!Tag>} List of tags that are invalidated when this tag is invalidated
045  */
046  Tag.prototype.cascade;
047   
048  /**
049  * @type {?Tag} End tag that unconditionally ends this start tag
050  */
051  Tag.prototype.endTag;
052   
053  /**
054  * @type {boolean} Whether this tag is be invalid
055  */
056  Tag.prototype.invalid = false;
057   
058  /**
059  * @type {number} Length of text consumed by this tag
060  */
061  Tag.prototype.len;
062   
063  /**
064  * @type {string} Name of this tag
065  */
066  Tag.prototype.name;
067   
068  /**
069  * @type {number} Position of this tag in the text
070  */
071  Tag.prototype.pos;
072   
073  /**
074  * @type {number} Tiebreaker used when sorting identical tags
075  */
076  Tag.prototype.sortPriority;
077   
078  /**
079  * @type {?Tag} Start tag that is unconditionally closed this end tag
080  */
081  Tag.prototype.startTag;
082   
083  /**
084  * @type {number} Tag type
085  */
086  Tag.prototype.type;
087   
088  /**
089  * Add a set of flags to this tag's
090  *
091  * @param {number} flags
092  */
093  Tag.prototype.addFlags = function(flags)
094  {
095      this.flags |= flags;
096  };
097   
098  /**
099  * Set given tag to be invalidated if this tag is invalidated
100  *
101  * @param {!Tag} tag
102  */
103  Tag.prototype.cascadeInvalidationTo = function(tag)
104  {
105      this.cascade.push(tag);
106   
107      // If this tag is already invalid, cascade it now
108      if (this.invalid)
109      {
110          tag.invalidate();
111      }
112  };
113   
114  /**
115  * Invalidate this tag, as well as tags bound to this tag
116  */
117  Tag.prototype.invalidate = function()
118  {
119      // Only invalidate if this tag is valid to prevent infinite loops
120      if (!this.invalid)
121      {
122          this.invalid = true;
123          this.cascade.forEach(
124              /**
125              * @param {!Tag} tag
126              */
127              function(tag)
128              {
129                  tag.invalidate();
130              }
131          );
132      }
133  };
134   
135  /**
136  * Pair this tag with given tag
137  *
138  * @param {!Tag} tag
139  */
140  Tag.prototype.pairWith = function(tag)
141  {
142      if (this.canBePaired(this, tag))
143      {
144          this.endTag  = tag;
145          tag.startTag = this;
146   
147          this.cascadeInvalidationTo(tag);
148      }
149      else if (this.canBePaired(tag, this))
150      {
151          this.startTag = tag;
152          tag.endTag    = this;
153      }
154  };
155   
156  /**
157  * Test whether two tags can be paired
158  *
159  * @param  {!Tag} startTag
160  * @param  {!Tag} endTag
161  * @return {boolean}
162  */
163  Tag.prototype.canBePaired = function(startTag, endTag)
164  {
165      return startTag.name === endTag.name && startTag.type === Tag.START_TAG && endTag.type === Tag.END_TAG && startTag.pos <= startTag.pos;
166  };
167   
168  /**
169  * Remove a set of flags from this tag's
170  *
171  * @param {number} flags
172  */
173  Tag.prototype.removeFlags = function(flags)
174  {
175      this.flags &= ~flags;
176  };
177   
178  /**
179  * Set the bitfield of boolean rules that apply to this tag
180  *
181  * @param {number} flags Bitfield of boolean rules that apply to this tag
182  */
183  Tag.prototype.setFlags = function(flags)
184  {
185      this.flags = flags;
186  };
187   
188  //==========================================================================
189  // Getters
190  //==========================================================================
191   
192  /**
193  * Return this tag's attributes
194  *
195  * @return {!Object}
196  */
197  Tag.prototype.getAttributes = function()
198  {
199      var attributes = {};
200      for (var attrName in this.attributes)
201      {
202          attributes[attrName] = this.attributes[attrName];
203      }
204   
205      return attributes;
206  };
207   
208  /**
209  * Return this tag's end tag
210  *
211  * @return {?Tag} This tag's end tag
212  */
213  Tag.prototype.getEndTag = function()
214  {
215      return this.endTag;
216  };
217   
218  /**
219  * Return the bitfield of boolean rules that apply to this tag
220  *
221  * @return {number}
222  */
223  Tag.prototype.getFlags = function()
224  {
225      return this.flags;
226  };
227   
228  /**
229  * Return the length of text consumed by this tag
230  *
231  * @return {number}
232  */
233  Tag.prototype.getLen = function()
234  {
235      return this.len;
236  };
237   
238  /**
239  * Return this tag's name
240  *
241  * @return {string}
242  */
243  Tag.prototype.getName = function()
244  {
245      return this.name;
246  };
247   
248  /**
249  * Return this tag's position
250  *
251  * @return {number}
252  */
253  Tag.prototype.getPos = function()
254  {
255      return this.pos;
256  };
257   
258  /**
259  * Return this tag's tiebreaker
260  *
261  * @return {number}
262  */
263  Tag.prototype.getSortPriority = function()
264  {
265      return this.sortPriority;
266  };
267   
268  /**
269  * Return this tag's start tag
270  *
271  * @return {?Tag} This tag's start tag
272  */
273  Tag.prototype.getStartTag = function()
274  {
275      return this.startTag;
276  };
277   
278  /**
279  * Return this tag's type
280  *
281  * @return {number}
282  */
283  Tag.prototype.getType = function()
284  {
285      return this.type;
286  };
287   
288  //==========================================================================
289  // Tag's status
290  //==========================================================================
291   
292  /**
293  * Test whether this tag can close given start tag
294  *
295  * @param  {!Tag} startTag
296  * @return {boolean}
297  */
298  Tag.prototype.canClose = function(startTag)
299  {
300      if (this.invalid
301       || !this.canBePaired(startTag, this)
302       || (this.startTag && this.startTag !== startTag)
303       || (startTag.endTag && startTag.endTag !== this))
304      {
305          return false;
306      }
307   
308      return true;
309  };
310   
311  /**
312  * Test whether this tag is a br tag
313  *
314  * @return {boolean}
315  */
316  Tag.prototype.isBrTag = function()
317  {
318      return (this.name === 'br');
319  };
320   
321  /**
322  * Test whether this tag is an end tag (self-closing tags inclusive)
323  *
324  * @return {boolean}
325  */
326  Tag.prototype.isEndTag = function()
327  {
328      return !!(this.type & Tag.END_TAG);
329  };
330   
331  /**
332  * Test whether this tag is an ignore tag
333  *
334  * @return {boolean}
335  */
336  Tag.prototype.isIgnoreTag = function()
337  {
338      return (this.name === 'i');
339  };
340   
341  /**
342  * Test whether this tag is invalid
343  *
344  * @return {boolean}
345  */
346  Tag.prototype.isInvalid = function()
347  {
348      return this.invalid;
349  };
350   
351  /**
352  * Test whether this tag represents a paragraph break
353  *
354  * @return {boolean}
355  */
356  Tag.prototype.isParagraphBreak = function()
357  {
358      return (this.name === 'pb');
359  };
360   
361  /**
362  * Test whether this tag is a self-closing tag
363  *
364  * @return {boolean}
365  */
366  Tag.prototype.isSelfClosingTag = function()
367  {
368      return (this.type === Tag.SELF_CLOSING_TAG);
369  };
370   
371  /**
372  * Test whether this tag is a special tag: "br", "i", "pb" or "v"
373  *
374  * @return {boolean}
375  */
376  Tag.prototype.isSystemTag = function()
377  {
378      return ('br i pb v'.indexOf(this.name) > -1);
379  };
380   
381  /**
382  * Test whether this tag is a start tag (self-closing tags inclusive)
383  *
384  * @return {boolean}
385  */
386  Tag.prototype.isStartTag = function()
387  {
388      return !!(this.type & Tag.START_TAG);
389  };
390   
391  /**
392  * Test whether this tag represents verbatim text
393  *
394  * @return {boolean}
395  */
396  Tag.prototype.isVerbatim = function()
397  {
398      return (this.name === 'v');
399  };
400   
401  //==========================================================================
402  // Attributes handling
403  //==========================================================================
404   
405  /**
406  * Return the value of given attribute
407  *
408  * @param  {string} attrName
409  * @return {string}
410  */
411  Tag.prototype.getAttribute = function(attrName)
412  {
413      return this.attributes[attrName];
414  };
415   
416  /**
417  * Return whether given attribute is set
418  *
419  * @param  {string} attrName
420  * @return {boolean}
421  */
422  Tag.prototype.hasAttribute = function(attrName)
423  {
424      return (attrName in this.attributes);
425  };
426   
427  /**
428  * Remove given attribute
429  *
430  * @param {string} attrName
431  */
432  Tag.prototype.removeAttribute = function(attrName)
433  {
434      delete this.attributes[attrName];
435  };
436   
437  /**
438  * Set the value of an attribute
439  *
440  * @param {string} attrName  Attribute's name
441  * @param {*}       attrValue Attribute's value
442  */
443  Tag.prototype.setAttribute = function(attrName, attrValue)
444  {
445      this.attributes[attrName] = attrValue;
446  };
447   
448  /**
449  * Set all of this tag's attributes at once
450  *
451  * @param {!Object} attributes
452  */
453  Tag.prototype.setAttributes = function(attributes)
454  {
455      this.attributes = {};
456      for (var attrName in attributes)
457      {
458          this.attributes[attrName] = attributes[attrName];
459      }
460  };