Skip to content

Commit ccfa980

Browse files
committed
first commit
0 parents  commit ccfa980

11 files changed

+316
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.xdc
2+
*~

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Test Webxdc Tool
2+
3+
A little webxdc tool to test webxdc-interpreter implementations.

create-xdc.sh

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
3+
case "$1" in
4+
"-h" | "--help")
5+
echo "usage: ${0##*/} [PACKAGE_NAME]"
6+
exit
7+
;;
8+
"")
9+
PACKAGE_NAME=${PWD##*/} # '##*/' removes everything before the last slash and the last slash
10+
;;
11+
*)
12+
PACKAGE_NAME=${1%.xdc} # '%.xdc' removes the extension and allows PACKAGE_NAME to be given with or without extension
13+
;;
14+
esac
15+
16+
rm "$PACKAGE_NAME.xdc" 2> /dev/null
17+
zip -9 --recurse-paths "$PACKAGE_NAME.xdc" * --exclude README.md webxdc.js "*.sh" "*.xdc" "*~"
18+
19+
echo "success, archive contents:"
20+
unzip -l "$PACKAGE_NAME.xdc"
21+
22+
# check package size
23+
MAXSIZE=102400
24+
size=$(wc -c < "$PACKAGE_NAME.xdc")
25+
if [ $size -ge $MAXSIZE ]; then
26+
echo "WARNING: package size exceeded the limit ($size > $MAXSIZE)"
27+
fi

index.html

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
8+
<script src="webxdc.js"></script>
9+
<style>
10+
.red {
11+
color: red;
12+
}
13+
h1 {
14+
background-color: #415e6b;
15+
color: white;
16+
padding: 10px;
17+
}
18+
</style>
19+
</head>
20+
<body>
21+
<div id="races-output"></div>
22+
<script src="js/races.js"></script>
23+
24+
<div id="storage-output"></div>
25+
<script src="js/storage.js"></script>
26+
27+
<div id="uploads-output"></div>
28+
<script src="js/uploads.js"></script>
29+
30+
<div id="links-output">
31+
<h1>Links</h1>
32+
<ul>
33+
<li><a href="https://delta.chat">Normal link: https://delta.chat</a></li>
34+
<li><a href="mailto:[email protected]?body=test+message">Mailto link</a></li>
35+
<li><a href="OPENPGP4FPR:571E6FDC22C1605512A1B0C8F7AC9331B82AFB5B#a=delta%40example.org&n=TestContact&i=pHMb3fRw-JV&s=VcWU-pQSEeB">QR verification link</a></li>
36+
<li><a href="cabal://cabal.chat">Custom scheme link</a></li>
37+
<li><a href="./page.html">Link to an internal HTML page</a></li>
38+
</ul>
39+
<hr>
40+
</div>
41+
42+
<!-- debugging -->
43+
<script src="js/eruda.min.js"></script>
44+
<script>window.addEventListener("load", () => eruda.init());</script>
45+
</body>
46+
</html>

js/eruda.min.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/races.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function reloadWidth() {
2+
document.getElementById("races-width").innerHTML = "window.innerWidth = " + window.innerWidth;
3+
}
4+
5+
window.addEventListener("load", () => {
6+
var output = document.getElementById("races-output");
7+
output.innerHTML = "<h1>innerWidth</h1>";
8+
output.innerHTML += '<span id="races-width"><strong>On Load:</strong> window.innerWidth = ' + window.innerWidth + "</span>";
9+
output.innerHTML += ' <button onclick="reloadWidth()">Refresh</button>'
10+
output.innerHTML += "<hr>";
11+
});
12+
13+
window.addEventListener("resize", () => {
14+
console.log("[innerWidth] window size changed: window.innerWidth = " + window.innerWidth);
15+
});

