How to close window without triggering 'window.onunload'? - javascript

I have an external program that opens an .hta file which contains some JavaScript:
function getLUTKey(key) {
// Write txt file to user's file system
var fso, fh;
fso = new ActiveXObject("Scripting.FileSystemObject");
fh = fso.CreateTextFile("PartID.txt", true);
fh.Write(key);
fh.close();
self.close();
}
The idea is that the window contains a number of links for different parts which, when clicked, will write their respective "Part ID" to a file using the above js function. The previously-mentioned external program then waits in the background for this file to be created, then uses the file's contents.
However, in order to prevent the user from exiting without selecting a part -
therefore never creating a file and leaving the external program to loop until a timeout triggers - I've added the following code:
window.onunload = function(){ getLUTKey('cancel') };
This creates another problem. When getLUTKey() is run with a valid ID, and it closes the window, the window.unload the code runs immediately after, overwriting whatever the ID in the file was with "cancel". My question is this:
Is there a way to close a window in javascript without triggering window.unload?

I guess it's way easier for you to manage the state of your app. For example you can simply remove the handler of window closing after you're done with the function.
function getLUTKey(key){
// Write txt file to user's file system
var fso, fh;
fso = new ActiveXObject('Scripting.FileSystemObject');
fh = fso.CreateTextFile('PartID.txt', true);
fh.Write(key);
fh.close();
window.onunload = null;
self.close();
}

Related

Running Javascript in new window.open

