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 |
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 tag = addStartTag(getTagName(), startPos, pos - startPos);
093 tag.setAttributes(attributes);
094
095 return tag;
096 }
097
098 /**
099 * Parse the end tag that matches given BBCode name and suffix starting at current position
100 *
101 * @return {Tag}
102 */
103 function captureEndTag()
104 {
105 if (!uppercaseText)
106 {
107 uppercaseText = text.toUpperCase();
108 }
109 var match = '[/' + bbcodeName + bbcodeSuffix + ']',
110 endTagPos = uppercaseText.indexOf(match, pos);
111 if (endTagPos < 0)
112 {
113 return null;
114 }
115
116 return addEndTag(getTagName(), endTagPos, match.length);
117 }
118
119 /**
120 * Get the tag name for current BBCode
121 *
122 * @return string
123 */
124 function getTagName()
125 {
126 // Use the configured tagName if available, or reuse the BBCode's name otherwise
127 return bbcodeConfig.tagName || bbcodeName;
128 }
129
130 /**
131 * Parse attributes starting at current position
132 *
133 * @return array Associative array of [name => value]
134 */
135 function parseAttributes()
136 {
137 var firstPos = pos, attrName;
138 attributes = {};
139 while (pos < textLen)
140 {
141 var c = text.charAt(pos);
142 if (" \n\t".indexOf(c) > -1)
143 {
144 ++pos;
145 continue;
146 }
147 if ('/]'.indexOf(c) > -1)
148 {
149 return;
150 }
151
152 // Capture the attribute name
153 var spn = /^[-\w]*/.exec(text.substr(pos, 100))[0].length;
154 if (spn)
155 {
156 attrName = text.substr(pos, spn).toLowerCase();
157 pos += spn;
158 if (pos >= textLen)
159 {
160 // The attribute name extends to the end of the text
161 throw '';
162 }
163 if (text.charAt(pos) !== '=')
164 {
165 // It's an attribute name not followed by an equal sign, ignore it
166 continue;
167 }
168 }
169 else if (c === '=' && pos === firstPos)
170 {
171 // This is the default param, e.g. [quote=foo]
172 attrName = bbcodeConfig.defaultAttribute || bbcodeName.toLowerCase();
173 }
174 else
175 {
176 throw '';
177 }
178
179 // Move past the = and make sure we're not at the end of the text
180 if (++pos >= textLen)
181 {
182 throw '';
183 }
184
185 attributes[attrName] = parseAttributeValue();
186 }
187 }
188
189 /**
190 * Parse the attribute value starting at current position
191 *
192 * @return string
193 */
194 function parseAttributeValue()
195 {
196 // Test whether the value is in quotes
197 if (text.charAt(pos) === '"' || text.charAt(pos) === "'")
198 {
199 return parseQuotedAttributeValue();
200 }
201
202 // Capture everything up to whichever comes first:
203 // - an endline
204 // - whitespace followed by a slash and a closing bracket
205 // - a closing bracket, optionally preceded by whitespace
206 // - whitespace followed by another attribute (name followed by equal sign)
207 //
208 // NOTE: this is for compatibility with some forums (such as vBulletin it seems)
209 // that do not put attribute values in quotes, e.g.
210 // [quote=John Smith;123456] (quoting "John Smith" from post #123456)
211 var match = /[^\]\n]*?(?=\s*(?:\s\/)?\]|\s+[-\w]+=)/.exec(text.substr(pos));
212 if (!match)
213 {
214 throw '';
215 }
216
217 var attrValue = match[0];
218 pos += attrValue.length;
219
220 return attrValue;
221 }
222
223 /**
224 * Parse current BBCode
225 *
226 * @return void
227 */
228 function parseBBCode()
229 {
230 parseBBCodeSuffix();
231
232 // Test whether this is an end tag
233 if (text.charAt(startPos + 1) === '/')
234 {
235 // Test whether the tag is properly closed and whether this tag has an identifier.
236 // We skip end tags that carry an identifier because they're automatically added
237 // when their start tag is processed
238 if (text.charAt(pos) === ']' && bbcodeSuffix === '')
239 {
240 ++pos;
241 addBBCodeEndTag();
242 }
243
244 return;
245 }
246
247 // Parse attributes and fill in the blanks with predefined attributes
248 parseAttributes();
249 if (bbcodeConfig.predefinedAttributes)
250 {
251 for (var attrName in bbcodeConfig.predefinedAttributes)
252 {
253 if (!(attrName in attributes))
254 {
255 attributes[attrName] = bbcodeConfig.predefinedAttributes[attrName];
256 }
257 }
258 }
259
260 // Test whether the tag is properly closed
261 if (text.charAt(pos) === ']')
262 {
263 ++pos;
264 }
265 else
266 {
267 // Test whether this is a self-closing tag
268 if (text.substr(pos, 2) === '/]')
269 {
270 pos += 2;
271 addBBCodeSelfClosingTag();
272 }
273
274 return;
275 }
276
277 // Record the names of attributes that need the content of this tag
278 var contentAttributes = [];
279 if (bbcodeConfig.contentAttributes)
280 {
281 bbcodeConfig.contentAttributes.forEach(function(attrName)
282 {
283 if (!(attrName in attributes))
284 {
285 contentAttributes.push(attrName);
286 }
287 });
288 }
289
290 // Look ahead and parse the end tag that matches this tag, if applicable
291 var requireEndTag = (bbcodeSuffix || bbcodeConfig.forceLookahead),
292 endTag = (requireEndTag || contentAttributes.length) ? captureEndTag() : null;
293 if (endTag)
294 {
295 contentAttributes.forEach(function(attrName)
296 {
297 attributes[attrName] = text.substr(pos, endTag.getPos() - pos);
298 });
299 }
300 else if (requireEndTag)
301 {
302 return;
303 }
304
305 // Create this start tag
306 var tag = addBBCodeStartTag();
307
308 // If an end tag was created, pair it with this start tag
309 if (endTag)
310 {
311 tag.pairWith(endTag);
312 }
313 }
314
315 /**
316 * Parse the BBCode suffix starting at current position
317 *
318 * Used to explicitly pair specific tags together, e.g.
319 * [code:123][code]type your code here[/code][/code:123]
320 *
321 * @return void
322 */
323 function parseBBCodeSuffix()
324 {
325 bbcodeSuffix = '';
326 if (text[pos] === ':')
327 {
328 // Capture the colon and the (0 or more) digits following it
329 bbcodeSuffix = /^:\d*/.exec(text.substr(pos))[0];
330
331 // Move past the suffix
332 pos += bbcodeSuffix.length;
333 }
334 }
335
336 /**
337 * Parse a quoted attribute value that starts at current offset
338 *
339 * @return {!string}
340 */
341 function parseQuotedAttributeValue()
342 {
343 var quote = text.charAt(pos),
344 valuePos = pos + 1;
345 while (1)
346 {
347 // Look for the next quote
348 pos = text.indexOf(quote, pos + 1);
349 if (pos < 0)
350 {
351 // No matching quote. Apparently that string never ends...
352 throw '';
353 }
354
355 // Test for an odd number of backslashes before this character
356 var n = 0;
357 do
358 {
359 ++n;
360 }
361 while (text.charAt(pos - n) === '\\');
362
363 if (n % 2)
364 {
365 // If n is odd, it means there's an even number of backslashes. We can exit this loop
366 break;
367 }
368 }
369
370 // Unescape special characters ' " and \
371 var attrValue = text.substr(valuePos, pos - valuePos).replace(/\\([\\'"])/g, '$1');
372
373 // Skip past the closing quote
374 ++pos;
375
376 return attrValue;
377 }