HTML within Javascript Function Not Working Properly - javascript

I am using the following JavaScript function:
function Projects()
{
var PrjTb1 = "<input type=text id=PrjNme size=100/>"
var PrjTb2 = "<textarea rows=5 col=200 wrap=hard></textarea>"
var Info = "1. Project or activity name:<br>" + PrjTb1 + "<br><br>2. Project or activity description:<br>" + PrjTb2
if (document.getElementById('PrjNo').value == 1)
{
document.getElementById('AllPrj').innerHTML = "<b>Project or activity 1.</b><br><br>" + Info
}
}
This function executes well, after an onclick event; however, certain portions of the HTML within the declared variables are not working. For example, within the variable PrjTb2, my textarea's rows and columns do not change. Also, I cannot add the HTML tags <dd> and </dd> anywhere within the variables to create an indentation. What is interesting is that both the textarea properties and the HTML tags, <dd> and </dd>, work within the body of my form, just not in my JS function. Would anyone know what I am doing wrong.

Not sure if its the problem, but I'd enclose all your parameters in quotes.
<input type=text id=PrjNme size=100/>
should really be:
<input type='text' id='PrjNme' size='100' />
additionally, depending on your Doctype, you may want to change
<br>
to
<br />
Things that are allowed in direct HTML are not necessarily allowed using innerHTML. For example, in Firefox, try embedding a form within a form in JS vs html, or in IE, try putting a block element inside an inline element. They both work fine, if you have it in HTML, but if you try it with innerHTML, both browsers will complain.

It could be that your browser is caching your Javascript. Try clearing your cache.

I don't know if your syntax error are due to copying you code here, but here is a couple of things I noticed in your code.
Are you omitting semi-columns at the end of you lines on purpose?
HTML proprieties should be surrounded by quotation marks. (Although not necessary)
Also regarding the <dd></dd>, did you put those inside a definition list (dl)?
Because they shouldn't be used as standalone tags.

Related

How do I prevent html element from escaping parent? (security)

I tried to Google this, but everything is related to css, not security.
I have this as a comment form:
<pre name="comment">
<comment-content>
This is a sample comment by a user
</comment-content>
</pre>
I allowed some controlled html tags that include [pre][/pre] and this is where the problem starts.
if I do something like this:
<pre name="comment">
<comment-content>
This is a sample comment by a user
[/pre]
This text will be outside the comment container
</comment-content>
</pre>
The comment escapes the pre tag, and ignores that its inside the <comment-content></comment-content> tag. I added this tag as an attempt to block escaping, but it doesn't work. I also notice my controlled html tags will run outside the container. I have a second container that is not escaped, but this issue with escaping the first container means if I put a <pre> tag outside that container, it could be escaped. I also tried doubling up the container, but that did not work either.
Here is an image of the [/pre] tag escaping the container
here is a quick sample of what javascript is doing in the background:
//I added .cleanHTML() as a similar function to php htmlentities() and .clean() is similar to php strip_tags()
let content = $(this).html().cleanHTML().clean();
commentHtml += '<pre name="comment" type="text/plain"><comment-content>'+setUserCommentHtml(content.clean())+'</comment-content></pre>';
$(this).html(commentHtml);
Note: I am aware that most security should be done server side, but would also like to keep client side secure as well.
I basically need a way to force html to require the first closing tag before the second parents closing tag will work.
Posting solutions (with help from comments) as an answer to mark as solved.
Jared Farrish answered question in comments.
changing my javascript to something like this fixes the issue:
//I added .cleanHTML() as a similar function to php htmlentities() and .clean() is similar to php strip_tags()
let content = $(this).html().cleanHTML().clean();
let setContentId = Math.floor(Math.random()*10000);
commentHtml += '<pre name="comment" type="text/plain"><comment-content set-content="'+setContentId+'"></comment-content></pre>';
$(this).html(commentHtml);
$('comment-content[set-content="'+setContentId+'"]').html(setUserCommentHtml(content.clean()));
I also added this method Inside the setUserCommentHtml() function.
let htmlOpenTags = [];
//in a loop
if(tagType === 'close' && htmlOpenTags.includes(commentTag)){
htmlOpenTags.splice(htmlOpenTags.lastIndexOf(commentTag));
//close tag here
...
}else if(tagType === 'open'){
htmlOpenTags.push(commentTag);
//open tag here
...
}
If I push to an array, every time the user opens a tag, Then I can verify the opened tag exists in that array before closing it and remove that tag from the list.
edit: stack overflow says I must wait 2 days before marking as answer

