How to get the uri of the .js file itself - javascript

is there a method in JavaScript by which I can find out the path/uri of the executing script.
For example:
index.html includes a JavaScript file stuff.js and since stuff.js file depends on ./commons.js, it wants to include it too in the page. Problem is that stuff.js only knows the relative path of ./commons.js from itself and has no clue of full url/path.
index.html includes stuff.js file as <script src="http://example.net/js/stuff.js?key=value" /> and stuff.js file wants to read the value of key. How to?
UPDATE: Is there any standard method to do this? Even in draft status? (Which I can figure out by answers, that answer is "no". Thanks to all for answering).

This should give you the full path to the current script (might not work if loaded on request etc.)
var scripts = document.getElementsByTagName("script");
var thisScript = scripts[scripts.length-1];
var thisScriptsSrc = thisScript.src;

If your script knows that it's called "stuff.js", then it can look at all the script tags in the DOM.
var scripts = document.getElementsByTagName('script');
and then it can look at the "src" attributes for its name. Kind-of a hack, however, and to me it seems like something you should really work out server-side.

script.aculo.us (source) solves a similar problem. here is the relevant code
var js = /scriptaculous\.js(\?.*)?$/;
$$('script[src]').findAll(function(s) {
return s.src.match(js);
}).each(function(s) {
var path = s.src.replace(js, ''),
includes = s.src.match(/\?.*load=([a-z,]*)/);
(includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
function(include) { Scriptaculous.require(path+include+'.js') });
});
(some parts of this like .each require prototype)

Related

InDesign CS6 Import multiple XML files in document via scripting