js/storage.js

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
function isStorageSupported(storageType) {
2+
var testKey = "__test__";
3+
4+
try {
5+
var storage = (storageType === "localStorage")? window.localStorage : window.sessionStorage;
6+
storage.setItem(testKey, "1");
7+
storage.removeItem(testKey);
8+
return true;
9+
} catch (error) {
10+
return false;
11+
}
12+
}
13+
14+
function testStorage(output, storageType) {
15+
var storage = (storageType === "localStorage")? window.localStorage : window.sessionStorage;
16+
output.innerHTML += "<h2>" + storageType + "</h2>";
17+
if (isStorageSupported(storageType)) {
18+
var counterKey = storageType + "_storageCounter";
19+
var count = parseInt(storage.getItem(counterKey) || 0) + 1;
20+
var counter = document.createElement("span");
21+
counter.id = storageType + "-counter";
22+
counter.innerHTML = count;
23+
24+
output.innerHTML += "Counter: ";
25+
output.append(counter);
26+
storage.setItem(counterKey, count);
27+
window.addEventListener('storage', (event) => {
28+
console.log("[Storage] WARNING: got a new event: " + event.key + "=" + JSON.stringify(event.newValue));
29+
if (event.key === counterKey) {
30+
document.getElementById(counter.id).innerHTML = event.newValue;
31+
}
32+
});
33+
} else {
34+
output.innerHTML += "<strong class=\"red\">WARNING: </strong>" + storageType + " is not supported.";
35+
}
36+
}
37+
38+
function testIndexedDB(output) {
39+
output.innerHTML += "<h2>indexedDB</h2>";
40+
var div = document.createElement("div");
41+
div.id = "indexeddb-counter";
42+
output.append(div);
43+
44+
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
45+
if (indexedDB) {
46+
var open = indexedDB.open("__testDatabase", 1);
47+
48+
open.onupgradeneeded = function () {
49+
var db = open.result;
50+
var store = db.createObjectStore("MyObjectStore", {keyPath: "id"});
51+
store.createIndex("NameIndex", ["counter"]);
52+
};
53+
54+
open.onsuccess = function () {
55+
var db = open.result;
56+
var tx = db.transaction("MyObjectStore", "readwrite");
57+
var store = tx.objectStore("MyObjectStore");
58+
59+
var getter = store.get(12345);
60+
61+
getter.onsuccess = function () {
62+
var cnt = 0;
63+
if (typeof getter.result == "undefined") {
64+
cnt = 1;
65+
} else {
66+
cnt = parseInt(getter.result.counter) + 1;
67+
}
68+
document.getElementById("indexeddb-counter").innerHTML = "Counter: " + cnt;
69+
store.put({id: 12345, counter: cnt});
70+
};
71+
72+
tx.oncomplete = function () {
73+
db.close();
74+
};
75+
}
76+
} else {
77+
div.innerHTML = "<strong class=\"red\">WARNING: </strong>IndexDB not available.";
78+
}
79+
}
80+
81+
window.addEventListener("load", () => {
82+
var output = document.getElementById("storage-output");
83+
output.innerHTML = "<h1>Storage</h1>";
84+
85+
testStorage(output, "localStorage");
86+
testStorage(output, "sessionStorage");
87+
testIndexedDB(output);
88+
output.innerHTML += "<hr>";
89+
});

js/uploads.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
window.addEventListener("load", () => {
2+
var output = document.getElementById("uploads-output");
3+
output.innerHTML = "<h1>Uploads</h1>";
4+
5+
var input = document.createElement('input');
6+
input.type = 'file';
7+
8+
output.append(input);
9+
output.innerHTML += "<hr>";
10+
});

manifest.toml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
name = "Test Webxdc"

page.html

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
</head>
6+
<body>
7+
<h2><a href="./index.html">« Go Back</a></h2>
8+
</body>
9+
</html>

