HTML textarea ignores 1st new line character, why? - javascript

Could you explain why this:
<script type="text/javascript">
document.write("<textarea cols='10' rows='10'>" + "\nhello\nbabe\n" + "</textarea>");
</script>
renders a textarea with one new line at the bottom, but NO new line at the top?
Tested IE8, FF11, Safari 5.1, Chrome 24
And it's not a JS issue, even when you write HTML in page you get the same result, i.e.
<textarea cols='10' rows='10'>
hello
babe
</textarea>
The 1st new line is still missing!!!
I need to add another new line at the top in order to show one:
document.write("<textarea cols='10' rows='10'>" + "\n\nhello\nbabe\n" + "</textarea>");

When writing inside of XHTML use proper entities.
<textarea>
hello</textarea>
If a text node begins with white space (space, new line) it will be ignored by HTML parsers. Encoding the new line into a proper HTML entity forces the parser to acknowledge it.
== carriage return

Answering the question "Why". This is specified in HTML 5 specification in the chapter that describes how DOM tree is created from tags found in a HTML document.
In the current HTML 5 living standard it is "12.2 Parsing HTML documents" > "12.2.6 Tree construction" > "12.2.6.4 The rules for parsing tokens in HTML content" > "12.2.6.4.7 The "in body" insertion mode".
(In HTML 5.2 the same section is numbered 8.2.5.4.7).
Scroll down for item "A start tag whose tag name is "textarea""
A start tag whose tag name is "textarea"
Run these steps:
1. Insert an HTML element for the token.
2. If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
3. Switch the tokenizer to the RCDATA state.
...
The algorithm deals with LF characters only, because CR characters are handled earlier.
(Historically, looking into obsolete HTML 4.01 specification:
Its Chapter 17.7 "The TEXTAREA element" has an example that shows that text content for a textarea starts from a new line.
Appendix B.3.1 Line breaks (informative) explains that such behaviour originates from SGML.)
A line break character before </textarea> end tag is not ignored nowadays, in HTML 5.

If possible, change your code to have the textarea pre-defined as html, then write the string like this instead:
HTML:
<textarea cols='10' rows='10' id='test'></textarea>
Script:
document.getElementById('test').innerHTML = '\nhello\nbabe\n';
That should preserve white-space. Optionally you can add a css rule:
textarea {
white-space:pre;
}
A fiddle to play with:
http://jsfiddle.net/RFLwH/1/
Update:
OP tested in IE8 which this does not work - it appear to be a limitation/bug with this browser. IE8 do actually use CR+LF if you manually insert a line-feed at the top, but when set programmatic this is completely ignored by the browser.
Add this to the html to do a test:
<span onclick="this.innerHTML = escape(document.getElementById('test').innerHTML);">
Get textarea content
</span>
You can see the string returned is:
%0D%0Ahello%20babe%20
meaning the CR+LF is there (the other line-feeds are converted to spaces - but inserting a space at the beginning does not help either). I guess there is nothing you can do about this behavior; the browser is obsolete (but unfortunately still widely used so this can be a problem for those users if this is essential).

Add a whitespace before the first "\n" like this :
<script type="text/javascript">
document.write("<textarea cols='10' rows='10'>" + " \nhello\nbabe\n" + "</textarea>");
</script>
or
<textarea cols='10' rows='10'> <!-- whitespace here -->
hello
babe
</textarea>
otherwise it won't work.
Update:
Later in your server side, you can remove the first whitespace by doing
$str = ltrim ($str,' ');
or
$str2 = substr($str, 4);
if it is PHP.

It should be a \n\r at the top:
document.write("<textarea cols='10' rows='10'>" + "\n\rhello\nbabe\n" + "</textarea>");
jsbin

Finally i finished with this server-side solution:
to double leading(only first!) nl symbol before output it in textarea:
if(str_startswith("\r\n",$value))
{
$value = "\r\n".$value;
}elseif(str_startswith("\n",$value))
{
$value = "\n".$value;
}elseif(str_startswith("\r",$value))
{
$value = "\r".$value;
}
function str_startswith($start, $string)
{
if(mb_strlen($start)>mb_strlen($string))
return FALSE;
return (mb_substr($string, 0,mb_strlen($start))==$start);
}

Related

Why splitting script closing tag in a string?

