[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 /** 2 * @type {!Object} Attributes of the BBCode being parsed 3 */ 4 var attributes; 5 6 /** 7 * @type {!Object} Configuration for the BBCode being parsed 8 */ 9 var bbcodeConfig; 10 11 /** 12 * @type {!string} Name of the BBCode being parsed 13 */ 14 var bbcodeName; 15 16 /** 17 * @type {!string} Suffix of the BBCode being parsed, including its colon 18 */ 19 var bbcodeSuffix; 20 21 /** 22 * @type {!number} Position of the cursor in the original text 23 */ 24 var pos; 25 26 /** 27 * @type {!number} Position of the start of the BBCode being parsed 28 */ 29 var startPos; 30 31 /** 32 * @type {!number} Length of the text being parsed 33 */ 34 var textLen = text.length; 35 36 /** 37 * @type {!string} Text being parsed, normalized to uppercase 38 */ 39 var uppercaseText = ''; 40 41 matches.forEach(function(m) 42 { 43 bbcodeName = m[1][0].toUpperCase(); 44 if (!(bbcodeName in config.bbcodes)) 45 { 46 return; 47 } 48 bbcodeConfig = config.bbcodes[bbcodeName]; 49 startPos = m[0][1]; 50 pos = startPos + m[0][0].length; 51 52 try 53 { 54 parseBBCode(); 55 } 56 catch (e) 57 { 58 // Do nothing 59 } 60 }); 61 62 /** 63 * Add the end tag that matches current BBCode 64 * 65 * @return {!Tag} 66 */ 67 function addBBCodeEndTag() 68 { 69 return addEndTag(getTagName(), startPos, pos - startPos); 70 } 71 72 /** 73 * Add the self-closing tag that matches current BBCode 74 * 75 * @return {!Tag} 76 */ 77 function addBBCodeSelfClosingTag() 78 { 79 var tag = addSelfClosingTag(getTagName(), startPos, pos - startPos); 80 tag.setAttributes(attributes); 81 82 return tag; 83 } 84 85 /** 86 * Add the start tag that matches current BBCode 87 * 88 * @return {!Tag} 89 */ 90 function addBBCodeStartTag() 91 { 92 var tag = addStartTag(getTagName(), startPos, pos - startPos); 93 tag.setAttributes(attributes); 94 95 return tag; 96 } 97 98 /** 99 * 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[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[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[pos] === '"' || text[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[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[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[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[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[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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |