Accessing file system using javascript in firefox or chrome? - javascript

I had been able to do this up until Firefox 15 using:
netscape.security.privilegeManager.enablePrivilege("UniversalXPConnect")
and setting the signed.applets.codebase_principal_support option to true. Unfortunately as of FF 17 this functionality has been removed. From what I understand Chrome has been the same way for some time now.
Does anyone know if there has been a Firefox or Chrome extension created that allows for the use of enablePrivilege? If not, recommendations on where to start if building my own?

File API, the reason those have stopped working is because both have now implemented the html5 file api.
Here is a html5 demo of the api.
Here is the relevant script in case they remove the demo:
<script>
var holder = document.getElementById('holder'),
state = document.getElementById('status');
if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'File API & FileReader available';
}
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
console.log(event.target);
holder.style.background = 'url(' + event.target.result + ') no-repeat center';
};
console.log(file);
reader.readAsDataURL(file);
return false;
};
</script>
As a note: if you need to access a file on your local machine in chrome you need to run the program using this switch --allow-file-access-from-files (for using a file input without it actually loading to the server, otherwise you get a xhr cross-domain error).
I don't know of the equivalent in firefox.

Related

Javascript inline script onchange not working

i'm having a problem on making my code to adjust to my web server, because of the security purposes, all inline javascript code to my html is not allowed.
everything is already okay i'm just having a hard time converting my other code to pure javascript
Here is my existing code,,,
<label class=qrcode-text-btn><input type=file accept="image/*" capture=environment id="openQRCamera" tabindex=-1></label>
the original code is this
<label class=qrcode-text-btn><input type=file accept="image/*" capture=environment onchange="openQRCamera(this);" tabindex=-1></label>
the onchange is not working because it is inline in the html.
this function needs to open a camera and detect if there is a qr that exists.
here is what i have now on converting it.
document.querySelector("#openQRCamera").addEventListener('onchange', (node) => {
var reader = new FileReader();
reader.onload = function() {
node.value = "";
qrcode.callback = function(res) {
if(res instanceof Error) {
alert("There is no QR detected");
} else {
node.parentNode.previousElementSibling.value = res;
}
};
qrcode.decode(reader.result);
};
reader.readAsDataURL(node.files[0]);
});
here is the original code
function openQRCamera(node) {
var reader = new FileReader();
reader.onload = function() {
node.value = "";
qrcode.callback = function(res) {
if(res instanceof Error) {
alert("There is no QR detected");
} else {
node.parentNode.previousElementSibling.value = res;
}
};
qrcode.decode(reader.result);
};
reader.readAsDataURL(node.files[0]);
}
i am using this website as my source of code, everything is working fine in my localhost, but the server is just strict, and i think that's normal for all the websites.
https://www.sitepoint.com/create-qr-code-reader-mobile-website/
i just been stuck and try to do other solution like adding event listener, and append of input just by using jquery, but it's not working. thanks in advance.
The event listener you are using is faulty, instead of listenning to 'onchange' you have to listen to 'change' like so:
document.querySelector("#openQRCamera").addEventListener('change', () => {
//remove the node as parameter and get it with javascript:
var node = document.getElementById('openQRCamera');
..

Is there a polyfill for link download with data uri?

I have some code should be generated by the server:
<a download="test.csv" href="data:text/plain;charset=utf-8;base64,w4FydsOtenTFsXLFkXTDvGvDtnJmw7p0w7Nnw6lwLg==">
teszt
</a>
It works with current chrome, firefox, opera. I'd like it to support MSIE11. Afaik msSaveBlob is the solution for that. Is there an existing js polyfill I could use, or should I write it?
Okay I made a simple polyfill based on the code I found in SO answers and here. I tested it on MSIE11, it works. It does not support file download with XHR, just data URIs. I recommend to use the Content-Disposition response header instead if you want to force file download. In my case the server just creates the file, but should not store it and I needed a HTML response as well, so this was the way to go. An alternative solution would be to send the file in email, but I found this one better by small files.
(function (){
addEvent(window, "load", function (){
if (isInternetExplorer())
polyfillDataUriDownload();
});
function polyfillDataUriDownload(){
var links = document.querySelectorAll('a[download], area[download]');
for (var index = 0, length = links.length; index<length; ++index) {
(function (link){
var dataUri = link.getAttribute("href");
var fileName = link.getAttribute("download");
if (dataUri.slice(0,5) != "data:")
throw new Error("The XHR part is not implemented here.");
addEvent(link, "click", function (event){
cancelEvent(event);
try {
var dataBlob = dataUriToBlob(dataUri);
forceBlobDownload(dataBlob, fileName);
} catch (e) {
alert(e)
}
});
})(links[index]);
}
}
function forceBlobDownload(dataBlob, fileName){
window.navigator.msSaveBlob(dataBlob, fileName);
}
function dataUriToBlob(dataUri) {
if (!(/base64/).test(dataUri))
throw new Error("Supports only base64 encoding.");
var parts = dataUri.split(/[:;,]/),
type = parts[1],
binData = atob(parts.pop()),
mx = binData.length,
uiArr = new Uint8Array(mx);
for(var i = 0; i<mx; ++i)
uiArr[i] = binData.charCodeAt(i);
return new Blob([uiArr], {type: type});
}
function addEvent(subject, type, listener){
if (window.addEventListener)
subject.addEventListener(type, listener, false);
else if (window.attachEvent)
subject.attachEvent("on" + type, listener);
}
function cancelEvent(event){
if (event.preventDefault)
event.preventDefault();
else
event.returnValue = false;
}
function isInternetExplorer(){
return /*#cc_on!#*/false || !!document.documentMode;
}
})();

NWJS updating progress bar during long loop javascript

I'm having some troubles with javascript.
I'm trying to do a desktop app with NW.JS. I have a .xml file which I drag and drop in my app then it run a function to read the XML do some stuff and save a new file in .csv
It's work fine but now i would be able to update a progress bar during the function...
I tried setInterval and setTimeOut() but I'mhaving always the same result : nothing append until the function is finished.
here is my code
//Same as $(document).ready();
function ready(fn) {
if (document.readyState != 'loading'){
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
//When the page has loaded, run this code
ready(function(){
// prevent default behavior from changing page on dropped file
window.ondragover = function(e) { e.preventDefault(); return false };
// NOTE: ondrop events WILL NOT WORK if you do not "preventDefault" in the ondragover event!!
window.ondrop = function(e) { e.preventDefault(); return false };
var holder = document.getElementById('holder');
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragleave = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
########I'm doing stuff here to convert file and i want to update the progressbar##########
};
reader.readAsText(file);
//reader.readAsDataURL(file);
return false;
};
});
Thanks for your help
best regards,
After trying the same code in NWJS and Electron, I found the problem to be that any long-running process in the 'main' Chromium process blocks rendering. The solution is to spawn a child process that communicates via Node's IPC. More details in this answer.

jQuery How to detect if file is being currently uploading (event is runing)

I written this code:
var fi = self.find('.file');
fi.on('change', function() {
if(fi.prop('files').length === 1) {
var file = fi.prop('files')[0],
name = file.name,
ext = name.split('.').pop().toLowerCase(),
size = (file.size / 1048576).toFixed(2),
type = file.type;
if($.inArray(ext, ['jpg', 'png', 'gif']) == -1) {
return false;
}
if($.inArray(type, ['image/jpeg', 'image/png', 'image/gif']) == -1) {
return false;
}
if(size > 1.2) {
return false;
}
ajax(createData(file));
return false;
}
return false;
});
I am allowing to upload only 1 file at the time ( from html side, js side and php side of view ), but with this script if user selects bigger size file, lets say 2+ MB and he is really fast clicker he can select another file and it creates second event and both files are being uploaded to the server which causes chaos and problems. Also i will be implementing drag and drop upload option so as a beginner javascript coder im asking the community if there is a way to:
Prevent from triggering script while file is being already uploaded ( i dont mean methods like hide input or diable it or take off event listener for a while, i mean method that detects if event is running and prevent executing script ). I tried things like default prevent or stop propagation but these dont work obviously.
Adding a button that will cancel on going script ( meaning stop file uploading and "clean it up" so user can safetly try again )
Thank you in advance for all your hints and guidance ;)
I worked on this recently for one of my side projects. Here's a code sample:
var fileReader = new FileReader();
var fileFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
var imageObject = { valid: false };
fileReader.onload = function (fileReaderEvent) {
imageObject.data = fileReaderEvent.target.result;
};
var loadImage = function() {
if (element[0].files.length === 0) {
return;
}
var file = element[0].files[0];
imageObject.filename = file.name;
if (!fileFilter.test(file.type)) {
imageObject.error = 'You must select a valid image!';
imageObject.valid = false;
return;
}else{
imageObject.error = '';
imageObject.valid = true;
}
fileReader.readAsDataURL(file);
};
element.on('change', loadImage);
}
This was from an AngularJS project so I've removed all the angular components but it should be pretty easy to add in the necessary JQuery code.