need to add contentEditable=false to p tag inside CKEditor

i need inside my CKEditor some boilerplate verbiage that is not editable, then the rest of the my string information. I concatenate the boilerplate verbiage [which is in a p tag], to a string variable that my CKEditor displays inside a certain div. By the time the verbiage, here:
<p id='abc' contentEditable='false'>verbiage</p>
... and the string information is displayed on the page, they are deep inside a number of nested tags - within a body with multiple classes. So both the verbiage, which is now in only a p tag with no attributes[they got stripped out], is nested way inside the original body tag [the first body tag, way up in the page] with lots and lots of divs, then finally comes an iframe, then ... the verbiage and string are like this:
<body contenteditable="true" class="cke_editable cke_editable_themed cke_contents_ltr cke_show_borders" spellcheck="false">
<p>boilerplate verbiage</p>
...then the rest of the information is displayed in the editor, inside various spans, etc. i need to make the boilerplate verbiage readonly, contentEditable='false'. Yet everything I try both from the console in Chrome, and in code.... nothing changes that boilerplate verbiage tag. i have tried various things, including these - perhaps you can see where I need to tweak something; and i hope this will show you things i have tried and that i am run out of options so far:
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").first().contentEditable='false';
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").attr("readonly", "1");
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders p:first-child").contentEditable='false';
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").find( "p" ).contentEditable='false';
jQuery("iframe", ".cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").contents().find("p").contentEditable='false';
jQuery("iframe", "body .cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").contents().find("p").contentEditable='false';
var editor= jQuery("body", ".cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders");
editor.val(editor.val().replace(/<p>/gi, "<p class='tiny_p'>"))
var editor= jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders");
editor.val(editor.val().replace(/<p>/gi, "<p class='tiny_p'>"))
yet if i hard code in the Chrome browser, contenteditable="false",
it works perfectly. So, how can i access that p tag and assign it this attribute?
It really depends on moment and how you want to access, one option to access directly from separate script.
CKEDITOR.instances[YOUR_INSTANCE].window.$.document.getElementById("your_p_tag")
Note, that it should be done after CKEDITOR initilized
UPDATE:
CKEDITOR.instances[YOUR_INSTANCE].window.$.document.body.firstChild

JS Regexp: get the inline javascripts from html

I need to get all script tags from an html string, separated the inline scripts and the "linked" scripts. By inline scripts I mean script tags without the src attribute.
Here is how I get the "linked scripts":
<script(.)+src=(.)+(/>|</script>)
so, having <script followed by one or more any character, followed by src=, followed by /> or </script>.
This works as expected.
Now I want to get all the script tags without the src tag, having some javascript code between <script .....> and </script>, but I can't figure it out how to do that. I just started understanding regular expressions, so the help of a more experienced r.e. guru is needed :)
UPDATE
Ok, so dear downvoters. I have the html code for a whole html page in a variable. I want to extract script tags from it. How to do it, using jquery for example?
var dom = $(html);
console.log(html.find('script');
will not work. So, what is the way to accomplish that?
UPDATE 2
I don't need to solve this problem with regex, but because now I am learning about them, I thought I will try it. I am opened for any other solution.
Create a DOM element using document.createElement, then set its innerHTML to the contents of your HTML string. This will automatically parse your HTML using the browser's built-in parser and fill your newly-created element with children.
dummyDoc = document.createElement("html");
dummyDoc.innerHTML = "<body><script>alert('foo');</script></body>"; // or myInput.value
var dom = $(dummyDoc);
var scripts = dom.find('script');
(I only use jQuery because you do so in your question. This is certainly also possible without jQuery.)
If you are in the position where no dom access is available (nodejs?), you'd be forced to use regex. Here is a solution that worked for me in the similar circumstances:
function scrapeInlineScripts(sHtml) {
var a = sHtml.split(/<script[^>]*>/).join('</script>').split('</script>'),
s = '';
for (var n=1; n<a.length; n+=2) {
s += a[n];
}
return s;
}

JavaScript variable name and HTML input name attribute: namespace collision?

In an HTML file I have the following:
<input type="..." name="myInput1" />
In a corresponding JS file I have the following variable which will hold the string value of that input after blur:
var myInput1;
Is there any problem in having these two identical names? I'm guessing that the namespaces are separate so it is ok.
Short answer, no problem whatsoever.
A short answer is, indeed, no. However, it also greatly depends on how you use the variable. Let's consider that you use javascript for validating that the variable is set as follows:
if(myInput1) {do something}
If you also decide to set the id to be the same as the name is as follows (cause you didn't specify that, it can be anything):
<input type="myInput1" name="myInput1" />
your variable myInput1 will be set to contain the DOM element and won't be empty anymore.
This link between JS and HTML is not only interesting but can be used to create an exploit as described in the section 3.1.2 of Postcards from the post-XSS world (that's where I have the idea from - and yes, it still works even though the article is from 2011).

Expansion of Struts 2 Tags Messes Up Rendering Of Page

Often times, when I use struts 2 tags, the loading of a page will be incomplete apparently because of single quote or double quote characters from the struts 2 tag interfering with such characters from javascript.
One example I am very eager to get working is as follows:
var me = '<s:a href=\'http://www.google.com\'>Google Link</s:a>';
$('#appnSelect').html(me);
So what I am concerned about is when single and double quotes are inside that me string on the right side of line 1. Ultimately, I need to get <s:select> to work, but this problem seems to creep in with a number of tags like the above example. Replace the <s:a> tag with an <a> tag, and voila, it works. However, when the <s:a> tag gets expanded, the page will incompletely load.
Is there an easy solution somewhere I am missing? One thing I did try was with the theme attribute setting theme="simple" because sometimes that helps me when the output gets rendered incorrectly. That did not work in this case.
Generating HTML from tags like that in the middle of a JavaScript string constant is always going to be an ugly business. In addition to quote characters, you're also likely to get newlines. Strictly speaking you don't know what you're going to get, and you can't control it.
One thing that comes to mind is that you could drop the tags into dummy <script> blocks marked as a non-JavaScript type:
<script id='anAnchor' type='text/html'>
<s:a href='http://www.google.com'>Google Link</s:a>
</script>
The browser won't try to execute that. You can then do this in your JavaScript code:
$('#appnSelect').html($('#anAnchor').html());
What should work with very little thinking:
<s:a id="google" style="display: none;" href="www.google.com">Google Link</s:a>
Now just grab the the element using the id in your script. Might be better if you set up a class. There are id, style and class attributes for all struts2 tags.
I believe the issue is with your escaping of the single quotes inside the <s:a> tag. In my experience with using <s:url>, I've done the following:
var url = "<s:url value='/someAction.action' />"
I believe the same syntax should hold true for <s:a>.
Additionally, look in your JSP container's error log, and see if you can find an error relating to that <s:a> tag. That may provide some additional insight to the problem.
This is my answer, which will not be the best answer because Pointy's response pointed me in the correct direction. However, up votes still appreciated :)
First, you need the script blocks which are not rendered. I have 2 because a checkbox will toggle between which one is displayed:
<script type="myType" id="abc">
<s:select name="selectName" list="#list1" listValue="%{prefix + '-' + name}" theme="simple"/>
</script>
<script type="myType" id="abc2">
<s:select name="selectName" list="#list2" listValue="%{prefix + '-' + name}" theme="simple"/>
</script>
Next, I create a region which is blank in the html code
<div id="innerRegion">
</div>
Then, I need to put something on the screen when the page first comes up, so go with this:
<script type="text/javascript">
$(document).ready(function(){
$('#innerRegion').html( $('#abc').html() )
});
I needed to put this at the end of my document because onLoad was already being used by a parent page. So I am saying abc is the correct default.
Then I need logic to handle what happens when the checkbox is pushed:
var buttonPressed = false;
$(window).load(
function()
{
LocalInit();
});
function LocalInit() {
$('#myForm input[name=buttonValue]').change(
function()
{
buttonPressed = !buttonPressed;
if (buttonPressed == true)
{
$('#innerRegion').html( $('#abc2').html() )
} else
{
$('#innerRegion').html( $('#abc').html() )
}
$('#dataId').href = document.location.href;
}
);
}
I think what was tripping me up ultimately was that I was trying to force the s:select tag through jQuery functions when as you see above it did not turn out to be necessary. I could just write the s:select as normal.

Categories