From 0145a4b315ec14b8adf3e0bd1fdf13f82893efde Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Thu, 21 Sep 2023 13:07:01 +0200 Subject: [PATCH 01/15] auto-set css from step-property --- build/nodegame-window.js | 6 +++++- build/nodegame-window.min.js | 2 +- lib/GameWindow.js | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build/nodegame-window.js b/build/nodegame-window.js index 3624410..b643ea9 100644 --- a/build/nodegame-window.js +++ b/build/nodegame-window.js @@ -1860,6 +1860,7 @@ * - decrements the counter of loading iframes * - executes a given callback function * - auto parses the elements specified (if any) + * - updates UI, e.g., scroll-up or adds CSS * - set the window state as loaded (eventually) * * @param {function} func Optional. A callback function @@ -1882,7 +1883,7 @@ autoParsePrefix, scrollUp) { - var loaded, stageLevel; + var css, loaded, stageLevel; loaded = updateAreLoading(this, -1); if (loaded) this.setStateLevel('LOADED'); if (func) func.call(node.game); @@ -1891,6 +1892,9 @@ } if (scrollUp && window.scrollTo) window.scrollTo(0,0); + css = node.game.getProperty('css'); + if (css) W.cssRule(css); + // ng event emitter is not used. node.events.ee.game.emit('FRAME_LOADED'); node.events.ee.stage.emit('FRAME_LOADED'); diff --git a/build/nodegame-window.min.js b/build/nodegame-window.min.js index 2f06753..0c5883b 100644 --- a/build/nodegame-window.min.js +++ b/build/nodegame-window.min.js @@ -15,4 +15,4 @@ * * Depends on JSUS and nodegame-client. */ -(function(e,t){"use strict";function a(e,t){function r(){e.removeEventListener("load",r,!1),n.removeEventListener("load",r,!1),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.addEventListener("load",r,!1),n.addEventListener("load",r,!1)}function f(e,t){function r(i){var s;s=J.getIFrameDocument(e);if(i.type==="load"||s.readyState==="complete")e.detachEvent("onreadystatechange",r),n.detachEvent("onload",r),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.attachEvent("onreadystatechange",r),n.attachEvent("onload",r)}function l(e,t){W.isIE?f(e,t):a(e,t)}function c(){this.setStateLevel("UNINITIALIZED");if("undefined"==typeof e)throw new Error("GameWindow: no window found. Are you in a browser?");if("undefined"==typeof t)throw new Error("GameWindow: nodeGame not found");t.silly("node-window: loading..."),this.frameName=null,this.frameElement=null,this.frameWindow=null,this.frameDocument=null,this.frameRoot=null,this.headerElement=null,this.headerName=null,this.headerRoot=null,this.headerPosition=null,this.defaultHeaderPosition="top",this.conf={},this.uriChannel=null,this.areLoading=0,this.cacheSupported=null,this.directFrameDocumentAccess=null,this.cache={},this.currentURIs={},this.unprocessedUri=null,this.globalLibs=[],this.frameLibs={},this.uriPrefix=null,this.stateLevel=null,this.waitScreen=null,this.listenersAdded=null,this.screenState=t.constants.screenLevels.ACTIVE,this.styleElement=null,this.isIE=!!document.createElement("span").attachEvent,this.headerOffset=0,this.willResizeFrame=!1,this.addDefaultSetups(),this.addDefaultListeners(),setTimeout(function(){(function(e){e.length>=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f;a=m(this,-1),a&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),a?(f=t.game.getStageLevel(),f===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(t=arguments[1],n=arguments[2]);if("undefined"==typeof n)n="ng_replace_";else if(null===n)n="";else if("string"!=typeof n)throw new TypeError("GameWindow.searchReplace: prefix must be string, null or undefined. Found: "+n);e=arguments[0];if(J.isArray(e)){s=-1,i=e.length;for(;++sn.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l;f=m(this,-1),f&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),f?(l=t.game.getStageLevel(),l===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(t=arguments[1],n=arguments[2]);if("undefined"==typeof n)n="ng_replace_";else if(null===n)n="";else if("string"!=typeof n)throw new TypeError("GameWindow.searchReplace: prefix must be string, null or undefined. Found: "+n);e=arguments[0];if(J.isArray(e)){s=-1,i=e.length;for(;++sn.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a Date: Fri, 22 Sep 2023 12:45:37 +0200 Subject: [PATCH 02/15] Fix searchReplace --- lib/modules/extra.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/extra.js b/lib/modules/extra.js index f0558ff..ea00f46 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -410,7 +410,7 @@ } } - else if ('object' !== typeof elements) { + else if ('object' === typeof elements) { for (name in elements) { if (elements.hasOwnProperty(name)) { this.setInnerHTML(prefix + name, elements[name], mod); From 351d4dfb1374981b5d4e75639511b9f3f984126d Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Wed, 27 Sep 2023 11:22:55 +0200 Subject: [PATCH 03/15] refactor extra --- build/nodegame-window.js | 35 ++++++-- build/nodegame-window.min.js | 2 +- lib/modules/extra.js | 162 +++++++++++++++++++++-------------- 3 files changed, 128 insertions(+), 71 deletions(-) diff --git a/build/nodegame-window.js b/build/nodegame-window.js index b643ea9..af4d787 100644 --- a/build/nodegame-window.js +++ b/build/nodegame-window.js @@ -4093,10 +4093,11 @@ * * Returns the "screen" of the game * - * i.e. the innermost element inside which to display content + * i.e., the innermost element inside which to display content * * In the following order the screen can be: * + * - the element with id "container" (presumably inside the iframe) * - the body element of the iframe * - the document element of the iframe * - the body element of the document @@ -4106,9 +4107,12 @@ */ GameWindow.prototype.getScreen = function() { var el; - el = this.getFrameDocument(); - if (el) el = el.body || el; - else el = document.body || document.lastElementChild; + el = this.gid('container'); + if (!el) { + el = this.getFrameDocument(); + if (el) el = el.body || el; + else el = document.body || document.lastElementChild; + } return el; }; @@ -4451,7 +4455,7 @@ */ GameWindow.prototype.searchReplace = function() { var elements, mod, prefix; - var name, len, i; + var name, len, i, el, rep; if (arguments.length === 2) { mod = 'g'; @@ -4478,16 +4482,31 @@ if (J.isArray(elements)) { i = -1, len = elements.length; for ( ; ++i < len ; ) { - this.setInnerHTML(prefix + elements[i].search, + el = elements[i].search; + if ('string' !== typeof el && 'number' !== typeof el) { + continue; + } + rep = elements[i].replace; + if ('string' !== typeof rep && 'number' !== typeof rep) { + continue; + } + + this.setInnerHTML(prefix + el, elements[i].replace, elements[i].mod || mod); } } - else if ('object' !== typeof elements) { + else if ('object' === typeof elements) { for (name in elements) { if (elements.hasOwnProperty(name)) { - this.setInnerHTML(prefix + name, elements[name], mod); + el = elements[name]; + if ('string' !== typeof el && 'number' !== typeof el) { + node.warn('W.searchReplace: replace for key ' + name + + ' is invalid. Found: ' + el); + continue; + } + this.setInnerHTML(prefix + name, el, mod); } } } diff --git a/build/nodegame-window.min.js b/build/nodegame-window.min.js index 0c5883b..20e0cc8 100644 --- a/build/nodegame-window.min.js +++ b/build/nodegame-window.min.js @@ -15,4 +15,4 @@ * * Depends on JSUS and nodegame-client. */ -(function(e,t){"use strict";function a(e,t){function r(){e.removeEventListener("load",r,!1),n.removeEventListener("load",r,!1),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.addEventListener("load",r,!1),n.addEventListener("load",r,!1)}function f(e,t){function r(i){var s;s=J.getIFrameDocument(e);if(i.type==="load"||s.readyState==="complete")e.detachEvent("onreadystatechange",r),n.detachEvent("onload",r),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.attachEvent("onreadystatechange",r),n.attachEvent("onload",r)}function l(e,t){W.isIE?f(e,t):a(e,t)}function c(){this.setStateLevel("UNINITIALIZED");if("undefined"==typeof e)throw new Error("GameWindow: no window found. Are you in a browser?");if("undefined"==typeof t)throw new Error("GameWindow: nodeGame not found");t.silly("node-window: loading..."),this.frameName=null,this.frameElement=null,this.frameWindow=null,this.frameDocument=null,this.frameRoot=null,this.headerElement=null,this.headerName=null,this.headerRoot=null,this.headerPosition=null,this.defaultHeaderPosition="top",this.conf={},this.uriChannel=null,this.areLoading=0,this.cacheSupported=null,this.directFrameDocumentAccess=null,this.cache={},this.currentURIs={},this.unprocessedUri=null,this.globalLibs=[],this.frameLibs={},this.uriPrefix=null,this.stateLevel=null,this.waitScreen=null,this.listenersAdded=null,this.screenState=t.constants.screenLevels.ACTIVE,this.styleElement=null,this.isIE=!!document.createElement("span").attachEvent,this.headerOffset=0,this.willResizeFrame=!1,this.addDefaultSetups(),this.addDefaultListeners(),setTimeout(function(){(function(e){e.length>=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l;f=m(this,-1),f&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),f?(l=t.game.getStageLevel(),l===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(t=arguments[1],n=arguments[2]);if("undefined"==typeof n)n="ng_replace_";else if(null===n)n="";else if("string"!=typeof n)throw new TypeError("GameWindow.searchReplace: prefix must be string, null or undefined. Found: "+n);e=arguments[0];if(J.isArray(e)){s=-1,i=e.length;for(;++sn.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l;f=m(this,-1),f&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),f?(l=t.game.getStageLevel(),l===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError("GameWindow.searchReplace: prefix must be string, null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){o=-1,s=e.length;for(;++on.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a Date: Wed, 27 Sep 2023 11:45:24 +0200 Subject: [PATCH 04/15] extra refactor: cssRule in GameWindow --- lib/GameWindow.js | 36 +++- lib/modules/extra.js | 503 +++++++++++++++++++++++-------------------- 2 files changed, 307 insertions(+), 232 deletions(-) diff --git a/lib/GameWindow.js b/lib/GameWindow.js index 53f8653..40a185f 100644 --- a/lib/GameWindow.js +++ b/lib/GameWindow.js @@ -1,6 +1,6 @@ /** * # GameWindow - * Copyright(c) 2021 Stefano Balietti + * Copyright(c) 2023 Stefano Balietti * MIT Licensed * * API to interface nodeGame with the browser window @@ -2163,6 +2163,40 @@ }; + /** + * ### GameWindow.cssRule + * + * Add a css rule to the page + * + * @param {string} rule The css rule + * @param {boolean} clear Optional. TRUE to clear all previous rules + * added with this method to the page + * + * @return {Element} The HTML style element where the rules were added + * + * @see handleFrameLoad + */ + GameWindow.prototype.cssRule = function(rule, clear) { + var root; + if ('string' !== typeof rule) { + throw new TypeError(G + 'cssRule: style property must be ' + + 'string. Found: ' + rule); + } + if (!this.styleElement) { + root = W.getFrameDocument() || window.document; + this.styleElement = W.append('style', root.head, { + type: 'text/css', + id: 'ng_style' + }); + } + else if (clear) { + this.styleElement.innerHTML = ''; + } + this.styleElement.innerHTML += rule; + return this.styleElement; + }; + + // ## Helper functions /** diff --git a/lib/modules/extra.js b/lib/modules/extra.js index 7399f0a..65a830d 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -1,6 +1,6 @@ /** * # extra - * Copyright(c) 2022 Stefano Balietti + * Copyright(c) 2023 Stefano Balietti * MIT Licensed * * GameWindow extras @@ -16,6 +16,8 @@ var G = G + ''; + // ### BASIC. + /** * ### GameWindow.getScreen * @@ -45,38 +47,35 @@ }; /** - * ### GameWindow.cssRule + * ### GameWindow.uniqueId|generateUniqueId * - * Add a css rule to the page + * Generates a unique id * - * @param {string} rule The css rule - * @param {boolean} clear Optional. TRUE to clear all previous rules - * added with this method to the page + * Overrides JSUS.DOM.generateUniqueId. * - * @return {Element} The HTML style element where the rules were added + * @param {string} prefix Optional. The prefix to use * - * @see handleFrameLoad + * @return {string} The generated id + * + * @experimental + * TODO: it is not always working fine. */ - GameWindow.prototype.cssRule = function(rule, clear) { - var root; - if ('string' !== typeof rule) { - throw new TypeError(G + 'cssRule: style property must be ' + - 'string. Found: ' + rule); - } - if (!this.styleElement) { - root = W.getFrameDocument() || window.document; - this.styleElement = W.append('style', root.head, { - type: 'text/css', - id: 'ng_style' - }); - } - else if (clear) { - this.styleElement.innerHTML = ''; - } - this.styleElement.innerHTML += rule; - return this.styleElement; + GameWindow.prototype.uniqueId = + GameWindow.prototype.generateUniqueId = function(prefix) { + var id, found; + + id = '' + (prefix || J.randomInt(0, 1000)); + found = this.gid(id); + + while (found) { + id = '' + prefix + '_' + J.randomInt(0, 1000); + found = this.gid(id); + } + return id; }; + // ### WRITE TO SCREEN. + /** * ### GameWindow.write * @@ -90,6 +89,7 @@ * * @return {string|object} The content written * + * @see JSUS.write * @see GameWindow.writeln * @see getDefaultRoot */ @@ -111,6 +111,7 @@ * * @return {string|object} The content written * + * @see JSUS.writeln * @see GameWindow.write * @see getDefaultRoot */ @@ -120,214 +121,69 @@ }; /** - * ### GameWindow.generateUniqueId - * - * Generates a unique id - * - * Overrides JSUS.DOM.generateUniqueId. - * - * @param {string} prefix Optional. The prefix to use - * - * @return {string} The generated id - * - * @experimental - * TODO: it is not always working fine. - */ - GameWindow.prototype.generateUniqueId = function(prefix) { - var id, found; - - id = '' + (prefix || J.randomInt(0, 1000)); - found = this.gid(id); - - while (found) { - id = '' + prefix + '_' + J.randomInt(0, 1000); - found = this.gid(id); - } - return id; - }; - - /** - * ### GameWindow.toggleInputs - * - * Enables / disables the input forms - * - * If an id is provided, only input elements that are children - * of the element with the specified id are toggled. - * - * If id is not given, it toggles the input elements on the whole page, - * including the frame document, if found. - * - * If a state parameter is given, all the input forms will be either - * disabled or enabled (and not toggled). - * - * @param {string} id Optional. The id of the element container - * of the forms. Default: the whole page, including the frame document - * @param {boolean} disabled Optional. Forces all the inputs to be either - * disabled or enabled (not toggled) - * - * @return {boolean} FALSE, if the method could not be executed - * - * @see GameWindow.getFrameDocument - * @see toggleInputs - */ - GameWindow.prototype.toggleInputs = function(id, disabled) { - var container; - if (!document.getElementsByTagName) { - node.err(G + 'toggleInputs: getElementsByTagName not found'); - return false; - } - if (id && 'string' === typeof id) { - throw new Error(G + 'toggleInputs: id must be string or ' + - 'undefined. Found: ' + id); - } - if (id) { - container = this.gid(id); - if (!container) { - throw new Error(G + 'toggleInputs: no elements found with id ' + - id); - } - toggleInputs(disabled, container); - } - else { - // The whole page. - toggleInputs(disabled); - container = this.getFrameDocument(); - // If there is a frame, apply it there too. - if (container) toggleInputs(disabled, container); - } - return true; - }; - - /** - * ### GameWindow.getLoadingDots - * - * Creates and returns a span element with incrementing dots inside - * - * New dots are added every second until the limit is reached, then it - * starts from the beginning. - * - * Gives the impression of a loading time. - * - * @param {number} len Optional. The maximum length of the loading dots. - * Default: 5 - * @param {string} id Optional. The id of the span - * - * @return {object} An object containing two properties: the span element - * and a method stop, that clears the interval - */ - GameWindow.prototype.getLoadingDots = function(len, id) { - var spanDots, counter, intervalId; - if (len & len < 0) { - throw new Error(G + 'getLoadingDots: len cannot be < 0. Found: ' + - len); - } - spanDots = document.createElement('span'); - spanDots.id = id || 'span_dots'; - // Refreshing the dots... - counter = 0; - len = len || 5; - // So the height does not change. - spanDots.innerHTML = ' '; - intervalId = setInterval(function() { - if (counter < len) { - counter++; - spanDots.innerHTML = spanDots.innerHTML + '.'; - } - else { - counter = 0; - spanDots.innerHTML = '.'; - } - }, 1000); - - function stop() { - spanDots.innerHTML = '.'; - clearInterval(intervalId); - } - - return { - span: spanDots, - stop: stop - }; - }; - - /** - * ### GameWindow.addLoadingDots - * - * Appends _loading dots_ to an HTML element - * - * By invoking this method you lose access to the _stop_ function of the - * _loading dots_ element. - * - * @param {HTMLElement} root The element to which the loading dots will be - * appended - * @param {number} len Optional. The maximum length of the loading dots. - * Default: 5 - * @param {string} id Optional The id of the span - * - * @return {object} An object containing two properties: the span element - * and a method stop, that clears the interval - * - * @see GameWindow.getLoadingDots - */ - GameWindow.prototype.addLoadingDots = function(root, len, id) { - var ld; - ld = this.getLoadingDots(len, id); - root.appendChild(ld.span); - return ld; - }; - - /** - * ### GameWindow.getEventButton - * - * Creates an HTML button element that will emit an event when clicked - * - * @param {string} event The event to emit when clicked - * @param {string|object} attributes Optional. The attributes of the - * button, or if string the text to display inside the button. - * - * @return {Element} The newly created button - * - * @see GameWindow.get - */ - GameWindow.prototype.getEventButton = function(event, attributes) { - var b; - if ('string' !== typeof event) { - throw new TypeError(G + 'getEventButton: event must ' + - 'be string. Found: ' + event); - } - if ('string' === typeof attributes) { - attributes = { innerHTML: attributes }; - } - else if (!attributes) { - attributes = {}; - } - if (!attributes.innerHTML) attributes.innerHTML = event; - b = this.get('button', attributes); - b.onclick = function() { node.emit(event); }; - return b; + * ### DOM.sprintf + * + * Builds up a decorated HTML text element + * + * Performs string substitution from an args object where the first + * character of the key bears the following semantic: + * + * - '@': variable substitution with escaping + * - '!': variable substitution without variable escaping + * - '%': wraps a portion of string into a _span_ element to which is + * possible to associate a css class or id. Alternatively, + * it also possible to add in-line style. E.g.: + * + * ```javascript + * sprintf('%sImportant!%s An error has occurred: %pre@err%pre', { + * '%pre': { + * style: 'font-size: 12px; font-family: courier;' + * }, + * '%s': { + * id: 'myId', + * 'class': 'myClass', + * }, + * '@err': 'file not found', + * }, document.body); + * ``` + * + * Special span elements are %strong and %em, which add + * respectively a _strong_ and _em_ tag instead of the default + * _span_ tag. They cannot be styled. + * + * @param {string} string A text to transform + * @param {object} args Optional. An object containing string + * transformations + * @param {Element} root Optional. An HTML element to which append the + * string. Defaults, a new _span_ element + * + * @return {Element} The root element. + */ + GameWindow.prototype.sprintf = function(string, args, root) { + if (!root) root = getDefaultRoot(root, 'sprintf'); + return DOM.sprintf(string, args, root); }; /** - * ### GameWindow.addEventButton + * ### GameWindo.add|append * - * Adds an EventButton to the specified root element + * Creates and append an element with specified attributes to a root * - * @param {string} event The event to emit when clicked - * @param {Element} root Optional. The root element. Default: last element - * on the page - * @param {string|object} attributes Optional. The attributes of the - * button, or if string the text to display inside the button. + * @param {string} name The name of the HTML tag + * @param {HTMLElement} root The root element to which the new element + * will be appended + * @param {object|string} options Optional. Object containing + * attributes for the element and rules about how to insert it relative + * to root. Available options: insertAfter, insertBefore (default: + * child of root). If string, it is the id of the element. Examples: * - * @return {Element} The newly created button * - * @see GameWindow.get - * @see GameWindow.getEventButton + * @see getDefaultRoot */ - GameWindow.prototype.addEventButton = function(event, root, attributes) { - var eb; - eb = this.getEventButton(event, attributes); - if (!root) root = this.getScreen(); - return root.appendChild(eb); + GameWindow.prototype.add = + GameWindow.prototype.append = function(el, root, opts) { + if (!root) root = getDefaultRoot(root, 'add'); + return DOM.add(el, root, opts); }; /** @@ -433,12 +289,8 @@ }; - GameWindow.prototype.setInnerHTML = function(search, replace, mod) { - this.html(search, replace, mod); - }; - /** - * ### GameWindow.html + * ### GameWindow.html|setInnerHTML * * Replaces the innerHTML of the element with matching id or class name * @@ -451,6 +303,7 @@ * - 'className': replaces all elements with same class name * - 'g': replaces globally, both by id and className */ + GameWindow.prototype.setInnerHTML = GameWindow.prototype.html = function(search, replace, mod) { var el, i, len; @@ -503,6 +356,194 @@ } }; + // ### ADD STUFF: Event button, loading dots. + + /** + * ### GameWindow.getLoadingDots + * + * Creates and returns a span element with incrementing dots inside + * + * New dots are added every second until the limit is reached, then it + * starts from the beginning. + * + * Gives the impression of a loading time. + * + * @param {number} len Optional. The maximum length of the loading dots. + * Default: 5 + * @param {string} id Optional. The id of the span + * + * @return {object} An object containing two properties: the span element + * and a method stop, that clears the interval + */ + GameWindow.prototype.getLoadingDots = function(len, id) { + var spanDots, counter, intervalId; + if (len & len < 0) { + throw new Error(G + 'getLoadingDots: len cannot be < 0. Found: ' + + len); + } + spanDots = document.createElement('span'); + spanDots.id = id || 'span_dots'; + // Refreshing the dots... + counter = 0; + len = len || 5; + // So the height does not change. + spanDots.innerHTML = ' '; + intervalId = setInterval(function() { + if (counter < len) { + counter++; + spanDots.innerHTML = spanDots.innerHTML + '.'; + } + else { + counter = 0; + spanDots.innerHTML = '.'; + } + }, 1000); + + function stop() { + spanDots.innerHTML = '.'; + clearInterval(intervalId); + } + + return { + span: spanDots, + stop: stop + }; + }; + + /** + * ### GameWindow.addLoadingDots + * + * Appends _loading dots_ to an HTML element + * + * By invoking this method you lose access to the _stop_ function of the + * _loading dots_ element. + * + * @param {HTMLElement} root The element to which the loading dots will be + * appended + * @param {number} len Optional. The maximum length of the loading dots. + * Default: 5 + * @param {string} id Optional The id of the span + * + * @return {object} An object containing two properties: the span element + * and a method stop, that clears the interval + * + * @see GameWindow.getLoadingDots + */ + GameWindow.prototype.addLoadingDots = function(root, len, id) { + var ld; + ld = this.getLoadingDots(len, id); + root.appendChild(ld.span); + return ld; + }; + + /** + * ### GameWindow.getEventButton + * + * Creates an HTML button element that will emit an event when clicked + * + * @param {string} event The event to emit when clicked + * @param {string|object} attributes Optional. The attributes of the + * button, or if string the text to display inside the button. + * + * @return {Element} The newly created button + * + * @see GameWindow.get + */ + GameWindow.prototype.getEventButton = function(event, attributes) { + var b; + if ('string' !== typeof event) { + throw new TypeError(G + 'getEventButton: event must ' + + 'be string. Found: ' + event); + } + if ('string' === typeof attributes) { + attributes = { innerHTML: attributes }; + } + else if (!attributes) { + attributes = {}; + } + if (!attributes.innerHTML) attributes.innerHTML = event; + b = this.get('button', attributes); + b.onclick = function() { node.emit(event); }; + return b; + }; + + /** + * ### GameWindow.addEventButton + * + * Adds an EventButton to the specified root element + * + * @param {string} event The event to emit when clicked + * @param {Element} root Optional. The root element. Default: last element + * on the page + * @param {string|object} attributes Optional. The attributes of the + * button, or if string the text to display inside the button. + * + * @return {Element} The newly created button + * + * @see GameWindow.get + * @see GameWindow.getEventButton + */ + GameWindow.prototype.addEventButton = function(event, root, attributes) { + var eb; + eb = this.getEventButton(event, attributes); + if (!root) root = this.getScreen(); + return root.appendChild(eb); + }; + + // ### SHOWING, HIDING, TOGGLING. + + /** + * ### GameWindow.toggleInputs + * + * Enables / disables the input forms + * + * If an id is provided, only input elements that are children + * of the element with the specified id are toggled. + * + * If id is not given, it toggles the input elements on the whole page, + * including the frame document, if found. + * + * If a state parameter is given, all the input forms will be either + * disabled or enabled (and not toggled). + * + * @param {string} id Optional. The id of the element container + * of the forms. Default: the whole page, including the frame document + * @param {boolean} disabled Optional. Forces all the inputs to be either + * disabled or enabled (not toggled) + * + * @return {boolean} FALSE, if the method could not be executed + * + * @see GameWindow.getFrameDocument + * @see toggleInputs + */ + GameWindow.prototype.toggleInputs = function(id, disabled) { + var container; + if (!document.getElementsByTagName) { + node.err(G + 'toggleInputs: getElementsByTagName not found'); + return false; + } + if (id && 'string' === typeof id) { + throw new Error(G + 'toggleInputs: id must be string or ' + + 'undefined. Found: ' + id); + } + if (id) { + container = this.gid(id); + if (!container) { + throw new Error(G + 'toggleInputs: no elements found with id ' + + id); + } + toggleInputs(disabled, container); + } + else { + // The whole page. + toggleInputs(disabled); + container = this.getFrameDocument(); + // If there is a frame, apply it there too. + if (container) toggleInputs(disabled, container); + } + return true; + }; + /** * ## GameWindow.hide * From bd878934c8bf9d3680a89dd4813541fcae854699 Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Wed, 27 Sep 2023 11:59:12 +0200 Subject: [PATCH 05/15] minor --- lib/modules/extra.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/extra.js b/lib/modules/extra.js index 65a830d..ea8af99 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -14,7 +14,7 @@ var GameWindow = node.GameWindow; var DOM = J.require('DOM'); - var G = G + ''; + var G = 'GameWindow.'; // ### BASIC. From 7cbc069ada7e4a5aeab7d80aa12121d6353b01ce Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Wed, 27 Sep 2023 11:59:33 +0200 Subject: [PATCH 06/15] minor --- lib/modules/extra.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/modules/extra.js b/lib/modules/extra.js index ea8af99..f894913 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -63,10 +63,8 @@ GameWindow.prototype.uniqueId = GameWindow.prototype.generateUniqueId = function(prefix) { var id, found; - id = '' + (prefix || J.randomInt(0, 1000)); found = this.gid(id); - while (found) { id = '' + prefix + '_' + J.randomInt(0, 1000); found = this.gid(id); From 29b98147bad5f669f0301c9d17cb01abe3596a36 Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Wed, 27 Sep 2023 12:08:37 +0200 Subject: [PATCH 07/15] fix --- build/nodegame-window.js | 642 ++++++++++++++++++++--------------- build/nodegame-window.min.js | 4 +- lib/modules/extra.js | 2 +- 3 files changed, 370 insertions(+), 278 deletions(-) diff --git a/build/nodegame-window.js b/build/nodegame-window.js index af4d787..7fccd11 100644 --- a/build/nodegame-window.js +++ b/build/nodegame-window.js @@ -1,6 +1,6 @@ /** * # GameWindow - * Copyright(c) 2021 Stefano Balietti + * Copyright(c) 2023 Stefano Balietti * MIT Licensed * * API to interface nodeGame with the browser window @@ -2163,6 +2163,40 @@ }; + /** + * ### GameWindow.cssRule + * + * Add a css rule to the page + * + * @param {string} rule The css rule + * @param {boolean} clear Optional. TRUE to clear all previous rules + * added with this method to the page + * + * @return {Element} The HTML style element where the rules were added + * + * @see handleFrameLoad + */ + GameWindow.prototype.cssRule = function(rule, clear) { + var root; + if ('string' !== typeof rule) { + throw new TypeError(G + 'cssRule: style property must be ' + + 'string. Found: ' + rule); + } + if (!this.styleElement) { + root = W.getFrameDocument() || window.document; + this.styleElement = W.append('style', root.head, { + type: 'text/css', + id: 'ng_style' + }); + } + else if (clear) { + this.styleElement.innerHTML = ''; + } + this.styleElement.innerHTML += rule; + return this.styleElement; + }; + + // ## Helper functions /** @@ -4074,7 +4108,7 @@ /** * # extra - * Copyright(c) 2022 Stefano Balietti + * Copyright(c) 2023 Stefano Balietti * MIT Licensed * * GameWindow extras @@ -4088,6 +4122,10 @@ var GameWindow = node.GameWindow; var DOM = J.require('DOM'); + var G = 'GameWindow.'; + + // ### BASIC. + /** * ### GameWindow.getScreen * @@ -4117,38 +4155,33 @@ }; /** - * ### GameWindow.cssRule + * ### GameWindow.uniqueId|generateUniqueId * - * Add a css rule to the page + * Generates a unique id * - * @param {string} rule The css rule - * @param {boolean} clear Optional. TRUE to clear all previous rules - * added with this method to the page + * Overrides JSUS.DOM.generateUniqueId. * - * @return {Element} The HTML style element where the rules were added + * @param {string} prefix Optional. The prefix to use * - * @see handleFrameLoad + * @return {string} The generated id + * + * @experimental + * TODO: it is not always working fine. */ - GameWindow.prototype.cssRule = function(rule, clear) { - var root; - if ('string' !== typeof rule) { - throw new TypeError('Game.execStep: style property must be ' + - 'string. Found: ' + rule); - } - if (!this.styleElement) { - root = W.getFrameDocument() || window.document; - this.styleElement = W.append('style', root.head, { - type: 'text/css', - id: 'ng_style' - }); - } - else if (clear) { - this.styleElement.innerHTML = ''; + GameWindow.prototype.uniqueId = + GameWindow.prototype.generateUniqueId = function(prefix) { + var id, found; + id = '' + (prefix || J.randomInt(0, 1000)); + found = this.gid(id); + while (found) { + id = '' + prefix + '_' + J.randomInt(0, 1000); + found = this.gid(id); } - this.styleElement.innerHTML += rule; - return this.styleElement; + return id; }; + // ### WRITE TO SCREEN. + /** * ### GameWindow.write * @@ -4162,16 +4195,12 @@ * * @return {string|object} The content written * + * @see JSUS.write * @see GameWindow.writeln + * @see getDefaultRoot */ GameWindow.prototype.write = function(text, root) { - if ('string' === typeof root) root = this.getElementById(root); - else if (!root) root = this.getScreen(); - - if (!root) { - throw new - Error('GameWindow.write: could not determine where to write'); - } + root = getDefaultRoot(root, 'write'); return DOM.write(root, text); }; @@ -4188,229 +4217,79 @@ * * @return {string|object} The content written * + * @see JSUS.writeln * @see GameWindow.write + * @see getDefaultRoot */ GameWindow.prototype.writeln = function(text, root, br) { - if ('string' === typeof root) root = this.getElementById(root); - else if (!root) root = this.getScreen(); - - if (!root) { - throw new Error('GameWindow.writeln: ' + - 'could not determine where to write'); - } + root = getDefaultRoot(root, 'writeln'); return DOM.writeln(root, text, br); }; /** - * ### GameWindow.generateUniqueId - * - * Generates a unique id - * - * Overrides JSUS.DOM.generateUniqueId. - * - * @param {string} prefix Optional. The prefix to use - * - * @return {string} The generated id - * - * @experimental - * TODO: it is not always working fine. - */ - GameWindow.prototype.generateUniqueId = function(prefix) { - var id, found; - - id = '' + (prefix || J.randomInt(0, 1000)); - found = this.getElementById(id); - - while (found) { - id = '' + prefix + '_' + J.randomInt(0, 1000); - found = this.getElementById(id); - } - return id; - }; - - /** - * ### GameWindow.toggleInputs - * - * Enables / disables the input forms - * - * If an id is provided, only input elements that are children - * of the element with the specified id are toggled. - * - * If id is not given, it toggles the input elements on the whole page, - * including the frame document, if found. - * - * If a state parameter is given, all the input forms will be either - * disabled or enabled (and not toggled). - * - * @param {string} id Optional. The id of the element container - * of the forms. Default: the whole page, including the frame document - * @param {boolean} disabled Optional. Forces all the inputs to be either - * disabled or enabled (not toggled) - * - * @return {boolean} FALSE, if the method could not be executed - * - * @see GameWindow.getFrameDocument - * @see toggleInputs - */ - GameWindow.prototype.toggleInputs = function(id, disabled) { - var container; - if (!document.getElementsByTagName) { - node.err( - 'GameWindow.toggleInputs: getElementsByTagName not found'); - return false; - } - if (id && 'string' === typeof id) { - throw new Error('GameWindow.toggleInputs: id must be string or ' + - 'undefined. Found: ' + id); - } - if (id) { - container = this.getElementById(id); - if (!container) { - throw new Error('GameWindow.toggleInputs: no elements found ' + - 'with id ' + id); - } - toggleInputs(disabled, container); - } - else { - // The whole page. - toggleInputs(disabled); - container = this.getFrameDocument(); - // If there is a frame, apply it there too. - if (container) toggleInputs(disabled, container); - } - return true; - }; - - /** - * ### GameWindow.getLoadingDots - * - * Creates and returns a span element with incrementing dots inside - * - * New dots are added every second until the limit is reached, then it - * starts from the beginning. - * - * Gives the impression of a loading time. - * - * @param {number} len Optional. The maximum length of the loading dots. - * Default: 5 - * @param {string} id Optional The id of the span - * - * @return {object} An object containing two properties: the span element - * and a method stop, that clears the interval - */ - GameWindow.prototype.getLoadingDots = function(len, id) { - var spanDots, counter, intervalId; - if (len & len < 0) { - throw new Error('GameWindow.getLoadingDots: len cannot be < 0. ' + - 'Found: ' + len); - } - spanDots = document.createElement('span'); - spanDots.id = id || 'span_dots'; - // Refreshing the dots... - counter = 0; - len = len || 5; - // So the height does not change. - spanDots.innerHTML = ' '; - intervalId = setInterval(function() { - if (counter < len) { - counter++; - spanDots.innerHTML = spanDots.innerHTML + '.'; - } - else { - counter = 0; - spanDots.innerHTML = '.'; - } - }, 1000); - - function stop() { - spanDots.innerHTML = '.'; - clearInterval(intervalId); - } - - return { - span: spanDots, - stop: stop - }; - }; - - /** - * ### GameWindow.addLoadingDots - * - * Appends _loading dots_ to an HTML element - * - * By invoking this method you lose access to the _stop_ function of the - * _loading dots_ element. - * - * @param {HTMLElement} root The element to which the loading dots will be - * appended - * @param {number} len Optional. The maximum length of the loading dots. - * Default: 5 - * @param {string} id Optional The id of the span - * - * @return {object} An object containing two properties: the span element - * and a method stop, that clears the interval - * - * @see GameWindow.getLoadingDots - */ - GameWindow.prototype.addLoadingDots = function(root, len, id) { - var ld; - ld = this.getLoadingDots(len, id); - root.appendChild(ld.span); - return ld; - }; - - /** - * ### GameWindow.getEventButton - * - * Creates an HTML button element that will emit an event when clicked - * - * @param {string} event The event to emit when clicked - * @param {string|object} attributes Optional. The attributes of the - * button, or if string the text to display inside the button. - * - * @return {Element} The newly created button - * - * @see GameWindow.get - */ - GameWindow.prototype.getEventButton = function(event, attributes) { - var b; - if ('string' !== typeof event) { - throw new TypeError('GameWindow.getEventButton: event must ' + - 'be string. Found: ' + event); - } - if ('string' === typeof attributes) { - attributes = { innerHTML: attributes }; - } - else if (!attributes) { - attributes = {}; - } - if (!attributes.innerHTML) attributes.innerHTML = event; - b = this.get('button', attributes); - b.onclick = function() { node.emit(event); }; - return b; + * ### DOM.sprintf + * + * Builds up a decorated HTML text element + * + * Performs string substitution from an args object where the first + * character of the key bears the following semantic: + * + * - '@': variable substitution with escaping + * - '!': variable substitution without variable escaping + * - '%': wraps a portion of string into a _span_ element to which is + * possible to associate a css class or id. Alternatively, + * it also possible to add in-line style. E.g.: + * + * ```javascript + * sprintf('%sImportant!%s An error has occurred: %pre@err%pre', { + * '%pre': { + * style: 'font-size: 12px; font-family: courier;' + * }, + * '%s': { + * id: 'myId', + * 'class': 'myClass', + * }, + * '@err': 'file not found', + * }, document.body); + * ``` + * + * Special span elements are %strong and %em, which add + * respectively a _strong_ and _em_ tag instead of the default + * _span_ tag. They cannot be styled. + * + * @param {string} string A text to transform + * @param {object} args Optional. An object containing string + * transformations + * @param {Element} root Optional. An HTML element to which append the + * string. Defaults, a new _span_ element + * + * @return {Element} The root element. + */ + GameWindow.prototype.sprintf = function(string, args, root) { + if (!root) root = getDefaultRoot(root, 'sprintf'); + return DOM.sprintf(string, args, root); }; /** - * ### GameWindow.addEventButton + * ### GameWindo.add|append * - * Adds an EventButton to the specified root element + * Creates and append an element with specified attributes to a root * - * @param {string} event The event to emit when clicked - * @param {Element} root Optional. The root element. Default: last element - * on the page - * @param {string|object} attributes Optional. The attributes of the - * button, or if string the text to display inside the button. + * @param {string} name The name of the HTML tag + * @param {HTMLElement} root The root element to which the new element + * will be appended + * @param {object|string} options Optional. Object containing + * attributes for the element and rules about how to insert it relative + * to root. Available options: insertAfter, insertBefore (default: + * child of root). If string, it is the id of the element. Examples: * - * @return {Element} The newly created button * - * @see GameWindow.get - * @see GameWindow.getEventButton + * @see getDefaultRoot */ - GameWindow.prototype.addEventButton = function(event, root, attributes) { - var eb; - eb = this.getEventButton(event, attributes); - if (!root) root = this.getScreen(); - return root.appendChild(eb); + GameWindow.prototype.add = + GameWindow.prototype.append = function(el, root, opts) { + if (!root) root = getDefaultRoot(root, 'add'); + return DOM.add(el, root, opts); }; /** @@ -4473,9 +4352,8 @@ prefix = ''; } else if ('string' !== typeof prefix) { - throw new TypeError('GameWindow.searchReplace: prefix ' + - 'must be string, null or undefined. Found: ' + - prefix); + throw new TypeError(G + 'searchReplace: prefix must be string, ' + + 'null or undefined. Found: ' + prefix); } elements = arguments[0]; @@ -4502,7 +4380,7 @@ if (elements.hasOwnProperty(name)) { el = elements[name]; if ('string' !== typeof el && 'number' !== typeof el) { - node.warn('W.searchReplace: replace for key ' + name + + node.warn(G + 'searchReplace: replace for key ' + name + ' is invalid. Found: ' + el); continue; } @@ -4511,18 +4389,14 @@ } } else { - throw new TypeError('GameWindow.setInnerHTML: elements must be ' + + throw new TypeError(G + 'setInnerHTML: elements must be ' + 'object or arrray. Found: ' + elements); } }; - GameWindow.prototype.setInnerHTML = function(search, replace, mod) { - this.html(search, replace, mod); - }; - /** - * ### GameWindow.html + * ### GameWindow.html|setInnerHTML * * Replaces the innerHTML of the element with matching id or class name * @@ -4535,19 +4409,20 @@ * - 'className': replaces all elements with same class name * - 'g': replaces globally, both by id and className */ + GameWindow.prototype.setInnerHTML = GameWindow.prototype.html = function(search, replace, mod) { var el, i, len; // Only process strings or numbers. if ('string' !== typeof search && 'number' !== typeof search) { - throw new TypeError('GameWindow.setInnerHTML: search must be ' + + throw new TypeError(G + 'setInnerHTML: search must be ' + 'string or number. Found: ' + search + " (replace = " + replace + ")"); } // Only process strings or numbers. if ('string' !== typeof replace && 'number' !== typeof replace) { - throw new TypeError('GameWindow.setInnerHTML: replace must be ' + + throw new TypeError(G + 'setInnerHTML: replace must be ' + 'string or number. Found: ' + replace + " (search = " + search + ")"); } @@ -4557,13 +4432,13 @@ } else if ('string' === typeof mod) { if (mod !== 'g' && mod !== 'id' && mod !== 'className') { - throw new Error('GameWindow.setInnerHTML: invalid ' + + throw new Error(G + 'setInnerHTML: invalid ' + 'mod value: ' + mod + " (search = " + search + ")"); } } else { - throw new TypeError('GameWindow.setInnerHTML: mod must be ' + + throw new TypeError(G + 'setInnerHTML: mod must be ' + 'string or undefined. Found: ' + mod + " (search = " + search + ")"); } @@ -4587,6 +4462,194 @@ } }; + // ### ADD STUFF: Event button, loading dots. + + /** + * ### GameWindow.getLoadingDots + * + * Creates and returns a span element with incrementing dots inside + * + * New dots are added every second until the limit is reached, then it + * starts from the beginning. + * + * Gives the impression of a loading time. + * + * @param {number} len Optional. The maximum length of the loading dots. + * Default: 5 + * @param {string} id Optional. The id of the span + * + * @return {object} An object containing two properties: the span element + * and a method stop, that clears the interval + */ + GameWindow.prototype.getLoadingDots = function(len, id) { + var spanDots, counter, intervalId; + if (len & len < 0) { + throw new Error(G + 'getLoadingDots: len cannot be < 0. Found: ' + + len); + } + spanDots = document.createElement('span'); + spanDots.id = id || 'span_dots'; + // Refreshing the dots... + counter = 0; + len = len || 5; + // So the height does not change. + spanDots.innerHTML = ' '; + intervalId = setInterval(function() { + if (counter < len) { + counter++; + spanDots.innerHTML = spanDots.innerHTML + '.'; + } + else { + counter = 0; + spanDots.innerHTML = '.'; + } + }, 1000); + + function stop() { + spanDots.innerHTML = '.'; + clearInterval(intervalId); + } + + return { + span: spanDots, + stop: stop + }; + }; + + /** + * ### GameWindow.addLoadingDots + * + * Appends _loading dots_ to an HTML element + * + * By invoking this method you lose access to the _stop_ function of the + * _loading dots_ element. + * + * @param {HTMLElement} root The element to which the loading dots will be + * appended + * @param {number} len Optional. The maximum length of the loading dots. + * Default: 5 + * @param {string} id Optional The id of the span + * + * @return {object} An object containing two properties: the span element + * and a method stop, that clears the interval + * + * @see GameWindow.getLoadingDots + */ + GameWindow.prototype.addLoadingDots = function(root, len, id) { + var ld; + ld = this.getLoadingDots(len, id); + root.appendChild(ld.span); + return ld; + }; + + /** + * ### GameWindow.getEventButton + * + * Creates an HTML button element that will emit an event when clicked + * + * @param {string} event The event to emit when clicked + * @param {string|object} attributes Optional. The attributes of the + * button, or if string the text to display inside the button. + * + * @return {Element} The newly created button + * + * @see GameWindow.get + */ + GameWindow.prototype.getEventButton = function(event, attributes) { + var b; + if ('string' !== typeof event) { + throw new TypeError(G + 'getEventButton: event must ' + + 'be string. Found: ' + event); + } + if ('string' === typeof attributes) { + attributes = { innerHTML: attributes }; + } + else if (!attributes) { + attributes = {}; + } + if (!attributes.innerHTML) attributes.innerHTML = event; + b = this.get('button', attributes); + b.onclick = function() { node.emit(event); }; + return b; + }; + + /** + * ### GameWindow.addEventButton + * + * Adds an EventButton to the specified root element + * + * @param {string} event The event to emit when clicked + * @param {Element} root Optional. The root element. Default: last element + * on the page + * @param {string|object} attributes Optional. The attributes of the + * button, or if string the text to display inside the button. + * + * @return {Element} The newly created button + * + * @see GameWindow.get + * @see GameWindow.getEventButton + */ + GameWindow.prototype.addEventButton = function(event, root, attributes) { + var eb; + eb = this.getEventButton(event, attributes); + if (!root) root = this.getScreen(); + return root.appendChild(eb); + }; + + // ### SHOWING, HIDING, TOGGLING. + + /** + * ### GameWindow.toggleInputs + * + * Enables / disables the input forms + * + * If an id is provided, only input elements that are children + * of the element with the specified id are toggled. + * + * If id is not given, it toggles the input elements on the whole page, + * including the frame document, if found. + * + * If a state parameter is given, all the input forms will be either + * disabled or enabled (and not toggled). + * + * @param {string} id Optional. The id of the element container + * of the forms. Default: the whole page, including the frame document + * @param {boolean} disabled Optional. Forces all the inputs to be either + * disabled or enabled (not toggled) + * + * @return {boolean} FALSE, if the method could not be executed + * + * @see GameWindow.getFrameDocument + * @see toggleInputs + */ + GameWindow.prototype.toggleInputs = function(id, disabled) { + var container; + if (!document.getElementsByTagName) { + node.err(G + 'toggleInputs: getElementsByTagName not found'); + return false; + } + if (id && 'string' === typeof id) { + throw new Error(G + 'toggleInputs: id must be string or ' + + 'undefined. Found: ' + id); + } + if (id) { + container = this.gid(id); + if (!container) { + throw new Error(G + 'toggleInputs: no elements found with id ' + + id); + } + toggleInputs(disabled, container); + } + else { + // The whole page. + toggleInputs(disabled); + container = this.getFrameDocument(); + // If there is a frame, apply it there too. + if (container) toggleInputs(disabled, container); + } + return true; + }; + /** * ## GameWindow.hide * @@ -4603,7 +4666,7 @@ */ GameWindow.prototype.hide = function(idOrObj) { var el; - el = getElement(idOrObj, 'GameWindow.hide'); + el = getElement(idOrObj, 'hide'); if (el) { el.style.display = 'none'; W.adjustFrameHeight(0, 0); @@ -4631,10 +4694,10 @@ var el; display = display || ''; if ('string' !== typeof display) { - throw new TypeError('GameWindow.show: display must be ' + + throw new TypeError(G + 'show: display must be ' + 'string or undefined. Found: ' + display); } - el = getElement(idOrObj, 'GameWindow.show'); + el = getElement(idOrObj, 'show'); if (el) { el.style.display = display; W.adjustFrameHeight(0, 0); @@ -4662,10 +4725,10 @@ var el; display = display || ''; if ('string' !== typeof display) { - throw new TypeError('GameWindow.toggle: display must ' + + throw new TypeError(G + 'toggle: display must ' + 'be string or undefined. Found: ' + display); } - el = getElement(idOrObj, 'GameWindow.toggle'); + el = getElement(idOrObj, 'toggle'); if (el) { if (el.style.display === 'none') el.style.display = display; else el.style.display = 'none'; @@ -4679,6 +4742,13 @@ /** * ### toggleInputs * + * Enable/disable inputs: 'button', 'select', 'textarea', 'input' + * + * @param {boolean} state Optional. True/false to enable/disable, undefined + * to toggle. + * @param {HTMLElement} container Optional. The element inside which + * toggling takes place. Default: `document`. + * * @api private */ function toggleInputs(state, container) { @@ -4709,26 +4779,48 @@ * * Gets the element or returns it * - * @param {string|HTMLElement} The id or the HTML element itself + * @param {string|HTMLElement} idOrObj The id or the HTML element itself + * @param {string|undefined} throwAs Optional. The name of the calling + * method used in the string of the error, or undefined to avoid + * throwing altogether. * - * @return {HTMLElement} The HTML Element + * @return {HTMLElement|undefined} The HTML Element or undefined if none + * is found and throwAs is falsy * - * @see GameWindow.getElementById + * @see GameWindow.gid * @api private */ - function getElement(idOrObj, prefix) { - var el; - if ('string' === typeof idOrObj) { - el = W.getElementById(idOrObj); - } - else if (J.isElement(idOrObj)) { - el = idOrObj; - } - else { - throw new TypeError(prefix + ': idOrObj must be string ' + - ' or HTML Element. Found: ' + idOrObj); + function getElement(idOrObj, throwAs) { + if ('string' === typeof idOrObj) return W.gid(idOrObj); + if (J.isElement(idOrObj)) return idOrObj; + if (throwAs) { + throw new TypeError(G + throwAs + ': idOrObj must be string or ' + + 'HTML Element. Found: ' + idOrObj); } - return el; + } + + /** + * ### getDefaultRoot + * + * Tries to find a default root and returns it + * + * @param {string|HTMLElement} root Optional. The id of or the HTML + * element itself to be used as root. + * @param {string|undefined} throwAs Optional. The name of the calling + * method used in the string of the error, or undefined to avoid + * throwing altogether. + * + * @return {HTMLElement|undefined} The root HTML Element, or undefined + * if none is found and `throwAs` is falsy + * + * @see GameWindow.gid + * @api private + */ + function getDefaultRoot(root, throwAs) { + if (!root) root = W.getScreen(); + else root = getElement(root); + if (root) return root; + if (thorwAs) throw new Error(G + throwAs + ': could not find root'); } })( diff --git a/build/nodegame-window.min.js b/build/nodegame-window.min.js index 20e0cc8..7d215df 100644 --- a/build/nodegame-window.min.js +++ b/build/nodegame-window.min.js @@ -1,6 +1,6 @@ /** * # GameWindow - * Copyright(c) 2021 Stefano Balietti + * Copyright(c) 2023 Stefano Balietti * MIT Licensed * * API to interface nodeGame with the browser window @@ -15,4 +15,4 @@ * * Depends on JSUS and nodegame-client. */ -(function(e,t){"use strict";function a(e,t){function r(){e.removeEventListener("load",r,!1),n.removeEventListener("load",r,!1),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.addEventListener("load",r,!1),n.addEventListener("load",r,!1)}function f(e,t){function r(i){var s;s=J.getIFrameDocument(e);if(i.type==="load"||s.readyState==="complete")e.detachEvent("onreadystatechange",r),n.detachEvent("onload",r),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.attachEvent("onreadystatechange",r),n.attachEvent("onload",r)}function l(e,t){W.isIE?f(e,t):a(e,t)}function c(){this.setStateLevel("UNINITIALIZED");if("undefined"==typeof e)throw new Error("GameWindow: no window found. Are you in a browser?");if("undefined"==typeof t)throw new Error("GameWindow: nodeGame not found");t.silly("node-window: loading..."),this.frameName=null,this.frameElement=null,this.frameWindow=null,this.frameDocument=null,this.frameRoot=null,this.headerElement=null,this.headerName=null,this.headerRoot=null,this.headerPosition=null,this.defaultHeaderPosition="top",this.conf={},this.uriChannel=null,this.areLoading=0,this.cacheSupported=null,this.directFrameDocumentAccess=null,this.cache={},this.currentURIs={},this.unprocessedUri=null,this.globalLibs=[],this.frameLibs={},this.uriPrefix=null,this.stateLevel=null,this.waitScreen=null,this.listenersAdded=null,this.screenState=t.constants.screenLevels.ACTIVE,this.styleElement=null,this.isIE=!!document.createElement("span").attachEvent,this.headerOffset=0,this.willResizeFrame=!1,this.addDefaultSetups(),this.addDefaultListeners(),setTimeout(function(){(function(e){e.length>=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l;f=m(this,-1),f&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),f?(l=t.game.getStageLevel(),l===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError("GameWindow.searchReplace: prefix must be string, null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){o=-1,s=e.length;for(;++on.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l;f=m(this,-1),f&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),f?(l=t.game.getStageLevel(),l===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError(i+"searchReplace: prefix must be string, "+"null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){u=-1,o=e.length;for(;++un.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a Date: Wed, 27 Sep 2023 12:52:16 +0200 Subject: [PATCH 08/15] write/ln supports HTML --- lib/modules/extra.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/modules/extra.js b/lib/modules/extra.js index 2155e16..7c39779 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -93,7 +93,7 @@ */ GameWindow.prototype.write = function(text, root) { root = getDefaultRoot(root, 'write'); - return DOM.write(root, text); + return DOM.write2(root, text); }; /** @@ -115,7 +115,7 @@ */ GameWindow.prototype.writeln = function(text, root, br) { root = getDefaultRoot(root, 'writeln'); - return DOM.writeln(root, text, br); + return DOM.writeln2(root, text, br); }; /** From 72d10914bfca22ebc2fc6c11f1195417ef02b4c9 Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Thu, 28 Sep 2023 14:28:24 +0200 Subject: [PATCH 09/15] html step-property --- build/nodegame-window.js | 11 +++++++---- build/nodegame-window.min.js | 2 +- lib/GameWindow.js | 5 ++++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/build/nodegame-window.js b/build/nodegame-window.js index 7fccd11..1c223bf 100644 --- a/build/nodegame-window.js +++ b/build/nodegame-window.js @@ -1883,7 +1883,7 @@ autoParsePrefix, scrollUp) { - var css, loaded, stageLevel; + var css, html, loaded, stageLevel; loaded = updateAreLoading(this, -1); if (loaded) this.setStateLevel('LOADED'); if (func) func.call(node.game); @@ -1895,6 +1895,9 @@ css = node.game.getProperty('css'); if (css) W.cssRule(css); + html = node.game.getProperty('html'); + if (html) W.write(html); + // ng event emitter is not used. node.events.ee.game.emit('FRAME_LOADED'); node.events.ee.stage.emit('FRAME_LOADED'); @@ -4201,7 +4204,7 @@ */ GameWindow.prototype.write = function(text, root) { root = getDefaultRoot(root, 'write'); - return DOM.write(root, text); + return DOM.write2(root, text); }; /** @@ -4223,7 +4226,7 @@ */ GameWindow.prototype.writeln = function(text, root, br) { root = getDefaultRoot(root, 'writeln'); - return DOM.writeln(root, text, br); + return DOM.writeln2(root, text, br); }; /** @@ -4820,7 +4823,7 @@ if (!root) root = W.getScreen(); else root = getElement(root); if (root) return root; - if (thorwAs) throw new Error(G + throwAs + ': could not find root'); + if (throwAs) throw new Error(G + throwAs + ': could not find root'); } })( diff --git a/build/nodegame-window.min.js b/build/nodegame-window.min.js index 7d215df..4637632 100644 --- a/build/nodegame-window.min.js +++ b/build/nodegame-window.min.js @@ -15,4 +15,4 @@ * * Depends on JSUS and nodegame-client. */ -(function(e,t){"use strict";function a(e,t){function r(){e.removeEventListener("load",r,!1),n.removeEventListener("load",r,!1),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.addEventListener("load",r,!1),n.addEventListener("load",r,!1)}function f(e,t){function r(i){var s;s=J.getIFrameDocument(e);if(i.type==="load"||s.readyState==="complete")e.detachEvent("onreadystatechange",r),n.detachEvent("onload",r),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.attachEvent("onreadystatechange",r),n.attachEvent("onload",r)}function l(e,t){W.isIE?f(e,t):a(e,t)}function c(){this.setStateLevel("UNINITIALIZED");if("undefined"==typeof e)throw new Error("GameWindow: no window found. Are you in a browser?");if("undefined"==typeof t)throw new Error("GameWindow: nodeGame not found");t.silly("node-window: loading..."),this.frameName=null,this.frameElement=null,this.frameWindow=null,this.frameDocument=null,this.frameRoot=null,this.headerElement=null,this.headerName=null,this.headerRoot=null,this.headerPosition=null,this.defaultHeaderPosition="top",this.conf={},this.uriChannel=null,this.areLoading=0,this.cacheSupported=null,this.directFrameDocumentAccess=null,this.cache={},this.currentURIs={},this.unprocessedUri=null,this.globalLibs=[],this.frameLibs={},this.uriPrefix=null,this.stateLevel=null,this.waitScreen=null,this.listenersAdded=null,this.screenState=t.constants.screenLevels.ACTIVE,this.styleElement=null,this.isIE=!!document.createElement("span").attachEvent,this.headerOffset=0,this.willResizeFrame=!1,this.addDefaultSetups(),this.addDefaultListeners(),setTimeout(function(){(function(e){e.length>=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l;f=m(this,-1),f&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),f?(l=t.game.getStageLevel(),l===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError(i+"searchReplace: prefix must be string, "+"null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){u=-1,o=e.length;for(;++un.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l,c;l=m(this,-1),l&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),f=t.game.getProperty("html"),f&&W.write(f),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),l?(c=t.game.getStageLevel(),c===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError(i+"searchReplace: prefix must be string, "+"null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){u=-1,o=e.length;for(;++un.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a Date: Thu, 28 Sep 2023 14:45:16 +0200 Subject: [PATCH 10/15] autoParse removed and replaceED --- build/nodegame-window.js | 66 ++++++------------------------------ build/nodegame-window.min.js | 2 +- lib/GameWindow.js | 64 +++++----------------------------- 3 files changed, 20 insertions(+), 112 deletions(-) diff --git a/build/nodegame-window.js b/build/nodegame-window.js index 1c223bf..bc9f3f1 100644 --- a/build/nodegame-window.js +++ b/build/nodegame-window.js @@ -1601,7 +1601,6 @@ var loadCache; var storeCacheNow, storeCacheLater; var scrollUp; - var autoParse, autoParsePrefix, autoParseMod; var iframe, iframeName, iframeDocument, iframeWindow; var frameDocumentElement, frameReady; var lastURI; @@ -1684,35 +1683,6 @@ } } - // Parsing options. - - if ('undefined' !== typeof opts.autoParse) { - if ('object' !== typeof opts.autoParse) { - throw new TypeError('GameWindow.loadFrame: opts.autoParse ' + - 'must be object or undefined. Found: ' + - opts.autoParse); - } - if ('undefined' !== typeof opts.autoParsePrefix) { - if ('string' !== typeof opts.autoParsePrefix) { - throw new TypeError('GameWindow.loadFrame: opts.' + - 'autoParsePrefix must be string ' + - 'or undefined. Found: ' + - opts.autoParsePrefix); - } - autoParsePrefix = opts.autoParsePrefix; - } - if ('undefined' !== typeof opts.autoParseMod) { - if ('string' !== typeof opts.autoParseMod) { - throw new TypeError('GameWindow.loadFrame: opts.' + - 'autoParseMod must be string ' + - 'or undefined. Found: ' + - opts.autoParseMod); - } - autoParseMod = opts.autoParseMod; - } - autoParse = opts.autoParse; - } - // Scroll Up. scrollUp = 'undefined' === typeof opts.scrollUp ? true : opts.scrollUp; @@ -1789,13 +1759,9 @@ handleFrameLoad(that, uri, iframe, iframeName, loadCache, storeCacheNow, function() { - // Executes callback, autoParses, + // Executes callback, css, replace, html, // and updates GameWindow state. - that.updateLoadFrameState(func, - autoParse, - autoParseMod, - autoParsePrefix, - scrollUp); + that.updateLoadFrameState(func, scrollUp); }); }); } @@ -1811,13 +1777,9 @@ handleFrameLoad(this, uri, iframe, iframeName, loadCache, storeCacheNow, function() { - // Executes callback + // Executes callback, css, replace, html, // and updates GameWindow state. - that.updateLoadFrameState(func, - autoParse, - autoParseMod, - autoParsePrefix, - scrollUp); + that.updateLoadFrameState(func, scrollUp); }); } } @@ -1864,11 +1826,6 @@ * - set the window state as loaded (eventually) * * @param {function} func Optional. A callback function - * @param {object} autoParse Optional. An object containing elements - * to replace in the HTML DOM. - * @param {string} autoParseMod Optional. Modifier for search and replace - * @param {string} autoParsePrefix Optional. Custom prefix to add to the - * keys of the elements in autoParse object * @param {boolean} scrollUp Optional. If TRUE, scrolls the page to the, * top (if window.scrollTo is defined). Default: FALSE. * @@ -1878,18 +1835,12 @@ * @emit FRAME_LOADED * @emit LOADED */ - GameWindow.prototype.updateLoadFrameState = function(func, autoParse, - autoParseMod, - autoParsePrefix, - scrollUp) { + GameWindow.prototype.updateLoadFrameState = function(func, scrollUp) { - var css, html, loaded, stageLevel; + var css, html, replace, loaded, stageLevel; loaded = updateAreLoading(this, -1); if (loaded) this.setStateLevel('LOADED'); - if (func) func.call(node.game); - if (autoParse) { - this.searchReplace(autoParse, autoParseMod, autoParsePrefix); - } + if (func) func.call(node.game); if (scrollUp && window.scrollTo) window.scrollTo(0,0); css = node.game.getProperty('css'); @@ -1898,6 +1849,9 @@ html = node.game.getProperty('html'); if (html) W.write(html); + replace = node.game.getProperty('replace'); + if (replace) W.searchReplace(replace, 'g', ''); + // ng event emitter is not used. node.events.ee.game.emit('FRAME_LOADED'); node.events.ee.stage.emit('FRAME_LOADED'); diff --git a/build/nodegame-window.min.js b/build/nodegame-window.min.js index 4637632..7b8c933 100644 --- a/build/nodegame-window.min.js +++ b/build/nodegame-window.min.js @@ -15,4 +15,4 @@ * * Depends on JSUS and nodegame-client. */ -(function(e,t){"use strict";function a(e,t){function r(){e.removeEventListener("load",r,!1),n.removeEventListener("load",r,!1),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.addEventListener("load",r,!1),n.addEventListener("load",r,!1)}function f(e,t){function r(i){var s;s=J.getIFrameDocument(e);if(i.type==="load"||s.readyState==="complete")e.detachEvent("onreadystatechange",r),n.detachEvent("onload",r),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.attachEvent("onreadystatechange",r),n.attachEvent("onload",r)}function l(e,t){W.isIE?f(e,t):a(e,t)}function c(){this.setStateLevel("UNINITIALIZED");if("undefined"==typeof e)throw new Error("GameWindow: no window found. Are you in a browser?");if("undefined"==typeof t)throw new Error("GameWindow: nodeGame not found");t.silly("node-window: loading..."),this.frameName=null,this.frameElement=null,this.frameWindow=null,this.frameDocument=null,this.frameRoot=null,this.headerElement=null,this.headerName=null,this.headerRoot=null,this.headerPosition=null,this.defaultHeaderPosition="top",this.conf={},this.uriChannel=null,this.areLoading=0,this.cacheSupported=null,this.directFrameDocumentAccess=null,this.cache={},this.currentURIs={},this.unprocessedUri=null,this.globalLibs=[],this.frameLibs={},this.uriPrefix=null,this.stateLevel=null,this.waitScreen=null,this.listenersAdded=null,this.screenState=t.constants.screenLevels.ACTIVE,this.styleElement=null,this.isIE=!!document.createElement("span").attachEvent,this.headerOffset=0,this.willResizeFrame=!1,this.addDefaultSetups(),this.addDefaultListeners(),setTimeout(function(){(function(e){e.length>=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E,S,x;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},v=this.getFrame(),g=this.frameName;if(!v)throw new Error("GameWindow.loadFrame: no frame found");if(!g)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,w=v.contentWindow,b=W.getIFrameDocument(v),S=b.readyState,S=S==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}if("undefined"!=typeof r.autoParse){if("object"!=typeof r.autoParse)throw new TypeError("GameWindow.loadFrame: opts.autoParse must be object or undefined. Found: "+r.autoParse);if("undefined"!=typeof r.autoParsePrefix){if("string"!=typeof r.autoParsePrefix)throw new TypeError("GameWindow.loadFrame: opts.autoParsePrefix must be string or undefined. Found: "+r.autoParsePrefix);p=r.autoParsePrefix}if("undefined"!=typeof r.autoParseMod){if("string"!=typeof r.autoParseMod)throw new TypeError("GameWindow.loadFrame: opts.autoParseMod must be string or undefined. Found: "+r.autoParseMod);d=r.autoParseMod}f=r.autoParse}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(x=this.currentURIs[g],this.cache.hasOwnProperty(x)&&this.cache[x].cacheOnClose&&(E=b.documentElement,this.cache[x].contents=E.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[g]=e,m(this,1),v.style.visibility="hidden",(!s||!S)&&l(v,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)})}),s?S&&h(this,e,v,g,s,o,function(){i.updateLoadFrameState(n,f,d,p,a)}):w.location.replace(e),w.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r,i,s,u){var a,f,l,c;l=m(this,-1),l&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&this.searchReplace(r,i,s),u&&e.scrollTo&&e.scrollTo(0,0),a=t.game.getProperty("css"),a&&W.cssRule(a),f=t.game.getProperty("html"),f&&W.write(f),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),l?(c=t.game.getStageLevel(),c===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError(i+"searchReplace: prefix must be string, "+"null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){u=-1,o=e.length;for(;++un.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},f=this.getFrame(),p=this.frameName;if(!f)throw new Error("GameWindow.loadFrame: no frame found");if(!p)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,v=f.contentWindow,d=W.getIFrameDocument(f),b=d.readyState,b=b==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(w=this.currentURIs[p],this.cache.hasOwnProperty(w)&&this.cache[w].cacheOnClose&&(g=d.documentElement,this.cache[w].contents=g.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[p]=e,m(this,1),f.style.visibility="hidden",(!s||!b)&&l(f,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,f,p,s,o,function(){i.updateLoadFrameState(n,a)})}),s?b&&h(this,e,f,p,s,o,function(){i.updateLoadFrameState(n,a)}):v.location.replace(e),v.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r){var i,s,u,a,f;a=m(this,-1),a&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&e.scrollTo&&e.scrollTo(0,0),i=t.game.getProperty("css"),i&&W.cssRule(i),s=t.game.getProperty("html"),s&&W.write(s),u=t.game.getProperty("replace"),u&&W.searchReplace(u,"g",""),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),a?(f=t.game.getStageLevel(),f===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError(i+"searchReplace: prefix must be string, "+"null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){u=-1,o=e.length;for(;++un.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a Date: Mon, 2 Oct 2023 12:48:20 +0200 Subject: [PATCH 11/15] Update package.json 8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a557c1a..0739a78 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegame-window", "description": "Provides a handy API to interface nodeGame with the browser window.", - "version": "7.0.0", + "version": "8.0.0", "keywords": [ "nodegame", "window", "browser", "frame", "behavioral", "multiplayer", "games", "ui" ], "author": "Stefano Balietti ", "license": "MIT", From 2b9f37f7bbc52f5e495aea80f100c7d33de9bc24 Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Fri, 20 Oct 2023 12:51:08 +0200 Subject: [PATCH 12/15] preCache improved and error removed --- build/nodegame-window.js | 43 ++++++++++++++++++++++++------------ build/nodegame-window.min.js | 2 +- lib/GameWindow.js | 41 +++++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/build/nodegame-window.js b/build/nodegame-window.js index bc9f3f1..874f941 100644 --- a/build/nodegame-window.js +++ b/build/nodegame-window.js @@ -1346,6 +1346,7 @@ */ GameWindow.prototype.preCacheTest = function(cb, uri) { var iframe, iframeName; + uri = uri || '/pages/testpage.htm'; if ('string' !== typeof uri) { throw new TypeError('GameWindow.precacheTest: uri must string ' + @@ -1372,8 +1373,15 @@ catch(e) { W.cacheSupported = false; } + // It's possible that it was already removed if two calls + // to preCacheTest are made one after the other. + try { + document.body.removeChild(iframe); + } + catch(e) { + node.warn('W.preCacheTest: iframe already removed'); + } - document.body.removeChild(iframe); if (cb) cb(); }); }; @@ -1599,7 +1607,7 @@ GameWindow.prototype.loadFrame = function(uri, func, opts) { var that; var loadCache; - var storeCacheNow, storeCacheLater; + var shouldTestCache, storeCacheNow, storeCacheLater; var scrollUp; var iframe, iframeName, iframeDocument, iframeWindow; var frameDocumentElement, frameReady; @@ -1657,6 +1665,7 @@ } else if (opts.cache.loadMode === 'cache') { loadCache = true; + shouldTestCache = true; } else { throw new Error('GameWindow.loadFrame: unkown cache ' + @@ -1668,17 +1677,22 @@ storeCacheNow = false; storeCacheLater = false; } - else if (opts.cache.storeMode === 'onLoad') { - storeCacheNow = true; - storeCacheLater = false; - } - else if (opts.cache.storeMode === 'onClose') { - storeCacheNow = false; - storeCacheLater = true; - } else { - throw new Error('GameWindow.loadFrame: unkown cache ' + - 'store mode: ' + opts.cache.storeMode); + + if (opts.cache.storeMode === 'onLoad') { + storeCacheNow = true; + storeCacheLater = false; + } + else if (opts.cache.storeMode === 'onClose') { + storeCacheNow = false; + storeCacheLater = true; + } + else { + throw new Error('GameWindow.loadFrame: unkown cache ' + + 'store mode: ' + opts.cache.storeMode); + } + + shouldTestCache = true; } } } @@ -1690,7 +1704,8 @@ // Store unprocessed uri parameter. this.unprocessedUri = uri; - if (this.cacheSupported === null) { + shouldTestCache = true; + if (shouldTestCache && this.cacheSupported === null) { this.preCacheTest(function() { that.loadFrame(uri, func, opts); }); @@ -1840,7 +1855,7 @@ var css, html, replace, loaded, stageLevel; loaded = updateAreLoading(this, -1); if (loaded) this.setStateLevel('LOADED'); - if (func) func.call(node.game); + if (func) func.call(node.game); if (scrollUp && window.scrollTo) window.scrollTo(0,0); css = node.game.getProperty('css'); diff --git a/build/nodegame-window.min.js b/build/nodegame-window.min.js index 7b8c933..f50273a 100644 --- a/build/nodegame-window.min.js +++ b/build/nodegame-window.min.js @@ -15,4 +15,4 @@ * * Depends on JSUS and nodegame-client. */ -(function(e,t){"use strict";function a(e,t){function r(){e.removeEventListener("load",r,!1),n.removeEventListener("load",r,!1),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.addEventListener("load",r,!1),n.addEventListener("load",r,!1)}function f(e,t){function r(i){var s;s=J.getIFrameDocument(e);if(i.type==="load"||s.readyState==="complete")e.detachEvent("onreadystatechange",r),n.detachEvent("onload",r),t&&setTimeout(function(){t()},120)}var n;n=e.contentWindow,e.attachEvent("onreadystatechange",r),n.attachEvent("onload",r)}function l(e,t){W.isIE?f(e,t):a(e,t)}function c(){this.setStateLevel("UNINITIALIZED");if("undefined"==typeof e)throw new Error("GameWindow: no window found. Are you in a browser?");if("undefined"==typeof t)throw new Error("GameWindow: nodeGame not found");t.silly("node-window: loading..."),this.frameName=null,this.frameElement=null,this.frameWindow=null,this.frameDocument=null,this.frameRoot=null,this.headerElement=null,this.headerName=null,this.headerRoot=null,this.headerPosition=null,this.defaultHeaderPosition="top",this.conf={},this.uriChannel=null,this.areLoading=0,this.cacheSupported=null,this.directFrameDocumentAccess=null,this.cache={},this.currentURIs={},this.unprocessedUri=null,this.globalLibs=[],this.frameLibs={},this.uriPrefix=null,this.stateLevel=null,this.waitScreen=null,this.listenersAdded=null,this.screenState=t.constants.screenLevels.ACTIVE,this.styleElement=null,this.isIE=!!document.createElement("span").attachEvent,this.headerOffset=0,this.willResizeFrame=!1,this.addDefaultSetups(),this.addDefaultListeners(),setTimeout(function(){(function(e){e.length>=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},f=this.getFrame(),p=this.frameName;if(!f)throw new Error("GameWindow.loadFrame: no frame found");if(!p)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,v=f.contentWindow,d=W.getIFrameDocument(f),b=d.readyState,b=b==="complete",s=c.defaults.cacheDefaults.loadCache,o=c.defaults.cacheDefaults.storeCacheNow,u=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")o=!1,u=!1;else if(r.cache.storeMode==="onLoad")o=!0,u=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);o=!1,u=!0}}a="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e;if(this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(o=!1,u=!1,s=!1):(w=this.currentURIs[p],this.cache.hasOwnProperty(w)&&this.cache[w].cacheOnClose&&(g=d.documentElement,this.cache[w].contents=g.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=u,this.cache[e].contents===null&&(s=!1)),this.currentURIs[p]=e,m(this,1),f.style.visibility="hidden",(!s||!b)&&l(f,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,f,p,s,o,function(){i.updateLoadFrameState(n,a)})}),s?b&&h(this,e,f,p,s,o,function(){i.updateLoadFrameState(n,a)}):v.location.replace(e),v.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r){var i,s,u,a,f;a=m(this,-1),a&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&e.scrollTo&&e.scrollTo(0,0),i=t.game.getProperty("css"),i&&W.cssRule(i),s=t.game.getProperty("html"),s&&W.write(s),u=t.game.getProperty("replace"),u&&W.searchReplace(u,"g",""),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),a?(f=t.game.getStageLevel(),f===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError(i+"searchReplace: prefix must be string, "+"null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){u=-1,o=e.length;for(;++un.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a=1&&(e[0].style.display="none")})(document.getElementsByTagName("noscript"))},1e3),this.init(c.defaults),t.silly("node-window: created.")}function h(e,t,n,r,i,s,o){var u,a;n=W.getElementById(r),u=W.getIFrameDocument(n).documentElement,i&&(u.innerHTML=e.cache[t].contents),r===e.frameName&&(e.frameWindow=n.contentWindow,e.frameDocument=e.getIFrameDocument(n),e.conf.rightClickDisabled&&J.disableRightClick(e.frameDocument),e.conf.noEscape&&(e.frameDocument.onkeydown=document.onkeydown)),e.styleElement=null,p(n),a=function(){v(n,e.globalLibs.concat(e.frameLibs.hasOwnProperty(t)?e.frameLibs[t]:[])),s&&(e.cache[t].contents=u.innerHTML),o(),b()},i?d(n,a):a()}function p(e){var t,n,r,i;n=W.getIFrameDocument(e),r=W.getElementsByClassName(n,"injectedlib","script");for(t=0;t=n.length&&r&&r()})}(o,a),e.frames[f].location.replace(o)},c.prototype.clearCache=function(){this.cache={}},c.prototype.getElementById=c.prototype.gid=function(e){var t,n;return n=this.getFrameDocument(),t=null,n&&n.getElementById&&(t=n.getElementById(e)),t||(t=document.getElementById(e)),t},c.prototype.getElementsByTagName=function(e){var t;return t=this.getFrameDocument(),t?t.getElementsByTagName(e):document.getElementsByTagName(e)},c.prototype.getElementsByClassName=function(e,t){var n;return n=this.getFrameDocument()||document,J.getElementsByClassName(n,e,t)},c.prototype.loadFrame=function(e,n,r){var i,s,o,u,a,f,p,d,v,g,b,w,E;if("string"!=typeof e)throw new TypeError("GameWindow.loadFrame: uri must be string. Found: "+e);if(n&&"function"!=typeof n)throw new TypeError("GameWindow.loadFrame: func must be function or undefined. Found: "+n);if(r&&"object"!=typeof r)throw new TypeError("GameWindow.loadFrame: opts must be object or undefined. Found: "+r);r=r||{},p=this.getFrame(),d=this.frameName;if(!p)throw new Error("GameWindow.loadFrame: no frame found");if(!d)throw new Error("GameWindow.loadFrame: frame has no name");this.setStateLevel("LOADING"),i=this,g=p.contentWindow,v=W.getIFrameDocument(p),w=v.readyState,w=w==="complete",s=c.defaults.cacheDefaults.loadCache,u=c.defaults.cacheDefaults.storeCacheNow,a=c.defaults.cacheDefaults.storeCacheLater;if(r.cache){if(r.cache.loadMode)if(r.cache.loadMode==="reload")s=!1;else{if(r.cache.loadMode!=="cache")throw new Error("GameWindow.loadFrame: unkown cache load mode: "+r.cache.loadMode);s=!0,o=!0}if(r.cache.storeMode)if(r.cache.storeMode==="off")u=!1,a=!1;else{if(r.cache.storeMode==="onLoad")u=!0,a=!1;else{if(r.cache.storeMode!=="onClose")throw new Error("GameWindow.loadFrame: unkown cache store mode: "+r.cache.storeMode);u=!1,a=!0}o=!0}}f="undefined"==typeof r.scrollUp?!0:r.scrollUp,this.unprocessedUri=e,o=!0;if(o&&this.cacheSupported===null){this.preCacheTest(function(){i.loadFrame(e,n,r)});return}e=this.processUri(e),this.cacheSupported===!1?(u=!1,a=!1,s=!1):(E=this.currentURIs[d],this.cache.hasOwnProperty(E)&&this.cache[E].cacheOnClose&&(b=v.documentElement,this.cache[E].contents=b.innerHTML),this.cache.hasOwnProperty(e)||(this.cache[e]={contents:null,cacheOnClose:!1}),this.cache[e].cacheOnClose=a,this.cache[e].contents===null&&(s=!1)),this.currentURIs[d]=e,m(this,1),p.style.visibility="hidden",(!s||!w)&&l(p,function(){i.directFrameDocumentAccess===null&&y(i),h(i,e,p,d,s,u,function(){i.updateLoadFrameState(n,f)})}),s?w&&h(this,e,p,d,s,u,function(){i.updateLoadFrameState(n,f)}):g.location.replace(e),g.node=t},c.prototype.processUri=function(e){return e.charAt(0)!=="/"&&e.substr(0,7)!=="http://"&&(this.uriPrefix&&(e=this.uriPrefix+e),this.uriChannel&&(e=this.uriChannel+e)),e},c.prototype.updateLoadFrameState=function(n,r){var i,s,u,a,f;a=m(this,-1),a&&this.setStateLevel("LOADED"),n&&n.call(t.game),r&&e.scrollTo&&e.scrollTo(0,0),i=t.game.getProperty("css"),i&&W.cssRule(i),s=t.game.getProperty("html"),s&&W.write(s),u=t.game.getProperty("replace"),u&&W.searchReplace(u,"g",""),t.events.ee.game.emit("FRAME_LOADED"),t.events.ee.stage.emit("FRAME_LOADED"),t.events.ee.step.emit("FRAME_LOADED"),a?(f=t.game.getStageLevel(),f===o&&t.emit("LOADED")):t.silly("game-window: "+this.areLoading+" frames "+"still loading.")},c.prototype.clearPageBody=function(){this.reset(),document.body.innerHTML=""},c.prototype.clearPage=function(){this.reset();try{document.documentElement.innerHTML=""}catch(e){this.removeChildrenFromNode(document.documentElement)}},c.prototype.setUriPrefix=function(e){if(e!==null&&"string"!=typeof e)throw new TypeError("GameWindow.setUriPrefix: uriPrefix must be string or null. Found: "+e);this.conf.uriPrefix=this.uriPrefix=e},c.prototype.setUriChannel=function(e){if("string"==typeof e)e.charAt(0)!=="/"&&(e="/"+e),e.charAt(e.length-1)!=="/"&&(e+="/");else if(e!==null)throw new TypeError("GameWindow.uriChannel: uriChannel must be string or null. Found: "+e);this.uriChannel=e},c.prototype.adjustFrameHeight=function(){var t,n;return n=function(t){var n,r,i;W.adjustHeaderOffset(),n=W.getFrame();if(!n||!n.contentWindow)return;if(!n.contentWindow.document.body){W.adjustFrameHeight(t,120);return}W.conf.adjustFrameHeight===!1?r="100vh":(r=e.innerHeight||e.clientHeight,i=n.contentWindow.document.body.offsetHeight,i+=60,W.headerPosition==="top"&&(i+=W.headerOffset),rDo not refresh the page!
Maximum Waiting Time: ",countdownResuming:e.countdownResumingText||"Resuming soon...",formatCountdown:function(e){var t;return t="",e=J.parseMilliseconds(e),e[2]&&(t+=e[2]+" min "),e[3]&&(t+=e[3]+" sec"),t||0}},this.lockedInputs=[],this.enable()}e.WaitScreen=l,l.version="0.10.0",l.description="Shows a waiting screen";var n,r;n=["button","select","textarea","input"],r=n.length,l.prototype.enable=function(){if(this.enabled)return;node.events.ee.game.on("REALLY_DONE",s),node.events.ee.game.on("STEPPING",o),node.events.ee.game.on("PLAYING",u),node.events.ee.game.on("PAUSED",a),node.events.ee.game.on("RESUMED",f),this.enabled=!0},l.prototype.disable=function(){if(!this.enabled)return;node.events.ee.game.off("REALLY_DONE",s),node.events.ee.game.off("STEPPING",o),node.events.ee.game.off("PLAYING",u),node.events.ee.game.off("PAUSED",a),node.events.ee.game.off("RESUMED",f),this.enabled=!1},l.prototype.lock=function(e,t){var n,r;r=this.defaultTexts,"undefined"==typeof e&&(e=r.locked),"undefined"==typeof document.getElementsByTagName&&node.warn("WaitScreen.lock: cannot lock inputs"),i(document),n=W.getFrameDocument(),n&&i(n),this.waitingDiv||(this.root||(this.root=W.getFrameRoot()||document.body),this.waitingDiv=W.add("div",this.root,this.id),this.contentDiv=W.add("div",this.waitingDiv,"ng_waitscreen-content-div")),this.waitingDiv.style.display==="none"&&(this.waitingDiv.style.display=""),this.contentDiv.innerHTML=e,this.displayCountdown&&t?(this.countdownDiv||(this.countdownDiv=W.add("div",this.waitingDiv,"ng_waitscreen-countdown-div"),this.countdownDiv.innerHTML=r.countdown,this.countdownSpan=W.add("span",this.countdownDiv,"ng_waitscreen-countdown-span")),this.countdown=t,this.countdownSpan.innerHTML=r.formatCountdown(t),this.countdownDiv.style.display="",this.countdownInterval=setInterval(function(){var e;e=W.waitScreen;if(!W.isScreenLocked()){clearInterval(e.countdownInterval);return}e.countdown-=1e3,e.countdown<0?(clearInterval(e.countdownInterval),e.countdownDiv.style.display="none",e.contentDiv.innerHTML=r.countdownResuming):e.countdownSpan.innerHTML=r.formatCountdown(e.countdown)},1e3)):this.countdownDiv&&(this.countdownDiv.style.display="none")},l.prototype.unlock=function(){var e,t;this.waitingDiv&&this.waitingDiv.style.display===""&&(this.waitingDiv.style.display="none"),this.countdownInterval&&clearInterval(this.countdownInterval);try{t=this.lockedInputs.length;for(e=-1;++e2&&(n=arguments[1],r=arguments[2]);if("undefined"==typeof r)r="ng_replace_";else if(null===r)r="";else if("string"!=typeof r)throw new TypeError(i+"searchReplace: prefix must be string, "+"null or undefined. Found: "+r);e=arguments[0];if(J.isArray(e)){u=-1,o=e.length;for(;++un.dt)return 1}else{if(e.dtn.dt)return-1}if(e.dt===n.dt){if("undefined"==typeof e.dd)return-1;if("undefined"==typeof n.dd)return 1;if(e.ddn.dd)return 1;if(e.nddbidn.nddbid)return-1}return 0},this.DL=e.list||document.createElement(this.FIRST_LEVEL),this.DL.id=e.id||this.id,e.className&&(this.DL.className=e.className),this.options.title&&this.DL.appendChild(document.createTextNode(e.title)),this.htmlRenderer=new r(e.render)},s.prototype._add=function(e){if(!e)return;this.insert(e),this.auto_update&&this.parse()},s.prototype.addDT=function(e,t){if("undefined"==typeof e)return;this.last_dt++,t="undefined"!=typeof t?t:this.last_dt,this.last_dd=0;var n=new o({dt:t,content:e});return this._add(n)},s.prototype.addDD=function(e,t,n){if("undefined"==typeof e)return;t="undefined"!=typeof t?t:this.last_dt,n="undefined"!=typeof n?n:this.last_dd++;var r=new o({dt:t,dd:n,content:e});return this._add(r)},s.prototype.parse=function(){this.sort();var e=null,t=null,n=function(){var n=document.createElement(this.SECOND_LEVEL);return this.DL.appendChild(n),t=null,e=n,n},r=function(){var e=document.createElement(this.THIRD_LEVEL);return this.DL.appendChild(e),e};if(this.DL){while(this.DL.hasChildNodes())this.DL.removeChild(this.DL.firstChild);this.options.title&&this.DL.appendChild(document.createTextNode(this.options.title))}for(var i=0;ithis.pointers[e])this.pointers[e]=t;return this.pointers[e]},u.prototype.addMultiple=function(e,t,n,r){var i,s,o,u;f("addMultiple",e,n,r);if(t&&"string"!=typeof t||t&&"undefined"==typeof this.pointers[t])throw new TypeError("Table.addMultiple: dim must be a valid dimension (x or y) or undefined.");t=t||"x",n=this.getCurrPointer("x",n),r=this.getNextPointer("y",r),n="undefined"!=typeof n?n:this.pointers.x===null?0:this.pointers.x,r="undefined"!=typeof r?r:this.pointers.y===null?0:this.pointers.y,J.isArray(e)||(e=[e]),i=-1,s=e.length;for(;++ih+1){d=this.db[u].y-(h+1);for(a=0;a Date: Mon, 18 Nov 2024 12:36:59 +0100 Subject: [PATCH 13/15] W.shake --- lib/modules/extra.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lib/modules/extra.js b/lib/modules/extra.js index 7c39779..3941fc9 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -629,6 +629,41 @@ return el; }; + /** + * ## GameWindow.shake + * + * Shakes an element briefly and adds the invalid class + * + * Adds a listener to remove the invalid class on change. + * + * @param {string|HTMLElement} idOrObj The id of or the HTML element itself + * + * @return {HTMLElement} The shaken element, if found + * + */ + GameWindow.prototype.shake = function(idOrObj) { + var el, listener; + el = getElement(idOrObj); + if (el) { + el.classList.add('is-invalid'); + el.classList.add('shake'); // Add shake class + setTimeout(function() { + el.classList.remove('shake'); + }, 500); // Match animation duration + + // Add an event listener that removes the invalid class if + // the element is interacted with. + listener = function() { + el.classList.remove('is-invalid'); + el.removeEventListener('change', listener); + }; + + el.addEventListener('change', listener); + } + return el; + }; + + // ## Helper Functions /** From a9d3bd09f28bc8f40a03e24d8f0d5bce14bd6281 Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Tue, 19 Nov 2024 21:15:10 +0100 Subject: [PATCH 14/15] fadein fadeout --- lib/modules/extra.js | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/lib/modules/extra.js b/lib/modules/extra.js index 3941fc9..75b0050 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -663,9 +663,75 @@ return el; }; + /** + * ## GameWindow.fadeIn + * + * Fades in an element + * + * @param {string|HTMLElement} idOrObj The id of or the HTML element itself + * @param {object} opts Configuration options + * + * @return {HTMLElement|null} The faded-in element if found, null otherwise + * + * @see _fade + */ + GameWindow.prototype.fadeIn = function(idOrObj, opts) { + return _fade(false, idOrObj, opts); + }; + + /** + * ## GameWindow.fadeOut + * + * Fades out an element + * + * @param {string|HTMLElement} idOrObj The id of or the HTML element itself + * @param {object} opts Configuration options + * + * @return {HTMLElement|null} The faded-out element if found, null otherwise + * + * @see _fade + */ + GameWindow.prototype.fadeOut = function(idOrObj, opts) { + return _fade(true, idOrObj, opts); + }; + + // ## Helper Functions + /** + * Fades an element in or out and adjust the frame height + * + * @param {boolean} out True if it is a fadeOut event, False otherwise + * @param {string|HTMLElement} idOrObj The id of or the HTML element itself + * @param {object} opts Configuration options: + * - `display`: The display property for the faded element + * - `adjustFrameHeight`: If not FALSE, W.adjustFrameHeight is called + * + * @return {HTMLElement|null} The faded* element if found, null otherwise + */ + function _fade(out, idOrObj, opts) { + var el, classRem, classAdd, defDisplay; + el = getElement(idOrObj); + if (!el) return null; + if (out) { + classRem = 'fadein'; + classAdd = 'fadeout'; + defDisplay = 'none'; + } + else { + classRem = 'fadeout'; + classAdd = 'fadein'; + defDisplay = ''; + } + opts = opts || {}; + el.classList.remove(classRem); + el.classList.add(classAdd); + el.style.display = opts.display || defDisplay; + if (opts.adjustFrameHeight !== false) W.adjustFrameHeight(); + return el; + } + /** * ### toggleInputs * From 9bd043dcb6751b4268dbbd8342ed038b2c850972 Mon Sep 17 00:00:00 2001 From: Stefano Balietti Date: Mon, 25 Nov 2024 12:12:58 +0100 Subject: [PATCH 15/15] W.isRtl --- lib/modules/extra.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/modules/extra.js b/lib/modules/extra.js index 75b0050..78310ef 100644 --- a/lib/modules/extra.js +++ b/lib/modules/extra.js @@ -694,6 +694,32 @@ GameWindow.prototype.fadeOut = function(idOrObj, opts) { return _fade(true, idOrObj, opts); }; + + + /** + * ### GameWindow.isRTL + * + * Returns TRUE is the page is written right to left + * + * Results are cached. + * + * @param {boolean} force If truthy, it resets the cache; + * if HTMLElement, it checks within that element. + * + * @returns {boolean} TRUE if the page is RTL + */ + GameWindow.prototype.isRTL = GameWindow.prototype.isRtl = (function(cache) { + return function(force) { + var d; + if ('undefined' === typeof cache || force) { + d = J.isElement(force) ? force : document.documentElement; + cache = d.dir === 'rtl' || + ('function' === typeof getComputedStyle && + getComputedStyle(d).direction === 'rtl'); + } + return cache; + }; + })();