apidocs.js (10497B)
1 YUI().use( 2 'yuidoc-meta', 3 'api-list', 'history-hash', 'node-screen', 'node-style', 'pjax', 4 function (Y) { 5 6 var win = Y.config.win, 7 localStorage = win.localStorage, 8 9 bdNode = Y.one('#bd'), 10 11 pjax, 12 defaultRoute, 13 14 classTabView, 15 selectedTab; 16 17 // Kill pjax functionality unless serving over HTTP. 18 if (!Y.getLocation().protocol.match(/^https?\:/)) { 19 Y.Router.html5 = false; 20 } 21 22 // Create the default route with middleware which enables syntax highlighting 23 // on the loaded content. 24 defaultRoute = Y.Pjax.defaultRoute.concat(function (req, res, next) { 25 prettyPrint(); 26 bdNode.removeClass('loading'); 27 28 next(); 29 }); 30 31 pjax = new Y.Pjax({ 32 container : '#docs-main', 33 contentSelector: '#docs-main > .content', 34 linkSelector : '#bd a', 35 titleSelector : '#xhr-title', 36 37 navigateOnHash: true, 38 root : '/', 39 routes : [ 40 // -- / ---------------------------------------------------------------- 41 { 42 path : '/(index.html)?', 43 callbacks: defaultRoute 44 }, 45 46 // -- /elements/* ------------------------------------------------------- 47 { 48 path : '/elements/:element.html*', 49 callbacks: defaultRoute 50 }, 51 52 // -- /classes/* ------------------------------------------------------- 53 { 54 path : '/classes/:class.html*', 55 callbacks: [defaultRoute, 'handleClasses'] 56 }, 57 58 // -- /files/* --------------------------------------------------------- 59 { 60 path : '/files/*file', 61 callbacks: [defaultRoute, 'handleFiles'] 62 }, 63 64 // -- /modules/* ------------------------------------------------------- 65 { 66 path : '/modules/:module.html*', 67 callbacks: defaultRoute 68 } 69 ] 70 }); 71 72 // -- Utility Functions -------------------------------------------------------- 73 74 pjax.checkVisibility = function (tab) { 75 tab || (tab = selectedTab); 76 77 if (!tab) { return; } 78 79 var panelNode = tab.get('panelNode'), 80 visibleItems; 81 82 // If no items are visible in the tab panel due to the current visibility 83 // settings, display a message to that effect. 84 visibleItems = panelNode.all('.item,.index-item').some(function (itemNode) { 85 if (itemNode.getComputedStyle('display') !== 'none') { 86 return true; 87 } 88 }); 89 90 panelNode.all('.no-visible-items').remove(); 91 92 if (!visibleItems) { 93 if (Y.one('#index .index-item')) { 94 panelNode.append( 95 '<div class="no-visible-items">' + 96 '<p>' + 97 'Some items are not shown due to the current visibility ' + 98 'settings. Use the checkboxes at the upper right of this ' + 99 'page to change the visibility settings.' + 100 '</p>' + 101 '</div>' 102 ); 103 } else { 104 panelNode.append( 105 '<div class="no-visible-items">' + 106 '<p>' + 107 'This class doesn\'t provide any methods, properties, ' + 108 'attributes, or events.' + 109 '</p>' + 110 '</div>' 111 ); 112 } 113 } 114 115 // Hide index sections without any visible items. 116 Y.all('.index-section').each(function (section) { 117 var items = 0, 118 visibleItems = 0; 119 120 section.all('.index-item').each(function (itemNode) { 121 items += 1; 122 123 if (itemNode.getComputedStyle('display') !== 'none') { 124 visibleItems += 1; 125 } 126 }); 127 128 section.toggleClass('hidden', !visibleItems); 129 section.toggleClass('no-columns', visibleItems < 4); 130 }); 131 }; 132 133 pjax.initClassTabView = function () { 134 if (!Y.all('#classdocs .api-class-tab').size()) { 135 return; 136 } 137 138 if (classTabView) { 139 classTabView.destroy(); 140 selectedTab = null; 141 } 142 143 classTabView = new Y.TabView({ 144 srcNode: '#classdocs', 145 146 on: { 147 selectionChange: pjax.onTabSelectionChange 148 } 149 }); 150 151 pjax.updateTabState(); 152 classTabView.render(); 153 }; 154 155 pjax.initLineNumbers = function () { 156 var hash = win.location.hash.substring(1), 157 container = pjax.get('container'), 158 hasLines, node; 159 160 // Add ids for each line number in the file source view. 161 container.all('.linenums>li').each(function (lineNode, index) { 162 lineNode.set('id', 'l' + (index + 1)); 163 lineNode.addClass('file-line'); 164 hasLines = true; 165 }); 166 167 // Scroll to the desired line. 168 if (hasLines && /^l\d+$/.test(hash)) { 169 if ((node = container.getById(hash))) { 170 win.scroll(0, node.getY()); 171 } 172 } 173 }; 174 175 pjax.initRoot = function () { 176 var terminators = /^(?:classes|files|elements|modules)$/, 177 parts = pjax._getPathRoot().split('/'), 178 root = [], 179 i, len, part; 180 181 for (i = 0, len = parts.length; i < len; i += 1) { 182 part = parts[i]; 183 184 if (part.match(terminators)) { 185 // Makes sure the path will end with a "/". 186 root.push(''); 187 break; 188 } 189 190 root.push(part); 191 } 192 193 pjax.set('root', root.join('/')); 194 }; 195 196 pjax.updateTabState = function (src) { 197 var hash = win.location.hash.substring(1), 198 defaultTab, node, tab, tabPanel; 199 200 function scrollToNode() { 201 if (node.hasClass('protected')) { 202 Y.one('#api-show-protected').set('checked', true); 203 pjax.updateVisibility(); 204 } 205 206 if (node.hasClass('private')) { 207 Y.one('#api-show-private').set('checked', true); 208 pjax.updateVisibility(); 209 } 210 211 setTimeout(function () { 212 // For some reason, unless we re-get the node instance here, 213 // getY() always returns 0. 214 var node = Y.one('#classdocs').getById(hash); 215 win.scrollTo(0, node.getY() - 70); 216 }, 1); 217 } 218 219 if (!classTabView) { 220 return; 221 } 222 223 if (src === 'hashchange' && !hash) { 224 defaultTab = 'index'; 225 } else { 226 if (localStorage) { 227 defaultTab = localStorage.getItem('tab_' + pjax.getPath()) || 228 'index'; 229 } else { 230 defaultTab = 'index'; 231 } 232 } 233 234 if (hash && (node = Y.one('#classdocs').getById(hash))) { 235 if ((tabPanel = node.ancestor('.api-class-tabpanel', true))) { 236 if ((tab = Y.one('#classdocs .api-class-tab.' + tabPanel.get('id')))) { 237 if (classTabView.get('rendered')) { 238 Y.Widget.getByNode(tab).set('selected', 1); 239 } else { 240 tab.addClass('yui3-tab-selected'); 241 } 242 } 243 } 244 245 // Scroll to the desired element if this is a hash URL. 246 if (node) { 247 if (classTabView.get('rendered')) { 248 scrollToNode(); 249 } else { 250 classTabView.once('renderedChange', scrollToNode); 251 } 252 } 253 } else { 254 tab = Y.one('#classdocs .api-class-tab.' + defaultTab); 255 256 // When the `defaultTab` node isn't found, `localStorage` is stale. 257 if (!tab && defaultTab !== 'index') { 258 tab = Y.one('#classdocs .api-class-tab.index'); 259 } 260 261 if (classTabView.get('rendered')) { 262 Y.Widget.getByNode(tab).set('selected', 1); 263 } else { 264 tab.addClass('yui3-tab-selected'); 265 } 266 } 267 }; 268 269 pjax.updateVisibility = function () { 270 var container = pjax.get('container'); 271 272 container.toggleClass('hide-inherited', 273 !Y.one('#api-show-inherited').get('checked')); 274 275 container.toggleClass('show-deprecated', 276 Y.one('#api-show-deprecated').get('checked')); 277 278 container.toggleClass('show-protected', 279 Y.one('#api-show-protected').get('checked')); 280 281 container.toggleClass('show-private', 282 Y.one('#api-show-private').get('checked')); 283 284 pjax.checkVisibility(); 285 }; 286 287 // -- Route Handlers ----------------------------------------------------------- 288 289 pjax.handleClasses = function (req, res, next) { 290 var status = res.ioResponse.status; 291 292 // Handles success and local filesystem XHRs. 293 if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) { 294 pjax.initClassTabView(); 295 } 296 297 next(); 298 }; 299 300 pjax.handleFiles = function (req, res, next) { 301 var status = res.ioResponse.status; 302 303 // Handles success and local filesystem XHRs. 304 if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) { 305 pjax.initLineNumbers(); 306 } 307 308 next(); 309 }; 310 311 // -- Event Handlers ----------------------------------------------------------- 312 313 pjax.onNavigate = function (e) { 314 var hash = e.hash, 315 originTarget = e.originEvent && e.originEvent.target, 316 tab; 317 318 if (hash) { 319 tab = originTarget && originTarget.ancestor('.yui3-tab', true); 320 321 if (hash === win.location.hash) { 322 pjax.updateTabState('hashchange'); 323 } else if (!tab) { 324 win.location.hash = hash; 325 } 326 327 e.preventDefault(); 328 return; 329 } 330 331 // Only scroll to the top of the page when the URL doesn't have a hash. 332 this.set('scrollToTop', !e.url.match(/#.+$/)); 333 334 bdNode.addClass('loading'); 335 }; 336 337 pjax.onOptionClick = function (e) { 338 pjax.updateVisibility(); 339 }; 340 341 pjax.onTabSelectionChange = function (e) { 342 var tab = e.newVal, 343 tabId = tab.get('contentBox').getAttribute('href').substring(1); 344 345 selectedTab = tab; 346 347 // If switching from a previous tab (i.e., this is not the default tab), 348 // replace the history entry with a hash URL that will cause this tab to 349 // be selected if the user navigates away and then returns using the back 350 // or forward buttons. 351 if (e.prevVal && localStorage) { 352 localStorage.setItem('tab_' + pjax.getPath(), tabId); 353 } 354 355 pjax.checkVisibility(tab); 356 }; 357 358 // -- Init --------------------------------------------------------------------- 359 360 pjax.on('navigate', pjax.onNavigate); 361 362 pjax.initRoot(); 363 pjax.upgrade(); 364 pjax.initClassTabView(); 365 pjax.initLineNumbers(); 366 pjax.updateVisibility(); 367 368 Y.APIList.rootPath = pjax.get('root'); 369 370 Y.one('#api-options').delegate('click', pjax.onOptionClick, 'input'); 371 372 Y.on('hashchange', function (e) { 373 pjax.updateTabState('hashchange'); 374 }, win); 375 376 });