I'm running this function to open a new window.
function htmlNewWindow(id) {
var html = $(id).html();
var newWindow = window.open('');
newWindow.document.body.innerHTML = '<html><head><title>Hi</title> <script src="js/myScript.js"></script> </head>' + html;
}
This successfully creates a new window with the HTML in it. I have a bunch of HTML tags which when clicked run a function called Foo1. I've tried printing the entire function of Foo1 to the new HTML document, and tried putting Foo1 inside myScript.js. I see both Foo1 inside a script tag in the new window, and but neither are loaded since they are just written to the new page as HTML.
Scripts added with .innerHTML aren't executed. You need to create a script node and append it to the window's DOM.
$("#button").click(newWindow);
function newWindow(id) {
var html = $(id).html();
var win = window.open('');
win.document.head.innerHTML = '<title>Hi</title></head>';
win.document.body.innerHTML = '<body>' + html + '</body>';
var script = document.createElement('script');
script.src = 'js/myScript.js';
win.document.head.appendChild(script);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Click me</button>
This doesn't run in Stack Snippet's sandbox, here's a working jsfiddle.
Try this:
var newWindow = window.open('');
newWindow.document.createElement('script');
script.src = 'js/myScript.js';
newWindow.document.head.appendChild(script);
Just in case someone has this to be done in a link. Do the following:
Link
This opens a new window with that URL, it set the focus to that windows, and as soon as the 'load' event is triggered, it executes the code in the function. It only works with a page in the same domain.
Hope this helps ⬆✌.
Cheers 👍
Here's how you create, and then append a script file within a new window:
var fileref = document.createElement('script');
//creates script in current document
fileref.setAttribute("type", "text/javascript")
//set it to JS by "type"
fileref.setAttribute("src", filename)
//set your "src=yourFile_href_Here.js"
//Then create your newWindow as you did above, but slightly updated
//Create your function which will consume the "fileref" argument
function htmlNewWindow(fileref) {
var newWindow = window.open('');
newWindow.document.getElementsByTagName("head")[0].appendChild(fileref);
}; //right now the function is made but you still have to execute it
//Execute your function, and pass it the variable "fileref" that you set above.
htmlNewWindow(fileref);
//Within this edit you will append the head element
//with your newly created script(or any other parameterized argument)
/* Replace your filename to pass any other script */
NOTE - Opening a page residing on a different domain, if not specifically allowed, will reject instances of this due to CORS(https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
It's not a safe practice to be sending your scripts into other people's pages or allowing them in your own if your domain hasn't sent them. Also, depending on your server/technology stack you may need to configure your *-origin settings within your backend stack. See here: (https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)

Javascript update function via change src script file

My javascript file with function:
scr.js:
function myf(){
alert('aaa');
}
myf();
After load page, I see dialog box with 'aaa'. This is right.
The next, I change script source to:
function myf(){
alert('bbb'); ///////////
}
myf();
and src file by add to him timestamp (for update file):
$('script[src^="./scr.js"]').attr('src','./scr.js?='+new Date().getTime());
The problems:
after update file, the myf() function doesn't run.
after run myf() function from browser console I see dialog with 'aaa' not with 'bbb'
when I remove script tag with src scr.js, I can call again my function
Where is problem and what do for update scritpt?
As far as I know, changing a script src attribute, doesn't force the browser to download the script; you need to create a new script tag and append it to the DOM.
Because the browser didn't downloaded and executed the new script.
When your script was first run by the browser it created a global function, which has been attached to the global object; that's why you can still call it, even though you've dinamically removed the script.
UPDATE (Possible solution):
Create a script element dinamically using something like this:
function createScript(src) {
var s = document.createElement("script");
s.src = src;
return s;
}
Update the DOM:
var oldScript = document.querySelector("script[src^='s.js']");
var newScript = createScript("s.js?t=" + (new Date()).getTime());
document.body.replaceChild(newScript, oldScript);
(you can translate that into jQuery if you want)

Vanishing panel

I've created a jsx script that creates a custom dialog box in illustrator that allows me to load a text file into a string.. It all seems to work OK in Extendscript but the moment I save it and run it standalone from Illustrator the dialog box appears then instantly vanishes. Any ideas, I've removed all the $writeIn statements.
I've looked around but there seems to be nothing on this
Code lookes like ths:
function init() {
dataFile=""//Load in paths to users day file and folder where spreadsheets are stored
var readFile = File(appPath+ "pathData"+".txt");
if(readFile != null) {
readFile.open('r')
dataPath=readFile.read();
readFile.close();
dataPath=dataPath.replace(/[\n\r]/g, '');//Seems to need this as without there is a cariage return added to the end of the string somewhere in the saving of the file
};
else dataPath="Press button to set path to day folder";
readFile = File(appPath+ "pathDay"+".txt");
if(readFile != null) {
readFile.open('r')
dayPath=readFile.read();
readFile.close()
dayPath=dayPath.replace(/[\n\r]/g, '');//Seems to need this as without there is a cariage return added to the end of the string somewhere in the saving of the file
//$.writeln("dayPath=",dayPath);
};
else dayPath="Press button to set path to day folder";
var initPanel=new Window("palette","iPlot", undefined);
initPanel.orientation="column"
var group1=initPanel.add("group",undefined,"GroupOne");
group1.orientation="column"
var loadButton=group1.add("button",undefined,"Load data");
loadButton.onClick = function() {
initPanel.close();
loadFile();
};
var closeButton=group1.add("button",undefined,"Close");
closeButton.onClick = function() {
//$.writeln("Close button pressed");
initPanel.close();
};
var setipButton=group1.add("button",undefined,"Setup");
setipButton.onClick = function() {
setup()
};
initPanel.center();
initPanel.show();
return true;
}
Palettes and dialogs only "live" as long as your script runs. As I understand it (barely), as soon as your script 'ends', i.e., you want to work outside the panel in Illustrator, the Extendscript engine thinks the script itself has ended.
The common cure for this is to dedicate private resources to your script. You do so by creating a dedicated "engine", which will persist in memory. The following two lines do the trick when added at the very top:
#target Illustrator
#targetengine main
The first one is obsolete if you run your script from within Illustrator, but it is required if you run it from elsewhere (such as from within the Extendscript Toolkit Editor). The second sets up a private engine with a specified name; in this case main but if you run several palettes at the same time, you need unique names for each.
See http://forums.adobe.com/thread/1238745 -- in particular, the very last post.

Saving without dialog window

I'm trying to write a script that will automate a bunch of stuff for Photoshop CS5. Part of this involves saving a bunch of files. Is there a way to save a file in a way that doesn't open up a dialog window? I've been looking over the JavaScript Tools Guide, but I didn't see a way to do this. This suggested I used an action to deal with it but I'd really prefer not to do that.
EDIT: specifically I want to save the files as crytiff format but I'd just like to know how to save a file with whatever extension I want
The following saves the active document as PNG. You can change the type to save it as.
// reference open doc
var doc = app.activeDocument;
// set save options
var opts = new ExportOptionsSaveForWeb();
opts.PNG8 = false;
opts.transparency = true;
opts.interlaced = false;
opts.quality = 100;
opts.includeProfile = false;
opts.format = SaveDocumentType.PNG; // Document Type
// save png file in same folder as open doc
activeDocument.exportDocument(doc.path, ExportType.SAVEFORWEB, opts);
Try using Document.saveAs(). But, like El Cas said, you still have to pass in some kind of SaveOptions object. You don't necessarily have to specify all the options if you don't want. You can just use the generic object like this:
app.activeDocument.saveAs(new File(doc.path + "/myDocument"), TiffSaveOptions);
// or BMPSaveOptions or GIFSaveOptions or JPEGSaveOptions...
Here's a much more complete Photoshop CS5 Javascript Reference
Open:
Windows > Actions
You will find Toggle Dialog On/Off check box before every action. Turn it off.

Auto Save a file in Firefox

I am trying to find a way where by we can auto save a file in Firefox using JS. The way I have done till yet using FireShot on a Windows Desktop:
var element = content.document.createElement("FireShotDataElement");
element.setAttribute("Entire", EntirePage);
element.setAttribute("Action", Action);
element.setAttribute("Key", Key);
element.setAttribute("BASE64Content", "");
element.setAttribute("Data", Data);
element.setAttribute("Document", content.document);
if (typeof(CapturedFrameId) != "undefined")
element.setAttribute("CapturedFrameId", CapturedFrameId);
content.document.documentElement.appendChild(element);
var evt = content.document.createEvent("Events");
evt.initEvent("capturePageEvt", true, false);
element.dispatchEvent(evt);
But the issue is that it opens a dialog box to confirm the local drive location details. Is there a way I can hard code the local drive storage location and auto save the file?
If you are creating a Firefox add-on then FileUtils and NetUtil.asyncCopy are your friends:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
var TEST_DATA = "this is a test string";
var source = Components.classes["#mozilla.org/io/string-input-stream;1"].
createInstance(Components.interfaces.nsIStringInputStream);
source.setData(TEST_DATA, TEST_DATA.length);
var file = new FileUtils.File("c:\\foo\\bar.txt");
var sink = file.openSafeFileOutputStream(file, FileUtils.MODE_WRONLY |
FileUtils.MODE_CREATE);
NetUtil.asyncCopy(source, sink);
This will asynchronously write the string this is a test string into the file c:\foo\bar.txt. Note that NetUtil.asyncCopy closes both streams automatically, you don't need to do it. However, you might want to pass a function as third parameter to this method - it will be called when the write operation is finished.
See also: Code snippets, writing to a file
Every computer has a different file structure. But still, there is a way. You can save it to cookie / session, depends on how "permanent" your data wants to be.
Do not consider writing a physical file as it requires extra permission.

Categories

Resources