Refactor margin moving code

This commit is contained in:
Buu Nguyen 2014-06-08 12:29:43 -07:00
parent 3d8ce21a60
commit e17746a56d
7 changed files with 58 additions and 65 deletions

View File

@ -3,20 +3,16 @@ Browser extensions (Chrome, Firefox, Safari and Opera) to display GitHub code in
* Easy-to-navigate code tree like IDEs * Easy-to-navigate code tree like IDEs
* Fast browsing with pjax * Fast browsing with pjax
* Toggle code tree with `cmd+b`, `ctrl+b` * Customizable hotkey
* Support private repositories (require [personal access token](#github-api-rate-limit)) * Support private repositories (require [personal access token](#github-api-rate-limit))
## Install on Chrome ## Install on Chrome
* Download and install [Octotree](https://chrome.google.com/webstore/detail/octotree/bkhaagjahfmjljalopjnoealnfndnagc) from the Chrome store * Download and install [Octotree](https://chrome.google.com/webstore/detail/octotree/bkhaagjahfmjljalopjnoealnfndnagc) from the Chrome store
* Navigate to any GitHub project (or just refresh this page as an example) * Navigate to any GitHub project (or just refresh this page as an example)
* The code tree should show as follows: * The code tree should show on the left-hand side of the screen
![When extension is active](docs/chrome.png)
## Install on Firefox, Safari and Opera ## Install on Firefox, Safari and Opera
Submitting to Mozilla and Safari stores is quite a tedious process. Octotree 1.0 (not even 1.1) was submitted to Mozilla store and is still being reviewed. Safari store requires even more work and time (that I don't have). You can just install the prebuilt extensions located in the [dist](https://github.com/buunguyen/octotree/tree/master/dist) folder. For security reason, be sure to install from this location only.
Alternatively, you can just install the prebuilt extensions located in the [dist](https://github.com/buunguyen/octotree/tree/master/dist) folder. For security reason, be sure to install from this location only.
* Firefox: drag `octotree.xpi` to the browser and follow the instructions * Firefox: drag `octotree.xpi` to the browser and follow the instructions
* Safari: drag `octotree.safariextz` to the browser and follow the instructions * Safari: drag `octotree.safariextz` to the browser and follow the instructions

View File

@ -10,7 +10,7 @@ const
, GH_BRANCH_BTN_SEL = '*[data-master-branch] > .js-select-button' , GH_BRANCH_BTN_SEL = '*[data-master-branch] > .js-select-button'
, GH_404_SEL = '#parallax_wrapper' , GH_404_SEL = '#parallax_wrapper'
, GH_PJAX_SEL = '#js-repo-pjax-container' , GH_PJAX_SEL = '#js-repo-pjax-container'
, GH_CONTAINERS = '.header > .container, .repohead > .container, .site > .container' , GH_CONTAINERS = 'body > .container, .header > .container, .site > .container, .repohead > .container'
, SIDEBAR_SPACE = 10 , SIDEBAR_SPACE = 10
function GitHub() {} function GitHub() {}
@ -40,15 +40,20 @@ GitHub.prototype.selectPath = function(url) {
* Updates page layout based on visibility status and width of the Octotree sidebar. * Updates page layout based on visibility status and width of the Octotree sidebar.
*/ */
GitHub.prototype.updateLayout = function(sidebarVisible, sidebarWidth) { GitHub.prototype.updateLayout = function(sidebarVisible, sidebarWidth) {
var containers = $(GH_CONTAINERS) var $containers = $(GH_CONTAINERS)
, marginLeft , autoMarginLeft
if (containers.length === 3) { , shouldPushLeft
marginLeft = parseInt($('body > .container').css('margin-left')) || ($('body').width() - $('body > .container').width()) / 2
containers.css('margin-left', (sidebarVisible && marginLeft <= sidebarWidth + SIDEBAR_SPACE) if ($containers.length === 4) {
autoMarginLeft = ($('body').width() - $containers.width()) / 2
shouldPushLeft = sidebarVisible && (autoMarginLeft <= sidebarWidth + SIDEBAR_SPACE)
$containers.css('margin-left', shouldPushLeft
? sidebarWidth + SIDEBAR_SPACE ? sidebarWidth + SIDEBAR_SPACE
: marginLeft) : autoMarginLeft)
} }
else $html.css('margin-left', sidebarVisible ? sidebarWidth - SIDEBAR_SPACE : 0)
// falls-back if GitHub DOM has been updated
else $('html').css('margin-left', sidebarVisible ? sidebarWidth - SIDEBAR_SPACE : 0)
} }
/** /**

View File

@ -5,7 +5,7 @@ const
TOKEN : 'octotree.github_access_token', TOKEN : 'octotree.github_access_token',
COLLAPSE : 'octotree.collapse', COLLAPSE : 'octotree.collapse',
REMEMBER : 'octotree.remember', REMEMBER : 'octotree.remember',
SHORTKEY : 'octotree.key', HOTKEYS : 'octotree.hotkeys',
WIDTH : 'octotree.sidebar_width', WIDTH : 'octotree.sidebar_width',
POPUP : 'octotree.popup_shown', POPUP : 'octotree.popup_shown',
SHOWN : 'octotree.sidebar_shown', SHOWN : 'octotree.sidebar_shown',

View File

@ -3,27 +3,31 @@
, $document = $(document) , $document = $(document)
, $dom = $(TEMPLATE) , $dom = $(TEMPLATE)
, $sidebar = $dom.find('.octotree_sidebar') , $sidebar = $dom.find('.octotree_sidebar')
, $toggleBtn = $sidebar.find('.octotree_toggle') , $toggler = $sidebar.find('.octotree_toggle')
, $views = $sidebar.find('.octotree_view') , $views = $sidebar.find('.octotree_view')
, store = new Storage() , store = new Storage()
, adapter = new GitHub() , adapter = new GitHub()
, currRepo = false
, hasError = false
, helpPopup = new HelpPopup($dom, store) , helpPopup = new HelpPopup($dom, store)
, treeView = new TreeView($dom, store, adapter) , treeView = new TreeView($dom, store, adapter)
, errorView = new ErrorView($dom, store) , errorView = new ErrorView($dom, store)
, optsView = new OptionsView($dom, store) , optsView = new OptionsView($dom, store)
, currRepo = false
, hasError = false
$document.ready(function() { $document.ready(function() {
$sidebar $sidebar
.appendTo($('body')) .appendTo($('body'))
.width(store.get(STORE.WIDTH) || 250) .width(store.get(STORE.WIDTH) || 250)
.resizable({ handles: 'e', minWidth: 200 }) .resizable({ handles: 'e', minWidth: 200 })
.resize(sidebarResized) .resize(layoutChanged)
$toggleBtn.click(toggleSidebarAndSave) $(window).resize(function(event) { // handle zoom
key.filter = function() { return $toggleBtn.is(':visible') } if (event.target === window) layoutChanged()
key(store.get(STORE.SHORTKEY), toggleSidebarAndSave) })
$toggler.click(toggleSidebarAndSave)
key.filter = function() { return $toggler.is(':visible') }
key(store.get(STORE.HOTKEYS), toggleSidebarAndSave)
;[treeView, errorView, optsView].forEach(function(view) { ;[treeView, errorView, optsView].forEach(function(view) {
$(view) $(view)
@ -39,26 +43,17 @@
$document $document
.on('pjax:send ' + EVENT.REQ_START, function() { .on('pjax:send ' + EVENT.REQ_START, function() {
$toggleBtn.addClass('loading') $toggler.addClass('loading')
}) })
.on('pjax:end ' + EVENT.REQ_END, function() { .on('pjax:end ' + EVENT.REQ_END, function() {
$toggleBtn.removeClass('loading') $toggler.removeClass('loading')
}) })
.on('pjax:timeout', function(event) { .on('pjax:timeout', function(event) {
event.preventDefault() event.preventDefault()
}) })
.on(EVENT.LOC_CHANGE, tryLoadRepo) .on(EVENT.LOC_CHANGE, tryLoadRepo)
.on(EVENT.TOGGLE, sidebarResized) .on(EVENT.TOGGLE, layoutChanged)
$(window).resize(function(ev) {
if(ev.target === window) {
$(GH_CONTAINERS).addClass('notransition')
sidebarResized()
setTimeout(function() {
$(GH_CONTAINERS).removeClass('notransition')
}, 300)
}
})
function optionsChanged(event, changes) { function optionsChanged(event, changes) {
var reload = false var reload = false
Object.keys(changes).forEach(function(storeKey) { Object.keys(changes).forEach(function(storeKey) {
@ -68,7 +63,7 @@
case STORE.TOKEN: case STORE.TOKEN:
reload = true reload = true
break break
case STORE.SHORTKEY: case STORE.HOTKEYS:
key.unbind(value[0]) key.unbind(value[0])
key(value[1], toggleSidebar) key(value[1], toggleSidebar)
break break
@ -82,7 +77,7 @@
, repoChanged = JSON.stringify(repo) !== JSON.stringify(currRepo) , repoChanged = JSON.stringify(repo) !== JSON.stringify(currRepo)
if (repo) { if (repo) {
helpPopup.show() helpPopup.show()
$toggleBtn.show() $toggler.show()
if (store.get(STORE.REMEMBER) && store.get(STORE.SHOWN)) toggleSidebar(true) if (store.get(STORE.REMEMBER) && store.get(STORE.SHOWN)) toggleSidebar(true)
if (repoChanged || reload === true) { if (repoChanged || reload === true) {
$document.trigger(EVENT.REQ_START) $document.trigger(EVENT.REQ_START)
@ -97,7 +92,7 @@
else treeView.syncSelection() else treeView.syncSelection()
} }
else { else {
$toggleBtn.hide() $toggler.hide()
toggleSidebar(false) toggleSidebar(false)
} }
} }
@ -123,7 +118,7 @@
} }
} }
function sidebarResized() { function layoutChanged() {
var width = $sidebar.width() var width = $sidebar.width()
adapter.updateLayout($html.hasClass(PREFIX), width) adapter.updateLayout($html.hasClass(PREFIX), width)
store.set(STORE.WIDTH, width) store.set(STORE.WIDTH, width)

View File

@ -1,9 +1,6 @@
html, .header > .container, .repohead > .container, .site > .container { html, .container {
transition: margin-left .2s ease; transition: margin-left .2s ease;
} }
.notransition {
transition: none !important;
}
.octotree_sidebar { .octotree_sidebar {
position: fixed !important; position: fixed !important;

View File

@ -33,13 +33,13 @@
</div> </div>
<div> <div>
<div> <div>
<label>Short keys</label> <label>Hotkeys</label>
<a href="https://github.com/madrobby/keymaster#supported-keys" target="_blank" tabIndex="-1">supported keys</a> <a href="https://github.com/madrobby/keymaster#defining-shortcuts" target="_blank" tabIndex="-1">supported keys</a>
</div> </div>
<input type="text" data-store="SHORTKEY"> <input type="text" data-store="HOTKEYS">
</div> </div>
<div> <div>
<label><input type="checkbox" data-store="REMEMBER"> Restore sidebar last visibility on load</label> <label><input type="checkbox" data-store="REMEMBER"> Show sidebar if previously shown</label>
</div> </div>
<div> <div>
<label><input type="checkbox" data-store="COLLAPSE"> Collapse folders with single sub-folder</label> <label><input type="checkbox" data-store="COLLAPSE"> Collapse folders with single sub-folder</label>

View File

@ -1,12 +1,12 @@
function OptionsView($dom, store) { function OptionsView($dom, store) {
var self = this var self = this
, $view = $dom.find('.octotree_optsview').submit(save) , $view = $dom.find('.octotree_optsview').submit(save)
, $toggleBtn = $dom.find('.octotree_opts').click(toggle) , $toggler = $dom.find('.octotree_opts').click(toggle)
this.$view = $view this.$view = $view
if (store.get(STORE.COLLAPSE) == null) store.set(STORE.COLLAPSE, false) if (store.get(STORE.COLLAPSE) == null) store.set(STORE.COLLAPSE, false)
if (store.get(STORE.REMEMBER) == null) store.set(STORE.REMEMBER, false) if (store.get(STORE.REMEMBER) == null) store.set(STORE.REMEMBER, false)
if (!store.get(STORE.SHORTKEY)) store.set(STORE.SHORTKEY, '⌘+b, ⌃+b') if (!store.get(STORE.HOTKEYS)) store.set(STORE.HOTKEYS, '⌘+b, ⌃+b')
$(document).on(EVENT.TOGGLE, function(event, visible) { $(document).on(EVENT.TOGGLE, function(event, visible) {
// hide options view when sidebar is hidden // hide options view when sidebar is hidden
@ -18,12 +18,12 @@ function OptionsView($dom, store) {
if ($view.hasClass('current') === visibility) return if ($view.hasClass('current') === visibility) return
return toggle() return toggle()
} }
if ($toggleBtn.hasClass('selected')) { if ($toggler.hasClass('selected')) {
$toggleBtn.removeClass('selected') $toggler.removeClass('selected')
$(self).trigger(EVENT.VIEW_CLOSE) $(self).trigger(EVENT.VIEW_CLOSE)
} }
else { else {
$toggleBtn.addClass('selected') $toggler.addClass('selected')
$view.find('[data-store]').each(function() { $view.find('[data-store]').each(function() {
var $elm = $(this) var $elm = $(this)
, storeKey = STORE[$elm.data('store')] , storeKey = STORE[$elm.data('store')]