-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplaindata-tools.js
1 lines (1 loc) · 13.7 KB
/
plaindata-tools.js
1
(function(plaindata){"use strict";plaindata.sortAccessor=function(accessor){if(plaindata.isArray(accessor)){accessor.sort(function(a,b){var ta=typeof a;var tb=typeof b;if(a===null)ta="null";if(b===null)tb="null";if(ta===tb){if(a<b)return-1;if(a>b)return 1;if(plaindata.isObject(a)&&plaindata.isObject(b)&&a.$so.originalId&&b.$so.originalId){a=a.$so.originalId;b=b.$so.originalId;if(a<b)return-1;if(a>b)return 1}return 0}if(ta<tb)return-1;if(ta>tb)return 1;return 0})}for(var prop in accessor){if(plaindata.isObject(accessor[prop])){plaindata.sortAccessor(accessor[prop])}}};plaindata.compareOriginals=function(debug,a,b){if(!plaindata.isOriginal(a)){if(debug&&a!=b)console.warn("primitive comparision "+a+" and "+b+" failed");return a==b}if(a.$so.parent&&b.$so.parent){if(a.$so.originalId!=b.$so.originalId){if(debug)console.warn("one id mismatch with other id node "+a.$so.originalId+" vs. "+b.$so.originalId);return false}}if(plaindata.isArray(a)){if(!plaindata.isArray(b)){if(debug)console.warn("one array, other object mismatch at node "+a.$so.originalId);return false}a=a.sort();b=b.sort();if(a.length!=b.length){if(debug)console.warn("array length mismatch "+a.length+" vs. "+b.length+" at node "+a.$so.originalId);return false}for(var i=0;i<a.length;i++){this.compareOriginals(debug,a[i],b[i])}}else{if(plaindata.isArray(b)){if(debug)console.warn("one object, other array mismatch at node "+a.$so.originalId);return false}for(var prop in b){if(typeof a[prop]=="undefined"){if(debug)console.warn("a misses property '"+prop+"' of b in "+a.$so.originalId);return false}}for(var prop in a){if(typeof b[prop]=="undefined"){if(debug)console.warn("b misses property '"+prop+"' of a in "+a.$so.originalId);return false}this.compareOriginals(debug,a[prop],b[prop])}}return true},plaindata.debugActions=function(accessor){var original=accessor.$so["original"];var plainStore=original.$so["plainStore"];for(var originalId in plainStore.actionsByOriginalId){var actions=plainStore.actionsByOriginalId[originalId];original=actions.$so.original;var originalName="";if(actions.$so.original.$so.name)originalName=actions.$so.original.$so.parent.$so.originalId+"["+actions.$so.original.$so.name+"]";console.log("actions on "+originalId+" "+originalName);for(var i=0;i<actions.length;i++){var action=actions[i];var propagated="";if(action.method==plaindata.UPDATE&&plaindata.isOriginal(original[action.prop]))propagated=" *propagated*";console.log(" "+action.method+" "+action.prop+propagated)}}console.log("---")};plaindata.parentAccessor=function(accessor){if(accessor.$so.original.$so.parent){return accessor.$so.original.$so.parent.$so.accessors[accessor.$so.accessorId]}return undefined};plaindata.accessorName=function(accessor){return accessor.$so.original.$so.name};plaindata.chkAccessor=function(debug,accessor,prefix,accessorId,original){if(typeof accessor.$so=="undefined"){console.warn("no secretObject in accessor");return}if(typeof prefix=="undefined"){return plaindata.chkOriginal(debug,accessor.$so["original"],"")}if(typeof accessor.$so["accessorId"]=="undefined"){console.warn("no accessorId ref in accessor "+accessorId);return false}if(accessor.$so["accessorId"]!=accessorId){console.warn("wrong accessorId ref in accessor "+accessorId);return false}if(typeof accessor.$so["original"]=="undefined"){console.warn("no original ref in accessor "+accessorId);return false}if(accessor.$so["original"]!=original){console.warn("wrong original ref in accessor "+accessorId);return false}if(!plaindata.isArray(accessor.$so["listeners"])){console.warn("no listeners array in accessor "+accessorId);return false}var listeners=accessor.$so["listeners"];if(debug){console.log(prefix+"accessor["+accessorId+"]: "+listeners.length+" listeners")}for(var prop in accessor){if(!plaindata.isObject(original[prop])&&accessor[prop]!=original[prop]){console.warn("value mismatch on property "+prop)}}return true};plaindata.chkOriginal=function(debug,original,prefix,plainStore,name,parent){var result=true;if(typeof original.$so=="undefined"){console.warn("no secretObject in original");return false}if(typeof original.$so["plainStore"]=="undefined"){console.warn("no plainStore ref in original");return false}if(typeof plainStore=="undefined")plainStore=original.$so["plainStore"];else if(plainStore!=original.$so["plainStore"]){console.warn("wrong plainStore ref in original");return false}if(typeof original.$so["originalId"]=="undefined"){console.warn("no originalId in original");return false}var originalId=original.$so["originalId"];if(typeof plainStore.originalById[originalId]=="undefined"){console.warn("originalId "+originalId+" not in store lookup table originalById");return false}if(plainStore.originalById[originalId]!=original){console.warn("originalById["+originalId+"] not correctly points back to original");return false}if(typeof original.$so["accessors"]=="undefined"){console.warn("no accessors in original "+originalId);return false}var accessors=original.$so["accessors"];if(name&&typeof original.$so["name"]=="undefined"){console.warn("no name property in original "+originalId+" should be:"+name);return false}if(name&&original.$so["name"]!=name){console.warn("wrong name in original "+originalId+" is:"+original.$so["name"]+" should be:"+name);return false}if(parent&&typeof original.$so["parent"]=="undefined"){console.warn("no parent property in original "+originalId);return false}if(parent&&original.$so["parent"]!=parent){console.warn("wrong parent in original "+originalId);return false}if(typeof name=="undefined")name="";if(debug){console.log(prefix+"original["+originalId+"] "+name);for(var prop in original){if(!plaindata.isObject(original[prop])){console.log(prefix+" "+prop+":"+original[prop]+" "+typeof original[prop])}}}for(var accessorId in accessors){if(typeof plainStore.accessors[accessorId]=="undefined"){console.warn("accessor id "+accessorId+" in original "+originalId+" not in plainstore");return false}result=result&&plaindata.chkAccessor(debug,accessors[accessorId],prefix+" ",accessorId,original)}for(var prop in original){if(plaindata.isObject(original[prop])){result=result&&plaindata.chkOriginal(debug,original[prop],prefix+" ",plainStore,prop,original)}}return result};plaindata.exists=function(accessor,path){var array;if(plaindata.isArray(path)){array=path}else{array=path.split("/")}var p=accessor;for(var i=0;i<array.length;i++){p=p[array[i]];if(p===null||typeof p==="undefined")return false}return true};plaindata.loadNodeDescriptions=function(pathes,whenReady){var plaincodeInfos={};var loaded=0;var count=3;pathes.forEach(function(path){var timeout=setTimeout(function(){whenReady(plaincodeInfos)},3e3);$.getJSON(path,function(data){clearTimeout(timeout);data.origin=path;plaincodeInfos[path]=data;if(++loaded===pathes.length){var baseURL="";var index=path.lastIndexOf("/");if(index>=0){baseURL=path.substring(0,index+1)}whenReady(plaincodeInfos,baseURL)}})})};plaindata.accessorCount=function(accessor){return Object.keys(accessor.$so["original"].$so["plainStore"].accessors).length};function NodeController(nodeDescription,webView){var THIS=this;if(!plaindata.isObject(nodeDescription)){THIS.errorText="nodeDescription argument for "+name+" is not a valid object "+nodeDescription;console.error(THIS.errorText);return}THIS.nodeDescription=nodeDescription;if(!THIS.nodeDescription.type){THIS.errorText="missing type in node description";console.error(THIS.errorText);return}if(THIS.nodeDescription.type==="html"){THIS.webView=webView}else if(THIS.nodeDescription.type==="javascript"){}else{THIS.errorText="unsupported type "+THIS.nodeDescription.type;console.error(THIS.errorText);return}THIS.input={};THIS.inputCreatedAccessor={};THIS.baseURL="";THIS.errorText="";THIS.state="stopped"}NodeController.prototype.setStateCallback=function(stateCallback){var THIS=this;THIS.stateCallback=stateCallback};NodeController.prototype.setLocale=function(locale){var THIS=this;THIS.locale=locale};NodeController.prototype.setInput=function(name,accessor){var THIS=this;if(THIS.state==="started"){console.warn("stopping node since input is reset");THIS.stop()}if(accessor===THIS.input[name])return;if(THIS.inputCreatedAccessor[name]){console.log("removing previously created accessor");if(plaindata.removeAccessor(THIS.inputCreatedAccessor[name])){console.log("success")}delete THIS.inputCreatedAccessor[name]}if(!accessor){if(THIS.input[name]){delete THIS.input[name]}return}else if(!plaindata.isAccessor(accessor)){accessor=plaindata.createAccessor(accessor);THIS.inputCreatedAccessor[name]=accessor}THIS.input[name]=accessor};NodeController.prototype.getInput=function(name){var THIS=this;return THIS.input[name]};NodeController.prototype.getOutput=function(name){var THIS=this;if(this.state!=="started")return;if(!THIS.nodeDescription.output[name]){console.error("no output with name "+name+" in "+THIS.nodeDescription.src);return}var getter=new Function("with(this) return "+THIS.nodeDescription.output[name].getter);try{var accessor=getter.call(THIS.callee(),THIS.input[name]);if(!plaindata.isAccessor(accessor)){throw"implementation of "+name+" in "+THIS.nodeDescription.src+" must implement accessor "+THIS.nodeDescription.output[name].getter}}catch(err){console.error(err);THIS.state="failed";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"failed");return}return accessor};NodeController.prototype.start=function(){var THIS=this;if(THIS.state==="started"||THIS.state==="undefined")return;THIS.state="undefined";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"undefined");if(THIS.nodeDescription.type==="javascript"){{var url=THIS.baseURL+THIS.nodeDescription.src;if(window.document.location.href.indexOf("file:")===0&&url.indexOf("/")!==0){url="file:"+url}if(true){url+="?bust="+Math.random();console.warn("prevent caching "+url)}require([url],function(){try{console.log("calling here");THIS.plainNode=new Function(THIS.nodeDescription.constructor).apply(this);console.log("called here");if(!THIS.connectAndStart()){THIS.state="failed";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"failed")}}catch(err){console.error("call to connect and start failed "+err);setTimeout(function(){THIS.state="failed";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"failed")},0)}})}}else{if(THIS.locale&&THIS.nodeDescription.localizations&&THIS.nodeDescription.localizations.indexOf(THIS.locale)>=0){var s=THIS.nodeDescription.src;s=s.substring(0,s.length-".html".length);THIS.webView.src=[THIS.baseURL,s,"-",THIS.nodeDescription.localizations[0],".html"].join("")}else{THIS.webView.src=THIS.baseURL+THIS.nodeDescription.src}var webViewLoadTimeout=setTimeout(function(){console.error("node implementation of "+THIS.nodeDescription.title+" did fail to load "+THIS.webView.src);THIS.state="failed";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"failed")},10*1e3);$(THIS.webView).on("load",function(){clearTimeout(webViewLoadTimeout);try{if(!THIS.connectAndStart()){THIS.stop()}}catch(err){console.error("call to connect and start failed "+err);setTimeout(function(){THIS.state="failed";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"failed")},0)}$(THIS.webView.contentWindow).on("unload",function(){$(THIS.webView.contentWindow).off("unload");setTimeout(function(){THIS.state="stopped";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"stopped")},0)})})}};NodeController.prototype.stop=function(){var THIS=this;if(THIS.state!=="started")return;THIS.state="undefined";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"undefined");if(THIS.nodeDescription.stop)new Function(THIS.nodeDescription.stop).call(THIS.callee());if(THIS.nodeDescription.type==="javascript"){setTimeout(function(){THIS.state="stopped";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"stopped"),0})}else{$(THIS.webView).off("load");THIS.webView.src="about:blank"}};NodeController.prototype.connectAndStart=function(){var THIS=this;if(!THIS.setInputs()){console.error("set inputs failed");return false}var selfSignalStarted=true;if(THIS.nodeDescription.start)new Function("with(this)"+THIS.nodeDescription.start).call(THIS.callee());if(THIS.nodeDescription.startResult){var startResultTimout=setTimeout(function(){console.error("node implementation of "+THIS.nodeDescription.title+" did fail to report start result state");THIS.state="failed";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"failed")},30*1e3);new Function(THIS.nodeDescription.startResult).call(THIS.callee(),THIS,function(state){clearTimeout(startResultTimout);if(state==="started"||state==="failed"){THIS.state=state;if(THIS.stateCallback)THIS.stateCallback.call(THIS,state)}else{console.error("node implementation of "+THIS.nodeDescription.title+" reported unknown state "+state)}})}else{setTimeout(function(){THIS.state="started";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"started")},0)}return true};NodeController.prototype.callee=function(){var THIS=this;if(THIS.nodeDescription.type==="javascript")return THIS.plainNode;else return THIS.webView.contentWindow};NodeController.prototype.setInputs=function(){var THIS=this;for(var name in THIS.nodeDescription.input){if(THIS.input[name]){var setter=new Function("with(this)"+THIS.nodeDescription.input[name].setter.prefix+"arguments[0]"+THIS.nodeDescription.input[name].setter.suffix);setter.call(THIS.callee(),THIS.input[name])}else{if(THIS.nodeDescription.input[name].mandatory){THIS.errorText=name+" was not defined as input for "+THIS.nodeDescription.src;console.error(THIS.errorText);THIS.state="failed";if(THIS.stateCallback)THIS.stateCallback.call(THIS,"failed");return false}}}return true};plaindata.createNodeController=function(nodeDescription,webView){return new NodeController(nodeDescription,webView)};if(typeof window!="undefined")window.plaindata=plaindata;if(typeof module!=="undefined"&&module.exports){module.exports=plaindata}if(typeof define==="function"){define("plaindata-tools",[],function(){return plaindata})}if(typeof exports!=="undefined"){exports.plaindata=plaindata}})(typeof plaindata==="undefined"?require("plaindata"):plaindata);