const {each, dom, cmp, naturalCmp} = require('../util'); const event = require('../core/event'); const location = require('../core/location'); const resource = require('../core/resource'); const allsettings = require('../core/settings'); const store = require('../core/store'); const settings = Object.assign({ enabled: false, show: true, maxSubfolders: 50, naturalSort: false, ignorecase: true }, allsettings.tree); const itemTpl = `
`; const settingsTpl = `

Tree

view-tree
`; const storekey = 'ext/tree'; const closestItem = el => { while (!el._item && el.parentNode) { el = el.parentNode; } return el._item; }; const onIndicatorClick = ev => { const item = closestItem(ev.target); if (item._treeState === 'unknown') { item.fetchContent().then(() => { item._treeState = 'open'; update(item); // eslint-disable-line no-use-before-define }); } else if (item._treeState === 'open') { item._treeState = 'closed'; item._$tree.rmCls('open').addCls('closed'); } else if (item._treeState === 'closed') { item._treeState = 'open'; item._$tree.rmCls('closed').addCls('open'); } }; const cmpItems = (item1, item2) => { let val1 = item1.label; let val2 = item2.label; if (settings.ignorecase) { val1 = val1.toLowerCase(); val2 = val2.toLowerCase(); } return settings.naturalSort ? naturalCmp(val1, val2) : cmp(val1, val2); }; const update = item => { const subfolders = item.getSubfolders(); const subLen = subfolders.length; const subMax = settings.maxSubfolders; const $html = dom(itemTpl); $html.find('.indicator').on('click', onIndicatorClick); $html.find('.label').text(item.label); location.setLink($html.find('a'), item); if (item.isCurrentFolder()) { $html.addCls('active'); } if (!item.isManaged) { $html.find('.icon img').attr('src', resource.icon('folder-page')); } // indicator item._treeState = item._treeState || 'none'; if (item.isManaged && !item.isContentFetched) { item._treeState = 'unknown'; } else if (!subLen) { item._treeState = 'none'; } $html.addCls(item._treeState); // subfolders if (subLen) { const $ul = dom('
').appTo($html); subfolders.sort(cmpItems); each(subfolders.slice(0, subMax), e => $ul.app(update(e))); if (subLen > subMax) { $ul.app(`
… ${subLen - subMax} more subfolders
`); } } if (item._$tree) { item._$tree.rpl($html); } item._$tree = $html; $html[0]._item = item; return $html; }; const fetchTree = item => { item._treeState = 'open'; return item.fetchContent().then(() => { if (item.parent) { return fetchTree(item.parent); } return item; }); }; const updateSettings = () => { if (store.get(storekey)) { dom('#view-tree').addCls('active'); dom('#tree').show(); } else { dom('#view-tree').rmCls('active'); dom('#tree').hide(); } }; const onLocationChanged = item => { fetchTree(item).then(root => { dom('#tree').clr().app(update(root)); updateSettings(); }); }; const init = () => { if (!settings.enabled) { return; } dom('
').hide().appTo('#mainrow'); dom(settingsTpl) .appTo('#sidebar') .find('#view-tree') .on('click', ev => { store.put(storekey, !store.get(storekey)); updateSettings(); event.pub('resize'); ev.preventDefault(); }); // ensure stored value is boolean, otherwise set default if (typeof store.get(storekey) !== 'boolean') { store.put(storekey, settings.show); } updateSettings(); event.sub('location.changed', onLocationChanged); }; init();