'use strict'; /*@ Ox.DocPanel <f> Documentation Panel () -> <f> Documentation Panel (options) -> <f> Documentation Panel (options, self) -> <f> Documentation Panel options <o> Options object collapsible <b|true> can be collabsed files <a|[]> files to parse for docs getModule <f> returns module for given item getSection <f> returns section for given item path <s|''> path prefix replace <[[]]|[]> See Ox.SyntaxHighlighter resizable <b|true> is resizable resize <a|[128, 256, 384]> resize positions size <s|256> default size self <o> shared private variable load <!> fired once all docs are loaded @*/ Ox.DocPanel = function(options, self) { // FIXME: defaults should be falsy self = self || {}; var that = Ox.Element({}, self) .defaults({ collapsible: true, files: [], getModule: function(item) { return item.file.replace(self.options.path, ''); }, getSection: function(item) { return item.section; }, path: '', replace: [], resizable: true, resize: [128, 256, 384], size: 256 }) .options(options || {}); self.$list = Ox.Element(); self.$page = Ox.Element(); that.$element = Ox.SplitPanel({ elements: [ { collapsible: self.options.collapsible, element: self.$list, resizable: self.options.resizable, resize: self.options.resize, size: self.options.size }, { element: self.$page } ], orientation: 'horizontal' }); loadList(function(docItems) { self.items = docItems; that.triggerEvent('load', {}); }); function loadList(callback) { var counter = 0, docItems = [], length = self.options.files.length; self.options.files.forEach(function(file) { Ox.doc(self.options.path + file, function(fileItems) { docItems = Ox.merge(docItems, fileItems); if (++counter == length) { makeTree(docItems); callback(docItems); } }); }); function makeTree(docItems) { var treeItems = []; docItems.forEach(function(docItem) { var moduleIndex, sectionIndex; docItem.module = self.options.getModule(docItem); moduleIndex = Ox.getIndexById(treeItems, '_' + docItem.module); if (moduleIndex == -1) { treeItems.push({ id: '_' + docItem.module, items: [], title: docItem.module }); moduleIndex = treeItems.length - 1; } docItem.section = self.options.getSection(docItem); if (docItem.section) { sectionIndex = Ox.getIndexById( treeItems[moduleIndex].items, '_' + docItem.module + '_' + docItem.section ); if (sectionIndex == -1) { treeItems[moduleIndex].items.push({ id: '_' + docItem.module + '_' + docItem.section, items: [], title: docItem.section }); sectionIndex = treeItems[moduleIndex].items.length - 1; } } ( docItem.section ? treeItems[moduleIndex].items[sectionIndex] : treeItems[moduleIndex] ).items.push({ id: docItem.name, title: docItem.name }); }); treeItems.sort(sortByTitle); treeItems.forEach(function(item) { item.items.sort(sortByTitle); item.items.forEach(function(subitem) { subitem.items.sort(sortByTitle); }); }); self.$list = Ox.TreeList({ items: treeItems, width: self.options.size - Ox.UI.SCROLLBAR_SIZE }) .bindEvent({ select: selectItem }); // fixme /* var $foo = Ox.Container(); self.$list.appendTo($foo); that.$element.replaceElement(0, $foo); */ that.$element.replaceElement(0, self.$list); } } function getItemByName(name) { var item = {}; Ox.forEach(self.items, function(v) { if (v.name == name) { item = v; return false; } }); return item; } function selectItem(data) { var selected; if (data.ids.length) { selected = data.ids[0]; if (selected[0] != '_') { self.$page = Ox.DocPage({ item: getItemByName(selected), replace: self.options.replace }); that.$element.replaceElement(1, self.$page); that.triggerEvent('select', { id: selected }); } } } function sortByTitle(a, b) { var ret = 0; if (a.title < b.title) { ret = -1; } else if (a.title > b.title) { ret = 1; } return ret; } /*@ selectItem <f> select item (id) -> <u> select an item id <s> if of item to select @*/ that.selectItem = function(id) { self.$list.triggerEvent('select', {'ids': [id]}); }; return that; };