I've created a script where I select the folder that holds the xml files I want to import, create the document and insert these XML files, but my script ends with the following message, which is not very helpful: "Execution finished. Result: undefined".
Any help will be appreciated.
var myDocument = app.documents.add();
var MyFolderWithFiles = Folder.selectDialog ("Choose a folder");
var myFiles = MyFolderWithFiles.getFiles("*.xml");
for(var i = 0; i < myFiles.length; i++) {
myDocument.importXML(myFiles[i]);
}
This question is a bit old but doesn't have an accepted answer so I'll see if I can help.
Your code for creating the new document looks to me like you're just creating a new blank document. How does the XML you're importing know where to go? One thing that might help is after you've completed the import check the "Structure" of the XML within the document.
var myDocument = app.documents.add();
When I import XML I don't create a new blank document, I create a new document from a template that has a predefined structure so InDesign knows where to place each XML node within your template. Here is a decent reference to help get started setting up your INDT file.
var myDoc = app.open( '//path/to/myTemplate/myTemplate.indt', OpenOption.OPEN_COPY );
// NOTE: I'm running against an InDesign server, if you're running against your ID GUI then you'll need an extra param on the app.open() call like in the following line
var myDoc = app.open( '//path/to/myTemplate/myTemplate.indt', true, OpenOption.OPEN_COPY ); // This is probably what you'll need to use
// The extra param for showingWindow should be true if running against the ID GUI, this feature is NOT available when executing against the ID server
Also I set my XML import preferences -- your's may differ from mine -- so InDesign knows what to do, say in case of an unmatched XML node in contrast to your XML import structure. For example here is one of the xmlImportPreference sets I use from time to time.
with ( myDoc.xmlImportPreferences )
{
allowTransform = false;
createLinkToXML = false;
ignoreUnmatchedIncoming = false;
ignoreWhitespace = true;
importCALSTables = false;
importStyle = XMLImportStyles.mergeImport;
importTextIntoTables = false;
importToSelected = false;
removeUnmatchedExisting = true;
repeatTextElements = true;
}
Something else to look into with the help of creating your XML structure for your INDT is the use of a DTD (Document Type Definition) file. Here is another good reference for help with InDesign and XML, it also goes into some detail about DTD files. An example of a simple DTD file might be something like this.
<!ELEMENT Root (Root*)>
<!ELEMENT Customer(name, Address*)>
<!ELEMENT name(#PCDATA)>
<!ELEMENT Address(street, city, state, zip)>
<!ELEMENT street(#PCDATA)>
<!ELEMENT city(#PCDATA)>
<!ELEMENT state(#PCDATA)>
<!ELEMENT zip(#PCDATA)>
In XML that would represent something like this:
<Root>
<Customer>
<name>Billy Bob</name>
<Address>
<street>123 Test Ave</street>
<city>Testville</city>
<state>IA</state>
<zip>12345</zip>
</Address>
</Customer>
</Root>
I hope this helps point someone in the right direction struggling with ID and XML. It can be tricky and temperamental at times.
I did ramble a little bit so if someone finds this helpful but still cannot quite get it to work I can elaborate on a specific issue all you have to do is ask! ;) HAPPY CODING!
"Execution finished. Result: undefined"
it means
the files are imported succesfully.
and indesign doesn't return any value for this statement...
I second Sulaiman_J. The message indicates everything went fine. The fact you don't have anything imported can be related to the xml import options. You should check with a manual xml import and display xml options. Check if the "Only import elements that match existing structure". Because if this option is checked and as you are working on new documents, there won't be existing structure and the import will not inject any nodes.
That's why you may not have injected contents even if InDesign says it did.

How do I rotate an ad on a page loading the list of ads from an external file using JavaScript?

I'm trying to load a variable from a file using javascript. I've found some examples but I can't seem to make it work and could really use some help on getting my syntax right.
Basically, I want to load a random ad image on a page, but I would like the list of ads to be pulled from a file. Currently I'm loading the images using the following script which I found on the internet:
<script type="text/javascript">
var picPaths = [
'/images/ad-1.jpg',
'/images/ad-2.jpg',
'/images/ad-3.jpg',
'/images/ad-4.jpg'
]
var oPics = [];
for(i=0; i < picPaths.length; i++){
oPics[i] = new Image();
oPics[i].src = picPaths[i];
}
curPic = Math.floor(Math.random()*oPics.length);
window.onload=function(){
document.getElementById('imgRotator').src = oPics[curPic].src;
}
</script>
I have been trying to get the picPath variable value to load from a file (instead of stating it in the code). I found some code here on stackoverflow and tried adjusted it to the following:
var picPaths = new XMLHttpRequest();
picPaths.open('GET', '/images/liveimages.inc');
picPaths.send();
I also created the file /images/liveimages.inc which containts the following:
'/images/ad-1.jpg',
'/images/ad-2.jpg',
'/images/ad-3.jpg',
'/images/ad-4.jpg'
But, alas, it’s not working and I’m not programmer enough to fix it. :-( I'm thinking my syntax is off but my code could be off too since I am not a JavaScript guy.
Any help would be appreciated and thanks for taking the time to read (and respond) to my question! :-D
If you store the data file as JSON you can use AJAX/XMLHTTPRequest to fetch it, and JSON.parse (available in all modern browsers) to read it.
An easier way perhaps is just to have a script that contains just the data, like:
var picPaths = [
'/images/ad-1.jpg',
'/images/ad-2.jpg',
'/images/ad-3.jpg',
'/images/ad-4.jpg'
];
And then include your scripts in the correct order:
<script type="text/javascript" src="picpaths.js"></script>
<script type="text/javascript" src="ad_script.js"></script>
ad_script.js will be able to access picPaths.
You could have some server-side script generate picpaths.js for you, for instance by looking at the contents of a folder or a database and pulling the ad info from that.

Inject local .js file into a webpage?

I'd like to inject a couple of local .js files into a webpage. I just mean client side, as in within my browser, I don't need anybody else accessing the page to be able to see it. I just need to take a .js file, and then make it so it's as if that file had been included in the page's html via a <script> tag all along.
It's okay if it takes a second after the page has loaded for the stuff in the local files to be available.
It's okay if I have to be at the computer to do this "by hand" with a console or something.
I've been trying to do this for two days, I've tried Greasemonkey, I've tried manually loading files using a JavaScript console. It amazes me that there isn't (apparently) an established way to do this, it seems like such a simple thing to want to do. I guess simple isn't the same thing as common, though.
If it helps, the reason why I want to do this is to run a chatbot on a JS-based chat client. Some of the bot's code is mixed into the pre-existing chat code -- for that, I have Fiddler intercepting requests to .../chat.js and replacing it with a local file. But I have two .js files which are "independant" of anything on the page itself. There aren't any .js files requested by the page that I can substitute them for, so I can't use Fiddler.
Since your already using a fiddler script, you can do something like this in the OnBeforeResponse(oSession: Session) function
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("MY.TargetSite.com") ) {
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
// Remove any compression or chunking
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
// Find the end of the HEAD script, so you can inject script block there.
var oRegEx = oRegEx = /(<\/head>)/gi
// replace the head-close tag with new-script + head-close
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>console.log('We injected it');</script></head>");
// Set the response body to the changed body string
oSession.utilSetResponseBody(oBody);
}
Working example for www.html5rocks.com :
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("html5rocks") ) { //goto html5rocks.com
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
var oRegEx = oRegEx = /(<\/head>)/gi
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>alert('We injected it')</script></head>");
oSession.utilSetResponseBody(oBody);
}
Note, you have to turn streaming off in fiddler : http://www.fiddler2.com/fiddler/help/streaming.asp and I assume you would need to decode HTTPS : http://www.fiddler2.com/fiddler/help/httpsdecryption.asp
I have been using fiddler script less and less, in favor of fiddler .Net Extensions - http://fiddler2.com/fiddler/dev/IFiddlerExtension.asp
If you are using Chrome then check out dotjs.
It will do exactly what you want!
How about just using jquery's jQuery.getScript() method?
http://api.jquery.com/jQuery.getScript/
save the normal html pages to the file system, add the js files manually by hand, and then use fiddler to intercept those calls so you get your version of the html file

Path to included Javascript page

How do I get the absolute or site-relative path for an included javascript file.
I know this can be done in PHP, (__file__, I think). Even for an included page, one can check the path (to the included file). Is there any way to have this self awareness in Javascript?
I know I can can get the page URL, but need to get the JS URL.
Eg. Javascript needs to modify the src of an image on the page. I know where the image is relative to the JavaScript file. I don't know where the Javascript is relative to the page.
<body>
<img id="img0" src="">
<script src="js/imgMaker/myscript.js"></script>
</body>
function fixPath(){
$$("#img0")[0].set('src','js/imgMaker/images/main.jpg');
}
Please do not tell me to restructure my function - the example is simplified to explain the need.
In the actual case, a Mootools class is being distributed and people can put it into whatever folder they want.
I would just read the src of the script element, but the class can be part of any number of javascript files, so I can't know what the element looks like.
JavaScript (not JScript) has no concept of file names. It was developed for Netscape back in the days. Therefore there is no __file__ feature or anything similar.
The closest you can come are these two possibilities:
What you already mentioned: Harvest all src attributes of all JS files and try to figure out which one is the right.
Make it a necessary option, that the path to the images must be set in the embedding HTML file. If not set, use a reasonable and well-documented default:
<script type="text/javascript">
var options = {
'path_to_images': '/static/images/' // defaults to '/js/img/'
};
</script>
Based on http://ejohn.org/blog/file-in-javascript/
(function(){
this.__defineGetter__("__FILE__", function() {
return (new Error).stack.split("\n")[2].split("#")[1].split(":").slice(0,-1).join(":");
});
})();
(function(){
this.__defineGetter__("__DIR__", function() {
return __FILE__.substring(0, __FILE__.lastIndexOf('/'));
});
})();
Then later
img.setAttribute('src', __DIR__ + '/' + file);
if you have folders:
/webroot
/images
/scripts
Then images would be an absolute path of /images/whatever.jpg and scripts would be an absolute path of /scripts/js.js
I'm using the following method to get the base URL and using it for loading the other prorotypes, maybe this is what you need. Lets say current script name is 'clone.js'.
/*
* get the base URL using current script
*/
var baseURL = '';
var myName = 'clone.js';
var myPattern = /(^|[\/\\])clone\.js(\?|$)/;
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
var src;
if (src = scripts[i].getAttribute("src")) {
if (src.match(myPattern)) {
baseURL = src.replace(myName, '');
break;
}
}
}
Var baseURL should contain what you need.
The path to the JS is irrelevant; links in the HTML file are always relative to the HTML file, even if you modify them from external JS.
[EDIT] If you need to build a path relative to the current web page, you can find its path in document.location.pathname. This path is relative to the web root but you should be able to find a known subpath and then work from there.
For example, for this page, it pathname would be /posts/1858724. You can look for posts and then build a relative path from there (for example posts/../images/smiley.png)
I know this question was asked awhile back but I have a similar situation to Sam's.
In my case, I have two reasons for the situation:
The user can access different sub-domains, each with its own index page.
The user can enter a password that causes index.php to adjust the paths.
Most of the references point to the same src locations for the scripts, but some do not. For instance, those at a different level of the tree would require a different path.
I addressed it by assigning an id to the index page's script tag. For example, the head might include...
<script id='scriptLocation' type='text/javascript' language='javascript' src='../scripts.test/script.js'></script>
My JavaScript is then able to read the path...
var myPath = document.getElementById("scriptLocation").src;
Found another approach, perhaps someone with more JS ninja can flush this out.
CSS stylesheet are able to find the node that called them using document.stylesheets.ownernode.
I could not find a similar call for javascript files.
But, in some cases, if one can include a CSS file together with the javascript, and give the first rule some unique identifier.
One can loop through all stylesheets till they find the one with the identifier [if(document.stylsheets[i].cssRules[0] == thisIs:myCSS)], than use ownerNode to get the path of that file, and assume the same for the JS.
Convoluted and not very useful, but its another approach - might trigger a better idea by someone.

Can I get the location of where a JavaScript library is loaded from, from within the script?

Lets say I have a page with this code on it on www.foo.com:
<script src="http://www.bar.com/script.js" />
Can I write code from within script.js that can check that it was served from bar.com? Obviously document.location.href would give me foo.com.
Thanks!
var scripts = document.getElementsByTagName("script");
give you a collection of all the scripts in the page
After this you can read their src property to find your target (I hope you know how the script is called)
for (var i=0, limit=scripts.lenght; i< limit; i++) {
if (scripts[i].src.substr(<calculate your offset>) == scriptName) {
// Have you found your script, extract your data
}
}
The only way to find out the location of a non-worker script is the non-standard error.fileName, which is only supported by Firefox and Opera:
var loc = (new Error).fileName;
If the script is a worker thread (which of course it isn't), then you could just use the location object.
If it's really important, you could work around it by defining a string containing the script URL in front of each script tag:
<script type="text/javascript">SCRIPT_URL = "http://www.bar.com/script.js"</script>
<script src="http://www.bar.com/script.js" />
Inside the script file you can then access the URL
alert("my URL is "+SCRIPT_URL);
Not too elegant but should work.
You could also, if you have a server-side language like PHP and don't mind sending JS files through the interpreter (Big performance caveat!), do something like this within the JS file:
<script type="text/javascript">var my_url = "<? echo $_SERVER["REQUEST_URI"]; ?>"</script>
but that should really, really be the last resort.
You can wrap your script in a condition, kind of like an adult diaper, if you insist.
if(top.location.host==='www.bar.com'){
//the whole script goes here
}
else alert('Nyah Nyah Nyah!')

Categories