../resources/dojo.cix // // $Rev: $ $current_version = "1.6.0"; header("Content-type: text/xml"); ini_set("memory_limit","512M"); include_once('includes/dojo.inc'); $files = dojo_get_files(); // our namespaces: $out = array("dijit" => array(), "dojox" => array(), "dojo" => array() ); // put the results of each file into $array[$namespace] foreach ($files as $set){ list($namespace,$file) = $set; $data = dojo_get_contents_cache($namespace, $file); $out[$namespace] = array_merge($out[$namespace],$data); } // and do some weeeird array manipulations: $out = @expando_dojo($out); // start a new document $doc = new DOMDocument('1.0'); // setup for codeintel: $codeintel = $doc->createElement('codeintel'); $codeintel->setAttribute("description","Dojo Toolkit API - version " . $current_version); $codeintel->setAttribute("version","2.0"); $codeintel->setAttribute("encoding","UTF-8"); // wrap all the api in one "file" tag: $data = $doc->createElement('file'); $data->setAttribute("lang","JavaScript"); $data->setAttribute("path",""); $f = $codeintel->appendChild($data); // and all the namespaces under one heading "dojo" $api = $doc->createElement('scope'); $api->setAttribute("ilk","blob"); $api->setAttribute("lang","JavaScript"); $api->setAttribute("name","dojo"); $namespace = $f->appendChild($api); // iterate through our modified array, and make an XML tree of the data: foreach ($out as $ns => $data){ // each top-level namespace get's it own scope $nsdata = $doc->createElement('scope'); $nsdata->setAttribute("ilk","class"); $nsdata->setAttribute("name",$ns); foreach ($data as $obj => $info){ $objElm = $doc->createElement('scope'); if(!empty($info['type'])){ $tt = $info['type']; switch($tt){ case "Object" : // inspect this object deeper, but append to namespace: $nsdata->appendChild(dojo_inspect($data[$obj],$obj,$doc, "variable")); break; case "Function" : if($info['classlike']){ // inspect deeper, append to namesapce: $nsdata->setAttribute("ilk","class"); $nsdata->appendChild(dojo_inspect($data[$obj],$obj,$doc)); }else{ // functions usually have param data: $objElm->setAttribute("ilk",strtolower($tt)); $objElm->setAttribute("name",$obj); if(is_array($info['parameters'])){ // generate the signature $sig = $obj."("; foreach($info['parameters'] as $param => $pData){ $sig .= $param.","; $paramElm = $doc->createElement('variable'); if(!empty($pData['type'])){ $paramElm->setAttribute("citdl",$pData['type']); } $paramElm->setAttribute("name",$param); $paramElm->setAttribute("ilk","argument"); if($pData['summary']){ $paramElm->setAttribute("doc", fix_utf(htmlentities($pData['summary']))); } $objElm -> appendChild($paramElm); } $sig = substr($sig,0,strlen($sig)-1); $sig .= ")"; $objElm->setAttribute("signature",$sig); unset($sig); } } break; } unset($tt); } // pertinent data: if(!empty($info['returns'])){ $objElm->setAttribute("returns",htmlentities($info['returns'])); } // helpful data: if(!empty($info['summary'])){ $objElm->setAttribute("doc", fix_utf(htmlentities($info['summary']))); } // avoid appending this node if we skipped popoulating it (in the case of nsdata->appendCHild()) if($objElm->hasAttribute("name")){ $nsdata->appendChild($objElm); } } // and dump all the data to this namesapce $namespace->appendChild($nsdata); } // append the APi to the document, and print: $doc->appendChild($codeintel); print $doc->saveXML(); function dojo_inspect($data,$ns,$doc,$t="scope"){ // summary: inspect some namespace (as top), with some passed data. if ($t == "argument") { $elm = $doc->createElement("variable"); $elm->setAttribute("ilk", "argument"); } else { $elm = $doc->createElement($t); } $elm->setAttribute("name",$ns); foreach ($data as $obj => $info){ switch($obj){ // these are all the ones we don't _really_ care about in this context: case "prototype" : //$elm->setAttribute("classref",$info['prototype']); break; case "chains" : case "mixins" : case "instance" : case "optional" : case "classlike" : case "examples" : case "private_parent" : case "description" : case "source" : case "style" : break; // mmm, duplicated from above: case "parameters" : $sig = $ns."("; foreach($info as $key => $val){ $sig .= $key.","; $elm->appendChild(dojo_inspect($val,$key,$doc,"argument")); } $sig = substr($sig,0,strlen($sig)-1); $sig .= ")"; $elm->setAttribute("signature",$sig); break; // some pertinant info about this element: case "returns" : $elm->setAttribute("returns",htmlentities($info)); case "private" : $elm->setAttribute("attributes","private"); break; case "type" : if($info) { switch ($info){ case "Function" : $elm->setAttribute("ilk","function"); break; default: if (is_array($info)) { if ($info["instance"]) { $elm->setAttribute("citdl",$info["instance"]); } } else { $elm->setAttribute("citdl",$info); } } } break; // ahhh, the blessed summary: case "summary" : $elm->setAttribute("doc", fix_utf(htmlentities($info))); break; // just in case we missed something? default : $scope_type = "scope"; if (($data[$obj]["instance"] != NULL) || ($data[$obj]["type"] == "Object")) { $scope_type = "variable"; } $elm->appendChild(dojo_inspect($data[$obj],$obj,$doc,$scope_type)); break; } } // give it back as a domNode: return $elm; } function dojo_get_contents_cache($namespace, $file, $forceNew = false){ // summary: a shim to dojo_get_contents, providing filemtime checking/caching // from parsing: XML takes ~ 80000ms on my MacBook Pro, from cache: // 7000ms ... pass true as third param to force cache reloading. // if the file hasn't been change since the last time, skip parsing it $mtime = dojo_get_file_time($namespace, $file); $cfile = "./cache/".md5($namespace.$file).".".$mtime; if(!$forceNew && file_exists($cfile)){ // read it from the cache: $cache = file_get_contents($cfile); $data = unserialize($cache); }else{ // parse the file, and save the cached results: $data = @dojo_get_contents($namespace, $file); $cache = serialize($data); $fp = fopen($cfile,"w+"); fputs($fp,$cache); fclose($fp); } return $data; } function expando_dojo($array){ // ugly array manipulation to turn an array like: // array( "one" => array("one","two","three"), "one.more"=>array("two","four","six") // into: // array("one" => array("more"=>array("two","four","six"), "one", "two", "three")); $ret = array(); foreach($array as $namespace => $results){ foreach($results as $item => $data){ switch($item{0}){ case "#" : break; default: $list = explode(".",$item); $n = count($list); $me = $list[$n]; // NOT happy with this: if(!($list[0]==$namespace)){ continue; } switch($n){ case 8 : fprintf("UNCAUGHT! %s", $item); // way tooooo deep. break; case 7 : $l1 = $list[1]; $l2 = $list[2]; $l3 = $list[3]; $l4 = $list[4]; $l5 = $list[5]; $l6 = $list[6]; if ($ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] == NULL) $ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] = $data; else $ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6]); break; case 6 : $l1 = $list[1]; $l2 = $list[2]; $l3 = $list[3]; $l4 = $list[4]; $l5 = $list[5]; if ($ret[$namespace][$l1][$l2][$l3][$l4][$l5] == NULL) $ret[$namespace][$l1][$l2][$l3][$l4][$l5] = $data; else $ret[$namespace][$l1][$l2][$l3][$l4][$l5] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4][$l5]); break; case 5 : $l1 = $list[1]; $l2 = $list[2]; $l3 = $list[3]; $l4 = $list[4]; if ($ret[$namespace][$l1][$l2][$l3][$l4] == NULL) $ret[$namespace][$l1][$l2][$l3][$l4] = $data; else $ret[$namespace][$l1][$l2][$l3][$l4] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4]); break; case 4 : $l1 = $list[1]; $l2 = $list[2]; $l3 = $list[3]; if ($ret[$namespace][$l1][$l2][$l3] == NULL) $ret[$namespace][$l1][$l2][$l3] = $data; else $ret[$namespace][$l1][$l2][$l3] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3]); break; case 3 : $l1 = $list[1]; $l2 = $list[2]; if ($ret[$namespace][$l1][$l2] == NULL) $ret[$namespace][$l1][$l2] = $data; else $ret[$namespace][$l1][$l2] = array_merge_recursive($data, $ret[$namespace][$l1][$l2]); break; case 2 : $l1 = $list[1]; $ret[$namespace][$l1] = $data; break; } break; } } } return $ret; } function fix_utf($str){ return iconv('utf-8','utf-8', $str); } ?>