Why is my tampermonkey script not deleting styles of html elements - javascript

So I currently have a tampermonkey script that runs when it's on https://code.org/projects/applab/* which is where I want it. However whenever I run my code to remove the attr 'style' of the grandparent and parent of the specified element nothing happens.
Even though when I ran a test of this jQuery on w3's interpreter it worked...
$(document).ready(function() {
$("body").append(themeChangesCss);
$("#screenSelector").parent().parent().removeAttr('style');
$("#screenSelector").parent().removeAttr('style');
$("#runButtonWrapper").parent().parent().removeAttr('style');
$("#runButtonWrapper").parent().removeAttr('style');
});
You can also view the whole script here : https://sourceb.in/vdZOU1B7fq

You should probably start by logging the element you're trying to change to console. It is quite possible, that the web app changes the style AFTER your script executes. In that case, your changes will not have any effect.
If that is the case, read up on Mutation Observer, which allows you to execute code any time something changes the style attribute on the elements you want to clear.
I have tested your code and it indeed does work as it should on my test document. I couldn't find how should I test your code on the website you linked.

Related

How to sandbox a div element?

I am trying to build a content editor. This contenteditor will load a HTML document (with JavaScript) into for example a #result element. The problem with this, is that if inside this HTML element there is for example $("input").hide();, then all of my inputs are gone throughout the whole page, so not just inside the loaded HTML (my goal).
What I want to do with the editor is when a client clicks on an element that represents something in the database, the info of this element will popup and the user will be able to edit this. (So, if a user hovers over a form with the class "contact-form" (which is in the database, connected to the loaded page) a new window will popup with information about this specific form element.
Also, I cannot completely disable Javascript, since the loaded HTML might contain Javascript for styling etc.
My goal: Remove Javascript, that can be annoying when a user loads in an HTML file. Like an alert(); Also, remove the ability for the Javascript to edit somehthing outside it's own DOM.
P.S. I am open to better workarounds like using an iframe for this, BUT I want to be able to hover over elements in interact with them.
Edit: It seems that this question might be a bit too broad, looking at the comments. Summary of my question: How can I disable alert() for a specific div and how can I create a sandbox so that code inside a div, can only change elements from inside that div.
What you're looking for is HTML sanitization. This is the process by which you remove any dangerous content from a snippet of HTML on the server, before it's loaded in the browser. There are plenty of sanitization libraries out there that can strip script tags, object tags, etc. Just remember, you can't sanitize using javascript because by the time you've injected your script, another malicious script may have already loaded and run.
The only way to effectively sandbox a javascript environment is with iframes. You'll notice that websites like CodePen, JSBin and JSFiddle use them extensively. There's something called the ShadowDOM, which is the basis of Web Components, but it isn't very well supported yet.
To make it possible to run your own frontend scripts that allow for hovering, you can inject your script after your sanitization process. This way, if it's loaded inside an iframe your script will also be loaded.
Finally, alert() doesn't belong to any elements on the DOM. You can trigger an alert as soon as the page loads, for example. However, if you're trying to prevent alerts from popping up on user interactions, you could try removing all event listeners from a particular element. This won't be necessary if you sanitize the HTML of script tags, however, since the script wouldn't have had a chance to load so there won't be any event listeners.
You can use ShadowDOM to load an html document into a host node. See also WHY SHADOW DOM?

Firefox debugger : Stepping over html code

I have this remote html page where i need to debug some javascript errors. I do not have access to the page so i have to resort to FF debugger for this. In there i have a js function being called on the body onLoad like this:
<body onLoad="someFunction();" id="bd" class="fs3 FF" >
I somehow want to step over it or replace it with this:
<body id="bd" class="fs3 FF" >
I suspect someFunction() is breaking other onload events since i'm getting the error that it is undefined, which it is. What would be the best way to debug this?
I am fairly new to JS debugging but I have tried setting up breakpoints at this line but they always move into the js code within this document. Any suggestions?
UPDATE: I do not have access to it since the website belongs to one of my clients. And he would rather have me debug and suggest him the fix instead of providing access!
I suspect someFunction() is breaking other onload events
A broken onload attribute doesn't prevent other load callbacks (e.g., hooked up via addEventListener) from being called (proof). But you've said in the comments you want to be able to eliminate it as a possible cause, so:
If there are any script elements on the page at all, you can do this:
Find the first script element.
Find the first line of code in that element (either directly in it, or in the file it refers to).
Set a breakpoint on that line.
Reload the page, which should trigger the breakpoint.
Type this in the console:
document.body.onload = null;
Click the resume button to allow the code to run.
That code in #5 will remove the handler that the attribute creates. (It won't remove the attribute, but there's no need to. If you really want to, add document.body.removeAttribute("onload"); to the above.) Since your breakpoint is on the first line of a script, it will get hit before the load event fires.

How to override html property created by script (mediaelement.js)

for some reason when using mediaelement.js, it creates a div for the progress bar called "mejs-time-rail", but then proceeds to set the html width value to "0" through an inline style.
Since this div is created when the script runs, I cannot edit this property in the source code, but if I edit it (the inline style) in Firefox's inspector, I get the desired result. Also, it seems that this html property created by mediaelement.js overrides any css rules I set.
Any ideas how to circumvent this issue? Maybe editing the actual js script?
Thanks
I can't post a picture because I don't have enough reputation, but I can update this post with a screenshot when I do have enough and/or if it helps
First, it seems the issue is that as the DOM loads, the external script is setting that desired value to 0 like you said. Try adding a custom JavaScript/jQuery file that simply runs after the DOM is completed and
.find the element you want to edit. Then try
.attr('desiredAttr', 'new val');
this should find, and then reset the attribute to whatever you like. Even if the external script changed it on load.

I can't get the toggle control with document.GetElementByID() in the windows8 setting charm

I'm very new to javascript, so this is confusing me. All of the settings charm tutorials only show how to put the controls into the settings charm, but none of them say how to find the information gotten in them.
I tried to do one of these (like I do in the main program):
var muteToggle = document.GetElementById("Mute");
where "Mute" is the id in the separate html file.
muteToggle just ends up being null all of the time. I tried putting it after
WinJS.UI.ProcessAll().then(function completed() {...
but that didn't work either. Everything else is the same as in this page: http://msdn.microsoft.com/en-us/library/windows/apps/hh780611.aspx
Make sure you're doing it in the ready function of the js file that is referenced from your settings HTML. Try opening the JavaScript console or QuickWatch while broken at that line and also look at the DOM Explorer to see if you can find your toggle control. You should be able to access it though. Also, try element.getElementById instead of document.getElementById. Either should work actually, but as long as you're troubleshooting. Good luck.
Your problem is that you are trying to get a reference to the HTML element from the code running during the app activation. Although that piece of code may define the HTML to be loaded for a settings pane, it does Not actually load the HTML into the DOM. You just simply can't get the instance from that location.
What you need to do is have the settings flyout have its own js file that implements IPageControlMembers. In particular, you need to implement the ready method. This method is called once all the HTML and controls are loaded for the page, including your toggle. The link has an example of how to do this.
Also see:
WinJS.UI.Pages.define
Using single page navigation

Hiding a div using JQuery

I want to hide a div using Javascript, as soon as the page gets loaded in the browser. I am able to do that, if i use the following code :
document.getElementById("div_id").style.display='none';
But, when i try to do the same thing using JQuery,i notice that the div is visible for a couple of seconds after page loads,and then it becomes hidden. The JQuery code i use is
$(document).ready(function() {
$("#div_id").css('display','none');
});
The same thing happens, if i use $("#div_id").hide(); Is this because im using a library,which would slow down the process a bit,instead of directly using document.getElementById ? . Any way to fix this ?
Thank You.
There's an easy solution to this. Set up a CSS class as follows
.js #div_id { display: none; }
Then have the following jQuery
$('html').addClass('js');
$(document).ready(function() {
/* normal code to run when DOM has loaded here */
});
the <div> will be hidden immediately (no flashes) if users have JavaScript enabled and won't be if they don't (which circumvents possible graceful degradation problems as meder points out in his option c).
This works because when can immediately access the <html> element when the page starts to load.
The reason why document.getElementById("div_id").style.display='none'; is probably working is because you have it in the <body> after the element and therefore the script does not wait for the whole DOM to be loaded before executing.
You could either
a) insert a script element directly after the element to hide it with jQuery:
b) have inconsistent Javascript by directly using DOM methods like your first code snippet
c) hide it with CSS with the disadvantage that for CSS enabled non-JS users they wouldn't be able to see anything
I would choose between A and C, though I'm not sure exactly what you're hiding.
A:
<div id="foo"></div>
<script>$('#foo').hide()</script>
C:
div#foo { display:none; }
First, use $("#div_id").hide();. It's more idiomatic for jQuery.
Second, it's because you're using $(document).ready. Usually, that event doesn't fire until the DOM is available for use. However, because of the way bindReady() is implemented, it's possible on some browsers for this event to be equivalent to the onload event, which won't fire until everything is loaded. Unfortunately, the only way that I know of to get around this (that doesn't cause problems for disabled users who can't use JavaScript because of a screen reader) is to set a short timeout (say 50ms) and repeatedly check for the existence of $("#div_id") while the page is loading. This is a horrible hack, and I hesitate to recommend it, but it should work. That said, you're almost better off just accepting the flash of content, knowing that most users won't see it.
I think a better option would be to style the div so that it is hidden when the page is written, without any javascript.
Then, whenever you are ready to show it again, use javascript to unhide it:
$('#someId').show();
It might be cause by the way you include the scripts. The browser has to download them before they are run. So if you have a lot of js files this can cause this problem.
I think the reason is that the DOM loads progressively and the $(document).ready event is waiting for the DOM to be fully loaded before executing.
If you really want the element to be invisible when the page loads, can you define that style in your CSS instead?
I haven't tried this, but if you still want the div to be visible for non-Javascript users then I think you could do something like this:
<noscript>
<style type="text/css">
#elementid {display: block !important;}
</style>
</noscript>
More likely it's because you are waiting until the document is ready to hide it. This seems more like a job for server side script if you want it hidden by default.

Categories