OK, got it eventually. Based on this answer of mine, I came up with a code that identifies the actual lines inside textarea, even when wrapped.
Next step was to translate div into textarea so we can use the above trick.
Having this, it's simple matter of manipulating the lines using .reverse()
method.
Final code is:
$("#btnInvert").click(function() {
var placeholder = $("#MyPlaceholder");
if (!placeholder.length) {
alert("placeholder div doesn't exist");
return false;
}
var oTextarea = $("<textarea></textarea>").attr("class", placeholder.attr("class")).html(placeholder.text());
oTextarea.width(placeholder.width());
//important to assign same font to have same wrapping
oTextarea.css("font-family", placeholder.css("font-family"));
oTextarea.css("font-size", placeholder.css("font-size"));
oTextarea.css("padding", placeholder.css("padding"));
$("body").append(oTextarea);
//make sure we have no vertical scroll:
var rawTextarea = oTextarea[0];
rawTextarea.style.height = (rawTextarea.scrollHeight + 100) + "px";
var lines = GetActualLines(rawTextarea);
var paragraphs = GetParagraphs(lines).reverse();
lines = [];
for (var i = 0; i < paragraphs.length; i++) {
var reversedLines = paragraphs[i].reverse();
for (var j = 0; j < reversedLines.length; j++)
lines.push(reversedLines[j]);
if (i < (paragraphs.length - 1))
lines.push("");
}
rawTextarea.value = lines.join("\n");
placeholder.html(rawTextarea.value.replace(new RegExp("\\n", "g"), "<br />"));
oTextarea.remove();
});
function GetParagraphs(lines) {
var paragraphs = [];
var buffer = [];
$.each(lines, function(index, item) {
var curText = $.trim(item);
if (curText.length === 0) {
if (buffer.length > 0) {
paragraphs.push(buffer);
buffer = [];
}
} else {
buffer.push(curText);
}
});
if (buffer.length > 0)
paragraphs.push(buffer);
return paragraphs;
}
function GetActualLines(oTextarea) {
oTextarea.setAttribute("wrap", "off");
var strRawValue = oTextarea.value;
oTextarea.value = "";
var nEmptyWidth = oTextarea.scrollWidth;
var nLastWrappingIndex = -1;
for (var i = 0; i < strRawValue.length; i++) {
var curChar = strRawValue.charAt(i);
if (curChar == ' ' || curChar == '-' || curChar == '+')
nLastWrappingIndex = i;
oTextarea.value += curChar;
if (oTextarea.scrollWidth > nEmptyWidth) {
var buffer = "";
if (nLastWrappingIndex >= 0) {
for (var j = nLastWrappingIndex + 1; j < i; j++)
buffer += strRawValue.charAt(j);
nLastWrappingIndex = -1;
}
buffer += curChar;
oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
oTextarea.value += "\n" + buffer;
}
}
oTextarea.setAttribute("wrap", "");
return oTextarea.value.split("\n");
}
Just put the actual ID of your div and it should work.
Live test case.