static gchar* textForRenderer(RenderObject* renderer) { GString* resultText = g_string_new(0); if (!renderer) return g_string_free(resultText, FALSE); // For RenderBlocks, piece together the text from the RenderText objects they contain. for (RenderObject* object = renderer->firstChild(); object; object = object->nextSibling()) { if (object->isBR()) { g_string_append(resultText, "\n"); continue; } RenderText* renderText; if (object->isText()) renderText = toRenderText(object); else { // List item's markers will be treated in an special way // later on this function, so ignore them here. if (object->isReplaced() && !renderer->isListItem()) g_string_append_unichar(resultText, objectReplacementCharacter); // We need to check children, if any, to consider when // current object is not a text object but some of its // children are, in order not to miss those portions of // text by not properly handling those situations if (object->firstChild()) g_string_append(resultText, textForRenderer(object)); continue; } InlineTextBox* box = renderText ? renderText->firstTextBox() : 0; while (box) { // WebCore introduces line breaks in the text that do not reflect // the layout you see on the screen, replace them with spaces. String text = String(renderText->characters(), renderText->textLength()).replace("\n", " "); g_string_append(resultText, text.substring(box->start(), box->end() - box->start() + 1).utf8().data()); // Newline chars in the source result in separate text boxes, so check // before adding a newline in the layout. See bug 25415 comment #78. // If the next sibling is a BR, we'll add the newline when we examine that child. if (!box->nextOnLineExists() && !(object->nextSibling() && object->nextSibling()->isBR())) { // If there was a '\n' in the last position of the // current text box, it would have been converted to a // space in String::replace(), so remove it first. if (renderText->characters()[box->end()] == '\n') g_string_erase(resultText, resultText->len - 1, -1); g_string_append(resultText, "\n"); } box = box->nextTextBox(); } } // Insert the text of the marker for list item in the right place, if present if (renderer->isListItem()) { String markerText = toRenderListItem(renderer)->markerTextWithSuffix(); if (renderer->style()->direction() == LTR) g_string_prepend(resultText, markerText.utf8().data()); else g_string_append(resultText, markerText.utf8().data()); } return g_string_free(resultText, FALSE); }