If I have a userscript that I've found online, and I'd like to incorporate it into a website as a normal javascript (i.e. not userscript), how can I do that?
This seems like it would be something pretty simple but I am new to javascript and userscript, hopefully somebody can help me out.
For example, I found this userscript: "Convert UPS and FedEx Tracking Numbers to Links"...
Which will parse a page for regular expressions matching any UPS/FEDEX/USPS tracking number, and convert them to links to the respective carriers' tracking website to track that number.
This works great as a userscript, but I would like it to be automatic on the site I am working on (not require visitors to download/install a userscript).
How can I use this userscript as a regular javascript?
UserScripts are usually executed after the page DOM is loaded, to make sure that the page contents can be completely accessed. So, you need some kind of mechanism to achieve that. But this is a bit tricky since older versions of IE need special treatment.
Doing it manually would require about 30 lines of code. Libraries like jQuery offer a ready() method like so:
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function () {
// put userScript here
});
</script>
It should just be a matter of linking it like any other Javascript file:
Save it as foo.js, then in your html,
<body>
<!-- body code here -->
<script src="foo.js"></script>
</body>
You can just put it in a JS file and include the file in your page.
UserScripts contain normal Javascript code, but are executed by a plugin rather than being on the page.
Related
Website that use JS tracking usually use this kind of code :
<script>
(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:9999,hjsv:5};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'//static.hotjar.com/c/hotjar-','.js?sv=');
</script>
In the end, those scripts just add a <script> tag to the <head> of the page, so surely there must be a reason why they're doing it this way.
Is it for ad-blocking bypass reasons ? Wouldn't the generated request be the same as if it was hardcoded in the <head> ?
I'm the chief architect at Hotjar so I'll explain the reasons why we did it in this particular way.
We need to do things before the main script is loaded.
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
That particular line allows us to store actions to execute once the main script is loaded. It allows for things like hj('trackVirtualPageView', '/url') to be called before our script is loaded.
We can store things like settings as part of the snippet.
h._hjSettings={hjid:9999,hjsv:5};
That could absolutely be added as part of the query string when loading the script. The downside of using that approach is that we would get less optimal caching since it would be impossible for a browser to know that script.js?hjid=1 and script.js?hjid=2 actually loads the same JS file.
What we're doing in the last part is actually just creating a <script async=1> tag and adding it to the <head> which works really well. The reason we're doing it through JS is that we like to make it as easy as possible for our users by only asking them to put code in one place.
There might be an even better to do what we're doing which I'm blissfully unaware of, and in case there is, please reach out and tell me about it! :)
At least part of the answer is that vendors want to load their libraries in a way that does not block page rendering.
If the browser hits a script element it tries to get the script source, and might prevent the page from rendering until the complete script is downloaded. In the bad old days it used to happen that website would show up blank, because the (then synchronous) Google Analytics script could not be downloaded in a timely fashion and stopped the page from rendering. Script injection became an accepted method to make scripts non-blocking.
There are other ways (defer, asynch, etc - for historical interest here is a link to an 2009 article that discusses the issue, because the problem is that old), but script injection is a convenient way to set up a few variables along the way (plus if Google does it it must be the best way, or so seems to be the though process with some companies).
When a script for some custom language appears in a webpage how are these scripts executed?
<script type='text/mighty-mouse'>
// logic expressed in mighty mouse language
</script>
I would guess it would be something like this:
Mighty Mouse interpreter queries the page on load for mighty-mouse scripts.
The interpreter parses the script using standard lexing/compilation strategies and transpiles to JavaScript.
The resulting JavaScript is dynamically injected into a standard script tag on the page, perhaps even eliminating the original mighty-mouse tag.
(I realize that we could have transcompiled before runtime to avoid having to load our interpreter.)
Is this an accurate and complete understanding?
As far as I know there are two ways. Either a browser plugin or more likely an interpreter written in JavaScript. Which essentially scans the DOM for the correct type and interpret the content.
CoffeeScript is a good example of the later.
This might be a silly question but i want to clarify this. what happens when we close a javascript two times.
<script type="text/javascript">
alert("hello");
</script>
</script>
i did this but am not getting any error.its like we closed the script so there wont be any execution so no error will trigger i believe. will this create trouble under any situation?
why am asking this is i would like to insert a </script> at the end of a plugin where user submits their script. So that i don't have to go for extra coding on validation if this works fine without creating any trouble
The browser will treat this as an extra, unexpected end tag. It doesn't matter that it's </script>, it could also be </link> or anything else allowed in the same context.
Most browers will silently ignore such extra tags unless you enable strict / XML mode. For strict mode, you should get errors in the console.
To properly wrap plugins supplied by the user, I suggest this strategy:
Always wrap them in your own tags (so you can be sure the structure is always correct).
Check the string that you put between the two tags for <script, <script> and </script> and report an error if you find any of them.
The idea here is that users should never use script tags in their code and that you put them where they belong.
Most browsers will just remove/ignore an extra tag. I can't see that it's would cause any problems, but it is quite an ugly way to do it. I have no better suggestion currently though.
nothing. the browser ignores it but it will obviously not pass standards.
as far as i know, if the browser comes across an opening <script> tag, it assumes everything until the closing </script> tag is script. so starting with a </script> will have no effect but to cause an 'unexpected` exception.
The effect may change depending on the browser, but in teory all ignore the second tag.
XHTML rules are much stricter than those of HTML. When special XML
characters (such as & and <) are used in scripts in XHTML files, they
cause errors. The simplest workaround is to use external script files.
However, if you simply must write inline scripts, then you will need
to include CDATA (character data) sections in your file. Within CDATA
sections the special XML characters can be used freely. The following
example uses a CDATA section that is compatible with both XHTML and
HTML syntax.
<script type="text/javascript">
//<![CDATA[
alert((1 < 2) && (3 > 2));
//]]>
</script>
Also it is not a correct practice and if the script is inline than it will break W3C compliance.
To answer your direct question: Nothing would happen, it's just invalid (x)HTML which the browser ignores.
To answer your indirect question, turned out in the comments:
#DanFromGermany So you are saying validation is the only way there otherwise this way is not recomended
Validation of external resources is always critical.
For example, simply reading external scripts into <script></script> tags, tells the browser "this is no external content" and hereby grants more access, for example, read your cookies and set cookies originating from your domain (external content....your domain).
Including external JS via <script src="...">, from a different host/domain, tells the browser "this is a 3rd party script, don't allow it as much as internal scripts." It is therefore not allowed to read or set your cookies and stuff.
Why putting in </script> does not help:
An attacker is easily able to screw your whole website and let it easily disappear.
See the following:
<script>
<!-- external script start -->
</script>
</head>
<body>
Attackers website start
<div style="display:hidden;">
everything below disappears
<!--
<!-- external script end -->
</script>
</head>
<body>
<!-- your website start !-->
Still if you prevent this, an attacker can always use document.write(); to insert HTML into your Website.
Probably the best way is to executed the given JS through an iframe, from a blank page and an independent (sub)domain.
Putting things into database, or save ones JS and let it execute by a different user needs additional validation.
Is there a way to include the prototype.js code directly in the html file?
I do not want to have something like this:
<script type="text/javascript" src="/path/to/prototype.js"></script>
I want something like this:
<script type="text/javascript" >
// the code of prototype.js to be here
</script>
The context for what I want this is more complex. I just want to know now if this is possible or not.
P.S.I'm not very familiar with Prototype.
Thank you.
Yes it will work if you copy paste the entire content inside the script tags.
We do something similar with jQuery and our other JS and CSS files for our web app. They are all compressed and included inline when we run our deployment script.
It makes the page relatively heavy (300kb) but the main advantage is you get everything in a single http request. This makes the app look very fast.
The page is then cached, making next visits even more responsive.
I am using jQuery UI and a few other JS libs which in total make for quite a chunk of JS (even minified and combined). My idea is to not include a script tag in the page but to stub out all functions that I defined as well as the $ sign for jQuery so that my inline JS on the page can still call them but will hit the stub. The stub will then load the .js file and actually call the function. The question now is:
How can I redirect all function calls on the window object/global object to a custom function of mine?
I am not used to dynamic languages so a little advice on how to do this in JS will be appreciated.
As stated previously ... this is likely an exercise in futility. Unless you are a researcher and are being paid to do this (and only this), I'd spend my time just working on my actual product and/or refactoring so that the page requires fewer disparate JS libs (for example. use jquery only, rather than jquery + yui)
edit, though, I suppose in the interest of actually answering the question. You can easily replace any function by simply setting it in javascript. For example ...
$ = function(searchString) {
// if this method is called
// and jquery hasn't been loaded yet
// load jquery (which will overwrite all of your local jquery functions with its own
};
The method to lazy load .js files is well documented throughout the web, for example here:
http://ajaxpatterns.org/On-Demand_Javascript
Well the root of your problem is the usage of library dependent in-line JS. We had an old legacy site that had a bunch of in-line JS in the Smarty templates. I ended up modding Smarty so that I could capture the JS calls and then output them all in the footer. Looked something like this
<!-- mySubContent.inc.html -->
<div id="theTabs">
<ul><li><!--
...
--></li></ul>
<div id="tab1"><!--
...
--></div>
</div>
{capture_js}
$("#theTabs").tabs();
{/capture_js}
<!-- footer.inc.html -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
{render_captured_js}
</script>
</body>
</html>
Anyway, maybe that'll give you some idea about how to tackle your in-line JS problem if you can't refactor the codebase right now. Oh, and read this - http://developer.yahoo.net/blog/archives/2007/07/high_performanc_5.html .