| OLD | NEW |
| 1 /** | 1 /** |
| 2 * @fileoverview This file is the controller for generating extension | 2 * @fileoverview This file is the controller for generating extension |
| 3 * doc pages. | 3 * doc pages. |
| 4 * | 4 * |
| 5 * It expects to have available via XHR (relative path): | 5 * It expects to have available via XHR (relative path): |
| 6 * 1) API_TEMPLATE which is the main template for the api pages. | 6 * 1) API_TEMPLATE which is the main template for the api pages. |
| 7 * 2) A file located at SCHEMA which is shared with the extension system and | 7 * 2) A file located at SCHEMA which is shared with the extension system and |
| 8 * defines the methods and events contained in one api. | 8 * defines the methods and events contained in one api. |
| 9 * 3) (Possibly) A static version of the current page url in /static/. I.e. | 9 * 3) (Possibly) A static version of the current page url in /static/. I.e. |
| 10 * if called as ../foo.html, it will look for ../static/foo.html. | 10 * if called as ../foo.html, it will look for ../static/foo.html. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 | 46 |
| 47 /* | 47 /* |
| 48 * Main entry point for composing the page. It will fetch it's template, | 48 * Main entry point for composing the page. It will fetch it's template, |
| 49 * the extension api, and attempt to fetch the matching static content. | 49 * the extension api, and attempt to fetch the matching static content. |
| 50 * It will insert the static content, if any, prepare it's pageData then | 50 * It will insert the static content, if any, prepare it's pageData then |
| 51 * render the template from |pageData|. | 51 * render the template from |pageData|. |
| 52 */ | 52 */ |
| 53 function renderPage() { | 53 function renderPage() { |
| 54 var pathParts = document.location.href.split(/\/|\./); | 54 var pathParts = document.location.href.split(/\/|\./); |
| 55 pageName = pathParts[pathParts.length - 2]; | 55 pageName = pathParts[pathParts.length - 2]; |
| 56 | 56 if (!pageName) { |
| 57 alert("Empty page name for: " + document.location.href); |
| 58 return; |
| 59 } |
| 60 |
| 57 // Fetch the api template and insert into the <body>. | 61 // Fetch the api template and insert into the <body>. |
| 58 fetchContent(API_TEMPLATE, function(templateContent) { | 62 fetchContent(API_TEMPLATE, function(templateContent) { |
| 59 document.getElementsByTagName("body")[0].innerHTML = templateContent; | 63 document.getElementsByTagName("body")[0].innerHTML = templateContent; |
| 60 fetchStatic(); | 64 fetchStatic(); |
| 61 }, function(error) { | 65 }, function(error) { |
| 62 alert("Failed to load " + API_TEMPLATE + ". " + error); | 66 alert("Failed to load " + API_TEMPLATE + ". " + error); |
| 63 }); | 67 }); |
| 64 } | 68 } |
| 65 | 69 |
| 66 function fetchStatic() { | 70 function fetchStatic() { |
| 67 // Fetch the static content and insert into the "static" <div>. | 71 // Fetch the static content and insert into the "static" <div>. |
| 68 fetchContent(staticResource(pageName), function(overviewContent) { | 72 fetchContent(staticResource(pageName), function(overviewContent) { |
| 69 document.getElementById("static").innerHTML = overviewContent; | 73 document.getElementById("static").innerHTML = overviewContent; |
| 70 fetchSchema(); | 74 fetchSchema(); |
| 71 | 75 |
| 72 }, function(error) { | 76 }, function(error) { |
| 73 // Not fatal. Some api pages may not have matching static content. | 77 // Not fatal. Some api pages may not have matching static content. |
| 74 fetchSchema(); | 78 fetchSchema(); |
| 75 }); | 79 }); |
| 76 } | 80 } |
| 77 | 81 |
| 78 function fetchSchema() { | 82 function fetchSchema() { |
| 79 // Now the page is composed with the authored content, we fetch the schema | 83 // Now the page is composed with the authored content, we fetch the schema |
| 80 // and populate the templates. | 84 // and populate the templates. |
| 81 fetchContent(SCHEMA, renderTemplate, function(error) { | 85 fetchContent(SCHEMA, renderTemplate, function(error) { |
| 82 alert("Failed to load " + SCHEMA); | 86 alert("Failed to load " + SCHEMA); |
| 83 }); | 87 }); |
| 84 } | 88 } |
| 85 | 89 |
| 86 /** | 90 /** |
| 87 * Fetches |url| and returns it's text contents from the xhr.responseText in | 91 * Fetches |url| and returns it's text contents from the xhr.responseText in |
| 88 * onSuccess(content) | 92 * onSuccess(content) |
| 89 */ | 93 */ |
| 90 function fetchContent(url, onSuccess, onError) { | 94 function fetchContent(url, onSuccess, onError) { |
| 95 var localUrl = url; |
| 91 var xhr = new XMLHttpRequest(); | 96 var xhr = new XMLHttpRequest(); |
| 92 var abortTimerId = window.setTimeout(function() { | 97 var abortTimerId = window.setTimeout(function() { |
| 93 xhr.abort(); | 98 xhr.abort(); |
| 94 console.log("XHR Timed out"); | 99 console.log("XHR Timed out"); |
| 95 }, REQUEST_TIMEOUT); | 100 }, REQUEST_TIMEOUT); |
| 96 | 101 |
| 97 function handleError(error) { | 102 function handleError(error) { |
| 98 window.clearTimeout(abortTimerId); | 103 window.clearTimeout(abortTimerId); |
| 99 if (onError) { | 104 if (onError) { |
| 100 onError(error); | 105 onError(error); |
| 101 } | 106 } |
| 102 console.error("XHR Failed: " + error); | 107 console.error("XHR Failed fetching: " + localUrl + "..." + error); |
| 103 } | 108 } |
| 104 | 109 |
| 105 try { | 110 try { |
| 106 xhr.onreadystatechange = function(){ | 111 xhr.onreadystatechange = function(){ |
| 107 if (xhr.readyState == 4) { | 112 if (xhr.readyState == 4) { |
| 108 if (xhr.responseText) { | 113 if (xhr.responseText) { |
| 109 window.clearTimeout(abortTimerId); | 114 window.clearTimeout(abortTimerId); |
| 110 onSuccess(xhr.responseText); | 115 onSuccess(xhr.responseText); |
| 111 } else { | 116 } else { |
| 112 handleError("responseText empty."); | 117 handleError("responseText empty."); |
| 113 } | 118 } |
| 114 } | 119 } |
| 115 } | 120 } |
| 116 | 121 |
| 117 xhr.onerror = handleError; | 122 xhr.onerror = handleError; |
| 118 | 123 |
| 119 xhr.open("GET", url, true); | 124 xhr.open("GET", url, true); |
| 120 xhr.send(null); | 125 xhr.send(null); |
| 121 } catch(e) { | 126 } catch(e) { |
| 122 console.log("ex: " + e); | 127 console.log("ex: " + e); |
| 123 console.error("exception: " + e); | 128 console.error("exception: " + e); |
| 124 handleError(); | 129 handleError(); |
| 125 } | 130 } |
| 126 } | 131 } |
| 127 | 132 |
| 128 /** | 133 /** |
| 129 * Parses the content in |schemaContent| to json, find appropriate api, adds any | 134 * Parses the content in |schemaContent| to json, find appropriate api, adds any |
| 130 * additional required values, renders to html via JSTemplate, and unhides the | 135 * additional required values, renders to html via JSTemplate, and unhides the |
| 131 * <body>. | 136 * <body>. |
| 132 * This uses the root <html> element (the entire document) as the template. | 137 * This uses the root <html> element (the entire document) as the template. |
| 133 */ | 138 */ |
| 134 function renderTemplate(schemaContent) { | 139 function renderTemplate(schemaContent) { |
| 135 pageData = {}; | 140 pageData = {}; |
| 136 var schema = JSON.parse(schemaContent); | 141 var schema = JSON.parse(schemaContent); |
| 137 | 142 |
| 138 schema.each(function(module) { | 143 schema.each(function(module) { |
| 139 if (module.namespace == pageName) { | 144 if (module.namespace == pageName) { |
| 140 // This page is an api page. Setup types and apiDefinition. | 145 // This page is an api page. Setup types and apiDefinition. |
| 141 if (module.types) { | 146 if (module.types) { |
| 142 module.types.each(function(t) { | 147 module.types.each(function(t) { |
| 143 types[t.id] = t; | 148 types[t.id] = t; |
| 144 }); | 149 }); |
| 145 } | 150 } |
| 146 pageData.apiDefinition = module; | 151 pageData.apiDefinition = module; |
| 147 preprocessApi(pageData, schema); | 152 preprocessApi(pageData, schema); |
| 148 } | 153 } |
| 149 }); | 154 }); |
| 150 | 155 |
| 151 setupPageData(pageData, schema); | 156 setupPageData(pageData, schema); |
| 152 | 157 |
| 153 // Render to template | 158 // Render to template |
| 154 var input = new JsEvalContext(pageData); | 159 var input = new JsEvalContext(pageData); |
| 155 var output = document.getElementsByTagName("html")[0]; | 160 var output = document.getElementsByTagName("html")[0]; |
| 156 jstProcess(input, output); | 161 jstProcess(input, output); |
| 157 | 162 |
| 158 // Show. | 163 // Show. |
| 159 document.getElementsByTagName("body")[0].className = ""; | 164 document.getElementsByTagName("body")[0].className = ""; |
| 165 |
| 166 if (parent && parent.done) |
| 167 parent.done(); |
| 168 } |
| 169 |
| 170 function serializePage() { |
| 171 var s = new XMLSerializer(); |
| 172 return s.serializeToString(document); |
| 160 } | 173 } |
| 161 | 174 |
| 162 function setupPageData(pageData, schema) { | 175 function setupPageData(pageData, schema) { |
| 163 // Add a list of modules for the master TOC. | 176 // Add a list of modules for the master TOC. |
| 164 pageData.apiModules = []; | 177 pageData.apiModules = []; |
| 165 schema.each(function(s) { | 178 schema.each(function(s) { |
| 166 var m = {}; | 179 var m = {}; |
| 167 m.module = s.namespace; | 180 m.module = s.namespace; |
| 168 m.name = s.namespace.substring(0, 1).toUpperCase() + | 181 m.name = s.namespace.substring(0, 1).toUpperCase() + |
| 169 s.namespace.substring(1); | 182 s.namespace.substring(1); |
| 170 pageData.apiModules.push(m); | 183 pageData.apiModules.push(m); |
| 171 }); | 184 }); |
| 172 pageData.apiModules.sort(function(a, b) { return a.name > b.name; }); | 185 pageData.apiModules.sort(function(a, b) { return a.name > b.name; }); |
| 173 | 186 |
| 174 if (!pageData.pageTitle) { | 187 if (!pageData.pageTitle) { |
| 175 pageData.pageTitle = pageName; | 188 pageData.pageTitle = pageName; |
| 176 pageData.h1Header = pageName; | 189 pageData.h1Header = pageName; |
| 177 } | 190 } |
| 178 } | 191 } |
| 179 | 192 |
| 180 /** | 193 /** |
| 181 * Augment the |module| with additional values that are required by the | 194 * Augment the |module| with additional values that are required by the |
| 182 * template. |schema| is the full schema (including all modules). | 195 * template. |schema| is the full schema (including all modules). |
| 183 */ | 196 */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 196 if (lastParam.type == "function" && lastParam.parameters) { | 209 if (lastParam.type == "function" && lastParam.parameters) { |
| 197 linkTypeReferences(lastParam.parameters); | 210 linkTypeReferences(lastParam.parameters); |
| 198 assignTypeNames(lastParam.parameters); | 211 assignTypeNames(lastParam.parameters); |
| 199 f.callbackParameters = lastParam.parameters; | 212 f.callbackParameters = lastParam.parameters; |
| 200 f.callbackSignature = generateSignatureString(lastParam.parameters); | 213 f.callbackSignature = generateSignatureString(lastParam.parameters); |
| 201 f.callbackParameters.each(function(p) { | 214 f.callbackParameters.each(function(p) { |
| 202 addPropertyListIfObject(p); | 215 addPropertyListIfObject(p); |
| 203 }); | 216 }); |
| 204 } | 217 } |
| 205 } | 218 } |
| 206 | 219 |
| 207 // Setup any type: "object" pameters to have an array of params (rather than
| 220 // Setup any type: "object" pameters to have an array of params (rather than
|
| 208 // named properties). | 221 // named properties). |
| 209 f.parameters.each(function(param) { | 222 f.parameters.each(function(param) { |
| 210 addPropertyListIfObject(param); | 223 addPropertyListIfObject(param); |
| 211 }); | 224 }); |
| 212 | 225 |
| 213 // Setup return typeName & _propertyList, if any. | 226 // Setup return typeName & _propertyList, if any. |
| 214 if (f.returns) { | 227 if (f.returns) { |
| 215 linkTypeReference(f.returns); | 228 linkTypeReference(f.returns); |
| 216 f.returns.typeName = typeName(f.returns); | 229 f.returns.typeName = typeName(f.returns); |
| 217 addPropertyListIfObject(f.returns); | 230 addPropertyListIfObject(f.returns); |
| 218 } | 231 } |
| 219 }); | 232 }); |
| 220 | 233 |
| 221 module.events.each(function(e) { | 234 module.events.each(function(e) { |
| 222 linkTypeReferences(e.parameters); | 235 linkTypeReferences(e.parameters); |
| 223 assignTypeNames(e.parameters); | 236 assignTypeNames(e.parameters); |
| 224 e.callSignature = generateSignatureString(e.parameters); | 237 e.callSignature = generateSignatureString(e.parameters); |
| 225 e.parameters.each(function(p) { | 238 e.parameters.each(function(p) { |
| 226 addPropertyListIfObject(p); | 239 addPropertyListIfObject(p); |
| 227 }); | 240 }); |
| 228 }); | 241 }); |
| 229 } | 242 } |
| 230 | 243 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 p.typeName = typeName(p); | 280 p.typeName = typeName(p); |
| 268 }); | 281 }); |
| 269 } | 282 } |
| 270 | 283 |
| 271 /** | 284 /** |
| 272 * Generates a short text summary of the |schema| type | 285 * Generates a short text summary of the |schema| type |
| 273 */ | 286 */ |
| 274 function typeName(schema) { | 287 function typeName(schema) { |
| 275 if (schema.$ref) | 288 if (schema.$ref) |
| 276 schema = types[schema.$ref]; | 289 schema = types[schema.$ref]; |
| 277 | 290 |
| 278 if (schema.choice) { | 291 if (schema.choice) { |
| 279 var typeNames = []; | 292 var typeNames = []; |
| 280 schema.choice.each(function(c) { | 293 schema.choice.each(function(c) { |
| 281 typeNames.push(typeName(c)); | 294 typeNames.push(typeName(c)); |
| 282 }); | 295 }); |
| 283 | 296 |
| 284 return typeNames.join(" or "); | 297 return typeNames.join(" or "); |
| 285 } | 298 } |
| 286 | 299 |
| 287 if (schema.type == "array") | 300 if (schema.type == "array") |
| 288 return "array of " + typeName(schema.items); | 301 return "array of " + typeName(schema.items); |
| 289 | 302 |
| 290 return schema.type; | 303 return schema.type; |
| 291 } | 304 } |
| 292 | 305 |
| 293 /** | 306 /** |
| 294 * Generates a simple string representation of the signature of a function | 307 * Generates a simple string representation of the signature of a function |
| 295 * whose |parameters| are json schemas. | 308 * whose |parameters| are json schemas. |
| 296 */ | 309 */ |
| 297 function generateSignatureString(parameters) { | 310 function generateSignatureString(parameters) { |
| 298 var retval = []; | 311 var retval = []; |
| 299 parameters.each(function(param, i) { | 312 parameters.each(function(param, i) { |
| 300 retval.push(param.typeName + " " + param.name); | 313 retval.push(param.typeName + " " + param.name); |
| 301 }); | 314 }); |
| 302 | 315 |
| 303 return retval.join(", "); | 316 return retval.join(", "); |
| 304 } | 317 } |
| OLD | NEW |