|
160 | 160 | '>'
|
161 | 161 | ].join( "" ), 'g' );
|
162 | 162 | } )(),
|
| 163 | + |
| 164 | + /** |
| 165 | + * @private |
| 166 | + * @property {RegExp} htmlCharacterEntities |
| 167 | + * |
| 168 | + * The regular expression that matches common HTML character entities. |
| 169 | + * |
| 170 | + * Ignoring & as it coule be part of a query string, handling it separately |
| 171 | + */ |
| 172 | + htmlCharacterEntities: /( | |<|<|>|>)/i, |
163 | 173 |
|
164 | 174 | /**
|
165 | 175 | * @private
|
|
330 | 340 | inBetweenTagsText,
|
331 | 341 | lastIndex = 0,
|
332 | 342 | anchorTagStackCount = 0,
|
333 |
| - resultHtml = []; |
| 343 | + resultHtml = [], |
| 344 | + htmlCharacterEntities = this.htmlCharacterEntities, |
| 345 | + unescapedText, |
| 346 | + textToProcess, |
| 347 | + i; |
334 | 348 |
|
335 | 349 | while( ( currentResult = htmlRegex.exec( html ) ) !== null ) {
|
336 | 350 | var tagText = currentResult[ 0 ],
|
|
339 | 353 |
|
340 | 354 | inBetweenTagsText = html.substring( lastIndex, currentResult.index );
|
341 | 355 | lastIndex = currentResult.index + tagText.length;
|
342 |
| - |
343 |
| - // Process around anchor tags, and any inner text / html they may have |
344 |
| - if( tagName === 'a' ) { |
345 |
| - if( !isClosingTag ) { // it's the start <a> tag |
346 |
| - anchorTagStackCount++; |
347 |
| - resultHtml.push( this.processTextNode( inBetweenTagsText ) ); |
348 |
| - |
349 |
| - } else { // it's the end </a> tag |
350 |
| - anchorTagStackCount = Math.max( anchorTagStackCount - 1, 0 ); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0 |
351 |
| - if( anchorTagStackCount === 0 ) { |
352 |
| - resultHtml.push( inBetweenTagsText ); // We hit the matching </a> tag, simply add all of the text from the start <a> tag to the end </a> tag without linking it |
| 356 | + |
| 357 | + //split at html entities |
| 358 | + unescapedText = inBetweenTagsText.split( htmlCharacterEntities ); |
| 359 | + |
| 360 | + for ( i = 0; i < unescapedText.length; i++ ) { |
| 361 | + textToProcess = unescapedText[i]; |
| 362 | + |
| 363 | + // Process around anchor tags, and any inner text / html they may have |
| 364 | + if( tagName === 'a' ) { |
| 365 | + if( !isClosingTag ) { // its the start <a> tag |
| 366 | + anchorTagStackCount++; |
| 367 | + resultHtml.push( this.processTextNode( textToProcess ) ); |
| 368 | + |
| 369 | + } else { // its the end </a> tag |
| 370 | + anchorTagStackCount = Math.max( anchorTagStackCount - 1, 0 ); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0 |
| 371 | + if( anchorTagStackCount === 0 ) { |
| 372 | + resultHtml.push( textToProcess ); // We hit the matching </a> tag, simply add all of the text from the start <a> tag to the end </a> tag without linking it |
| 373 | + } |
353 | 374 | }
|
| 375 | + |
| 376 | + } else if( anchorTagStackCount === 0 ) { // not within an anchor tag, link the "in between" text |
| 377 | + resultHtml.push( this.processTextNode( textToProcess ) ); |
| 378 | + |
| 379 | + } else { |
| 380 | + // if we have a tag that is in between anchor tags (ex: <a href="..."><b>google.com</b></a>), |
| 381 | + // just append the inner text |
| 382 | + resultHtml.push( textToProcess ); |
354 | 383 | }
|
355 |
| - |
356 |
| - } else if( anchorTagStackCount === 0 ) { // not within an anchor tag, link the "in between" text |
357 |
| - resultHtml.push( this.processTextNode( inBetweenTagsText ) ); |
358 |
| - |
359 |
| - } else { |
360 |
| - // if we have a tag that is in between anchor tags (ex: <a href="..."><b>google.com</b></a>), |
361 |
| - // just append the inner text |
362 |
| - resultHtml.push( inBetweenTagsText ); |
363 | 384 | }
|
364 | 385 |
|
365 | 386 | resultHtml.push( tagText ); // now add the text of the tag itself verbatim
|
366 | 387 | }
|
367 | 388 |
|
368 | 389 | // Process any remaining text after the last HTML element. Will process all of the text if there were no HTML elements.
|
369 | 390 | if( lastIndex < html.length ) {
|
370 |
| - var processedTextNode = this.processTextNode( html.substring( lastIndex ) ); |
371 |
| - resultHtml.push( processedTextNode ); |
| 391 | + //split at html entities |
| 392 | + unescapedText = html.substring( lastIndex ).split( htmlCharacterEntities ); |
| 393 | + |
| 394 | + for ( i = 0; i < unescapedText.length; i++ ) { |
| 395 | + textToProcess = unescapedText[i]; |
| 396 | + var processedTextNode = this.processTextNode( textToProcess ); |
| 397 | + resultHtml.push( processedTextNode ); |
| 398 | + } |
372 | 399 | }
|
373 | 400 |
|
374 | 401 | return resultHtml.join( "" );
|
|
993 | 1020 | * @return {String}
|
994 | 1021 | */
|
995 | 1022 | getAnchorHref : function() {
|
996 |
| - return this.getUrl(); |
| 1023 | + var url = this.getUrl(); |
| 1024 | + return url.replace('&', '&'); |
997 | 1025 | },
|
998 | 1026 |
|
999 | 1027 |
|
|
0 commit comments