diff --git a/source/Ox.UI/js/Code/DocPanel.js b/source/Ox.UI/js/Code/DocPanel.js index bcfaa9b9..be863ade 100644 --- a/source/Ox.UI/js/Code/DocPanel.js +++ b/source/Ox.UI/js/Code/DocPanel.js @@ -6,14 +6,18 @@ Ox.DocPanel Documentation Panel options Options object collapsible If true, the list can be collabsed element Default content - files Files to parse for docs + files Files to parse for docs (alternative to items option) getModule Returns module for given item getSection Returns section for given item - items Array of doc items (alternative to files options) + items Array of doc items (alternative to files option) path Path prefix replace <[[]]|[]> See Ox.SyntaxHighlighter resizable If true, list is resizable resize List resize positions + runTests If true, run tests + selected Id of the selected item + showTests If true, show test results in list + showTooltips If true, show test result tooltips in list size Default list size self Shared private variable load Fires once all docs are loaded @@ -39,8 +43,11 @@ Ox.DocPanel = function(options, self) { replace: [], resizable: false, resize: [128, 256, 384], + runTests: false, selected: '', - size: 256 + showTests: false, + showTooltips: false, + size: 256, }) .options(options || {}) .update({ @@ -49,6 +56,8 @@ Ox.DocPanel = function(options, self) { } }); + self.results = {}; + self.$list = Ox.Element(); self.$page = Ox.Element(); @@ -77,10 +86,49 @@ Ox.DocPanel = function(options, self) { }), function(docItems) { self.options.items = docItems; renderList(); + self.options.runTests && runTests(); that.triggerEvent('load', {items: docItems}); }); } else { renderList(); + self.options.runTests && runTests(); + } + + function getIcon(id, expanded) { + var $icon = null, results = self.results[id]; + if (!Ox.isEmpty(self.results)) { + $icon = Ox.Theme.getColorImage( + 'symbol' + (expanded === true ? 'Down' : expanded === false ? 'Right' : 'Center'), + !results ? 'none' : results.failed === 0 ? 'passed' : 'failed', + self.options.showTooltips ? getTooltip(results) : null + ); + } else if (!Ox.endsWith(id, '/')) { + $icon = $('').attr({src: Ox.UI.getImageURL('symbolCenter')}); + } + return $icon; + } + + function getItemByName(name) { + var item = {}; + Ox.forEach(self.options.items, function(v) { + if (v.name == name) { + item = v; + Ox.Break(); + } + }); + return item; + } + + function getTooltip(results) { + return results + ? results.passed + ' test' + + (results.passed == 1 ? '' : 's') + ' passed' + + (results.failed + ? ', ' + results.failed + ' test' + + (results.failed == 1 ? '' : 's') + ' failed' + : '' + ) + : 'No tests'; } function parseFiles(callback) { @@ -98,12 +146,12 @@ Ox.DocPanel = function(options, self) { function renderList() { var treeItems = []; self.options.items.forEach(function(docItem) { - var moduleIndex, sectionIndex; + var moduleIndex, results, sectionIndex; docItem.module = self.options.getModule(docItem); - moduleIndex = Ox.getIndexById(treeItems, '_' + docItem.module); + moduleIndex = Ox.getIndexById(treeItems, docItem.module + '/'); if (moduleIndex == -1) { treeItems.push({ - id: '_' + docItem.module, + id: docItem.module + '/', items: [], title: docItem.module }); @@ -113,11 +161,11 @@ Ox.DocPanel = function(options, self) { if (docItem.section) { sectionIndex = Ox.getIndexById( treeItems[moduleIndex].items, - '_' + docItem.module + '_' + docItem.section + docItem.module + '/' + docItem.section + '/' ); if (sectionIndex == -1) { treeItems[moduleIndex].items.push({ - id: '_' + docItem.module + '_' + docItem.section, + id: docItem.module + '/' + docItem.section + '/', items: [], title: docItem.section }); @@ -129,7 +177,9 @@ Ox.DocPanel = function(options, self) { ? treeItems[moduleIndex].items[sectionIndex] : treeItems[moduleIndex] ).items.push({ - id: docItem.name, + id: docItem.module + '/' + ( + docItem.section ? docItem.section + '/' : '' + ) + docItem.name, title: docItem.name }); }); @@ -141,42 +191,70 @@ Ox.DocPanel = function(options, self) { }); }); self.$list = Ox.TreeList({ + icon: self.options.showTests + ? getIcon + : Ox.UI.getImageURL('symbolCenter'), items: treeItems, selected: self.options.selected ? [self.options.selected] : '', - width: self.options.size - Ox.UI.SCROLLBAR_SIZE + width: self.options.size }) .bindEvent({ select: function(data) { selectItem(data.ids.length ? data.ids[0] : '') } }); - that.$element.replaceElement(0, self.$list); + self.$panel.replaceElement(0, self.$list); selectItem(self.options.selected); } - function getItemByName(name) { - var item = {}; - Ox.forEach(self.options.items, function(v) { - if (v.name == name) { - item = v; - Ox.Break(); - } - }); - return item; + function runTests() { + setTimeout(function() { + Ox.load({Geo: {}, Image: {}, Unicode: {}}, function() { + Ox.test(self.options.items, function(results) { + results.forEach(function(result) { + var item = getItemByName(result.name), + passed = result.passed ? 'passed' : 'failed'; + item.tests[Ox.indexOf(item.tests, function(test) { + return test.statement == result.statement; + })] = result; + ['', item.module + '/'].concat( + item.section ? item.module + '/' + item.section + '/' : [], + item.module + '/' + (item.section ? item.section + '/' : '') + item.name + ).forEach(function(key) { + self.results[key] = self.results[key] || {passed: 0, failed: 0}; + self.results[key][passed]++; + }); + }); + renderList(); + }); + }); + }, 1000); } function selectItem(id) { + var item, name; + if (id && !Ox.contains(id, '/')) { + name = id; + item = getItemByName(name); + id = item ? item.module + '/' + ( + item.section ? item.section + '/' : '' + ) + item.name : ''; + } if (id) { self.options.selected = id; - if (self.options.selected[0] != '_') { - self.$list.options({selected: [id]}); + if (!Ox.endsWith(self.options.selected, '/')) { + if (!item) { + name = self.options.selected.split('/').slice(-1); + item = getItemByName(name); + } + self.$list.options({selected: [self.options.selected]}); self.$page = Ox.DocPage({ - item: getItemByName(self.options.selected), + item: item, replace: self.options.replace }); that.$element.replaceElement(1, self.$page); - that.triggerEvent('select', {id: self.options.selected}); + that.triggerEvent('select', {id: name}); } } else { self.$page.empty().append(self.options.element); @@ -184,9 +262,9 @@ Ox.DocPanel = function(options, self) { } function sortByTitle(a, b) { - return a.title < b.title ? -1 - : a.title > b.title ? 1 - : 0; + var a = Ox.stripTags(a.title).toLowerCase(), + b = Ox.stripTags(b.title).toLowerCase(); + return a < b ? -1 : a > b ? 1 : 0; } return that;