diff --git a/src/DOM.js b/src/DOM.js index 98bb744e11..44ee402199 100644 --- a/src/DOM.js +++ b/src/DOM.js @@ -2221,6 +2221,13 @@ class HTMLIFrameElement extends HTMLSrcableElement { onrequest(req) { parentPort.postMessage(req); }, + onxrmode(event) { + this.dispatchEvent(new CustomEvent('xrmode', { + detail: { + xr: event.xr, + }, + })); + }, onhapticpulse(event) { parentPort.postMessage({ method: 'emit', diff --git a/src/Document.js b/src/Document.js index 73b1e40519..71f1dc2e07 100644 --- a/src/Document.js +++ b/src/Document.js @@ -162,6 +162,14 @@ function initDocument (document, window) { } process.nextTick(async () => { + const _tryDispatchEvent = (target, event) => { + try { + target.dispatchEvent(event); + } catch(err) { + console.warn(err); + } + }; + if (body) { const bodyChildNodes = body.childNodes; body.childNodes = new window.NodeList(); @@ -173,7 +181,11 @@ function initDocument (document, window) { } body.childNodes = bodyChildNodes; - body._emit('children', Array.from(bodyChildNodes), [], null, null); + try { + body._emit('children', Array.from(bodyChildNodes), [], null, null); + } catch(err) { + console.warn(err); + } try { await GlobalContext._runHtml(document.body, window); @@ -182,9 +194,9 @@ function initDocument (document, window) { } document.readyState = 'interactive'; - document.dispatchEvent(new Event('readystatechange', {target: document})); + _tryDispatchEvent(document, new Event('readystatechange', {target: document})); - document.dispatchEvent(new Event('DOMContentLoaded', { + _tryDispatchEvent(document, new Event('DOMContentLoaded', { target: document, bubbles: true, })); @@ -196,19 +208,24 @@ function initDocument (document, window) { } document.readyState = 'interactive'; - document.dispatchEvent(new Event('readystatechange', {target: document})); + _tryDispatchEvent(document, new Event('readystatechange', {target: document})); - document.dispatchEvent(new Event('DOMContentLoaded', { + _tryDispatchEvent(document, new Event('DOMContentLoaded', { target: document, bubbles: true, })); } document.readyState = 'complete'; - document.dispatchEvent(new Event('readystatechange', {target: document})); + _tryDispatchEvent(document, new Event('readystatechange', {target: document})); document.dispatchEvent(new Event('load', {target: document})); - window.dispatchEvent(new Event('load', {target: window})); + _tryDispatchEvent(window, new Event('load', {target: window})); + + parentPort.postMessage({ + method: 'xrMode', + xr: GlobalContext.requestedXr, + }); }); return document; diff --git a/src/Window.js b/src/Window.js index e8ba3188c1..b21e22c484 100644 --- a/src/Window.js +++ b/src/Window.js @@ -103,6 +103,7 @@ GlobalContext.id = id; GlobalContext.args = args; GlobalContext.version = version; GlobalContext.baseUrl = options.baseUrl; +GlobalContext.requestedXr = false; const {_parseDocument, _parseDocumentAst, getBoundDocumentElements, DocumentType, DOMImplementation, initDocument} = require('./Document'); const { @@ -824,7 +825,12 @@ const _makeRequestAnimationFrame = window => (fn, priority = 0) => { return _parseDocumentAst(htmlAst, window, false); } }; - window.addEventListener = EventTarget.prototype.addEventListener.bind(window); + window.addEventListener = function(e, fn, opts) { + if (e === 'vrdisplayactivate') { + GlobalContext.requestedXr = true; + } + return EventTarget.prototype.addEventListener.apply(window, arguments); + }; window.removeEventListener = EventTarget.prototype.removeEventListener.bind(window); window.dispatchEvent = EventTarget.prototype.dispatchEvent.bind(window); window.Image = HTMLImageElement; @@ -1193,6 +1199,8 @@ const _makeRequestAnimationFrame = window => (fn, priority = 0) => { const _makeMrDisplays = () => { const _onrequestpresent = async () => { + GlobalContext.requestedXr = true; + // if (!GlobalContext.xrState.isPresenting[0]) { await new Promise((accept, reject) => { vrPresentState.responseAccepts.push(accept); diff --git a/src/WindowVm.js b/src/WindowVm.js index 8239be67e0..21f5c28127 100644 --- a/src/WindowVm.js +++ b/src/WindowVm.js @@ -194,6 +194,9 @@ const _makeWindow = (options = {}, handlers = {}) => { window.on('framebuffer', e => { window.framebuffer = e; }); + window.on('xrMode', e => { + options.onxrmode && options.onxrmode(e); + }); window.on('hapticPulse', e => { options.onhapticpulse && options.onhapticpulse(e); });