Iframes
If your app is using iframes, you can add full support of the sos
JS API within the iframe, without bundling it with the iframe code. But
we recommend limiting the use of iframes inside your Applet to avoid performance hiccups.
The signageOS Snippet and API works ONLY if the iframe is served from the display's internal storage (e.g. saved by
sos.offline.cache.loadOrSaveFile()
). If your iframe is served from a live URL - <iframe src="https://your-iframe-url"...
the snippet and
signageOS API will NOT work. This is a security limitation to prevent random site took advantage of the API and alter the display
behavior. There is a simple way to
save and load your iframe from the internal storage.
Just make sure you are using full paths in your iframe for linking javascripts and css instead of the relative ones.
If your device cannot read a file stored in a local storage, such as html, you can try using an alternative method (instead of python) to zip the file when preparing the applet.
// applet
import sos from '@signageos/front-applet';
sos.onReady().then(async function () {
const contentElement = document.getElementById('index');
const iframeElement = document.getElementById('iframe');
const iframeUri =
sos.config.iframeUri ||
'https://raw.githubusercontent.com/signageos/applet-examples/master/examples/content-js-api/iframes/singlefile-applet/iframe.html';
const { filePath } = await sos.offline.cache.loadOrSaveFile('iframe.html', iframeUri);
contentElement.innerHTML = '';
iframeElement.src = filePath;
iframeElement.style.display = 'block';
});
This code will save an html page to the cache and creates a new iframe element with the saved filePath
.
To inject the sos
API into the iframe, add the snippet below to the iframe page, where the sos
API is used:
<!-- iframe.html -->
<script type="text/javascript">
// sOS JS API loader !function()
{
(window.addEventListener('message', function (t) {
if (t.source === window.parent && 'hug.api_js_uri' === t.data.type) {
var e = t.data.uri;
if (!e) throw new Error('Front applet JS is not set.');
var a = document.createElement('script');
a.setAttribute('type', 'text/javascript'),
a.setAttribute('src', e),
(a.onload = a.onreadystatechange =
function () {
(this.readyState && 'loaded' != this.readyState && 'complete' != this.readyState) ||
((window.sos.apiJsUri = t.data.uri),
window.dispatchEvent(new Event('hug.loaded')),
window.dispatchEvent(new Event('sos.loaded')));
}),
document.head.appendChild(a);
}
}),
window.parent.postMessage({ type: 'hug_loader.ready' }, '*'))
}
();
</script>
The snippet will inject the sos
API into the window
object and fires sos.loaded
event. When the event is fired, the sos
API is ready
to use.
// iframe.js
window.addEventListener('sos.loaded', async function () {
const contentElement = document.getElementById('index');
const videoArguments;
const videoUri = sos.config.videoUri || 'https://static.signageos.io/assets/video-test-1_e07fc21a7a72e3d33478243bd75d7743.mp4';
const { filePath } = sos.offline.cache.loadOrSaveFile('video.mp4', videoUri);
await sos.video.play(filePath, 0, 0, document.documentElement.clientWidth, document.documentElement.clientHeight);
});