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  }