diff --git a/source/Ox/js/HTML.js b/source/Ox/js/HTML.js index bff193ea..e7e850fe 100644 --- a/source/Ox/js/HTML.js +++ b/source/Ox/js/HTML.js @@ -20,7 +20,8 @@ '"': '"', '&': '&', "'": ''', '<': '<', '>': '>' }, regexp = { - entity: /&[^\s]*;/g, + entity: /&[^\s]+?;/g, + html: /[<&]/, tag: new RegExp('<\\/?(' + [ 'a', 'b', 'br', 'code', 'i', 's', 'span', 'u' ].join('|') + ')\\/?>', 'gi') @@ -234,8 +235,14 @@ query Case-insentitive query string, or regular expression classname Class name for matches isHTML If true, the input string is treated as HTML - > Ox.highlight('', 'name', 'c') - '<name>' + > Ox.highlight('', 'foo', 'c') + '<foo><bar>' + > Ox.highlight('&', '&', 'c') + '&amp;' + > Ox.highlight('&', '&', 'c') + '&' + > Ox.highlight('<foo> <foo>', '', 'c', true) + '<foo> <foo>' > Ox.highlight('name', 'name', 'c', true) 'name' > Ox.highlight('amp & amp', 'amp', 'c', true) @@ -260,6 +267,7 @@ var cursor = 0, entities = [], matches = [], + offset = 0, re = Ox.isRegExp(query) ? query : new RegExp(Ox.escapeRegExp(query), 'gi'), span = ['', ''], @@ -286,8 +294,8 @@ }); }); } - if (isHTML) { - string = Ox.normalizeHTML(string) + if (isHTML && regexp.html.test(string)) { + string = string // Ox.normalizeHTML(string) // remove inline tags .replace(regexp.tag, function(value, tag, position) { tags.push({ @@ -305,7 +313,9 @@ }); // if decoding entities has created new tags, ignore them splitHTMLTags(string, entities.map(function(entity) { - return entity.position; + var ret = entity.position + offset; + offset += entity.length - entity.value.length + return ret; })).forEach(function(v, i) { if (i % 2 == 0) { // outside tags, find matches and save position and value @@ -327,15 +337,22 @@ span.join(match.value) ); }); + // we may have enclosed single opening or closing tags in a span + if (matches.length && tags.length) { + string = Ox.normalizeHTML(string); + } } else { - string = string.replace(re, function(value) { - return span.join(value); + string = Ox.encodeHTMLEntities( + string.replace(re, function(value) { + matches.push(span.join(Ox.encodeHTMLEntities(value))); + return salt.join(matches.length - 1); + }) + ); + matches.forEach(function(match, i) { + string = string.replace(new RegExp(salt.join(i)), match); }); } - // if isHTML, we may have enclosed single opening or closing tags in a - // span, if not isHTML, the string may contain '<', '>' or '&', so in - // both cases, we have to normalize - return Ox.normalizeHTML(string); + return string; }; /*@ @@ -348,7 +365,7 @@ '<\'&"> äbçdê' @*/ Ox.normalizeHTML = function(html) { - return Ox.$('
').html(html).html(); + return regexp.html.test(html) ? Ox.$('
').html(html).html() : html; }; /*@