Public
Snippet $168 authored by Tristan Cavelier

OfficeJS / OnlyOffice document pseudo code

example-gadget.js
function equalsN(a, b, n) {
  for (var i = 0; i < n; i += 1) if (a[i] !== b[i]) return false;
  return true;
}

// https://en.wikipedia.org/wiki/Zip_(file_format)
function isNonEmptyZip(byteArray) {
  return equalsN(byteArray, [0x50, 0x4B, 0x03, 0x04], 4);  // ~ startsWith("PK\x03\x04")
}
function isEmptyZip(byteArray) {
  return equalsN(byteArray, [0x50, 0x4B, 0x05, 0x06], 4);  // ~ startsWith("PK\x05\x06")
}
function isZip(byteArray) {
  return isNonEmptyZip(byteArray) || isEmptyZip(byteArray);
}

function isDocyBody(byteArray) {
  return equalsN(byteArray, [0x44, 0x4F, 0x43, 0x59, 0x3B, 0x76, 0x32, 0x3B], 8);  // ~ startsWith("DOCY;v2;")
}
function isXslyBody(byteArray) {
  return equalsN(byteArray, [0x58, 0x53, 0x4C, 0x59, 0x3B, 0x76, 0x32, 0x3B], 8);  // ~ startsWith("XSLY;v2;")
}
function isPptyBody(byteArray) {
  return equalsN(byteArray, [0x50, 0x50, 0x54, 0x59, 0x3B, 0x76, 0x32, 0x3B], 8);  // ~ startsWith("PPTY;v2;")
}
function isYFormatBody(byteArray) {
  return isDocyBody(byteArray) || isXslyBody(byteArray) || isPptyBody(byteArray);
}

function render(option) {
  var data = option.value;
  return new Queue()
    .push(function () {
      if (isZip(data)) {
        return new Queue()
          .push(function () {
            // https://stuk.github.io/jszip/
            return new JSZip().loadAsync(data);
          })
          .push(function (zip) {
            var root_file_name_list = zip.files.filter(function (name) {
              return !(/\//.test(name));
            });
            if (root_file_name_list.length > 1) {
              throw new Error("too many body files");
            }
            return zip.file(root_file_name_list[0] || "body.txt").async("string");
          })
          .push(function (bodyData) {
            ONLYOFFICEAPP.SETDATA(bodyData);
          })
          .push(function () {
            var media_file_name_list = zip.files.filter(function (name) {
              return (/^media\//).test(name);
            });
            // [...]
            return zip.file("media/image1.png").async("uint8array");
          })
          .push(function (imageData) {
            ONLYOFFICEAPP.SETMEDIA("image1", imageData);
          });
      } else if (isYFormatBody(data)) {
        ONLYOFFICEAPP.SETDATA(data);  // no images
      } else {
        throw new Error("unhandled data");
      }
    });
}