void HTMLConstructionSite::flushPendingText() { if (m_pendingText.isEmpty()) return; PendingText pendingText; // Hold onto the current pending text on the stack so that queueTask doesn't recurse infinitely. m_pendingText.swap(pendingText); ASSERT(m_pendingText.isEmpty()); // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent); unsigned currentPosition = 0; const StringBuilder& string = pendingText.stringBuilder; while (currentPosition < string.length()) { unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, string.length()); unsigned breakIndex = findBreakIndexBetween(string, currentPosition, proposedBreakIndex); ASSERT(breakIndex <= string.length()); String substring = string.substring(currentPosition, breakIndex - currentPosition); substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode); HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); task.parent = pendingText.parent; task.child = Text::create(task.parent->document(), substring); queueTask(task); ASSERT(breakIndex > currentPosition); ASSERT(breakIndex - currentPosition == substring.length()); ASSERT(toText(task.child.get())->length() == substring.length()); currentPosition = breakIndex; } }
void HTMLConstructionSite::flushPendingText() { if (m_pendingText.isEmpty()) return; PendingText pendingText; // Hold onto the current pending text on the stack so that queueTask doesn't recurse infinitely. m_pendingText.swap(pendingText); ASSERT(m_pendingText.isEmpty()); // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent); unsigned currentPosition = 0; const StringBuilder& string = pendingText.stringBuilder; while (currentPosition < string.length()) { unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, string.length()); unsigned breakIndex = findBreakIndexBetween(string, currentPosition, proposedBreakIndex); ASSERT(breakIndex <= string.length()); String substring = string.substring(currentPosition, breakIndex - currentPosition); ASSERT(breakIndex > currentPosition); ASSERT(breakIndex - currentPosition == substring.length()); currentPosition = breakIndex; if (isAllWhitespace(substring)) { // Ignore whitespace nodes not inside inside a <t>. If we're splitting // a text node this isn't really a whitespace node and we can't ignore // it either. if (!m_openElements.preserveWhiteSpace() && string.length() == substring.length()) continue; // Strings composed entirely of whitespace are likely to be repeated. // Turn them into AtomicString so we share a single string for each. substring = AtomicString(substring).string(); } HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); task.parent = pendingText.parent; task.child = Text::create(task.parent->document(), substring); queueTask(task); ASSERT(toText(task.child.get())->length() == substring.length()); } }