// Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. function LoadData () { gTypeNames = []; ComplexTypeNames = []; SimpleTypeNames = []; for (var sName in Data) { gTypeNames.push(sName); switch(Data[sName].type) { case "complex-type": ComplexTypeNames.push(sName); break; case "simple-type": SimpleTypeNames.push(sName); break; } } document.getElementById("message").innerHTML = "there are " + ComplexTypeNames.length + " complex types and " + SimpleTypeNames.length +" simple types"; } function InitializeSearch () { CurrentTypeName = ""; TypeHistory = Array(); LoadData(); ShowType("A:ST_Overlap"); } function CheckInput (aField, aEvent) { switch(aEvent.keyCode) { case 38: --selection_index; if (selection_index < 0) selection_index = matches.length-1; break; case 40: ++selection_index; if (selection_index >= matches.length) selection_index = 0; break; default: matches = GetMatches(aField.value); selection_index = 0; } ShowMatches(matches, selection_index); } function GetMatches (sPattern) { var aLcPatterns = sPattern.toLowerCase().split(/\s+/); var nTypeCount = gTypeNames.length; var aMatches = []; for (index=0; index= 0) { var nMatchEnd = nMatchStart + sPattern.length; aParts.push(sTypeName.substring(nSearchStart, nMatchStart)); aParts.push(sTypeName.substring(nMatchStart, nMatchEnd)); nSearchStart = nMatchEnd; } else { // Only some patterns are matched. bIsMatch = false; } } if (bIsMatch) { if (nMatchEnd < sTypeName.length-1) aParts.push(sTypeName.substring(nMatchEnd)); aMatches.push(aParts); } } return aMatches; } /** Show the matching types. * As there can be a great many matching types, some sort of abbreviation is necessary. * Format all matches into lines of n entries. * Show the line containing the selected match and the ones before and after. * Show also the number of ommited matches. */ function ShowMatches (aMatches, nSelectionIndex) { var sText = ""; var nHalfRange = 10; var nMatchesPerLine = 5; var nLineCount = Math.floor((aMatches.length+nMatchesPerLine-1) / nMatchesPerLine); var nLineOfSelection = Math.floor(nSelectionIndex / nMatchesPerLine); var nFirstDisplayedLine = nLineOfSelection>0 ? nLineOfSelection-1 : 0; var nLastDisplayedLine = nLineOfSelection= aMatches.length) nLineEndIndex = aMatches.length-1; sText += "" for (nIndex=nLineStartIndex; nIndex<=nLineEndIndex; ++nIndex) { var aMatch = aMatches[nIndex]; var sTypeName = aMatch[0]; var sMatch = ""; for (nPartIndex=1; nPartIndex"+aMatch[nPartIndex]+""; else sMatch += aMatch[nPartIndex]; } sText += "" if (nIndex == nSelectionIndex) { sText += " " + sMatch + ""; } else { sText += " " + GetTypeLink(sMatch, sTypeName, -1); } sText += "" } sText += ""; } if (nFirstDisplayedLine > 0) sText = "["+(nFirstDisplayedLine*nMatchesPerLine)+" matches] ..." + sText; if (nLastDisplayedLine+1 < nLineCount) sText += "... ["+((nLineCount-nLastDisplayedLine-1)*nMatchesPerLine)+" matches]"; document.getElementById('matches').innerHTML = ""+sText+"
"; if (aMatches.length == 0) { document.getElementById('match-count').innerHTML = "no match:"; } else { if (aMatches.length == 1) document.getElementById('match-count').innerHTML = "single match:"; else document.getElementById('match-count').innerHTML = aMatches.length+" matches:"; ShowType(aMatches[nSelectionIndex][0]); } } function GetTopLevelNodeForTypeName(sTypeName) { if (sTypeName in Data) return Data[sTypeName]; else alert(sTypeName +" is not a known complex type, simple type, or group"); } /** Show the specified type. * When nHistoryIndex is not -1 then the history is shortened to that (before that) index. */ function ShowType (sTypeName, nHistoryIndex) { if (nHistoryIndex == -1) { if (CurrentTypeName != "") { TypeHistory.push(CurrentTypeName); ShowHistory(); } } else { TypeHistory = TypeHistory.slice(0,nHistoryIndex); ShowHistory(); } CurrentTypeName = sTypeName; var aElement = document.getElementById('result'); // Remove the old content. while(aElement.childNodes.length > 0) aElement.removeChild(aElement.firstChild); // Create the new content. var list = CreateDomTreeForType(GetTopLevelNodeForTypeName(sTypeName), "ul"); // Show the new content. aElement.appendChild(list); } /** Create a dom sub tree for the given OOXML type that is ready for insertion into the global DOM tree. */ function CreateDomTreeForType (aNode, sType) { var aEntry = document.createElement(sType); if (typeof aNode==='undefined') { aEntry.innerHTML = "undefined node"; } else if (typeof aNode.type==='undefined') { aEntry.innerHTML = "unknown type"; } else { switch(aNode.type) { case "attribute": aEntry.innerHTML = CreateValueTable([ "attribute", "type:", GetTypeLink(aNode["value-type"], aNode["value-type"], -1), "use:", aNode.use]); break; case "attribute-reference": aEntry.innerHTML = CreateReference(aNode["referenced-attribute"]); break; case "builtin": aEntry.innerHTML = CreateValueTable( ["builtin", "name:", aNode['builtin-type'] ]); break; case "complex-type": aEntry.innerHTML = aNode.type + " " + aNode.name; break; case "complex-type-reference": aEntry.innerHTML = CreateReference(aNode["referenced-complex-type"]); break; case "group": aEntry.innerHTML = aNode.type + " " + aNode.name; break; case "group-reference": aEntry.innerHTML = CreateReference("group", aNode["referenced-group"]); break; case "element": aEntry.innerHTML = "element " + aNode["tag"] + " -> " + GetTypeLink(aNode["result-type"], aNode["result-type"], -1); break; case "occurrence": aEntry.innerHTML = aNode.minimum +" -> " + aNode.maximum; break; case "restriction": aEntry.innerHTML = CreateRestrictionRepresentation(aNode); break; case "sequence": aEntry.innerHTML = "sequence"; break; case "simple-type": aEntry.innerHTML = aNode.type + " " + aNode.name; break; case "simple-type-reference": aEntry.innerHTML = CreateReference("simple-type", aNode["referenced-simple-type"]); break; default: aEntry.innerHTML = aNode.type; break; } // Add nodes for attributes. var aAttributes= aNode["attributes"]; if ( ! (typeof aAttributes==='undefined' || aAttributes.length == 0)) { var aAttributeList = document.createElement("ul"); aEntry.appendChild(aAttributeList); for (var nIndex=0; nIndex"+sText+""; } function CreateValueTable (aValues) { var sResult = ""; for (nIndex=3; nIndex"; } sResult += "
"+aValues[0]+""+aValues[1]+""+aValues[2]+"
"+aValues[nIndex+1]+"
"; return sResult; } function CreateReference (sWhat, sTypeName) { return "reference to "+sWhat+" "+GetTypeLink(sTypeName, sTypeName, -1) + " " +CreateButton( sTypeName, "show", "ToggleTypeReferenceExpansion('"+sTypeName+"')") +"
"; } function CreateButton (sId, sText, sExpandAction) { return ""+sText+""; } function ToggleTypeReferenceExpansion(sTypeName) { var aButton = document.getElementById("button-"+sTypeName); var aExpansion = document.getElementById("expansion-"+sTypeName); if (aButton.innerHTML == "show") { aExpansion.appendChild(CreateDomTreeForType(Data[sTypeName], "span")); aButton.innerHTML = "hide"; } else { aExpansion.innerHTML = ""; aButton.innerHTML = "show"; } } function ShowHistory () { var aElement = document.getElementById('history'); var sContent = "History:"; for (nIndex=0; nIndex