I need a Greasemonkey script to customize one of my frequently visited site. How can I make sure my script will excute first, modify the html, end sucessfully, only then allow any inline script runs?
EDIT:
I've splitted my original question into 2. one goes here: Find all elements have any attribute other than some specified attributes (solved)
my real goal with the page is targeting some special elements (which I got from my other question) but an inline script will change some elements's attributes, or even remove those elements. If that script CAN'T be blocked, what should I do?
Related
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?
Is there a script attribute in HTML for JS, like the style attribute for CSS, I asked this because I'm using an IDE that highlights script attributes inside elements, so I thought it might exist, and if it does, how to use it ?
<element style="it exists, and i know how to use it" script="no clue">...</element>
HTML5, like previous HTML elements, does not have a script attribute but has a script element: https://www.w3.org/TR/html5/scripting-1.html#the-script-element. You can either put some script directly between <script> and </script> tags, or use the script element to refer to an external JavaScript file.
The JavaScript itself can then dynamically (e.g. on load) add event listeners to HTML elements that need to respond to specific events.
No, there is no 'script' attribute. The IDE is probably doing a match on the pattern, without regard to context.
Your IDE is simply highlighting any tag attribute. Try making up some gibberish, and you'll see that it's highlighted.
As the other answers state, no script attribute exists. From w3.org,
There are two types of scripts authors may attach to an HTML document:
Those that are executed one time when the document is loaded by the
user agent. Scripts that appear within a SCRIPT element are executed
when the document is loaded. For user agents that cannot or will not
handle scripts, authors may include alternate content via the NOSCRIPT
element.
Those that are executed every time a specific event occurs.
These scripts may be assigned to a number of elements via the
intrinsic event attributes.
No there is no standard attribute in HTML 5 called script.
But as previous answers listed, your IDE may highlighted this because it highlight any attribute, or script keyword for something else based on your file type.
Also note that while script is not a standard attribute in HTML 5 but this doesn't mean you can't use it, you can write your own custom attributes to any element to access it using javascript getAttribute
I'm trying to get some custom JS into the company website which is severely restricted because of the platform (for example, the website editor our vendor provided automatically removes any "script" tags). For this reason I tried inserting my custom js scripts via Tag Manager with custom HTML.
It works, albeit unreliably. Sometimes my script loads but most times it doesn't. One point worth noting is that our vendor only allowed us to insert our tag container to the top of "body" and have a "script asyn" in "head". Also our GTM container was set up incorrectly on a separate dataLayer without proper tuning. So my questions are:
1) Is there a way for me to check how long it takes for my own script to load, in a waterfall type analysis (or whatever alternative really)?
2) Is the script loaded by Tag Manager fired only after absolutely everything on page is loaded?
3) Is pasting the code in external js or inline THE surefire way to have my custom tag loaded? Would fixing the dataLayer issue also increase firing speed?
Thanks in advance!
There is actually not much difference between using GTM, using an external file or even embedding your code inline. Unlike some other tag managers GTM does not fetch tags from a remote server; instead it packages all tags in a bit javascript function and links that to your page (you can test this by calling http://www.googletagmanager.com/gtm.js?id=GTM-XXXXXX where xxxxx is the id of your container, make a local copy and redirect the GTM request to that local copy - the tags will fire just like before).
The js file also contain all configured rules, and it is the rules that determine when a tag is fired.
The earliest possible point at which tags are fired is page load - that is the moment your browser renders the GTM code. Next (default) point is DOM ready, when all structural elements are created but not necessarily all assets are loaded, followed by window.loaded when everything is ready. After page load you can have custom events or click/submit etc. events.
As to your questions:
1) You can debug GTM tags just like any other JS tags (e.g. use the waterfall diagram in your browsers dev console)
2) No. When scripts are fired is determined by the configured rules. The earliest moment at which tags are fired is when the GTM code is loaded. However the tags do not (by default) fire in any specific sequence.
3) Any script that has problems from within GTM will probably have problems when pasted inline. Using GTM is not very different from using an external js file, except that GTM contains a lot of code to evaluate rules and triggers.
Do you know if it is possible to make sure that a JavaScript script site is ran first in a web page?
For the context, I'm trying to tag every span before another library (just like cufon) kicks in and messes with the original content. Since it's not possible to use onLoad() on spans, it's the only way I can see to do that on the client side.
Order of precedence is determined by the order in which things load.
Head tag scripts (in the order they are listed)
Scripts & other event attributes in the order they appear in the code.
Body onLoad
I did have #2 & #3 mixed up - to clarify the body onLoad event fires after the entire body (scripts included) loads
Also, scripts altering <span> tags will have no effect if placed in the head tag (unless they are a function) since the script runs when it is loaded, and when the head loads, the body & span tags haven't loaded yet.
Place <script> tag in page source after content that you need to modify, but before any other scripts. Scripts run in same order that their tags appear on page.
I have inline javascript within my HTML. Each individual component that requires animation or action (sliders, expanding text areas, etc.) each have their own inline script, that sets up the animation and such for that individual component.
The way i have it set up, Each script is position dependent: it references its own position in the DOM, and traverses it to find the component it wants to manipulate (e.g. "add onclick to the parent div"). This is normally an incredibly bad idea for several reasons:
having to repeat the same code all over the place, losing DRY
being very verbose, repeating the same chunk of text over and over, taking up bandwidth
cluttering up your HTML with a bunch of inline scripts, making it hard to read
However, the second problem is easily solved with GZIP, and i have solved the first and last problem.
This has the advantage of locality of reference: the component and the scripts they require are kept in one place, not spread out over separate files. Also, I isolate each set of scripts in a (function(){})(), and avoid polluting the global namespace, so each set of scripts for each component is written once and doesn't interact with scripts written elsewhere at all. Perfect modularity
So the question is, how can i stop JQuery eating my script tags when i do Ajax DOM insertions/replacements? If it didn't eat my scripts, because each component is completely self-contained with it's own scripts, i can simply run every script tag in the new component's DOM and that would be that; everything will be set up. No more fiddling with decided which global scripts need to be re-run depending on which component changed.
However, since JQuery seems to insist on stripping my script tags and moving them somewhere, this no longer works. I could do the insertion by modifying replacing the HTML of the entire document, but that causes the whole screen to flash as it reflows (among other problems). Any ideas?
I don't know about jQuery explicitly, but most libraries will remove script elements from content returned from XHR that they intend to insert using innerHTML. That is because inserting innerHTML does not execute the scripts (in the vast majority of browsers). Looking at the jQuery source, the load method strips out script elements.
So they strip out the script elements, then insert the HTML. This ensures the scripts aren't executed or cause issues.
Some libraries have an "execute script" (or similar) flag that, if set, means they will pass the script element content to eval, but there are pitfalls with that too.
One solution is to put all your script snippets into separate files, then use a src attribute on the script elements. If you can't find a jQuery method that doesn't remove the scripts, it's pretty simple to write your own "get" or "load" or whatever function that doesn't, or use one of the thousands that are already written.
If you are only using script elements, you can simply create a script element, set the src attribute and put it in the DOM (this is one method of doing AJAX).
in your html keep spaces for all the replacements using container divs, so that everything you're replacing through AJAX has a special place in the DOM. jQuery wont eat your script tag.
Alternatively, you can also put an id on your script tags and then access then by using the ids.