Chrome extension inject script before page load - javascript

I am developing a Chrome application on a 3rd party website.
The document that I am trying to alter has the following page format:
<head>
.
.meta data here
.
</head>
<body>
<script type="text/javascript">
function a1(){
..contents of function a1
}
</script>
.
.other contents of body
.
<script type="text/javascript">
a1(); // <-- I don't want this to be executed
</script>
</body>
My problem is I want the entire page to be loaded, except the function call a1();
So I thought of a simple solution: BEFORE the function definition ie; function a1(){..}, I want to create a1 as a CONSTANT function which does nothing, therefore rendering the a1() call useless.
Problem is that if I define the function to be constant in my js which run_at document_start, the execution environment is different, hence it wont affect the page.
So the alternate to run in the same execution environment is by INJECT the code using innerHTML+=" ... "
Another alternate is to construct a script element using "createElement" and the src is an external js file which has to be loaded before execution.
Both the alternatives does not work, as the parse tree isn't created in the run_at document_start script.
So, I thought of an other solution. I added the listeners for DOMModifySubTree event, hoping to alter the parse sequence(I know, it sounds funny :)) so that the function isn't called. Doesn't help.
So, my question is how do I prevent the call to a1() function??
P.S - I cannot contact the 3rd party website developer.

Greasemonkey is what you're looking for.
It's a Firefox extension that injects your own scripts in webpages of your choice.
Visit wiki.greasespot.net to get started on writing scripts.
Fontunately, Chrome natively supports Greasemonkey scripts. See this page for more info.

Sorry for the late late reply. What I had originally done to skip the function call is that I ran a script at document start and injected it into the "document" (as JS runs in separate envi). In that injected script I used
const a1=function(){};
This way, when the function is being declared again, it is NOT overwritten, hence the function is not executed (ie; it is executing our dummy function), thus essentially breaking the code. :)

Related

AJAX ready event once HTML page and scripts are loaded

