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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Tag.js
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 }