highlight: several bugfixes and performance improvements; normalizeHTML: only use dom if needed
This commit is contained in:
parent
743a36e308
commit
898cc702f5
1 changed files with 30 additions and 13 deletions
|
@ -20,7 +20,8 @@
|
||||||
'"': '"', '&': '&', "'": ''', '<': '<', '>': '>'
|
'"': '"', '&': '&', "'": ''', '<': '<', '>': '>'
|
||||||
},
|
},
|
||||||
regexp = {
|
regexp = {
|
||||||
entity: /&[^\s]*;/g,
|
entity: /&[^\s]+?;/g,
|
||||||
|
html: /[<&]/,
|
||||||
tag: new RegExp('<\\/?(' + [
|
tag: new RegExp('<\\/?(' + [
|
||||||
'a', 'b', 'br', 'code', 'i', 's', 'span', 'u'
|
'a', 'b', 'br', 'code', 'i', 's', 'span', 'u'
|
||||||
].join('|') + ')\\/?>', 'gi')
|
].join('|') + ')\\/?>', 'gi')
|
||||||
|
@ -234,8 +235,14 @@
|
||||||
query <r|s> Case-insentitive query string, or regular expression
|
query <r|s> Case-insentitive query string, or regular expression
|
||||||
classname <s> Class name for matches
|
classname <s> Class name for matches
|
||||||
isHTML <b|false> If true, the input string is treated as HTML
|
isHTML <b|false> If true, the input string is treated as HTML
|
||||||
> Ox.highlight('<name>', 'name', 'c')
|
> Ox.highlight('<foo><bar>', 'foo', 'c')
|
||||||
'<<span class="c">name</span>>'
|
'<<span class="c">foo</span>><bar>'
|
||||||
|
> Ox.highlight('&', '&', 'c')
|
||||||
|
'<span class="c">&amp;</span>'
|
||||||
|
> Ox.highlight('&', '&', 'c')
|
||||||
|
'&'
|
||||||
|
> Ox.highlight('<foo> <foo>', '<foo>', 'c', true)
|
||||||
|
'<span class="c"><foo></span> <span class="c"><foo></span>'
|
||||||
> Ox.highlight('<span class="name">name</span>', 'name', 'c', true)
|
> Ox.highlight('<span class="name">name</span>', 'name', 'c', true)
|
||||||
'<span class="name"><span class="c">name</span></span>'
|
'<span class="name"><span class="c">name</span></span>'
|
||||||
> Ox.highlight('amp & amp', 'amp', 'c', true)
|
> Ox.highlight('amp & amp', 'amp', 'c', true)
|
||||||
|
@ -260,6 +267,7 @@
|
||||||
var cursor = 0,
|
var cursor = 0,
|
||||||
entities = [],
|
entities = [],
|
||||||
matches = [],
|
matches = [],
|
||||||
|
offset = 0,
|
||||||
re = Ox.isRegExp(query) ? query
|
re = Ox.isRegExp(query) ? query
|
||||||
: new RegExp(Ox.escapeRegExp(query), 'gi'),
|
: new RegExp(Ox.escapeRegExp(query), 'gi'),
|
||||||
span = ['<span class="' + classname + '">', '</span>'],
|
span = ['<span class="' + classname + '">', '</span>'],
|
||||||
|
@ -286,8 +294,8 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (isHTML) {
|
if (isHTML && regexp.html.test(string)) {
|
||||||
string = Ox.normalizeHTML(string)
|
string = string // Ox.normalizeHTML(string)
|
||||||
// remove inline tags
|
// remove inline tags
|
||||||
.replace(regexp.tag, function(value, tag, position) {
|
.replace(regexp.tag, function(value, tag, position) {
|
||||||
tags.push({
|
tags.push({
|
||||||
|
@ -305,7 +313,9 @@
|
||||||
});
|
});
|
||||||
// if decoding entities has created new tags, ignore them
|
// if decoding entities has created new tags, ignore them
|
||||||
splitHTMLTags(string, entities.map(function(entity) {
|
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) {
|
})).forEach(function(v, i) {
|
||||||
if (i % 2 == 0) {
|
if (i % 2 == 0) {
|
||||||
// outside tags, find matches and save position and value
|
// outside tags, find matches and save position and value
|
||||||
|
@ -327,15 +337,22 @@
|
||||||
span.join(match.value)
|
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 {
|
} else {
|
||||||
string = string.replace(re, function(value) {
|
string = Ox.encodeHTMLEntities(
|
||||||
return span.join(value);
|
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
|
return string;
|
||||||
// span, if not isHTML, the string may contain '<', '>' or '&', so in
|
|
||||||
// both cases, we have to normalize
|
|
||||||
return Ox.normalizeHTML(string);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
@ -348,7 +365,7 @@
|
||||||
'<\'&"> äbçdê'
|
'<\'&"> äbçdê'
|
||||||
@*/
|
@*/
|
||||||
Ox.normalizeHTML = function(html) {
|
Ox.normalizeHTML = function(html) {
|
||||||
return Ox.$('<div>').html(html).html();
|
return regexp.html.test(html) ? Ox.$('<div>').html(html).html() : html;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
|
Loading…
Reference in a new issue