XUL:File Input
Jump to navigation
Jump to search
Here is a simple implementation of a file input control written in XBL. I tried returning a stream instead of a string from the inputText property, but the calling script didn't have the priviliges to call the readLine methods and such. Instead, I used an interface similar to XMLHttpRequest. Perhaps I should add a inputXML property.
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <binding id="fileinput"> <content> <xul:textbox flex="1" readonly="true"/> <xul:button label="Browse..."/> </content> <implementation> <constructor><![CDATA[ var textbox = document.getAnonymousNodes(this)[0]; var button = document.getAnonymousNodes(this)[1]; textbox.thefile = null;
var pickFunc = function pickFile() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, "Select a File", nsIFilePicker.modeOpen);
fp.appendFilters( nsIFilePicker.filterAll );
var res = fp.show();
if (res == nsIFilePicker.returnOK) {
textbox.thefile = fp.file;
textbox.value = textbox.thefile.path;
} else {
textbox.thefile = null;
textbox.value = "";
}
}
button.addEventListener("command", pickFunc, false);
]]></constructor>
<property name="inputText" readonly="true">
<getter><![CDATA[
var textbox = document.getAnonymousNodes(this)[0];
if (textbox.thefile != null) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance( Components.interfaces.nsIFileInputStream );
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
is.init( textbox.thefile, 0x01, 00004, null);
sstream.init(is);
var data = "";
var count = 0;
while (sstream.available() > 0) {
count = sstream.available();
if (count > 2048) {
count = 2048;
}
data += sstream.read(count);
}
return data;
} else {
return "";
}
]]></getter>
</property>
</implementation>
</binding>
</bindings>