I'm creating a web application that has multiple pages of content that I'm loading dynamically with AJAX and the HTML5 History API. When a user attempts to change the page, the new content is loaded with a $.get and injected into the body, like so:
$.get("somepage.html", function (data)
{
$("body").html(data);
});
Most of these pages require additional scripts to be loaded. This wouldn't be an issue except for the fact that $(document).ready fires before these scripts are loaded. Somepage.html looks something like this.
<script src='http://getjquerysomewhere/'></script>
<script src='my_script_that_depends_on_jQuery'></script>
This issue is complicated by the fact that these pages must have the ability to be loaded on their own. I'm therefore unsure how I can eliminate the $(document).ready functions without affecting this behavior as well.
How should I approach this problem?
What you are trying to do is certainly possible, but it's not going to be very maintainable in the long-run.
One of the biggest issues you'll run into is properly injecting the code from the ajax loaded html into the current page. You can't just ignore it and let it all run because then you'll be including libraries multiple times (resulting in plugins getting overwritten/removed), and the code for the page you are loading may happen too soon due to the dom already being ready.
This pretty much leaves you with two options: dependency injection or front-loading.
Dependency injection will probably be the easiest of the two for you to implement because it requires the least amount of changes to your current code-base. All you would have to do is ensure that all pages requested with ajax only include the content of the <body> (which can be done with server-side code), and ensure that all page-specific code is included before the closing </body> of each page. Then you would just have to use the dependency-injection methods to run your code with the proper dependencies.
You could also have it only include <div id="#content">...</div> for your partials, which ever makes more sense for your use-case.
Front-loading would be a little more difficult because you'll have this one giant file that has all of your code for all of the pages, unless you use a build process (if you've never used a build-process before, you really should try it, even if you don't think you need it.) With front-loading, you'll either have to use event delegation, or have init methods for each page that you selectively execute as you load each page. This could become a maintainability nightmare without good build processes.
You can call functions from the original scripts on the page which you have loaded. For Instance you could do this in your main:
<script>
function ExternalScriptLoaded(){}
</script>
Then on your external page:
<script>
try{ ExternalScriptLoaded(); }catch(err){alert('This page was not loaded with ajax because i can't find the function');}
</script>
The alert will trigger if the script can't find the function on your main page.
i.e. call the function after you know the script has finished runnng.
Hope this helped.

How do I get the path of the currently running script with Javascript?

We have an IE extension implemented as a Browser Helper Object (BHO). We have a utility function written in C++ that we add to the window object of the page so that other scripts in the page can use it to load local script files dynamically. In order to resolve relative paths to these local script files, however, we need to determine the path of the JavaScript file that calls our function:
myfunc() written in C++ and exposed to the page's JavaScript
file:///path/to/some/javascript.js
(additional stack frames)
From the top frame I want to get the information that the script calling myfunc() is located in file:///path/to/some/javascript.js.
I first expected that we could simply use the IActiveScriptDebug interface to get a stacktrace from our utility function. However, it appears to be impossible to get the IActiveScript interface from an IWebBrowser2 interface or associated document (see Full callstack for multiple frames JS on IE8).
The only thing I can think of is to register our own script debugger implementation and have myfunc() break into the debugger. However, I'm skeptical that this will work without prompting the user about whether they want to break into the debugger.
Before doing more thorough tests of this approach, I wanted to check whether anyone has definitive information about whether this is likely to work and/or can suggest an alternative approach that will enable a function written in C++ to get a stack trace from the scripting engine that invoked it.
Each script you load may have an id and each method of the script calling myfunc() may pass this id to myfunc(). This means that first you have to modify myfunct() and finally alter your scripts and calls.
This answer describes how I solved the actual issue I described in the original question. The question description isn't great since I was making assumptions about how to solve the problem that actually turned out to be unfounded. What I was really trying to do is determine the path of the currently running script. I've changed the title of the question to more accurately reflect this.
This is actually fairly easy to achieve since scripts are executed in an HTML document as they are loaded. So if I am currently executing some JavaScript that is loaded by a script tag, that script tag will always be the last script tag in the document (since the rest of the document hasn't loaded yet). To solve this problem, it is therefore enough just to get the URL of the src attribute of the last script tag and resolve any relative paths based on that.
Of course this doesn't work for script embedded directly in the HTML page, but that is bad practice anyway (IMO) so this doesn't seem like a very important limitation.

Implications of multiple <script> tags in HTML

I have read that it is not recommended to instantiate jQuery multiple times in your HTML. This makes perfect sense to me, but:
Isn't Javascript single-threaded anyway? And leaving jQuery behind, how does the browser execute these multiple script tags? In parallel or one after another?
Thanks, Philip
Simple answer:
In a simple scenario (tags are part of original HTML text), the browser definitely executes them one after another.
Detailed discussion with different caveats
JavaScript isn't necessarily single-threaded (it depends on the implementation of your JavaScript engine, e.g. see Web Workers).
BUT, the individual <script> tags are executed sequentially.
For reference, please see JavaScript: The Definitive Guide. Quoting Chapter "12.3. Execution of JavaScript Programs":
JavaScript statements that appear between and tags are executed in order of appearance; when more than one script appears in a file, the scripts are executed in the order in which they appear. If a script calls document.write( ), any text passed to that method is inserted into the document immediately after the closing tag and is parsed by the HTML parser when the script finishes running. The same rules apply to scripts included from separate files with the src attribute.
Please note that the above is only true of "straight up" execution of code in tags. The order can, however, be affected by:
setTimeout() calls (duh)
defer attribute
Dynamic attachement of the <script> tags - see the last section of this answer.
As a caveat, please note that JavaScript code loaded externally via <script src="xxxx" /> would still be executed sequentially, BUT, it is quite possible that the browser would DOWNLOAD the code in parallel - depends on browser implementation (but still schedule the execution of downloaded code snippets in correct order).
This caveat is important in case you want to have some weird hack whereas the URL for the JavaScript source is actually a CGI script which does something and you try to depend on the correct order of downloads for the logic in the script.
Again, it would have no bearing on your browser JS engine's execution order of those script pieces.
However, a far more important caveat is that if you actually attach the <script> tags with external sources dynamically (e.g. via appendChild() call), according to this SO post, as well as the MSDN blog the post was based on, non-IE browsers do NOT guarantee the order of execution! It will depend on which tag's code finished downloading first!
The fewer calls you make that instantiate a jQuery object, the less overhead you have -- but even if you are designing for old browsers running on 2nd generation hardware be wary of micro-optimizations. Profile your application and fix the parts that actually are the bottlenecks.
As for the way browsers handle multiple script tags -- it varies from browser to browser, from version to version, and sometimes even from operating system to operating system. All browsers execute each script tag in document order:
<script src="scripts/some_script.js"></script> <!-- Executed 1st -->
<script src="scripts/some_other_script.js"></script> <!-- Executed 2nd -->
<script>
// Some JavaScript
</script> <!-- Executed 3rd -->
<script>
// Some More JavaScript
</script> <!-- Executed 4th -->
However, other behaviors are not defined and there is variation. For example, Opera (at least on Windows XP for version 10.6) ran each script tag in its own context -- so local variables in the 3rd script block would be out of scope if referred to in the 4th script block.
<script>
var i = 42;
</script>
<script>
alert(i);
// Alerts "undefined" in Opera, but 42 in Firefox.
</script>
The browser executes JavaScript sequentially (the same is true for jQuery since jQuery is just JavaScript).
As for having multiple script tags in HTML, there's no reason why this would be a problem. As Nabab asked, I would be interested in seeing your source for that.
Doesn't the browser compile all the javascript anyway into one "file" during processing. For example, if you had multiple $(document).ready() calls across multiple files, when the browser pre-processes the page, it essentially condenses everything down for execution - and runs it sequentially in the order it was 'seen'.
Yes, we can write any number of tags inside tag. And browser access them in sequential order.
<html>
<body>
<!-- here your code-->
<script></script>
<script></script>
<script></script>
.
.
.
<script></script>
</body>
</html>

How to avoid lost calls to an external JS file before loading it

My issue is that multiple websites are going to include my JS file and when calling something like this:
<script src="..."></script>
hello.say("yay");
there going to be a race issue so sometimes it could make it sometimes not. i know that i can solve that easily by putting every function in a window.onload but that wouldn't be clean as i've seen other websites magically solve that like google analytics:
.. Calling google analytics JS..
<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-xxxxxx-x"); <-- this an object !
pageTracker._trackPageview();
} catch(err) {}
</script>
How to do that?
Google Analytics uses a trick that's a perfect example of something that can only be done in duck typed languages. The main object is an array if the GA-script hasn't loaded, but if it has it changes behaviour. Let's see if I can explain it.
I pulled this piece from the source here at stackoverflow:
var _gaq = _gaq || [];
_gaq.push(['_setAccount','UA-5620270-1']);
_gaq.push(['_trackPageview']);
It looks like an array with some values being pushed to it. In fact, if _gaq is falsy when this code is run (as it is if no other analytics-JavaScript has run yet), it as an array. Then, when the main analytics script (included with a script-tag anywhere on the page) loads it examines this array and performs some task based on the contents of the array.
So, if this happens in opposite order (the main script is loaded first, and then the snippet above) the main script set _gaq to an object with a push-method that does whatever google wants it to do. Later, when the code above runs, _gaq.push doesn't just add values to an array; it actually executes arbitrary code (and doesn't push to an array at all).
Hence, regardless of which script runs first, the end result will be the same when both have finished.
If you include your file in the header part of the html page, it will be loaded before any other javascript in the page is run.
UPD: Also, I think even files included in the text of thml are downloaded before the processing of the rest of javascripts. Are you sure that is your problem in the first place?
You will need to delay the execution of any javascript code that depends on the external javascript until after the page has been fully loaded and you can do that by attaching the execution to the window.onload event.
window.onload = function() {
hello.say('yay');
}
But this has the disadvantage of only working for one function and will override any functions that have been initially attached to that event. You would want to read Simon Wilson's post and the comments for solutions on how to handle this situation.
http://simonwillison.net/2004/May/26/addLoadEvent/
I'm a bit unsure as to what you think the race issue is here.
Browsers always* execute script tags in the order they see them. If this were not true, a good portion of the internet would break - as well as pretty much every common JavaScript library in existence.
So, as long as users load your script earlier in the document than when they call its APIs, you should have no problem. The only potential exception to this I can think of is if your script's initialization relies on asynchronous logic, in which case you should think about providing a standard callback mechanism of your own for users to write their code in.
If users might load your script AFTER the point they use its APIs, then the trick Jakob alludes to in his answer would work. But I'm not even sure you're aiming for that level of complexity.
*edit: I should note, to be perfectly honest, there are specific exceptions to this, but not so long as you're simply dealing with standard non-deferred usage of <script> tags within an HTML document.

I have an issue with inline vs included Javascript

I am relatively new to JavaScript and am trying to understand how to use it correctly.
If I wrap JavaScript code in an anonymous function to avoid making variables public the functions within the JavaScript are not available from within the html that includes the JavaScript.
On initially loading the page the JavaScript loads and is executed but on subsequent reloads of the page the JavaScript code does not go through the execution process again. Specifically there is an ajax call using httprequest to get that from a PHP file and passes the returned data to a callback function that in onsuccess processes the data, if I could call the function that does the httprequest from within the html in a
<script type="text/javascript" ></script>
block on each page load I'd be all set - as it is I have to inject the entire JavaScript code into that block to get it to work on page load, hoping someone can educate me.
If you aren't using a javascript framework, I strongly suggest it. I use MooTools, but there are many others that are very solid (Prototype, YUI, jQuery, etc). These include methods for attaching functionality to the DomReady event. The problem with:
window.onload = function(){...};
is that you can only ever have one function attached to that event (subsequent assignments will overwrite this one).
Frameworks provide more appropriate methods for doing this. For example, in MooTools:
window.addEvent('domready', function(){...});
Finally, there are other ways to avoid polluting the global namespace. Just namespacing your own code (mySite.foo = function...) will help you avoid any potential conflicts.
One more thing. I'm not 100% sure from your comment that the problem you have is specific to the page load event. Are you saying that the code needs to be executed when the ajax returns as well? Please edit your question if this is the case.
I'd suggest just doing window.onload:
<script type="text/javascript">
(function() {
var private = "private var";
window.onload = function() {
console.log(private);
}
})();
</script>
On initially loading the page the js loads and is executed but on subsequent reloads of the page the js code does not go through the execution process again
I'm not sure I understand your problem exactly, since the JS should execute every time, no matter if it's an include, or inline script. But I'm wondering if your problem somehow relates to browser caching. There may be two separate points of caching issues:
Your javascript include is being cached, and you are attempting to serve dynamically generated or recently edited javascript from this include.
Your ajax request is being cached.
You should be able to avoid caching by setting response headers on the server.
Also, this page describes another way to get around caching issues from ajax requests.
It might be best not to wrap everything in an anonymous function and just hope that it is executed. You could name the function, and put its name in the body tag's onload handler. This should ensure that it's run each time the page is loaded.
Depends what you want to do, but to avoid polluting the global namespace, you could attach your code to the element you care about.
e.g.
<div id="special">Hello World!</div>
<script>
(function(){
var foo = document.getElementById('special');
foo.mySpecialMethod = function(otherID, newData){
var bar = document.getElementById(otherID);
bar.innerHTML = newData;
};
//do some ajax... set callback to call "special" method above...
doAJAX(url, 'get', foo.mySpecialMethod);
})();
</script>
I'm not sure if this would solve your issue or not, but its one way to handle it.

Categories

Resources