/* globals cloneInto, createObjectIn, exportFunction, unsafeWindow */
"use strict";

const DEFAULT_TIMEOUT_SECONDS = 30;

console.info("insidePage");

var callbackId = 0;
var callbacks = {};
function sendToChrome(type, requests, callback, timeout) {
  var origin = document.location.origin;
  var id = callbackId;
  callbacks[callbackId++] = callback;
  setTimeout(function() {
    if (id in callbacks) {
      callback({errorCode: 5});
    }
    delete callbacks[id];
  }, 1000 * (timeout || DEFAULT_TIMEOUT_SECONDS));

  self.port.once(type + "Response", function(id, response) {
    var value = cloneInto({id: id, response: response}, document.defaultView);

    try {
      if (id in callbacks) {
        callbacks[id].call(null, value.response);
      }
      delete callbacks[id];
    } catch (ex) {
      console.info(ex + "");
    }
  });

  self.port.emit(type, requests, id, origin);
}

function register(requests, signRequests, callback, timeout) {
  sendToChrome("register", requests, callback, timeout);
}

function sign(signRequests, callback, timeout) {
  sendToChrome("sign", signRequests, callback, timeout);
}

var u2fonpage = createObjectIn(unsafeWindow, {defineAs: "u2f"});
exportFunction(register, u2fonpage, {defineAs: "register"});
exportFunction(sign, u2fonpage, {defineAs: "sign"});

Object.freeze(u2fonpage);

@@ -148,25 +148,29 @@
 );%0A%0Avar 
-c
+nextC
 allbackI
 d = 0;%0Av
@@ -165,34 +165,15 @@
 ackI
-d
+D
  = 0;%0A
-var callbacks = %7B%7D;
 %0Afun
@@ -278,13 +278,8 @@
  var
- id =
  cal
@@ -288,32 +288,25 @@
 ackI
-d;%0A  callbacks%5Bc
+D = nextC
 allbackI
 d++%5D
@@ -305,26 +305,26 @@
 ackI
-d++%5D = callback;%0A 
+D++;%0A  var timer =
  set
@@ -352,93 +352,32 @@
     
-if (id in callbacks) %7B%0A      callback(%7BerrorCode: 5%7D);%0A    %7D%0A    delete callbacks%5Bid%5D
+callback(%7BerrorCode: 5%7D)
 ;%0A  
@@ -444,10 +444,8 @@
 t.on
-ce
 (typ
@@ -468,16 +468,27 @@
 function
+ onResponse
 (id, res
@@ -504,207 +504,290 @@
     
-var value = cloneInto(%7Bid: id, response: response%7D, document.defaultView);%0A%0A    try %7B%0A      if (id in callbacks) %7B%0A        callbacks%5Bid%5D.call(null, value.response);%0A      %7D%0A      delete callbacks%5Bid%5D
+if (id != callbackID %7C%7C !timer) %7B%0A      return;%0A    %7D%0A    self.port.removeListener(type + %22Response%22, onResponse);%0A    var value = cloneInto(%7Bid: id, response: response%7D, document.defaultView);%0A%0A    try %7B%0A      callback(value.response);%0A      clearTimeout(timer);%0A      timer = null
 ;%0A  
@@ -878,18 +878,26 @@
 quests, 
-id
+callbackID
 , origin

Remove global `callbacks` object