-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshim.html
More file actions
131 lines (106 loc) · 4.49 KB
/
shim.html
File metadata and controls
131 lines (106 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<!DOCTYPE html>
<html>
<head>
<title>The FOTR Shim</title>
<meta charset="UTF-8">
<script type="text/javascript">
const loaderUtilities = { //This is exactly the same between shim.html and shim.js.
domReady: new Promise((resolve, reject)=>{
if(document.readyState === "loading"){
document.addEventListener('DOMContentLoaded', resolve);
}
else{
resolve();
} // add error handler?
}),
origin: (uri)=>{
const parser = window.document.createElement('a');
parser.href = uri;
return `${parser.protocol}//${parser.host}`;
},
loadTool: (uri)=>{
return new Promise((resolve, reject)=>{
const tag = window.document.createElement('iframe');
tag.src = uri;
tag.width = 0;
tag.height = 0;
tag.style = "visibility: hidden";
window.addEventListener("message",
(e)=>{
if(e.origin == loaderUtilities.origin(uri)){ //is it possible to refine the origin check?
resolve(e.data);
}
},
false);
loaderUtilities.domReady.then(()=>{
document.body.appendChild(tag);
});
}); // add error handler?
},
requestOverPort: (port, resource)=>{
return new Promise((resolve, reject)=>{
const disposableChannel = new MessageChannel();
disposableChannel.port1.onmessage = (e)=>{
resolve(e.data);
disposableChannel.port1.close();
};
port.postMessage(
{
resource: resource,
port: disposableChannel.port2
},
[disposableChannel.port2]);
});
},
};
const indexedDBPromise = (request)=>{
return new Promise(
(resolve, reject)=>{
request.onsuccess = (e)=>{
resolve(e.target.result);
};
request.onerror = (e)=>{
reject(e.target.error);
};
});
};
const defaultClient = window.location.href.split('#')[1] || '';
const objectStoreName = "chosen_clients";
const openDB = window.indexedDB.open("FOTR", 1);
openDB.onupgradeneeded = (e)=>{
e.target.result.createObjectStore(objectStoreName);
};
indexedDBPromise(openDB)
.then(
(db)=>{
const tx = db.transaction(objectStoreName, "readonly");
tx.oncomplete = ()=>{
db.close();
};
return indexedDBPromise(tx.objectStore(objectStoreName).getAll());
})//handle open-db error?
.then(
(db_result)=>{
const clientURI = db_result.uri || defaultClient;
return loaderUtilities.loadTool(clientURI);
})//handle db-read error?
.then(
(innerPort)=>{
const outerChannel = new MessageChannel();
outerChannel.port1.onmessage = (e)=>{
const newPort = e.data.port;
const request = e.data.resource;
console.log(`Forwarding request for [${request.method}]${request.url}.`);
loaderUtilities.requestOverPort(innerPort, request)
.then((response)=>{
console.log(`Forwarding requested value "${response}" for [${request.method}]${request.url}`);
newPort.postMessage(response);
newPort.close();
});
};
window.parent.postMessage(outerChannel.port2, '*', [outerChannel.port2]);
});//handle tool-load error?
</script>
</head>
<body</body>
</html>