add lazy load option
This commit is contained in:
parent
ac169ee16a
commit
576048baa8
|
@ -161,17 +161,19 @@ GitHub.prototype.getRepoFromPath = function(showInNonCodePage, currentRepo, toke
|
|||
|
||||
/**
|
||||
* Retrieves the code tree of a repository.
|
||||
* @param {Object} repo - the repo whose code tree is to be retrieved.
|
||||
* @param {String} token - the access token.
|
||||
* @param {Object} opts: { repo: repository, node(optional): selected node (null for resursively loading), token (optional): user access token, apiUrl (optional): base API URL }
|
||||
* @param {Function} cb(err: error, tree: array (of arrays) of items)
|
||||
*/
|
||||
GitHub.prototype.getCodeTree = function(repo, token, cb) {
|
||||
var self = this
|
||||
, folders = { '': [] }
|
||||
GitHub.prototype.getCodeTree = function(opts, cb) {
|
||||
var self = this
|
||||
, folders = { '': [] }
|
||||
, repo = opts.repo
|
||||
, token = opts.token
|
||||
, encodedBranch = encodeURIComponent(decodeURIComponent(repo.branch))
|
||||
, $dummyDiv = $('<div/>')
|
||||
, $dummyDiv = $('<div/>')
|
||||
|
||||
getTree(encodedBranch + '?recursive=true', function(err, tree) {
|
||||
var treePath = (opts.node && (opts.node.sha || encodedBranch)) || (encodedBranch + '?recursive=1')
|
||||
getTree(treePath, function(err, tree) {
|
||||
if (err) return cb(err)
|
||||
|
||||
fetchSubmodules(function(err, submodules) {
|
||||
|
@ -192,6 +194,10 @@ GitHub.prototype.getCodeTree = function(repo, token, cb) {
|
|||
// we're done
|
||||
if (item === undefined) return cb(null, folders[''])
|
||||
|
||||
// includes parent path
|
||||
if (opts.node && opts.node.path)
|
||||
item.path = opts.node.path + '/' + item.path
|
||||
|
||||
path = item.path
|
||||
type = item.type
|
||||
index = path.lastIndexOf('/')
|
||||
|
@ -201,10 +207,16 @@ GitHub.prototype.getCodeTree = function(repo, token, cb) {
|
|||
item.text = name
|
||||
item.icon = type // use `type` as class name for tree node
|
||||
|
||||
folders[path.substring(0, index)].push(item)
|
||||
if (opts.node) {
|
||||
// no hierarchy in lazy loading
|
||||
folders[''].push(item)
|
||||
}
|
||||
else
|
||||
folders[path.substring(0, index)].push(item)
|
||||
|
||||
if (type === 'tree') {
|
||||
folders[item.path] = item.children = []
|
||||
if (opts.node) item.children = true
|
||||
else folders[item.path] = item.children = []
|
||||
item.a_attr = { href: '#' }
|
||||
}
|
||||
else if (type === 'blob') {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Octotree",
|
||||
"version": "1.7.2",
|
||||
"version": "2.0.0",
|
||||
"manifest_version": 2,
|
||||
"author": "Buu Nguyen",
|
||||
"description": "Display GitHub code in tree format",
|
||||
|
|
|
@ -2,17 +2,18 @@ const
|
|||
PREFIX = 'octotree'
|
||||
|
||||
, STORE = {
|
||||
TOKEN : 'octotree.github_access_token',
|
||||
COLLAPSE : 'octotree.collapse',
|
||||
TABSIZE : 'octotree.tabsize',
|
||||
REMEMBER : 'octotree.remember',
|
||||
LAZYLOAD : 'octotree.lazyload',
|
||||
HOTKEYS : 'octotree.hotkeys',
|
||||
GHEURLS : 'octotree.gheurls',
|
||||
WIDTH : 'octotree.sidebar_width',
|
||||
POPUP : 'octotree.popup_shown',
|
||||
SHOWN : 'octotree.sidebar_shown',
|
||||
NONCODE : 'octotree.noncode_shown',
|
||||
TOKEN : 'octotree.github_access_token',
|
||||
COLLAPSE : 'octotree.collapse',
|
||||
TABSIZE : 'octotree.tabsize',
|
||||
REMEMBER : 'octotree.remember',
|
||||
LAZYLOAD : 'octotree.lazyload',
|
||||
RECURSIVE : 'octotree.recursive',
|
||||
HOTKEYS : 'octotree.hotkeys',
|
||||
GHEURLS : 'octotree.gheurls',
|
||||
WIDTH : 'octotree.sidebar_width',
|
||||
POPUP : 'octotree.popup_shown',
|
||||
SHOWN : 'octotree.sidebar_shown',
|
||||
NONCODE : 'octotree.noncode_shown',
|
||||
}
|
||||
|
||||
, DEFAULTS = {
|
||||
|
@ -21,6 +22,7 @@ const
|
|||
TABSIZE : '',
|
||||
REMEMBER : false,
|
||||
LAZYLOAD : false,
|
||||
RECURSIVE: true,
|
||||
// @ifdef SAFARI
|
||||
HOTKEYS : '⌘+b, ⌃+b',
|
||||
// @endif
|
||||
|
@ -43,4 +45,5 @@ const
|
|||
OPTS_CHANGE : 'octotree:change',
|
||||
VIEW_READY : 'octotree:ready',
|
||||
VIEW_CLOSE : 'octotree:close',
|
||||
FETCH_ERROR : 'octotree:error'
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
"icon": "data/icons/icon48.png",
|
||||
"icon64": "data/icons/icon64.png",
|
||||
"license": "MIT",
|
||||
"version": "1.7.2",
|
||||
"version": "2.0.0",
|
||||
"permissions": {
|
||||
"cross-domain-content": ["https://api.github.com", "https://github.com"]
|
||||
}
|
||||
|
|
|
@ -50,6 +50,9 @@ $(document).ready(function() {
|
|||
showView(hasError ? errorView.$view : treeView.$view)
|
||||
})
|
||||
.on(EVENT.OPTS_CHANGE, optionsChanged)
|
||||
.on(EVENT.FETCH_ERROR, function(event, err) {
|
||||
errorView.show(err)
|
||||
})
|
||||
})
|
||||
|
||||
$document
|
||||
|
@ -81,6 +84,9 @@ $(document).ready(function() {
|
|||
key.unbind(value[0])
|
||||
key(value[1], toggleSidebar)
|
||||
break
|
||||
case STORE.RECURSIVE:
|
||||
reload = true
|
||||
break
|
||||
}
|
||||
})
|
||||
if (reload) tryLoadRepo(true)
|
||||
|
@ -108,12 +114,9 @@ $(document).ready(function() {
|
|||
if (repoChanged || reload === true) {
|
||||
$document.trigger(EVENT.REQ_START)
|
||||
currRepo = repo
|
||||
|
||||
treeView.showHeader(repo)
|
||||
|
||||
adapter.getCodeTree(repo, token, function(err, tree) {
|
||||
if (err) errorView.show(err)
|
||||
else treeView.show(repo, tree)
|
||||
})
|
||||
treeView.show(repo, token)
|
||||
}
|
||||
else treeView.syncSelection()
|
||||
}
|
||||
|
|
|
@ -202,6 +202,11 @@
|
|||
label {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
label.disabled {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
input[type=text], textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.7.2</string>
|
||||
<string>2.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.7.2</string>
|
||||
<string>2.0.0</string>
|
||||
<key>Chrome</key>
|
||||
<dict/>
|
||||
<key>Content</key>
|
||||
|
|
|
@ -53,7 +53,10 @@
|
|||
<label><input type="checkbox" data-store="LAZYLOAD"> Only load tree when sidebar is open</label>
|
||||
</div>
|
||||
<div>
|
||||
<label><input type="checkbox" data-store="COLLAPSE"> Collapse folders with single sub-folder</label>
|
||||
<label><input type="checkbox" data-store="RECURSIVE"> Load repository recursively</label>
|
||||
</div>
|
||||
<div>
|
||||
<label><input type="checkbox" data-store="COLLAPSE" data-trigger-disable="RECURSIVE"> Collapse folders with single sub-folder</label>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
|
|
|
@ -6,6 +6,23 @@ function OptionsView($dom, store) {
|
|||
|
||||
this.$view = $view
|
||||
|
||||
$(document).ready(function() {
|
||||
function triggerChange(checkbox) {
|
||||
var store = $(checkbox).data('store')
|
||||
, checkboxs = $view.find('[data-trigger-disable=' + store + ']')
|
||||
checkboxs.prop('disabled', !checkbox.checked).closest('label').toggleClass('disabled', !checkbox.checked)
|
||||
}
|
||||
|
||||
eachOption(
|
||||
function($elm) {
|
||||
// triggers to disable all checkboxs having data-trigger-disable
|
||||
$elm.change(function(event) {
|
||||
triggerChange(event.target)
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// hide options view when sidebar is hidden
|
||||
$(document).on(EVENT.TOGGLE, function(event, visible) {
|
||||
if (!visible) toggle(false)
|
||||
|
@ -23,7 +40,8 @@ function OptionsView($dom, store) {
|
|||
else {
|
||||
eachOption(
|
||||
function($elm, key, local, value, cb) {
|
||||
if ($elm.is(':checkbox')) $elm.prop('checked', value)
|
||||
// Original jQuery prop function doesn't trigger change event
|
||||
if ($elm.is(':checkbox')) $elm.prop('checked', value).trigger("change")
|
||||
else $elm.val(value)
|
||||
cb()
|
||||
},
|
||||
|
@ -91,4 +109,4 @@ function OptionsView($dom, store) {
|
|||
completeFn
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,15 +74,30 @@ TreeView.prototype.showHeader = function(repo) {
|
|||
})
|
||||
}
|
||||
|
||||
TreeView.prototype.show = function(repo, treeData) {
|
||||
TreeView.prototype.show = function(repo, token) {
|
||||
var self = this
|
||||
, treeContainer = self.$view.find('.octotree_view_body')
|
||||
, tree = treeContainer.jstree(true)
|
||||
, collapseTree = self.store.get(STORE.COLLAPSE)
|
||||
, recursiveLoad = self.store.get(STORE.RECURSIVE)
|
||||
|
||||
treeData = sort(treeData)
|
||||
if (collapseTree) treeData = collapse(treeData)
|
||||
tree.settings.core.data = treeData
|
||||
function fetchData(node, success) {
|
||||
var selectedNode = node.original
|
||||
if (node.id === '#') selectedNode = {path: ''}
|
||||
self.adapter.getCodeTree({ repo: repo, token: token, node: recursiveLoad ? null : selectedNode}, function(err, treeData) {
|
||||
if (err) $(self).trigger(EVENT.FETCH_ERROR, [err])
|
||||
else success(treeData)
|
||||
})
|
||||
}
|
||||
|
||||
tree.settings.core.data = function (node, cb) {
|
||||
fetchData(node, function(treeData) {
|
||||
treeData = sort(treeData)
|
||||
if (collapseTree && recursiveLoad)
|
||||
treeData = collapse(treeData)
|
||||
cb(treeData)
|
||||
})
|
||||
}
|
||||
|
||||
treeContainer.one('refresh.jstree', function() {
|
||||
self.syncSelection()
|
||||
|
@ -97,7 +112,7 @@ TreeView.prototype.show = function(repo, treeData) {
|
|||
return a.type === 'blob' ? 1 : -1
|
||||
})
|
||||
folder.forEach(function(item) {
|
||||
if (item.type === 'tree') sort(item.children)
|
||||
if (item.type === 'tree' && item.children !== true && item.children.length > 0) sort(item.children)
|
||||
})
|
||||
return folder
|
||||
}
|
||||
|
@ -119,17 +134,41 @@ TreeView.prototype.show = function(repo, treeData) {
|
|||
|
||||
TreeView.prototype.syncSelection = function() {
|
||||
var tree = this.$view.find('.octotree_view_body').jstree(true)
|
||||
, path = location.pathname
|
||||
, path = decodeURIComponent(location.pathname)
|
||||
, recursiveLoad = this.store.get(STORE.RECURSIVE)
|
||||
|
||||
if (!tree) return
|
||||
tree.deselect_all()
|
||||
|
||||
// e.g. converts /buunguyen/octotree/type/branch/path to path
|
||||
var match = path.match(/(?:[^\/]+\/){4}(.*)/)
|
||||
, nodeId
|
||||
if (match) {
|
||||
nodeId = PREFIX + decodeURIComponent(match[1])
|
||||
tree.select_node(nodeId)
|
||||
tree.open_node(nodeId)
|
||||
if (!match) return
|
||||
|
||||
currentPath = match[1]
|
||||
|
||||
// e.g. converts ["lib/controllers"] to ["lib", "lib/controllers"]
|
||||
function createPaths(fullPath) {
|
||||
var paths = fullPath.split("/")
|
||||
, arrResult = [paths[0]]
|
||||
|
||||
paths.reduce(function(lastPath, curPath) {
|
||||
var path = (lastPath + "/" + curPath)
|
||||
arrResult.push(path)
|
||||
return path
|
||||
})
|
||||
return arrResult
|
||||
}
|
||||
|
||||
function openPathAtIndex (paths, index) {
|
||||
nodeId = PREFIX + paths[index]
|
||||
if (tree.get_node(nodeId)) {
|
||||
tree.deselect_all()
|
||||
tree.select_node(nodeId)
|
||||
tree.open_node(nodeId, function(node){
|
||||
if (index < paths.length - 1) openPathAtIndex(paths, index + 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var paths = recursiveLoad ? [currentPath] : createPaths(currentPath)
|
||||
openPathAtIndex(paths, 0)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue