How to correctly "bypass" Angular Sanitization? - javascript

I have an input type=text where my user will type his own HTML template.
I have a button that opens a modal which shows the formatted html as a "preview html template".
Whenever the user Clicks on my preview_button, it opens a modal that shows the html the user typed before. This is part of the modal, this is how I'm inserting the html:
<div class="flexBox mg-2">
<span [innerHTML]="my.element.text"></span>
</div>
Although it is working and showing the text correctly. It doesn't allow me to use style formatting. So If my user write this on the text_input
<h1 style="color:red;">Hello World</h1>
When the modal opens, I can see the text but not the color styling.
I found a few topics here suggesting to use this.sanitizer.bypassSecurityTrustHtml, but I also read its kind of dangerous and also it messes all my pages style up, so I can't use it.
And a few examples showing how to do this with a static html(on class constructor).
Edit
Tried to use iframe.
It works like this(inline css):
<iframe srcdoc="'<h1 style='color:red;'>Hello World</h1>'"></iframe>
Also works like this(style tag):
<iframe srcdoc="<h1 id='pp'>Hello World</h1><style>#pp{color:red;}</style>"></iframe>
BUT when I try to use interpolation it no longer applies the style. (due to the Angular Policy)
<iframe [srcdoc]="components.body.text"></iframe>
Any good/correct/safe way to do it when the html is dynamic?

Related

AppleScript cannot click input tag to add file

I am trying to use applescript to add a file to a website's input field.
This is my code so far:
set ClickInput to "var myInput = document.getElementByClassName('jsx-1828163283 upload-btn-input')[0]; myInput.dispatchEvent(new MouseEvent('mousedown')); myInput.dispatchEvent(new MouseEvent('mouseup'));"
set ClickInput2 to "var myInput = document.getElementsByName('upload-btn')[0]; myInput.dispatchEvent(new MouseEvent('mousedown')); myInput.dispatchEvent(new MouseEvent('mouseup'));"
activate application "Safari"
tell application "Safari"
open location "https://www.example.com/upload"
set theTab to tab 1 of window 1
-- wait until page loads
repeat while document 1's source = ""
delay 0.5
end repeat
-- do JavaScript ClickInput in theTab
do JavaScript ClickInput2 in theTab
delay(5)
close theTab
end tell
Here is the HTML around the input element I want to select:
<div class="jsx-3758851661 upload">
<div class="jsx-1828163283 upload-btn">
<div class="jsx-3758851661 card stage-1">
<div class="jsx-3758851661 text-main">Select video to upload</div>
<div class="jsx-3758851661 text-sub text-sub-margin">Or drag and drop a file</div>
<br class="jsx-3758851661">
<ul class="jsx-3758851661 text-sub">
<li class="jsx-3758851661">MP4 or WebM</li>
<li class="jsx-3758851661">720x1280 resolution or higher</li>
<li class="jsx-3758851661">Up to 60 seconds</li>
</ul>
</div>
<input type="file" name="upload-btn" accept="video/mp4,video/x-m4v,video/*" class="jsx-1828163283 upload-btn-input">
</div>
</div>
The way the site works is you click the outermost div <div class="jsx-3758851661 upload"> and the safari file finder pops up and you select what file you want.
I have tried clicking the divs outside of the input tag and I have tried clicking the input tag by itself.
I tried to do this by selecting the classnames of the divs and the input tag
I also tried to do this by selecting the input tag by its name and clicking on that
None of these worked.
Im not sure if it clicked but none of these made the file finder pop up
Do you guys have any ideas? Let me know if you would like some clarification. thanks!
figured out set ClickInput to "document.getElementsByName('upload-btn')[0].click();" works !
getElementsByName isn’t a function that I’m aware exists as standard, so you probably want to use getElementsByClassName or querySelector.
The input element has two class names, of which I’m going to choose ”upload-btn-input” in my example below:
tell application id "com.apple.safari"
open location "https://www.example.com/upload"
tell document 1
repeat while the source = ""
delay 0.5
end repeat
do javascript "document.querySelector('.upload-btn-input').click();"
end tell
end tell
If you can provide the actual URL of the page in question, this would allow me to refine this answer to ensure it’s appropriate for what you’re trying to do.

Are there reasons that Javascript can only access some of the new DOM after Ajax?

I am just learning JS and while implementing AJAX I ran into some strange behavior.
In my code I have the following
<div id="saved_listing_form"></div>
an onchange in a select element runs a script where ajax fills the above div with a preview of the saved listing along with a form populated with fields that can be edited in order to edit the listing if desired.
There is a button in the form that is used to preview the changes to the listing before saving them.
Below is the code that will be populated by the "preview" script that does not respond to JS
<article class="listing" id="listing_preview" style="display:none;" title="">
<a href="" id="preview_url" target="_blank"><img id="preview_picture" src="" alt=""><h3 id="preview_name"></h3>
<span id="preview_phone"></span><address><span id="preview_address_1"></span><br><span id="preview_address_2"></span>
<span id="preview_city_state_zip"></span></address>
</a>
</article>
I tried manipulating the listing through the console in Firefox as a last resort. The console is able to find the article,
document.getElementById('listing_preview')
but cannot produce changes in the DOM
document.getElementById('listing_preview').style.display = 'block';
will not make it appear
I can even
make changes to the object in the console, but that will not show up on the page.
ie document.getElementById('preview_name').innerHTML = 'Hello';
This change will show up in the console, but not in the page.
Here is the strange part. The already-saved listing that is populated by ajax in the saved_listing_form works perfectly and can be manipulated via the console and scripts as expected.
<article class="listing" id="listing" title="Dr. Peter Griffin of Q'Hog, RI"><img id="saved_image" src="images/clients/Peter_Griffin20200827180833.jpg"><h3>Peter Griffin, D.C.</h3>+11234567890<br><address>123 Spooner St<br>Q'Hog, RI 12345</address></article>
Are there any reasons that part of the ajax-populated div works as expected while other DOM objects within the same div would not? I don't appear to have any broken html elements that would throw things off.
The reference to the JS that controls the preview is loaded in at the very end of the code that ajax populates.
Any help would be much appreciated.

Toggle Visibility of Separate Javascript Files on Same Wordpress Page

Let me preface by saying this is all in relation to a Wordpress page. My knowledge of JS is lacking at best and the concept of installing/loading/enqueueing a function on one area of the site and then calling that function in another area of the site is a something that makes sense to me in my head but is very new to me in practice and might need a little explaining.
I have two separate javascript files that I would like to load on a single page, but toggle visibility/display of either based on radio button input. The JS is provided by a 3rd party and is offsite. Their provided code is this:
<script src="https://toolkit.rescuegroups.org/j/3/FzemP6HU/toolkit.js"></script>
and
<script src="https://toolkit.rescuegroups.org/j/3/4ANRW3x8/toolkit.js"></script>
Each file presents a separate set of filtered results from their database. How can I incorporate both onto a page but only have one or the other showing based on a radio button form input? I would like the page to start off with nothing visible (hopefully giving time for both JS to load in the background while the user selects an option) and then show one or the other depending on what they selected.
You can see a single one of these in action at http://pricelesspetrescue.org/adoptable-dogs/. I'm trying to incorporate the use of an additional file on that same page based on input from the user and only showing one or the other rather than both.
I have tried to manage the following
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
function displayForm(c) {
if (c.value == "2") {
jQuery('#claremontdogContainer').toggle('show');
jQuery('#chdogContainer').hide();
}
if (c.value == "1") {
jQuery('#chdogContainer').toggle('show');
jQuery('#claremontdogContainer').hide();
}
};
</script>
<label>Please select a location to view:</label>
<form>
<input value="1" type="radio" name="formselector" onClick="displayForm(this)"></input>Chino Hills
<input value="2" type="radio" name="formselector" onClick="displayForm(this)"></input>Claremont
</form>
<div style="display:none" id="chdogContainer">
<script src="https://toolkit.rescuegroups.org/j/3/FzemP6HU/toolkit.js"></script>
<script type="text/javascript">
</script>
</div>
<!-- If I uncomment this second block the whole thing breaks
<div style="display:none" id="claremontdogContainer">
<script src="https://toolkit.rescuegroups.org/j/3/4ANRW3x8/toolkit.js"></script>
<script type="text/javascript">
</script>
</div>
-->
This gets pretty close to what I need. The problem I have is the second script load seems to conflict with the functions they provide in the script. It will display the initial result but does not carry any of the functionality that it should have. http://pricelesspetrescue.org/test-page/ Nothing is clickable inside those results and should be.
Been searching through various similar posts and the wordpress codex and...and...I just haven't been able to come up with anything that seems close enough to what I'm looking for to make the answer click in my head.
Edit: It seems that if I only load one of the scripts in either what I have above or the suggested answer below, all functionality is present when loaded. It's the loading of the second toolkit script that is breaking the page. I'm guessing one would need to be loaded then unloaded before loading the second for it to work. Any ideas?
The toolkit.js file you linked adds some common scripts to the DOM (via document.write function, which is not a good solution - see here: http://www.jameswiseman.com/blog/2011/03/31/jslint-messages-document-write-can-be-a-form-of-eval/), then populates an array (toolkitObjects) with a series of variables that are custom per file and finally loads some other scripts.
It also seems that each file loads a div with a specific class containing all the pets, and each div is identifiable by a specific class ( "rgtk-SOMEID" ) and therefore can be shown/hidden via javascript.
Here is an example of what you can obtain using the div class:
http://jsbin.com/loneyijuye/edit?html,output

How can I make my HTML model data display in a <textarea> as it would in a browser?

My code returns HTML data from ASP.NET as a response from an action method.
I am displaying this in a <textarea> element.
<textarea style="width: 85rem; height: 15rem;"
ng-disabled=true
ng-model="access.response"></textarea>
However when it displays I see the actual HTML.
How can I make it so the information displayed in the textbox or some other way is the same as in my browser window? Note that I do not want to edit the data but I would like the scrollbar type feature.
Is correct to say that you cannot display it in a textarea, but you can't use a simple div neither to display the parsed HTML.
Take a look at this Plunkr --> http://plnkr.co/edit/ld4Nte2KKIbgMkIWnRcP
You have to make use of the $sce service and the ng-bind-html directive, like this:
<div ng-controller="SimpleCtrl">
<!-- This will be parsed as HTML-->
<div ng-bind-html="to_trusted(someCode)"></div>
<!-- This will not -->
<div>{{someCode}}</div>
</div>
No way to do it with textarea.
If you want editable HTML content, consider this:
<div contenteditable="true"></div>

How to access a <div> from the HTML embedded by <object>

I have a webpage that has several <div> sections ("navcol" and "maincol"). The "navcol" div contains <object data="mypage.html">. Inside mypage.html there are buttons the user can click to select pages to be inserted into "maincol". I need to gain access to the innerHTML of "maincol" in the main page with Javascript, so I can do the insertion (like using an iframe). Can someone put me on the right track?
PS. I am using <object>, because I want to have HTML 4.0 "Strict" and Iframes are not in "Strict", but s are.
From within the page in the object element, you can get access to the upper–most browsing context using:
window.top.document
so you can try:
window.top.document.getElementById('maincol');
no doubt only within limitations imposed by the same–origin policy though.
e.g.
<div id="mailcol">maincol</div>
<div id="navcol">
<object data="foo.html"></object>
</div>
in foo.html:
<button onclick="
alert(window.top.document.getElementById('mailcol').innerHTML)
">button</button>

Categories