I am working on an asp.net project and on part of it, I needed to print a part of the page which contains an image using javascript. After some digging, I found a code and it works fine.
<script>
function VoucherSourcetoPrint(source) {
return "<html><head><script>function step1(){\n" +
"setTimeout('step2()', 10);}\n" +
"function step2(){window.print();window.close()}" +
"\n</scri" + "pt></head><body onload='step1()'>\n" + <%-- lokk this line--%>
"<img src='" + source + "' style='width: 300px; height: 150px; margine:none;' /></body></html>";
}
function VoucherPrint(source) {
Pagelink = "about:blank";
var pwa = window.open(Pagelink, "_new");
pwa.document.open();
pwa.document.write(VoucherSourcetoPrint(source));
pwa.document.close();
}
</script>
As you can see on the first function it is returning a string and in that there is a script closing tag, which is written as </scri" + "pt>, first I thought it was a mistake and tried removing the extra quotes and plus sign and then the string showing error.
I am confused, why is it have to be like </scri" + "pt>??
Because the HTML parser will find the sequence of characters "</script>" and end the script element. It will then pass invalid JavaScript to the JavaScript parser.
Here is a simplified example:
<script>console.log("</script>");</script>
▲ ▲ ▲▲ ▲ ▲
1 2 34 5 6
Script element start tag.
Begining of JavaScript (console.log(" - not a compilable script).
End of JavaScript
Script element end tag
Text to show as plain text in the HTML document (");)
Script end for with no matching open tag. Discarded by HTML parser as an error.
A more elegant approach is to just escape the /:
<script>console.log("<\/script>");</script>

Textarea.value doesn't manipulate the HTML

Setting the value of the textarea, won't be reflected in the HTML.
For instance,
If you have <textarea></textarea> in your HTML, and set its value to 'Hello' the HTML will remain unchanged and not <textarea>Hello</textarea>
I think this is what you want, use this to your w3schools example
<script>
function myFunction() {
var x = document.getElementById("myTextarea").value;
document.getElementById("demo").innerHTML = x;
}
myTextarea.onkeyup=()=>myTextarea.innerText=myTextarea.value;
</script>
You seem to be working off some misconceptions. I take it you're expecting that line breaks in the text area will be reflected as line breaks in a paragraph if you insert it as the HTML of the paragraph. In HTML, all whitespace is collapsed into spaces, and line breaks in HTML source do not normally translate to breaks in HTML text flows. If you do want newlines to work in HTML, use a <pre></pre> element instead. Otherwise you'll need to convert newlines to <br> elements.
There's also the white-space CSS style that can change the way that whitespace is rendered.

Get full (and original) text of an HTML element

Edit: It looks like we identified the solution to this problem via the comments -- which is achieved by getting value of the .outerHTML property. However, it still appears that at least Firefox and Chrome "normalize" original source code when outerHTML is used. For example, outerHTML of
<div id = "a"> <!-- string is 14 characters long //-->
still returns
<div id="a"> <!-- string is 12 characters long //-->
Apparently, the problem would be considered solved if the formatting of the resulting string would match that of the original HTML source code. Ah! Why must outerHTML adjust the original value?
--- Having said this: ---
I'm looking for a solution to get full text of a clicked HTML tag.
Starting point examples (note intentional, legal but mangled formatting):
<div id = "a" style ="color: blue ;">text</div>
// Returns: div
var doc = document.getElementById("id").tagName;
// Returns: array of attribute name/value pair (without = or ")
var attrs = document.getElementById("id").attributes;
How would we go about generating the following text string, when element #a is clicked:
<div id = "a" style= "color: blue ;">
I seem to have not found a solution for this as of yet.
What's this for?
Ultimately, the goal is to determine the length in characters of the arbitrary contents of a tag. Assuming it can be edited in any way that produces acceptable HTML output. For example, the two cases below should return:
<div id=a style="color:blue"> // 28
<div id = "a" style= "color: blue ;"> // 36
Counting is the easy part. It's getting the actual string of that tag, just as it appears in the source code, that is the problem.
Have you tried this?
document.getElementById('a').outerHTML
But this doesn't work in every browser i guess
Use outerHTML to get the full tag and then strip out everything after the open tag.
var openTag = document.getElementById("a").outerHTML.split(">")[0] + ">";
This seems to do what you want:
http://jsfiddle.net/abalter/c3eqnLrc/
html:
<div id="a" class="find-my-length" style="color:blue">First One</div>
<div id="a " class="find-my-length" style= "color: blue ; " > Second One </div >
JavaScript:
$('.find-my-length').on('click', function () {
var htmlString = $(this).prop('outerHTML');
alert(htmlString + " has " + htmlString.length + " characters.");
});
Note: The one thing that doesn't get counted is spaces between attributes. Spaces within attributes are counted.
From: Get selected element's outer HTML
What about: prop('outerHTML')?
var outerHTML_text = $('#item-to-be-selected').prop('outerHTML');
And to set:
$('#item-to-be-selected').prop('outerHTML', outerHTML_text);

Why is my textarea manipulating javascript insertion of text?

I have a textarea that is designed to take in some script tags that are extracted from an AJAX request and upon appending the text to the textarea, it's being mutated to - I'm assuming - conform to the text boxes rules.
In this case, the code to add the script to the text area is as follows:
for( i = 0; i <= ResponseScripts.length; i++ )
{
JavascriptContent.innerText = JavascriptContent.innerText + "\r\n" + ResponseScripts[i].outerHTML;
}
Rather than a += I just tried a more 'direct' route to no avail - but the issues still prevails.
Effectively, what I'm ending up with in the DOM is the following ( literally ):
<br>
"<script type="text/javascript" src="/tinymce/js/tinymce/tinymce.min.js"></script>"
I've tried using a substring of the outerHTML of the element, but just end up with malformed script tags - as if the text box itself is manipulating the text on input.
Is there a way to modify a text boxes behavior to adapt to this? So I end with:
// Literal \r\n*
<script type="text/javascript" src="/tinymce/js/tinymce/tinymce.min.js"></script>

HTML5 Href "sms" content with break line tag?

I want to use html link href to text message(sms) in android smart phone.But i try want the breakline in my message content.I have to display my message in messengers like below
"adgsd
sdgsf
asdfdf"
I try use "< br >","< br/ >","/n","/r" also cant break line.
Any Idea?Below is sample code with replace the < br > to other tag.
link = "smsto:" + "601" + "?body=" + document.getElementById("DetailContent").innerHTML.replace(/<br>/g, '\n');
document.getElementById("smsDetailLink1").setAttribute("href", link);
"%0D%0A"
with this format can get break line.
For anyone wondering, the answers given above are just the hex ASCII codes for the DOS/Windows line ending CR-LF (\r\n), i.e. carriage return and line feed. A lot of you probably knew that, some may not.

Categories