Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions _includes/combined.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<html>
<head>
<meta http-equiv="content-security-policy" content="default-src 'none' data: 'unsafe-inline'">

<!-- The credential data block injected into the Shim Code. -->
<script name="credential" type="application/vc">{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"type": [
"VerifiableCredential",
"NameCredential"
],
"issuer": {
"id": "did:example:1234",
"name": "The Issuer"
},
"credentialSubject": {
"name": "Example Name"
}
}</script>
<!-- End credential data block -->

</head>
<body>

<!-- The template HTML injected into the Shim Code. -->
<div>
<script>
console.log('running template render script');

// display credential as JSON as an example renderer; anything
// could be done here instead, including mustache/other-style
// template processing to generate the HTML for display

// FIXME: determine best name/location for the datablock/script tag
const credential = JSON.parse(document.querySelector(
'head > script[name="credential"]').innerHTML);

document.querySelector('#credentialSubject-name').innerText =
credential.credentialSubject.name;
document.querySelector('#issuer-name').innerText =
credential.issuer.name;

// TBD: signal to host that rendering is complete
window.renderMethodReady()
</script>
<style>
h1 {
color: blue;
}
</style>

<h1 id="credentialSubject-name"></h1>
<p>Issued by: <span id="issuer-name"></span></p>
</div>
<!-- End template HTML -->

</body>
</html>
41 changes: 41 additions & 0 deletions _includes/message-channel-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// a promise that resolves when the rendering is ready (or rejects if it
// fails); can be used to show the display or an error instead
let resolveRender;
let rejectRender;
const readyPromise = new Promise((resolve, reject) => {
resolveRender = resolve;
rejectRender = reject;
});

// Setup communication channel for use by the template code in the iframe
renderer.onload = () => {
// create a MessageChannel; transfer one port to the iframe
const channel = new MessageChannel();
// start message queue so messages won't be lost while iframe loads
channel.port1.start();
// handle `ready` message
channel.port1.onmessage = function ready(event) {
if(event.data === 'ready') {
// unhide the iframe because it's ready
resolveRender();
} else {
rejectRender(new Error(event.data?.error?.message));
}
channel.port1.onmessage = undefined;
};
// send "start" message; send `port2` to iframe for return communication
renderer.contentWindow.postMessage('start', '*', [channel.port2]);
};

// setup event responses to ready or error
// NOTE: this section is idiosyncratic to the Wallet/Renderer's UX needs
readyPromise.then(() => {
console.log('rendering ready');
const renderer = document.getElementById('renderer');
renderer.hidden = false;
}).catch(err => {
const errorMessage = document.getElementById('error-message');
errorMessage.style.display = 'block';
errorMessage.innerText = 'Rendering failed: ' + err.message;
console.error('rendering failed', err);
});
8 changes: 8 additions & 0 deletions _includes/minimal-host-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<html>
<head>
<meta http-equiv="content-security-policy" content="frame-src 'none'">
</head>
<body>
<iframe id="renderer" sandbox="allow-scripts allow-modals" srcdoc=""></iframe>
</body>
</html>
18 changes: 18 additions & 0 deletions _includes/render-method-ready-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// add promise that will resolve to the communication port from
// the parent window
const portPromise = new Promise(resolve => {
window.addEventListener('message', function start(event) {
if(event.data === 'start' && event.ports?.[0]) {
window.removeEventListener('message', start);
resolve(event.ports[0]);
}
});
});

// attach a function to the window for the template to call when
// it's "ready" (or that an error occurred) that will send a message
// to the parent so the parent can decide whether to show the iframe
window.renderMethodReady = function(err) {
portPromise.then(port => port.postMessage(
!err ? 'ready' : {error: {message: err.message}}));
};
7 changes: 7 additions & 0 deletions _includes/shim-code.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<html>
<head>
<meta http-equiv="content-security-policy" content="default-src 'none' data: 'unsafe-inline'">
<script name="credential" type="application/vc">${JSON.stringify(credential)}</script>
</head>
<body>${template}</body>
</html>
29 changes: 29 additions & 0 deletions _includes/template-fragment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div>
<script>
console.log('running template render script');

// display credential as JSON as an example renderer; anything
// could be done here instead, including mustache/other-style
// template processing to generate the HTML for display

// FIXME: determine best name/location for the datablock/script tag
const credential = JSON.parse(document.querySelector(
'head > script[name="credential"]').innerHTML);

document.querySelector('#credentialSubject-name').innerText =
credential.credentialSubject.name;
document.querySelector('#issuer-name').innerText =
credential.issuer.name;

// TBD: signal to host that rendering is complete
window.renderMethodReady()
</script>
<style>
h1 {
color: blue;
}
</style>

<h1 id="credentialSubject-name"></h1>
<p>Issued by: <span id="issuer-name"></span></p>
</div>
Loading