Thunderbird extension - How to use relative paths with Javascript? - javascript

I'm developing my own Thunderbird extension.
The extension adds an .xml-file as an attachment to a Thunderbird mail (it works very well).
My only problem is that I don’t know how to use a relative path.
It looks something like that:
var file= 'C:\\...[… \\…]...\\chrome\\VHitG2.xml';
var attachments = [];
attachments.push(FileToAttachment(file));
AddAttachments(attachments);
If the extension is installed in a different path, the extension can’t work.
Doe’s anyone know how to use relative paths ?

The FileToAttachment() function doesn't do magic, it is actually very simple. I assume that you are talking about a static file that is part of your extension - it should be accessible under a URL like chrome://myextension/content/VHitG2.xml. Then you can simply create an nsIMsgAttachment instance yourself using that URL:
var attachment = Components.classes["#mozilla.org/messengercompose/attachment;1"]
.createInstance(Components.interfaces.nsIMsgAttachment);
attachment.url = "chrome://myextension/content/VHitG2.xml";
AddAttachments([attachment]);
Note that your extension doesn't need to be installed unpacked for that, you don't need an actual file on disk.

I used a very circuitous way to get the URL of the extension’s files:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
var test1 = FileUtils.getFile("CurProcD", ["VHitG2.xml"]);
var test2 = FileUtils.getFile("CurProcD", ["VHitG.xml"]);
var file1 = test1.path.replace(/VHitG2.xml/i, "extensions\\custom-toolbar-button#example.com\\chrome\\VHitG2.xml");
var file2 = test2.path.replace(/VHitG.xml/i, "extensions\\custom-toolbar-button#example.com\\chrome\\VHitG.xml");
var attachment1 = file1.replace(/\\/g, "\\\\");
var attachment2 = file2.replace(/\\/g, "\\\\");

Related

Create a platform independent path string

