tabris-js
tabris-js copied to clipboard
Support atob and btoa
Hi, While using the cordova-plugin-file I have found an inconsistency between IOS and Android. Android reads binary files as array buffer's fine, but IOS does not (I'll then be using JPEGJS to decode it into ImageData and write it to a canvas.. this works ok on Android but I can't read in the binary image data in IOS).
Here's some sample code that works in the scratchpad to illustrate the problem... it extends the file browser to allow reading image (png files as I the demo app has some easy to find png's we can use) and just outputs to the console when it has worked.
var currentDirectory;
tabris.create("Page", {
title: "Using the Cordova file plugin...",
topLevel: true,
background: "#fff"
}).once("appear", createExample).open();
function createExample(page) {
var rootDirMappings = [
{name: "cordova.file.applicationDirectory", value: cordova.file.applicationDirectory},
{name: "cordova.file.applicationStorageDirectory", value: cordova.file.applicationStorageDirectory}
];
var rootDirPickerLabel = tabris.create("TextView", {
layoutData: {left: 16, top: 8, right: 16},
text: "Cordova Filesystem Entry Point",
textColor: "#000088"
}).appendTo(page);
var rootDirPicker = tabris.create("Picker", {
layoutData: {left: 16, top: [rootDirPickerLabel, 0], height: 48, right: 16},
items: rootDirMappings.map(function(item) {return item.name;}),
selectionIndex: 0
}).appendTo(page);
var urlBar = tabris.create("Composite", {
layoutData: {left: 0, right: 0, top: [rootDirPicker, 0], height: 48},
}).appendTo(page);
var currentDirectoryView = tabris.create("TextInput", {
layoutData: {left: 16, top: 0, right: [0, 80]},
font: "16px",
editable: false,
autoCorrect: false,
text: currentDirectory
}).appendTo(urlBar);
var upButton = tabris.create("Button", {
layoutData: {left: [currentDirectoryView, 16], right: 16, top: 0},
text: "Up",
enabled: false
}).appendTo(urlBar);
var scrollView = tabris.create("ScrollView", {
direction: "vertical",
layoutData: {left: 0, top: [urlBar, 16], right: 0, bottom: 0}
}).appendTo(page);
var success = function(param) {
console.log("using directory:\n" + JSON.stringify(param));
var directoryReader = param.createReader();
console.log("directoryReader:\n" + JSON.stringify(directoryReader));
directoryReader.readEntries(function(result) {
result.forEach(function (entry) {
var row = tabris.create("Composite", {
layoutData: {left: 0, right: 0, top: ["prev()", 1], height: 72},
background: "#ddd"
}).appendTo(scrollView);
var dirEntryView = tabris.create("TextView", {
layoutData: {left: 16, right: 16, centerY: 0},
font: "10px",
text: entry.fullPath,
markupEnabled: true
}).appendTo(row);
if(entry.isDirectory) {
dirEntryView.set("font", "bold 12px");
dirEntryView.set("textColor", "blue");
dirEntryView.on("tap", function() {
console.log("tapped: " + entry.fullPath);
changeDir(entry.nativeURL);
});
}
if(entry.fullPath.indexOf(".png") != -1) {
dirEntryView.set("font", "bold 12px");
dirEntryView.set("textColor", "green");
dirEntryView.on("tap", function() {
console.log("tapped: " + entry.fullPath);
entry.file(function (entry) {
var reader = new FileReader();
reader.onloadend = function (e) {
console.log("file reading ended", this);
console.log(this.result);
//android reaches here and has the binary file data.. IOS does not
};
console.log("file reading about to start", this);
reader.readAsArrayBuffer(entry);
// IOS fails to in here with "can't find variable atob" .. Android works ok
console.log("file reading about to started", this);
}, console.log("erre", entry));
});
}
});
});
};
var error = function(param) {console.log('== error \"' + param + '\"');};
function changeDir(dir) {
currentDirectory = dir;
console.log("====\nCURRENT DIRECTORY:\n" + currentDirectory);
currentDirectoryView.set("text", currentDirectory);
scrollView.children().dispose();
window.resolveLocalFileSystemURL(currentDirectory, success, error);
}
rootDirPicker.on("select", function(picker, selection, options) {
changeDir(rootDirMappings[options.index].value);
});
}
Thanks for your feedback. We are currently in the progress of extending TypedArray support on iOS. Please stay tuned for that.
Hello. There is an issue in JavaScriptCore engine (that is WebKit) https://bugs.webkit.org/show_bug.cgi?id=158576. It has been closed recently but there is no telling when they merge it and release it. I would file an issue in Cordova bug tracker. Closing for now.
We can provide a fix in our iOS implementation in the mean time, probably in the next couple of days.
A workaround for you until we support atob, btoa on iOS is to include a dependency to base64 in your package.json
"dependencies": {
"tabris": "1.8.0",
"Base64": "^0.3.0"
}
and require it before using the file plugin, e.g. like this:
if(device.platform === "iOS") {
var base64 = require('base64');
global.btoa = base64.btoa;
global.atob = base64.atob;
}
See also
The functions atob and atob should be available in the global JS context. The implementations are small, so we should include shims.
The functions are available in iOS as can be seen here: https://caniuse.com/#search=btoa
Closing as "no action needed".
This issue was closed by mistake (see https://github.com/eclipsesource/tabris-js/issues/2071). Reopening.