<commit_before><commit_msg>add support for sending serial over window.postMessage<commit_after>/*
<NAME> (<EMAIL>)

If we're running in an iframe, this gets enabled and allows the IDE
to work by passing messages using window.postMessage.

Use embed.js on the client side to link this in.
*/

(function() {
  if (typeof window == "undefined" || typeof window.parent == undefined) return;
  console.log("Running in a frame - enabling frame messaging support");

  var callbacks = {
    connected : undefined,
    receive : undefined,
    disconnected : undefined,
    ports : undefined
  };

  var str2ab=function(str) {
    var buf=new ArrayBuffer(str.length);
    var bufView=new Uint8Array(buf);
    for (var i=0; i<str.length; i++) {
      var ch = str.charCodeAt(i);
      if (ch>=256) {
        console.warn("Attempted to send non-8 bit character - code "+ch);
        ch = "?".charCodeAt(0);
      }
      bufView[i] = ch;
    }
    return buf;
  };

  window.addEventListener('message', function(e) {
    var event = e.data;
    //console.log("IDE MESSAGE ---------------------------------------");
    //console.log(event);
    //console.log("-----------------------------------------------");
    if (typeof event!="object" || event.for!="ide") return;
    switch (event.type) {
      case "ports": if (callbacks.ports) {
        callbacks.ports(event.data);
        callbacks.ports = undefined;
      } break;
      case "connect":
        if (Espruino.Core.Serial.isConnected())
          console.error("serial_frame: already connected");

        Espruino.Core.MenuPortSelector.connectToPort(event.data, function() {
          console.log("serial_frame: connected");
        });
        break;
      case "connected": if (callbacks.connected) {
        callbacks.connected({ok:true});
        callbacks.connected = undefined;
      } break;
      case "disconnected": if (callbacks.disconnected) {
        callbacks.disconnected();
        callbacks.disconnected = undefined;
      } break;
      case "receive": if (callbacks.receive) {
        if (typeof event.data!="string")
          console.error("serial_frame: receive event expecting data string");
        callbacks.receive(str2ab(event.data));
      } break;
      default:
        console.error("Unknown event type ",event.type);
        break;
    }
  });

  function post(msg) {
    msg.from="ide";
    window.parent.postMessage(msg,"*");
  }

  Espruino.Core.Serial.devices.push({
    "name" : "window.postMessage",
    "init" : function() {
      post({type:"init"});
    },
    "getPorts": function(callback) {
      post({type:"getPorts"});
      var timeout = setTimeout(function() {
        timeout = undefined;
        callbacks.ports = undefined;
        callback([]);
        console.error("serial_frame: getPorts timeout");
      },100);
      callbacks.ports = function(d) {
        if (!timeout) {
          console.error("serial_frame: ports received after timeout");
          return;
        }
        clearTimeout(timeout);
        timeout = undefined;
        callback(d);
      };
    },
    "open": function(path, openCallback, receiveCallback, disconnectCallback) {
      callbacks.connected = openCallback;
      callbacks.receive = receiveCallback;
      callbacks.disconnected = disconnectCallback;
      post({type:"connect"});
    },
    "write": function(d, callback) {
      post({type:"write",data:d});
      setTimeout(callback,1); // for now just always call the callback
    },
    "close": function() {
      post({type:"disconnect"});
    },
  });
})();

{'fraction_non_alphanumeric': 0.16287559674248805, 'fraction_numerical': 0.0036506599269868017, 'mean_word_length': 2.454898157129001, 'pattern_counts': {'":': 9, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1834628', 'n_tokens_mistral': 1031, 'n_tokens_neox': 1010, 'n_words': 237}