4d3d63812c244da1653a39ac4564f76ba384c548
[atutor.git] / docs / jscripts / infusion / framework / renderer / js / fluidParser.js
1 fluid_1_4=fluid_1_4||{};(function($,fluid){fluid.parseTemplate=function(template,baseURL,scanStart,cutpoints_in,opts){opts=opts||{};if(!template){fluid.fail("empty template supplied to fluid.parseTemplate")}var t;var parser;var tagstack;var lumpindex=0;var nestingdepth=0;var justended=false;var defstart=-1;var defend=-1;var debugMode=false;var cutpoints=[];var simpleClassCutpoints={};var cutstatus=[];var XMLLump=function(lumpindex,nestingdepth){return{nestingdepth:nestingdepth,lumpindex:lumpindex,parent:t}};function isSimpleClassCutpoint(tree){return tree.length===1&&tree[0].predList.length===1&&tree[0].predList[0].clazz}function init(baseURLin,debugModeIn,cutpointsIn){t.rootlump=XMLLump(0,-1);tagstack=[t.rootlump];lumpindex=0;nestingdepth=0;justended=false;defstart=-1;defend=-1;baseURL=baseURLin;debugMode=debugModeIn;if(cutpointsIn){for(var i=0;i<cutpointsIn.length;++i){var tree=fluid.parseSelector(cutpointsIn[i].selector);var clazz=isSimpleClassCutpoint(tree);if(clazz){simpleClassCutpoints[clazz]=cutpointsIn[i].id}else{cutstatus.push([]);cutpoints.push($.extend({},cutpointsIn[i],{tree:tree}))}}}}function findTopContainer(){for(var i=tagstack.length-1;i>=0;--i){var lump=tagstack[i];if(lump.rsfID!==undefined){return lump}}return t.rootlump}function newLump(){var togo=XMLLump(lumpindex,nestingdepth);if(debugMode){togo.line=parser.getLineNumber();togo.column=parser.getColumnNumber()}t.lumps[lumpindex]=togo;++lumpindex;return togo}function addLump(mmap,ID,lump){var list=mmap[ID];if(!list){list=[];mmap[ID]=list}list[list.length]=lump}function checkContribute(ID,lump){if(ID.indexOf("scr=contribute-")!==-1){var scr=ID.substring("scr=contribute-".length);addLump(t.collectmap,scr,lump)}}function debugLump(lump){return"<"+lump.tagname+">"}function hasCssClass(clazz,totest){if(!totest){return false}return(" "+totest+" ").indexOf(" "+clazz+" ")!==-1}function matchNode(term,headlump,headclazz){if(term.predList){for(var i=0;i<term.predList.length;++i){var pred=term.predList[i];if(pred.id&&headlump.attributemap.id!==pred.id){return false}if(pred.clazz&&!hasCssClass(pred.clazz,headclazz)){return false}if(pred.tag&&headlump.tagname!==pred.tag){return false}}return true}}function tagStartCut(headlump){var togo;var headclazz=headlump.attributemap["class"];if(headclazz){var split=headclazz.split(" ");for(var i=0;i<split.length;++i){var simpleCut=simpleClassCutpoints[$.trim(split[i])];if(simpleCut){return simpleCut}}}for(var i=0;i<cutpoints.length;++i){var cut=cutpoints[i];var cutstat=cutstatus[i];var nextterm=cutstat.length;if(nextterm<cut.tree.length){var term=cut.tree[nextterm];if(nextterm>0){if(cut.tree[nextterm-1].child&&cutstat[nextterm-1]!==headlump.nestingdepth-1){continue}}var isMatch=matchNode(term,headlump,headclazz);if(isMatch){cutstat[cutstat.length]=headlump.nestingdepth;if(cutstat.length===cut.tree.length){if(togo!==undefined){fluid.fail("Cutpoint specification error - node "+debugLump(headlump)+" has already matched with rsf:id of "+togo)}if(cut.id===undefined||cut.id===null){fluid.fail("Error in cutpoints list - entry at position "+i+" does not have an id set")}togo=cut.id}}}}return togo}function tagEndCut(){if(cutpoints){for(var i=0;i<cutpoints.length;++i){var cutstat=cutstatus[i];if(cutstat.length>0&&cutstat[cutstat.length-1]===nestingdepth){cutstat.length--}}}}function processTagEnd(){tagEndCut();var endlump=newLump();--nestingdepth;endlump.text="</"+parser.getName()+">";var oldtop=tagstack[tagstack.length-1];oldtop.close_tag=t.lumps[lumpindex-1];tagstack.length--;justended=true}function processTagStart(isempty,text){++nestingdepth;if(justended){justended=false;var backlump=newLump();backlump.nestingdepth--}if(t.firstdocumentindex===-1){t.firstdocumentindex=lumpindex}var headlump=newLump();var stacktop=tagstack[tagstack.length-1];headlump.uplump=stacktop;var tagname=parser.getName();headlump.tagname=tagname;var attrs=headlump.attributemap=parser.m_attributes;var ID=attrs[fluid.ID_ATTRIBUTE];if(ID===undefined){ID=tagStartCut(headlump)}for(var attrname in attrs){if(ID===undefined){if(/href|src|codebase|action/.test(attrname)){ID="scr=rewrite-url"}else{if(ID===undefined&&/for|headers/.test(attrname)){ID="scr=null"}}}}if(ID){if(ID.charCodeAt(0)===126){ID=ID.substring(1);headlump.elide=true}checkContribute(ID,headlump);headlump.rsfID=ID;var downreg=findTopContainer();if(!downreg.downmap){downreg.downmap={}}while(downreg){if(downreg.downmap){addLump(downreg.downmap,ID,headlump)}downreg=downreg.uplump}addLump(t.globalmap,ID,headlump);var colpos=ID.indexOf(":");if(colpos!==-1){var prefix=ID.substring(0,colpos);if(!stacktop.finallump){stacktop.finallump={}}stacktop.finallump[prefix]=headlump}}headlump.text="<"+tagname+fluid.dumpAttributes(attrs)+(isempty&&!ID?"/>":">");tagstack[tagstack.length]=headlump;if(isempty){if(ID){processTagEnd()}else{--nestingdepth;tagstack.length--}}}function processDefaultTag(){if(defstart!==-1){if(t.firstdocumentindex===-1){t.firstdocumentindex=lumpindex}var text=parser.getContent().substr(defstart,defend-defstart);justended=false;var newlump=newLump();newlump.text=text;defstart=-1}}t=fluid.XMLViewTemplate();init(baseURL,opts.debugMode,cutpoints_in);var idpos=template.indexOf(fluid.ID_ATTRIBUTE);if(scanStart){var brackpos=template.indexOf(">",idpos);parser=fluid.XMLP(template.substring(brackpos+1))}else{parser=fluid.XMLP(template)}parseloop:while(true){var iEvent=parser.next();switch(iEvent){case fluid.XMLP._ELM_B:processDefaultTag();processTagStart(false,"");break;case fluid.XMLP._ELM_E:processDefaultTag();processTagEnd();break;case fluid.XMLP._ELM_EMP:processDefaultTag();processTagStart(true,"");break;case fluid.XMLP._PI:case fluid.XMLP._DTD:defstart=-1;continue;case fluid.XMLP._TEXT:case fluid.XMLP._ENTITY:case fluid.XMLP._CDATA:case fluid.XMLP._COMMENT:if(defstart===-1){defstart=parser.m_cB}defend=parser.m_cE;break;case fluid.XMLP._ERROR:fluid.setLogging(true);var message="Error parsing template: "+parser.m_cAlt+" at line "+parser.getLineNumber();fluid.log(message);fluid.log("Just read: "+parser.m_xml.substring(parser.m_iP-30,parser.m_iP));fluid.log("Still to read: "+parser.m_xml.substring(parser.m_iP,parser.m_iP+30));fluid.fail(message);break parseloop;case fluid.XMLP._NONE:break parseloop}}processDefaultTag();var excess=tagstack.length-1;if(excess){fluid.fail("Error parsing template - unclosed tag(s) of depth "+(excess)+": "+fluid.transform(tagstack.splice(1,excess),function(lump){return debugLump(lump)}).join(", "))}return t};fluid.debugLump=function(lump){var togo=lump.text;togo+=" at ";togo+="lump line "+lump.line+" column "+lump.column+" index "+lump.lumpindex;togo+=lump.parent.href===null?"":" in file "+lump.parent.href;return togo};fluid.ID_ATTRIBUTE="rsf:id";fluid.getPrefix=function(id){var colpos=id.indexOf(":");return colpos===-1?id:id.substring(0,colpos)};fluid.SplitID=function(id){var that={};var colpos=id.indexOf(":");if(colpos===-1){that.prefix=id}else{that.prefix=id.substring(0,colpos);that.suffix=id.substring(colpos+1)}return that};fluid.XMLViewTemplate=function(){return{globalmap:{},collectmap:{},lumps:[],firstdocumentindex:-1}};fluid.XMLEncode=function(text){return text.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;")};fluid.dumpAttributes=function(attrcopy){var togo="";for(var attrname in attrcopy){var attrvalue=attrcopy[attrname];if(attrvalue!==null&&attrvalue!==undefined){togo+=" "+attrname+'="'+attrvalue+'"'}}return togo};fluid.aggregateMMap=function(target,source){for(var key in source){var targhas=target[key];if(!targhas){target[key]=[]}target[key]=target[key].concat(source[key])}};fluid.parseTemplates=function(resourceSpec,templateList,opts){var togo=[];opts=opts||{};togo.globalmap={};for(var i=0;i<templateList.length;++i){var resource=resourceSpec[templateList[i]];var lastslash=resource.href.lastIndexOf("/");var baseURL=lastslash===-1?"":resource.href.substring(0,lastslash+1);var template=fluid.parseTemplate(resource.resourceText,baseURL,opts.scanStart&&i===0,resource.cutpoints,opts);if(i===0){fluid.aggregateMMap(togo.globalmap,template.globalmap)}template.href=resource.href;template.baseURL=baseURL;template.resourceKey=resource.resourceKey;togo[i]=template;fluid.aggregateMMap(togo.globalmap,template.rootlump.downmap)}return togo};var chars="(?:[\\w\u0128-\uFFFF*_-]|\\\\.)";var quickClass=new RegExp("([#.]?)("+chars+"+)","g");var childSeg=new RegExp("\\s*(>)?\\s*","g");fluid.parseSelector=function(selstring){var togo=[];selstring=$.trim(selstring);quickClass.lastIndex=0;var lastIndex=0;while(true){var atNode=[];while(true){var segMatch=quickClass.exec(selstring);if(!segMatch||segMatch.index!==lastIndex){break}var thisNode={};var text=segMatch[2];if(segMatch[1]===""){thisNode.tag=text}else{if(segMatch[1]==="#"){thisNode.id=text}else{if(segMatch[1]==="."){thisNode.clazz=text}}}atNode[atNode.length]=thisNode;lastIndex=quickClass.lastIndex}childSeg.lastIndex=lastIndex;var fullAtNode={predList:atNode};var childMatch=childSeg.exec(selstring);if(!childMatch||childMatch.index!==lastIndex){var remainder=selstring.substring(lastIndex);fluid.fail("Error in selector string - can not match child selector expression at "+remainder)}if(childMatch[1]===">"){fullAtNode.child=true}togo[togo.length]=fullAtNode;if(childSeg.lastIndex>=selstring.length){break}lastIndex=childSeg.lastIndex;quickClass.lastIndex=childSeg.lastIndex}return togo}})(jQuery,fluid_1_4);