I'm using the Mozilla addon sdk for development and need to create a file on the local system.
Currently I use the statement below but feel it may not cover all platforms.
Running the statement on Windows 7 and Windows XP returns:
console.log(system.platform);
winnt
Running it on Linux returns:
console.log(system.platform);
linux
Is there a more reliable way to create the fullPath string, without having to check contents of system.platform?
pathToFile = Cc["#mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties).get("Home", Ci.nsIFile).path;
if (system.platform.indexOf("win") == 0) {
fileSeparator = "\";
}else{
fileSeparator = "/";
}
fullPath=pathToFile + fileSeparator + 'myFile.txt'
Just a little modfication to your code should do the trick
var file = Cc["#mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties).get("Home", Ci.nsIFile);
file.append("myFile.txt");
var fullPath = file.path;
I'd like to point out an alternative to #Kashif's answer.
Use FileUtils.getFile(), which is just a convenience function, essentially doing multiple .append()s, one per item in the parts array.
Cu.import("resource://gre/modules/FileUtils.jsm");
var file = FileUtils.getFile("Home", ["myFile.txt"]);
var path = file.path;
The SDK has a 'fs/path' module that has parity with Node's path API

Thunderbird extension: open EML file as draft

After my first question here, I am now looking for a way do the the same, but instead of opening an EML as a message, I want to open it as a draft.
Basically, I want to load a generated EML file into the compose window, so I can directly send it.
I already found some code, but I can't find the correct documentation on how to use it
var filePath = new FileUtils.File(getPath(params));
var uri = io.newFileURI(filePath);
var msgComposeService = Components.classes["#mozilla.org/messengercompose;1"].getService(Components.interfaces.nsIMsgComposeService);
var messenger = Components.classes["#mozilla.org/messenger;1"].createInstance(Components.interfaces.nsIMessenger);
var hdr = messenger.msgHdrFromURI(uri.spec);
var identity = getIdentityForHeader(hdr, Components.interfaces.nsIMsgCompType.Draft);
var msgWindow = Components.classes["#mozilla.org/messenger/msgwindow;1"].createInstance(Components.interfaces.nsIMsgWindow);
msgComposeService.OpenComposeWindow(null,null,uri,Components.interfaces.nsIMsgCompType.Draft,Components.interfaces.nsIMsgCompFormat.Default,identity,msgWindow);
I would suggest injecting the eml file into a local Drafts folder so as to get an nsIMsgDBHdr, and then calling the ComposeMessage function with Ci.nsIMsgCompType.Draft, Ci.nsIMsgCompFormat.Default, yourMsgHdr.folder, yourMsgHdr'sURI.
I think there are several StackOverflow answers on how to inject a given message into a folder.

How to open network folder with XUL

How can I open network folder for XUL? for my Firefox toolbar, it can access drives like C:, not network paths like //Development...with the code: file.initWithPath("\\DEVELOPMENT2");
Full code:
var file = Components.classes["#mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("\\\DEVELOPMENT2"); //---> this is not working
//file.initWithPath("Y:"); ---> this is working
file.reveal();
var process = Components.classes["#mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
process.init(file);
var args = [];
process.run(false, args, args.length);
//end
I can see two issues:
Missing bachslash - you need two backslashes, each of them escaped, this makes four backslashes in total. Meaning "\\\\DEVELOPMENT2" rather than "\\\DEVELOPMENT2".
Firefox cannot open the listing for a server - it is a virtual location, not an actual folder. It can open any of the shared folders on the server however:
var file = Components.classes["#mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("\\\\DEVELOPMENT2\\folder");
file.reveal();

Javascript: how to append data to a file

how can i append data to a file using javascript?
i tried to use this code, but i got an error:
var fso = new ActiveXObject("Scripting.FileSystemOject");
var filepath = fso.GetFile("member.txt");
var fileObject = fso.OpenTextFile(filepath, 8);
file.WriteLine(id + "|" + pass);
fileObject.close();
the error is on var fso = new ActiveXObject("Scripting.FileSystemOject");, written: Error: Automation server can't create object
is there any other way to append the file using javascript or the way to fix this? thanks :)
EDIT:
i have doing what's written on this, and it still not working :/
I just realized these in your code:
var fileObject = fso.OpenTextFile(filepath, 8,true);
You'll need the true-argument, if the file does not exist, or you want to overwrite/append it.
var filepath = fso.GetFile("member.txt");// This won't work.
var filepath = "your_filePath"; // Use this instead
var fileObject = fso.OpenTextFile(filepath, 8, true);
OpenTextFile() needs a path as a string like "D:/test/file.txt". GetFile() returns an object, which you can see as a string (D:\test\file.txt), but it's not a string. Use also absolute paths, relative paths don't seem to work by my experience.
EDIT
Add the code below to the <head>-part of your html-file, then save locally as a hta (with file extension hta, not htm or html).
<hta:application
applicationName="MyApp"
id="myapp"
singleInstance="yes"
/>
Then run the hta-file. If you still getting an ActiveX-error, it's not supported by your OS. If this works, you haven't done all the security settings correct.
EDIT II
In this case it's not very usefull to get the path through ActiveX, you'll need to write it literal anyway. And I'm not supposed to do your homeworks, but this does the trick...
var filepath = new String(fso.GetFile("member.txt")).replace(/\\/g,'/');
And don't forget what I've said above about using absolute paths...
The 8 in the OpenTextFile function specify that you want to append to the file. Your problem comes from the security restriction of your browser. To make it work you'll have to lower the security level, which is not really recommended.
The error is thrown because there are security restrictions which donot allow the activex to run. change your security settings to allow the activex if your using internet explorer (which i think you are).
This might be useful http://windows.microsoft.com/en-US/windows/help/genuine/ie-activex
Cheers
EDIT: i have doing what's written on this, and it still not working :/
* try Restarting your browser
As pointed out in this comment
Javascript: how to append data to a file
the cause of the error Error: Automation server can't create object is the typo in the progid passed to ActiveXObject: Oject instead of Object:
var fso = new ActiveXObject("Scripting.FileSystemOject");
there is a missing b!

Find %LocalAppData% path and add new folder with JavaScript

I created a Windows 7 Gadget and I need to create a place on each user's computer to store the Settings.ini file (Created from my SettingsManager.js file). The application packaging team at my company recommends I use
%LOCALAPPDATA%\Microsoft\Windows Sidebar\
and then add
Gadgets\iMon.Gadget\
subfolders. This is so each user's settings are stored in a unique location and won't be changed by any other applications or gadgets.
Do I need to use something along the lines of
var fso = new ActiveXObject("Scripting.FileSystemObject");
var folder = fso.CreateFolder("path");
Any help on how to do this would be appreciated.
Update: I found how to get the %localappdata% path, but I still need to create the new folder. Here's what I've tried without success:
var wshshell = new ActiveXObject("wscript.shell");
var localAppData = wshshell.ExpandEnvironmentStrings("%localappdata%");
var filePath = localAppData + "\\Microsoft\\Windows Sidebar\\Gadgets\\iMon.Gadget";
var fso = new ActiveXObject("Scripting.FileSystemObject");
var filePath = localAppData + "\\Microsoft\\Windows Sidebar\\Gadgets\\iMon.Gadget";
I'm not sure I understand what you're trying to do here. is iMon.Gadget the name of your gadget? If so, this folder is automatically created for you upon installation of the gadget when the .gadget archive is executed. All the gadget's files and folders will be unpacked to
%LOCALAPPDATA\Microsoft\Windows Sidebar\Gadgets\iMon.gadget\
In your code, you can then proceed to manipulate files within this folder (and it's subfolders). To get the full path, you use
var gadgetPath = System.Gadget.path;
For example:
var oFile,
gadgetPath = System.Gadget.path,
oFSO = ActiveXObject("Scripting.FileSystemObject");
oFile = oFSO.CreateTextFile(gadgetPath + "\\test.txt", true);
oFile.WriteLine("Test.");
oFile.Close();

Categories