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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Parser.js
001 /**
002 * @type {!Object} Attributes of the BBCode being parsed
003 */
004 var attributes;
005
006 /**
007 * @type {!Object} Configuration for the BBCode being parsed
008 */
009 var bbcodeConfig;
010
011 /**
012 * @type {string} Name of the BBCode being parsed
013 */
014 var bbcodeName;
015
016 /**
017 * @type {string} Suffix of the BBCode being parsed, including its colon
018 */
019 var bbcodeSuffix;
020
021 /**
022 * @type {number} Position of the cursor in the original text
023 */
024 var pos;
025
026 /**
027 * @type {number} Position of the start of the BBCode being parsed
028 */
029 var startPos;
030
031 /**
032 * @type {number} Length of the text being parsed
033 */
034 var textLen = text.length;
035
036 /**
037 * @type {string} Text being parsed, normalized to uppercase
038 */
039 var uppercaseText = '';
040
041 matches.forEach(function(m)
042 {
043 bbcodeName = m[1][0].toUpperCase();
044 if (!(bbcodeName in config.bbcodes))
045 {
046 return;
047 }
048 bbcodeConfig = config.bbcodes[bbcodeName];
049 startPos = m[0][1];
050 pos = startPos + m[0][0].length;
051
052 try
053 {
054 parseBBCode();
055 }
056 catch (e)
057 {
058 // Do nothing
059 }
060 });
061
062 /**
063 * Add the end tag that matches current BBCode
064 *
065 * @return {!Tag}
066 */
067 function addBBCodeEndTag()
068 {
069 return addEndTag(getTagName(), startPos, pos - startPos);
070 }
071
072 /**
073 * Add the self-closing tag that matches current BBCode
074 *
075 * @return {!Tag}
076 */
077 function addBBCodeSelfClosingTag()
078 {
079 var tag = addSelfClosingTag(getTagName(), startPos, pos - startPos);
080 tag.setAttributes(attributes);
081
082 return tag;
083 }
084
085 /**
086 * Add the start tag that matches current BBCode
087 *
088 * @return {!Tag}
089 */
090 function addBBCodeStartTag()
091 {
092 var prio = (bbcodeSuffix !== '') ? -10 : 0,
093 tag = addStartTag(getTagName(), startPos, pos - startPos, prio);
094 tag.setAttributes(attributes);
095
096 return tag;
097 }
098
099 /**
100 * Parse the end tag that matches given BBCode name and suffix starting at current position
101 *
102 * @return {?Tag}
103 */
104 function captureEndTag()
105 {
106 if (!uppercaseText)
107 {
108 uppercaseText = text.toUpperCase();
109 }
110 var match = '[/' + bbcodeName + bbcodeSuffix + ']',
111 endTagPos = uppercaseText.indexOf(match, pos);
112 if (endTagPos < 0)
113 {
114 return null;
115 }
116
117 return addEndTag(getTagName(), endTagPos, match.length);
118 }
119
120 /**
121 * Get the tag name for current BBCode
122 *
123 * @return {string}
124 */
125 function getTagName()
126 {
127 // Use the configured tagName if available, or reuse the BBCode's name otherwise
128 return bbcodeConfig.tagName || bbcodeName;
129 }
130
131 /**
132 * Parse attributes starting at current position
133 */
134 function parseAttributes()
135 {
136 var firstPos = pos, attrName;
137 attributes = {};
138 while (pos < textLen)
139 {
140 var c = text[pos];
141 if (" \n\t".indexOf(c) > -1)
142 {
143 ++pos;
144 continue;
145 }
146 if ('/]'.indexOf(c) > -1)
147 {
148 return;
149 }
150
151 // Capture the attribute name
152 var spn = /^[-\w]*/.exec(text.substring(pos, pos + 100))[0].length;
153 if (spn)
154 {
155 attrName = text.substring(pos, pos + spn).toLowerCase();
156 pos += spn;
157 if (pos >= textLen)
158 {
159 // The attribute name extends to the end of the text
160 throw '';
161 }
162 if (text[pos] !== '=')
163 {
164 // It's an attribute name not followed by an equal sign, ignore it
165 continue;
166 }
167 }
168 else if (c === '=' && pos === firstPos)
169 {
170 // This is the default param, e.g. [quote=foo]
171 attrName = bbcodeConfig.defaultAttribute || bbcodeName.toLowerCase();
172 }
173 else
174 {
175 throw '';
176 }
177
178 // Move past the = and make sure we're not at the end of the text
179 if (++pos >= textLen)
180 {
181 throw '';
182 }
183
184 attributes[attrName] = parseAttributeValue();
185 }
186 }
187
188 /**
189 * Parse the attribute value starting at current position
190 *
191 * @return {string}
192 */
193 function parseAttributeValue()
194 {
195 // Test whether the value is in quotes
196 if (text[pos] === '"' || text[pos] === "'")
197 {
198 return parseQuotedAttributeValue();
199 }
200
201 // Capture everything up to whichever comes first:
202 // - an endline
203 // - whitespace followed by a slash and a closing bracket
204 // - a closing bracket, optionally preceded by whitespace
205 // - whitespace followed by another attribute (name followed by equal sign)
206 //
207 // NOTE: this is for compatibility with some forums (such as vBulletin it seems)
208 // that do not put attribute values in quotes, e.g.
209 // [quote=John Smith;123456] (quoting "John Smith" from post #123456)
210 var match = /(?:[^\s\]]|[ \t](?!\s*(?:[-\w]+=|\/?\])))*/.exec(text.substring(pos)),
211 attrValue = match[0];
212 pos += attrValue.length;
213
214 return attrValue;
215 }
216
217 /**
218 * Parse current BBCode
219 */
220 function parseBBCode()
221 {
222 parseBBCodeSuffix();
223
224 // Test whether this is an end tag
225 if (text[startPos + 1] === '/')
226 {
227 // Test whether the tag is properly closed and whether this tag has an identifier.
228 // We skip end tags that carry an identifier because they're automatically added
229 // when their start tag is processed
230 if (text[pos] === ']' && bbcodeSuffix === '')
231 {
232 ++pos;
233 addBBCodeEndTag();
234 }
235
236 return;
237 }
238
239 // Parse attributes and fill in the blanks with predefined attributes
240 parseAttributes();
241 if (bbcodeConfig.predefinedAttributes)
242 {
243 for (var attrName in bbcodeConfig.predefinedAttributes)
244 {
245 if (!(attrName in attributes))
246 {
247 attributes[attrName] = bbcodeConfig.predefinedAttributes[attrName];
248 }
249 }
250 }
251
252 // Test whether the tag is properly closed
253 if (text[pos] === ']')
254 {
255 ++pos;
256 }
257 else
258 {
259 // Test whether this is a self-closing tag
260 if (text.substring(pos, pos + 2) === '/]')
261 {
262 pos += 2;
263 addBBCodeSelfClosingTag();
264 }
265
266 return;
267 }
268
269 // Record the names of attributes that need the content of this tag
270 var contentAttributes = [];
271 if (bbcodeConfig.contentAttributes)
272 {
273 bbcodeConfig.contentAttributes.forEach(function(attrName)
274 {
275 if (!(attrName in attributes))
276 {
277 contentAttributes.push(attrName);
278 }
279 });
280 }
281
282 // Look ahead and parse the end tag that matches this tag, if applicable
283 var requireEndTag = (bbcodeSuffix || bbcodeConfig.forceLookahead),
284 endTag = (requireEndTag || contentAttributes.length) ? captureEndTag() : null;
285 if (endTag)
286 {
287 contentAttributes.forEach(function(attrName)
288 {
289 attributes[attrName] = text.substring(pos, endTag.getPos());
290 });
291 }
292 else if (requireEndTag)
293 {
294 return;
295 }
296
297 // Create this start tag
298 var tag = addBBCodeStartTag();
299
300 // If an end tag was created, pair it with this start tag
301 if (endTag)
302 {
303 tag.pairWith(endTag);
304 }
305 }
306
307 /**
308 * Parse the BBCode suffix starting at current position
309 *
310 * Used to explicitly pair specific tags together, e.g.
311 * [code:123][code]type your code here[/code][/code:123]
312 */
313 function parseBBCodeSuffix()
314 {
315 bbcodeSuffix = '';
316 if (text[pos] === ':')
317 {
318 // Capture the colon and the (0 or more) digits following it
319 bbcodeSuffix = /^:\d*/.exec(text.substring(pos))[0];
320
321 // Move past the suffix
322 pos += bbcodeSuffix.length;
323 }
324 }
325
326 /**
327 * Parse a quoted attribute value that starts at current offset
328 *
329 * @return {string}
330 */
331 function parseQuotedAttributeValue()
332 {
333 var quote = text[pos],
334 valuePos = pos + 1;
335 do
336 {
337 // Look for the next quote
338 pos = text.indexOf(quote, pos + 1);
339 if (pos < 0)
340 {
341 // No matching quote. Apparently that string never ends...
342 throw '';
343 }
344
345 // Test for an odd number of backslashes before this character
346 var n = 1;
347 while (text[pos - n] === '\\')
348 {
349 ++n;
350 }
351 }
352 while (n % 2 === 0);
353
354 var attrValue = text.substring(valuePos, pos);
355 if (attrValue.indexOf('\\') > -1)
356 {
357 attrValue = attrValue.replace(/\\([\\'"])/g, '$1');
358 }
359
360 // Skip past the closing quote
361 ++pos;
362
363 return attrValue;
364 }