tabris-js icon indicating copy to clipboard operation
tabris-js copied to clipboard

Support atob and btoa

Open trevorwat opened this issue 9 years ago • 7 comments

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);
  });

}

trevorwat avatar Jun 22 '16 09:06 trevorwat

Thanks for your feedback. We are currently in the progress of extending TypedArray support on iOS. Please stay tuned for that.

mpost avatar Jun 22 '16 13:06 mpost

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.

patrykmol avatar Jun 28 '16 13:06 patrykmol

We can provide a fix in our iOS implementation in the mean time, probably in the next couple of days.

jkrause avatar Jun 30 '16 14:06 jkrause

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

jkrause avatar Jun 30 '16 16:06 jkrause

The functions atob and atob should be available in the global JS context. The implementations are small, so we should include shims.

ralfstx avatar Jun 14 '17 14:06 ralfstx

The functions are available in iOS as can be seen here: https://caniuse.com/#search=btoa

Closing as "no action needed".

mpost avatar Jun 18 '18 12:06 mpost

This issue was closed by mistake (see https://github.com/eclipsesource/tabris-js/issues/2071). Reopening.

cpetrov avatar Oct 25 '21 15:10 cpetrov