4836: side menu inline edit now properly saved after exiting edit mode.
[acontent.git] / docs / include / jscripts / infusion / framework / core / js / DataBinding.js
1 fluid_1_1=fluid_1_1||{};(function($,fluid){fluid.VALUE={};fluid.BINDING_ROOT_KEY="fluid-binding-root";fluid.findData=function(elem,name){while(elem){var data=$.data(elem,name);if(data){return data}elem=elem.parentNode}};fluid.bindFossils=function(node,data,fossils){$.data(node,fluid.BINDING_ROOT_KEY,{data:data,fossils:fossils})};fluid.findForm=function(node){return fluid.findAncestor(node,function(element){return element.nodeName.toLowerCase()==="form"})};fluid.value=function(nodeIn,newValue){var node=fluid.unwrap(nodeIn);var multiple=false;if(node.nodeType===undefined&&node.length>1){node=node[0];multiple=true}var jNode=$(node);if("input"!==node.nodeName.toLowerCase()||!/radio|checkbox/.test(node.type)){return $(node).val(newValue)}var name=node.name;if(name===undefined){fluid.fail("Cannot acquire value from node "+fluid.dumpEl(node)+" which does not have name attribute set")}var elements;if(multiple){elements=nodeIn}else{var elements=document.getElementsByName(name);var scope=fluid.findForm(node);elements=$.grep(elements,function(element){if(element.name!==name){return false}return !scope||fluid.dom.isContainer(scope,element)})}if(newValue!==undefined){if(typeof (newValue)==="boolean"){newValue=(newValue?"true":"false")}$.each(elements,function(){this.checked=(newValue instanceof Array?$.inArray(this.value,newValue)!==-1:newValue===this.value)})}else{var checked=$.map(elements,function(element){return element.checked?element.value:null});return node.type==="radio"?checked[0]:checked}};fluid.applyChange=function(node,newValue,applier){node=fluid.unwrap(node);if(newValue===undefined){newValue=fluid.value(node)}if(node.nodeType===undefined&&node.length>0){node=node[0]}var root=fluid.findData(node,fluid.BINDING_ROOT_KEY);if(!root){fluid.fail("Bound data could not be discovered in any node above "+fluid.dumpEl(node))}var name=node.name;var fossil=root.fossils[name];if(!fossil){fluid.fail("No fossil discovered for name "+name+" in fossil record above "+fluid.dumpEl(node))}if(typeof (fossil.oldvalue)==="boolean"){newValue=newValue[0]?true:false}var EL=root.fossils[name].EL;if(applier){applier.fireChangeRequest({path:EL,value:newValue,source:node.id})}else{fluid.model.setBeanValue(root.data,EL,newValue)}};fluid.pathUtil={};var getPathSegmentImpl=function(accept,path,i){var segment=null;if(accept){segment=""}var escaped=false;var limit=path.length;for(;i<limit;++i){var c=path.charAt(i);if(!escaped){if(c==="."){break}else{if(c==="\\"){escaped=true}else{if(segment!==null){segment+=c}}}}else{escaped=false;if(segment!==null){accept+=c}}}if(segment!==null){accept[0]=segment}return i};var globalAccept=[];fluid.pathUtil.getPathSegment=function(path,i){getPathSegmentImpl(globalAccept,path,i);return globalAccept[0]};fluid.pathUtil.getHeadPath=function(path){return fluid.pathUtil.getPathSegment(path,0)};fluid.pathUtil.getFromHeadPath=function(path){var firstdot=getPathSegmentImpl(null,path,0);return firstdot===path.length?null:path.substring(firstdot+1)};function lastDotIndex(path){return path.lastIndexOf(".")}fluid.pathUtil.getToTailPath=function(path){var lastdot=lastDotIndex(path);return lastdot==-1?null:path.substring(0,lastdot)};fluid.pathUtil.getTailPath=function(path){var lastdot=lastDotIndex(path);return fluid.pathUtil.getPathSegment(path,lastdot+1)};var composeSegment=function(prefix,toappend){for(var i=0;i<toappend.length;++i){var c=toappend.charAt(i);if(c==="."||c==="\\"||c==="}"){prefix+="\\"}prefix+=c}return prefix};fluid.pathUtil.composePath=function(prefix,suffix){if(prefix.length!==0){prefix+="."}return composeSegment(prefix,suffix)};fluid.pathUtil.matchPath=function(spec,path){var togo="";while(true){if(!spec){break}if(!path){return null}var spechead=fluid.pathUtil.getHeadPath(spec);var pathhead=fluid.pathUtil.getHeadPath(path);if(spechead!=="*"&&spechead!==pathhead){return null}togo=fluid.pathUtil.composePath(togo,pathhead);spec=fluid.pathUtil.getFromHeadPath(spec);path=fluid.pathUtil.getFromHeadPath(path)}return togo};fluid.model.applyChangeRequest=function(model,request){if(request.type==="ADD"){fluid.model.setBeanValue(model,request.path,request.value)}else{if(request.type==="DELETE"){var totail=fluid.pathUtil.getToTailPath(request.path);var tail=fluid.pathUtil.getTailPath(request.path);var penult=fluid.model.getBeanValue(model,penult);delete penult[tail]}}};fluid.makeChangeApplier=function(model){var baseEvents={guards:fluid.event.getEventFirer(false,true),modelChanged:fluid.event.getEventFirer(false,false)};var that={model:model};function makePredicate(listenerMember,requestIndex){return function(listener,args){var changeRequest=args[requestIndex];return fluid.pathUtil.matchPath(listener[listenerMember],changeRequest.path)}}function adaptListener(that,name,listenerMember,requestIndex){var predicate=makePredicate(listenerMember,requestIndex);that[name]={addListener:function(pathSpec,listener,namespace){listener[listenerMember]=pathSpec;baseEvents[name].addListener(listener,namespace,predicate)},removeListener:function(listener){baseEvents[name].removeListener(listener)}}}adaptListener(that,"guards","guardedPathSpec",1);adaptListener(that,"modelChanged","triggerPathSpec",2);that.fireChangeRequest=function(changeRequest){if(!changeRequest.type){changeRequest.type="ADD"}var prevent=baseEvents.guards.fire(model,changeRequest);if(prevent===false){return }var oldModel={};fluid.model.copyModel(oldModel,model);fluid.model.applyChangeRequest(model,changeRequest);baseEvents.modelChanged.fire(model,oldModel,changeRequest)};that.requestChange=function(path,value,type){var changeRequest={path:path,value:value,type:type};that.fireChangeRequest(changeRequest)};return that};fluid.makeSuperApplier=function(){var subAppliers=[];var that={};that.addSubApplier=function(path,subApplier){subAppliers.push({path:path,subApplier:subApplier})};that.fireChangeRequest=function(request){for(var i=0;i<subAppliers.length;++i){var path=subAppliers[i].path;if(request.path.indexOf(path)===0){var subpath=request.path.substring(path.length+1);var subRequest=fluid.copy(request);subRequest.path=subpath;subAppliers[i].subApplier.fireChangeRequest(subRequest)}}};return that};fluid.attachModel=function(baseModel,path,model){var segs=fluid.model.parseEL(path);for(var i=0;i<segs.length-1;++i){var seg=segs[i];var subModel=baseModel[seg];if(!subModel){baseModel[seg]=subModel={}}baseModel=subModel}baseModel[segs[segs.length-1]]=model};fluid.assembleModel=function(modelSpec){var model={};var superApplier=fluid.makeSuperApplier();var togo={model:model,applier:superApplier};for(path in modelSpec){var rec=modelSpec[path];fluid.attachModel(model,path,rec.model);if(rec.applier){superApplier.addSubApplier(path,rec.applier)}}return togo}})(jQuery,fluid_1_1);