why is my save dialog not appearing chrome app

I am creating a HTML5 SVG editor for Chrome. As a packaged app, I implemented a save dialog using this code:
function prepareExport(){
var svg = document.getElementById("canvas");
svgDoc = svg.children;
var exported = document.querySelector('#canvasWrap').innerHTML;
/*old stuff, does not work in packed apps. well for me anyway
var output = document.querySelector(".opt");
var outputTextarea = document.querySelector(".optText");
output.style.display = "block";
outputTextarea.style.display = "none";
var dlButton = document.querySelector(".dragout");
dlButton.setAttribute("href" ,"data:image/xml+svg;base64," + window.btoa(exported));
dlButton.setAttribute("data-downloadurl" ,dlButton.dataset['downloadurl'] + window.btoa(exported));
dlButton.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('DownloadURL', this.dataset.downloadurl);
}, false);
*/
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry, unused) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
writer.write(new Blob([exported], {type: 'image/svg+xml'}));
}, errorHandler);
});
}
I ran this function using a button, Export SVG, and guess what? the dialog did not appear. I do not know why and this is my javascript console:
http://prntscr.com/1uklw7
This is probably a permission error. Have you added the write filesystem permission to your manifest? See http://developer.chrome.com/apps/fileSystem.html for details.
If that isn't the problem, you can get more details from chrome.lastError in your callback. See http://developer.chrome.com/apps/runtime.html#property-lastError for details of this.
Also you might want to check out the file system sample: https://github.com/GoogleChrome/chrome-app-samples/tree/master/filesystem-access.

Categories