Bug 922681 - Add SetInnerHTML fast path for short strings with no markup. r=bz

This commit is contained in:
Jan de Mooij
2013-12-17 14:58:32 +01:00
parent bab09875ca
commit efb84633a2
12 changed files with 55 additions and 0 deletions

View File

@@ -2613,6 +2613,28 @@ FragmentOrElement::GetMarkup(bool aIncludeSelf, nsAString& aMarkup)
}
}
static bool
ContainsMarkup(const nsAString& aStr)
{
// Note: we can't use FindCharInSet because null is one of the characters we
// want to search for.
const PRUnichar* start = aStr.BeginReading();
const PRUnichar* end = aStr.EndReading();
while (start != end) {
PRUnichar c = *start;
if (c == PRUnichar('<') ||
c == PRUnichar('&') ||
c == PRUnichar('\r') ||
c == PRUnichar('\0')) {
return true;
}
++start;
}
return false;
}
void
FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError)
{
@@ -2625,6 +2647,19 @@ FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult
target = frag;
}
// Fast-path for strings with no markup. Limit this to short strings, to
// avoid ContainsMarkup taking too long. The choice for 100 is based on
// gut feeling.
//
// Don't do this for elements with a weird parser insertion mode, for
// instance setting innerHTML = "" on a <html> element should add the
// optional <head> and <body> elements.
if (!target->HasWeirdParserInsertionMode() &&
aInnerHTML.Length() < 100 && !ContainsMarkup(aInnerHTML)) {
aError = nsContentUtils::SetNodeTextContent(target, aInnerHTML, false);
return;
}
nsIDocument* doc = target->OwnerDoc();
// Batch possible DOMSubtreeModified events.