nbot

A clone of the eBot by @deStrO fully based on node.js with build in Web Page - WIP
git clone git://archive.git.mtrnord.blog/MTRNord/nbot.git
Log | Files | Refs | README | LICENSE

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 });