webxdc.js

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// debug friend: document.writeln(JSON.stringify(value));
2+
//@ts-check
3+
/** @type {import('./webxdc').Webxdc<any>} */
4+
window.webxdc = (() => {
5+
var updateListener = (_) => {};
6+
var updatesKey = "__xdcUpdatesKey__";
7+
window.addEventListener('storage', (event) => {
8+
if (event.key == null) {
9+
window.location.reload();
10+
} else if (event.key === updatesKey) {
11+
var updates = JSON.parse(event.newValue);
12+
var update = updates[updates.length-1];
13+
update.max_serial = updates.length;
14+
console.log("[Webxdc] " + JSON.stringify(update));
15+
updateListener(update);
16+
}
17+
});
18+
19+
function getUpdates() {
20+
var updatesJSON = window.localStorage.getItem(updatesKey);
21+
return updatesJSON ? JSON.parse(updatesJSON) : [];
22+
}
23+
24+
var params = new URLSearchParams(window.location.hash.substr(1));
25+
return {
26+
selfAddr: params.get("addr") || "[email protected]",
27+
selfName: params.get("name") || "device0",
28+
setUpdateListener: (cb, serial) => {
29+
var updates = getUpdates();
30+
var maxSerial = updates.length;
31+
updates.forEach((update) => {
32+
if (update.serial > serial) {
33+
update.max_serial = maxSerial;
34+
cb(update);
35+
}
36+
});
37+
updateListener = cb;
38+
},
39+
getAllUpdates: () => {
40+
console.log('[Webxdc] WARNING: getAllUpdates() is deprecated.');
41+
return Promise.resolve([]);
42+
},
43+
sendUpdate: (update, description) => {
44+
var updates = getUpdates();
45+
var serial = updates.length + 1;
46+
var _update = {payload: update.payload, summary: update.summary, info: update.info, serial: serial};
47+
updates.push(_update);
48+
window.localStorage.setItem(updatesKey, JSON.stringify(updates));
49+
_update.max_serial = serial;
50+
console.log('[Webxdc] description="' + description + '", ' + JSON.stringify(_update));
51+
updateListener(_update);
52+
},
53+
};
54+
})();
55+
56+
window.addXdcPeer = () => {
57+
var loc = window.location;
58+
// get next peer ID
59+
var params = new URLSearchParams(loc.hash.substr(1));
60+
var peerId = Number(params.get("next_peer")) || 1;
61+
62+
// open a new window
63+
var peerName = "device" + peerId;
64+
var url = loc.protocol + "//" + loc.host + loc.pathname + "#name=" + peerName + "&addr=" + peerName + "@local.host";
65+
window.open(url);
66+
67+
// update next peer ID
68+
params.set("next_peer", String(peerId + 1));
69+
window.location.hash = "#" + params.toString();
70+
}
71+
72+
window.clearXdcStorage = () => {
73+
window.localStorage.clear();
74+
window.location.reload();
75+
}
76+
77+
window.alterXdcApp = () => {
78+
var styleControlPanel = 'position: fixed; bottom:1em; left:1em; background-color: #000; opacity:0.8; padding:.5em; font-family: sans-serif; color:#fff; z-index: 9999';
79+
var styleMenuLink = 'color:#fff; text-decoration: none; vertical-align: middle';
80+
var styleAppIcon = 'height: 1.5em; width: 1.5em; margin-right: 0.5em; border-radius:10%; vertical-align: middle';
81+
var title = document.getElementsByTagName('title')[0];
82+
if (typeof title == 'undefined') {
83+
title = document.createElement('title');
84+
document.getElementsByTagName('head')[0].append(title);
85+
}
86+
title.innerText = window.webxdc.selfAddr;
87+
88+
if (window.webxdc.selfName === "device0") {
89+
var div = document.createElement('div');
90+
div.innerHTML =
91+
'<div style="' + styleControlPanel + '">' +
92+
'<a href="javascript:window.addXdcPeer();" style="' + styleMenuLink + '">Add Peer</a>' +
93+
'<span style="' + styleMenuLink + '"> | </span>' +
94+
'<a href="javascript:window.clearXdcStorage();" style="' + styleMenuLink + '">Clear Storage</a>' +
95+
'<div>';
96+
var controlPanel = div.firstChild;
97+
98+
function loadIcon(name) {
99+
var tester = new Image();
100+
tester.onload = () => {
101+
div.innerHTML = '<img src="' + name + '" style="' + styleAppIcon +'">';
102+
controlPanel.insertBefore(div.firstChild, controlPanel.firstChild);
103+
};
104+
tester.src = name;
105+
}
106+
loadIcon("icon.png");
107+
loadIcon("icon.jpg");
108+
109+
document.getElementsByTagName('body')[0].append(controlPanel);
110+
}
111+
}
112+
113+
window.addEventListener("load", window.alterXdcApp);

0 commit comments

Comments
 (0)