864gchar* textForRenderer(RenderObject* renderer)
865{
866 GString* str = g_string_new(0);
867
868 if (!renderer)
869 return g_string_free(str, FALSE);
870
871 // For RenderBlocks, piece together the text from the RenderText objects they contain.
872 for (RenderObject* obj = renderer->firstChild(); obj; obj = obj->nextSibling()) {
873 if (obj->isBR()) {
874 g_string_append(str, "\n");
875 continue;
876 }
877
878 RenderText* renderText;
879 if (obj->isText())
880 renderText = toRenderText(obj);
881 else {
882 // We need to check children, if any, to consider when
883 // current object is not a text object but some of its
884 // children are, in order not to miss those portions of
885 // text by not properly handling those situations
886 if (obj->firstChild())
887 g_string_append(str, textForRenderer(obj));
888
889 continue;
890 }
891
892 InlineTextBox* box = renderText->firstTextBox();
893 while (box) {
894 gchar* text = convertUniCharToUTF8(renderText->characters(), renderText->textLength(), box->start(), box->end());
895 g_string_append(str, text);
896 // Newline chars in the source result in separate text boxes, so check
897 // before adding a newline in the layout. See bug 25415 comment #78.
898 // If the next sibling is a BR, we'll add the newline when we examine that child.
899 if (!box->nextOnLineExists() && (!obj->nextSibling() || !obj->nextSibling()->isBR()))
900 g_string_append(str, "\n");
901 box = box->nextTextBox();
902 }
903 }
904
905 // Insert the text of the marker for list item in the right place, if present
906 if (renderer->isListItem()) {
907 String markerText = toRenderListItem(renderer)->markerTextWithSuffix();
908 if (renderer->style()->direction() == LTR)
909 g_string_prepend(str, markerText.utf8().data());
910 else
911 g_string_append(str, markerText.utf8().data());
912 }
913
914 return g_string_free(str, FALSE);
915}
916