move code up one directory
[atutor.git] / jscripts / infusion / framework / renderer / js / RendererUtilities.js
1 fluid_1_4=fluid_1_4||{};(function($,fluid){if(!fluid.renderer){fluid.fail("fluidRenderer.js is a necessary dependency of RendererUtilities")}fluid.iota=function(count,first){first=first||0;var togo=[];for(var i=0;i<count;++i){togo[togo.length]=first++}return togo};fluid.renderer.visitDecorators=function(that,visitor){fluid.visitComponentChildren(that,function(component,name){if(name.indexOf(fluid.renderer.decoratorComponentPrefix)===0){visitor(component,name)}},{flat:true})};fluid.renderer.clearDecorators=function(instantiator,that){fluid.renderer.visitDecorators(that,function(component,name){instantiator.clearComponent(that,name)})};fluid.renderer.getDecoratorComponents=function(that){var togo={};fluid.renderer.visitDecorators(that,function(component,name){togo[name]=component});return togo};fluid.renderer.modeliseOptions=function(options,defaults,baseOptions){return $.extend({},defaults,options,fluid.filterKeys(baseOptions,["model","applier"]))};fluid.renderer.reverseMerge=function(target,source,names){names=fluid.makeArray(names);fluid.each(names,function(name){if(target[name]===undefined&&source[name]!==undefined){target[name]=source[name]}})};fluid.renderer.createRendererSubcomponent=function(container,selectors,options,baseObject,fossils){options=options||{};var source=options.templateSource?options.templateSource:{node:$(container)};var rendererOptions=fluid.renderer.modeliseOptions(options.rendererOptions,null,baseObject);rendererOptions.fossils=fossils||{};var expanderOptions=fluid.renderer.modeliseOptions(options.expanderOptions,{ELstyle:"${}"},baseObject);fluid.renderer.reverseMerge(expanderOptions,options,["resolverGetConfig","resolverSetConfig"]);var that={};if(!options.noexpand){that.expander=fluid.renderer.makeProtoExpander(expanderOptions)}var templates=null;that.render=function(tree){var cutpointFn=options.cutpointGenerator||"fluid.renderer.selectorsToCutpoints";rendererOptions.cutpoints=rendererOptions.cutpoints||fluid.invokeGlobalFunction(cutpointFn,[selectors,options]);container=typeof (container)==="function"?container():$(container);if(templates){fluid.clear(rendererOptions.fossils);fluid.reRender(templates,container,tree,rendererOptions)}else{if(typeof (source)==="function"){source=source()}templates=fluid.render(source,container,tree,rendererOptions)}};return that};fluid.defaults("fluid.rendererComponent",{gradeNames:["fluid.viewComponent"],initFunction:"fluid.initRendererComponent",mergePolicy:{protoTree:"noexpand, replace"},rendererOptions:{autoBind:true},events:{prepareModelForRender:null,onRenderTree:null,afterRender:null,produceTree:"unicast"}});fluid.initRendererComponent=function(componentName,container,options){var that=fluid.initView(componentName,container,options,{gradeNames:["fluid.rendererComponent"]});fluid.fetchResources(that.options.resources);var rendererOptions=fluid.renderer.modeliseOptions(that.options.rendererOptions,null,that);if(!that.options.noUpgradeDecorators){fluid.withInstantiator(that,function(currentInst){rendererOptions.instantiator=currentInst;rendererOptions.parentComponent=that})}var messageResolver;if(!rendererOptions.messageSource&&that.options.strings){messageResolver=fluid.messageResolver({messageBase:that.options.strings,resolveFunc:that.options.messageResolverFunction,parents:fluid.makeArray(that.options.parentBundle)});rendererOptions.messageSource={type:"resolver",resolver:messageResolver}}fluid.renderer.reverseMerge(rendererOptions,that.options,["resolverGetConfig","resolverSetConfig"]);var rendererFnOptions=$.extend({},that.options.rendererFnOptions,{rendererOptions:rendererOptions,repeatingSelectors:that.options.repeatingSelectors,selectorsToIgnore:that.options.selectorsToIgnore,expanderOptions:{envAdd:{styles:that.options.styles}}});if(that.options.resources&&that.options.resources.template){rendererFnOptions.templateSource=function(){return that.options.resources.template.resourceText}}var produceTree=that.events.produceTree;produceTree.addListener(function(){return that.options.protoTree});if(that.options.produceTree){produceTree.addListener(that.options.produceTree)}fluid.renderer.reverseMerge(rendererFnOptions,that.options,["resolverGetConfig","resolverSetConfig"]);if(rendererFnOptions.rendererTargetSelector){container=function(){return that.dom.locate(rendererFnOptions.rendererTargetSelector)}}var renderer={fossils:{},boundPathForNode:function(node){return fluid.boundPathForNode(node,renderer.fossils)}};var rendererSub=fluid.renderer.createRendererSubcomponent(container,that.options.selectors,rendererFnOptions,that,renderer.fossils);that.renderer=$.extend(renderer,rendererSub);if(messageResolver){that.messageResolver=messageResolver}that.refreshView=renderer.refreshView=function(){if(rendererOptions.instantiator&&rendererOptions.parentComponent){fluid.renderer.clearDecorators(rendererOptions.instantiator,rendererOptions.parentComponent)}that.events.prepareModelForRender.fire(that.model,that.applier,that);var tree=produceTree.fire(that);if(that.renderer.expander){tree=that.renderer.expander(tree)}that.events.onRenderTree.fire(that,tree);that.renderer.render(tree);that.events.afterRender.fire(that)};if(that.options.renderOnInit){that.refreshView()}return that};var removeSelectors=function(selectors,selectorsToIgnore){fluid.each(fluid.makeArray(selectorsToIgnore),function(selectorToIgnore){delete selectors[selectorToIgnore]});return selectors};var markRepeated=function(selectorKey,repeatingSelectors){if(repeatingSelectors){fluid.each(repeatingSelectors,function(repeatingSelector){if(selectorKey===repeatingSelector){selectorKey=selectorKey+":"}})}return selectorKey};fluid.renderer.selectorsToCutpoints=function(selectors,options){var togo=[];options=options||{};selectors=fluid.copy(selectors);if(options.selectorsToIgnore){selectors=removeSelectors(selectors,options.selectorsToIgnore)}for(var selectorKey in selectors){togo.push({id:markRepeated(selectorKey,options.repeatingSelectors),selector:selectors[selectorKey]})}return togo};fluid.renderer.NO_COMPONENT={};fluid.renderer.mergeComponents=function(target,source){for(var key in source){target[key]=source[key]}return target};fluid.registerNamespace("fluid.renderer.selection");fluid.renderer.selection.inputs=function(options,container,key,config){fluid.expect("Selection to inputs expander",["selectID","inputID","labelID","rowID"],options);var selection=config.expander(options.tree);var rows=fluid.transform(selection.optionlist.value,function(option,index){var togo={};var element={parentRelativeID:"..::"+options.selectID,choiceindex:index};togo[options.inputID]=element;togo[options.labelID]=fluid.copy(element);return togo});var togo={};togo[options.selectID]=selection;togo[options.rowID]={children:rows};togo=config.expander(togo);return togo};fluid.renderer.repeat=function(options,container,key,config){fluid.expect("Repetition expander",["controlledBy","tree"],options);var path=fluid.extractContextualPath(options.controlledBy,{ELstyle:"ALL"},fluid.threadLocal());var list=fluid.get(config.model,path,config.resolverGetConfig);var togo={};if(!list||list.length===0){return options.ifEmpty?config.expander(options.ifEmpty):togo}var expanded=[];fluid.each(list,function(element,i){var EL=fluid.model.composePath(path,i);var envAdd={};if(options.pathAs){envAdd[options.pathAs]=EL}if(options.valueAs){envAdd[options.valueAs]=fluid.get(config.model,EL,config.resolverGetConfig)}var expandrow=fluid.withEnvironment(envAdd,function(){return config.expander(options.tree)},"rendererEnvironment");if(fluid.isArrayable(expandrow)){if(expandrow.length>0){expanded.push({children:expandrow})}}else{if(expandrow!==fluid.renderer.NO_COMPONENT){expanded.push(expandrow)}}});var repeatID=options.repeatID;if(repeatID.indexOf(":")===-1){repeatID=repeatID+":"}fluid.each(expanded,function(entry){entry.ID=repeatID});return expanded};fluid.renderer.condition=function(options,container,key,config){fluid.expect("Selection to condition expander",["condition"],options);var condition;if(options.condition.funcName){var args=config.expandLight(options.condition.args);condition=fluid.invoke(options.condition.funcName,args)}else{if(options.condition.expander){condition=config.expander(options.condition)}else{condition=config.expandLight(options.condition)}}var tree=(condition?options.trueTree:options.falseTree);if(!tree){tree=fluid.renderer.NO_COMPONENT}return config.expander(tree)};fluid.extractContextualPath=function(string,options,env){var parsed=fluid.extractELWithContext(string,options);if(parsed){if(parsed.context){var fetched=env[parsed.context];if(typeof (fetched)!=="string"){fluid.fail("Could not look up context path named "+parsed.context+" to string value")}return fluid.model.composePath(fetched,parsed.path)}else{return parsed.path}}};fluid.renderer.makeProtoExpander=function(expandOptions){var options=$.extend({ELstyle:"${}"},expandOptions);options.fetcher=fluid.makeEnvironmentFetcher("rendererEnvironment",options.model);var IDescape=options.IDescape||"\\";function fetchEL(string){var env=fluid.threadLocal().rendererEnvironment;return fluid.extractContextualPath(string,options,env)}var expandLight=function(source){return fluid.resolveEnvironment(source,options)};var expandBound=function(value,concrete){if(value.messagekey!==undefined){return{componentType:"UIMessage",messagekey:expandBound(value.messagekey),args:expandLight(value.args)}}var proto;if(!fluid.isPrimitive(value)&&!fluid.isArrayable(value)){proto=$.extend({},value);if(proto.decorators){proto.decorators=expandLight(proto.decorators)}value=proto.value;delete proto.value}else{proto={}}var EL=typeof (value)==="string"?fetchEL(value):null;if(EL){proto.valuebinding=EL}else{if(value!==undefined){proto.value=value}}if(options.model&&proto.valuebinding&&proto.value===undefined){proto.value=fluid.get(options.model,proto.valuebinding,options.resolverGetConfig)}if(concrete){proto.componentType="UIBound"}return proto};options.filter=fluid.expander.lightFilter;var expandCond;var expandLeafOrCond;var expandEntry=function(entry){var comp=[];expandCond(entry,comp);return{children:comp}};var expandExternal=function(entry){if(entry===fluid.renderer.NO_COMPONENT){return entry}var singleTarget;var target=[];var pusher=function(comp){singleTarget=comp};expandLeafOrCond(entry,target,pusher);return singleTarget||target};var expandConfig={model:options.model,resolverGetConfig:options.resolverGetConfig,resolverSetConfig:options.resolverSetConfig,expander:expandExternal,expandLight:expandLight};var expandLeaf=function(leaf,componentType){var togo={componentType:componentType};var map=fluid.renderer.boundMap[componentType]||{};for(var key in leaf){if(/decorators|args/.test(key)){togo[key]=expandLight(leaf[key]);continue}else{if(map[key]){togo[key]=expandBound(leaf[key])}else{togo[key]=leaf[key]}}}return togo};var expandChildren=function(entry,pusher){var children=entry.children;for(var i=0;i<children.length;++i){var target=[];var comp={children:target};var child=children[i];var childPusher=function(comp){target[target.length]=comp};expandLeafOrCond(child,target,childPusher);if(comp.children.length===1&&!comp.children[0].ID){comp=comp.children[0]}pusher(comp)}};function detectBareBound(entry){return fluid.find(entry,function(value,key){return key==="decorators"})!==false}var expandLeafOrCond=function(entry,target,pusher){var componentType=fluid.renderer.inferComponentType(entry);if(!componentType&&(fluid.isPrimitive(entry)||detectBareBound(entry))){componentType="UIBound"}if(componentType){pusher(componentType==="UIBound"?expandBound(entry,true):expandLeaf(entry,componentType))}else{if(!target){fluid.fail("Illegal cond->cond transition")}expandCond(entry,target)}};expandCond=function(proto,target){for(var key in proto){var entry=proto[key];if(key.charAt(0)===IDescape){key=key.substring(1)}if(key==="expander"){var expanders=fluid.makeArray(entry);fluid.each(expanders,function(expander){var expanded=fluid.invokeGlobalFunction(expander.type,[expander,proto,key,expandConfig]);if(expanded!==fluid.renderer.NO_COMPONENT){fluid.each(expanded,function(el){target[target.length]=el})}})}else{if(entry){var condPusher=function(comp){comp.ID=key;target[target.length]=comp};if(entry.children){if(key.indexOf(":")===-1){key=key+":"}expandChildren(entry,condPusher)}else{if(fluid.renderer.isBoundPrimitive(entry)){condPusher(expandBound(entry,true))}else{expandLeafOrCond(entry,null,condPusher)}}}}}};return function(entry){var initEnvironment=$.extend({},options.envAdd);return fluid.withEnvironment({rendererEnvironment:initEnvironment},function(){return expandEntry(entry)})}}})(jQuery,fluid_1_4);