Improve option handling and GitLab styling
* Refactor storage support * Options except urls are per-site * Fix GitLab styling bug
This commit is contained in:
parent
f8161c02c7
commit
63e111e438
|
@ -50,8 +50,9 @@ By default, Octotree only works on `github.com` and `gitlab.com`. To support ent
|
|||
|
||||
### v2.0.0
|
||||
* Support GitLab
|
||||
* Modify Octotree options
|
||||
* Support lazy-load individual folder (GitHub)
|
||||
* Support lazy-load individual folder (GitHub only)
|
||||
* Simplify Octotree options
|
||||
* Support selecting different options for each host
|
||||
|
||||
### v1.7.2
|
||||
* Fix bug long branches are not loaded correctly due to GitHub DOM change
|
||||
|
|
88
gulpfile.js
88
gulpfile.js
|
@ -1,29 +1,31 @@
|
|||
var gulp = require('gulp')
|
||||
, path = require('path')
|
||||
, merge = require('event-stream').merge
|
||||
, map = require('map-stream')
|
||||
, spawn = require('child_process').spawn
|
||||
, $ = require('gulp-load-plugins')()
|
||||
'use strict'
|
||||
|
||||
const gulp = require('gulp')
|
||||
const path = require('path')
|
||||
const merge = require('event-stream').merge
|
||||
const map = require('map-stream')
|
||||
const spawn = require('child_process').spawn
|
||||
const $ = require('gulp-load-plugins')()
|
||||
|
||||
// Tasks
|
||||
gulp.task('clean', function () {
|
||||
gulp.task('clean', () => {
|
||||
return pipe('./tmp', [$.clean()])
|
||||
})
|
||||
|
||||
gulp.task('build', function (cb) {
|
||||
gulp.task('build', (cb) => {
|
||||
$.runSequence('clean', 'styles', 'chrome', 'opera', 'safari', 'firefox', cb)
|
||||
})
|
||||
|
||||
gulp.task('default', ['build'], function () {
|
||||
gulp.task('default', ['build'], () => {
|
||||
gulp.watch(['./libs/**/*', './src/**/*'], ['default'])
|
||||
})
|
||||
|
||||
gulp.task('dist', ['build'], function (cb) {
|
||||
gulp.task('dist', ['build'], (cb) => {
|
||||
$.runSequence('firefox:xpi', 'chrome:zip', 'chrome:crx', 'opera:nex', cb)
|
||||
})
|
||||
|
||||
gulp.task('test', ['build'], function (cb) {
|
||||
var ps = spawn(
|
||||
gulp.task('test', ['build'], (cb) => {
|
||||
const ps = spawn(
|
||||
'./node_modules/.bin/mocha',
|
||||
['--harmony', '--reporter', 'spec', '--bail', '--recursive', '--timeout', '-1']
|
||||
)
|
||||
|
@ -32,62 +34,62 @@ gulp.task('test', ['build'], function (cb) {
|
|||
ps.on('close', cb)
|
||||
})
|
||||
|
||||
gulp.task('styles', function () {
|
||||
gulp.task('styles', () => {
|
||||
return pipe('./src/styles/octotree.less',
|
||||
[$.less(), $.autoprefixer({cascade: true})],
|
||||
'./tmp')
|
||||
})
|
||||
|
||||
// Chrome
|
||||
gulp.task('chrome:template', function () {
|
||||
gulp.task('chrome:template', () => {
|
||||
return buildTemplate({CHROME: true})
|
||||
})
|
||||
|
||||
gulp.task('chrome:js', ['chrome:template'], function () {
|
||||
return buildJs(['./src/config/chrome/storage.js'], {CHROME: true})
|
||||
gulp.task('chrome:js', ['chrome:template'], () => {
|
||||
return buildJs(['./src/config/chrome/overrides.js'], {CHROME: true})
|
||||
})
|
||||
|
||||
gulp.task('chrome', ['chrome:js'], function () {
|
||||
gulp.task('chrome', ['chrome:js'], () => {
|
||||
return merge(
|
||||
pipe('./icons/**/*', './tmp/chrome/icons'),
|
||||
pipe(['./libs/**/*', './tmp/octotree.*', './src/config/chrome/**/*', '!./src/config/chrome/storage.js'], './tmp/chrome/')
|
||||
)
|
||||
})
|
||||
|
||||
gulp.task('chrome:zip', function () {
|
||||
gulp.task('chrome:zip', () => {
|
||||
return pipe('./tmp/chrome/**/*', [$.zip('chrome.zip')], './dist')
|
||||
})
|
||||
|
||||
gulp.task('chrome:_crx', function (cb) {
|
||||
gulp.task('chrome:_crx', (cb) => {
|
||||
$.run('"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"' +
|
||||
' --pack-extension=' + path.join(__dirname, './tmp/chrome') +
|
||||
' --pack-extension-key=' + path.join(process.env.HOME, '.ssh/chrome.pem')
|
||||
).exec(cb)
|
||||
})
|
||||
|
||||
gulp.task('chrome:crx', ['chrome:_crx'], function () {
|
||||
gulp.task('chrome:crx', ['chrome:_crx'], () => {
|
||||
return pipe('./tmp/chrome.crx', './dist')
|
||||
})
|
||||
|
||||
// Opera
|
||||
gulp.task('opera', ['chrome'], function () {
|
||||
gulp.task('opera', ['chrome'], () => {
|
||||
return pipe('./tmp/chrome/**/*', './tmp/opera')
|
||||
})
|
||||
|
||||
gulp.task('opera:nex', function () {
|
||||
gulp.task('opera:nex', () => {
|
||||
return pipe('./dist/chrome.crx', [$.rename('opera.nex')], './dist')
|
||||
})
|
||||
|
||||
// Safari
|
||||
gulp.task('safari:template', function () {
|
||||
gulp.task('safari:template', () => {
|
||||
return buildTemplate({SAFARI: true})
|
||||
})
|
||||
|
||||
gulp.task('safari:js', ['safari:template'], function () {
|
||||
return buildJs(['./src/config/safari/storage.js'], {SAFARI: true})
|
||||
gulp.task('safari:js', ['safari:template'], () => {
|
||||
return buildJs([], {SAFARI: true})
|
||||
})
|
||||
|
||||
gulp.task('safari', ['safari:js'], function () {
|
||||
gulp.task('safari', ['safari:js'], () => {
|
||||
return merge(
|
||||
pipe('./icons/**/*', './tmp/safari/octotree.safariextension/icons'),
|
||||
pipe(['./libs/**/*', './tmp/octotree.js', './tmp/octotree.css',
|
||||
|
@ -96,15 +98,15 @@ gulp.task('safari', ['safari:js'], function () {
|
|||
})
|
||||
|
||||
// Firefox
|
||||
gulp.task('firefox:template', function () {
|
||||
gulp.task('firefox:template', () => {
|
||||
return buildTemplate({FIREFOX: true})
|
||||
})
|
||||
|
||||
gulp.task('firefox:js', ['firefox:template'], function () {
|
||||
return buildJs(['./src/config/firefox/storage.js'], {FIREFOX: true})
|
||||
gulp.task('firefox:js', ['firefox:template'], () => {
|
||||
return buildJs([], {FIREFOX: true})
|
||||
})
|
||||
|
||||
gulp.task('firefox', ['firefox:js'], function () {
|
||||
gulp.task('firefox', ['firefox:js'], () => {
|
||||
return merge(
|
||||
pipe('./icons/**/*', './tmp/firefox/data/icons'),
|
||||
pipe(['./libs/**/*', './tmp/octotree.js', './tmp/octotree.css'], './tmp/firefox/data'),
|
||||
|
@ -113,7 +115,7 @@ gulp.task('firefox', ['firefox:js'], function () {
|
|||
)
|
||||
})
|
||||
|
||||
gulp.task('firefox:xpi', function (cb) {
|
||||
gulp.task('firefox:xpi', (cb) => {
|
||||
$.run('cd ./tmp/firefox && cfx xpi --output-file=../../dist/firefox.xpi').exec(cb)
|
||||
})
|
||||
|
||||
|
@ -123,10 +125,12 @@ function pipe(src, transforms, dest) {
|
|||
dest = transforms
|
||||
transforms = null
|
||||
}
|
||||
var stream = gulp.src(src)
|
||||
|
||||
let stream = gulp.src(src)
|
||||
transforms && transforms.forEach(function (transform) {
|
||||
stream = stream.pipe(transform)
|
||||
})
|
||||
|
||||
if (dest) stream = stream.pipe(gulp.dest(dest))
|
||||
return stream
|
||||
}
|
||||
|
@ -135,20 +139,22 @@ function html2js(template) {
|
|||
return map(escape)
|
||||
|
||||
function escape(file, cb) {
|
||||
var path = $.util.replaceExtension(file.path, '.js')
|
||||
, content = file.contents.toString()
|
||||
, escaped = content.replace(/\\/g, "\\\\")
|
||||
const path = $.util.replaceExtension(file.path, '.js')
|
||||
const content = file.contents.toString()
|
||||
const escaped = content
|
||||
.replace(/\\/g, "\\\\")
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(/\r?\n/g, "\\n' +\n '")
|
||||
, body = template.replace('$$', escaped)
|
||||
const body = template.replace('$$', escaped)
|
||||
|
||||
file.path = path
|
||||
file.contents = new Buffer(body)
|
||||
cb(null, file)
|
||||
}
|
||||
}
|
||||
|
||||
function buildJs(additions, ctx) {
|
||||
var src = additions.concat([
|
||||
function buildJs(overrides, ctx) {
|
||||
const src = [
|
||||
'./tmp/template.js',
|
||||
'./src/constants.js',
|
||||
'./src/adapters/adapter.js',
|
||||
|
@ -161,8 +167,10 @@ function buildJs(additions, ctx) {
|
|||
'./src/util.location.js',
|
||||
'./src/util.module.js',
|
||||
'./src/util.async.js',
|
||||
'./src/octotree.js',
|
||||
])
|
||||
'./src/util.storage.js'
|
||||
].concat(overrides)
|
||||
.concat('./src/octotree.js')
|
||||
|
||||
return pipe(src, [
|
||||
$.babel({presets: ['es2015']}),
|
||||
$.concat('octotree.js'),
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"crx": "^0.4.4",
|
||||
"event-stream": "*",
|
||||
"firefox-profile": "~0.3.6",
|
||||
"gulp": "^3.8.6",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-autoprefixer": "0.0.8",
|
||||
"gulp-babel": "^6.1.0",
|
||||
"gulp-clean": "^0.3.1",
|
||||
|
|
|
@ -191,13 +191,31 @@ class Adapter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the CSS class to be added to the Octotree sidebar.
|
||||
* Inits behaviors after the sidebar is added to the DOM.
|
||||
* @api public
|
||||
*/
|
||||
init($sidebar) {
|
||||
$sidebar
|
||||
.resizable({ handles: 'e', minWidth: this.getMinWidth() })
|
||||
.addClass(this.getCssClass())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSS class to be added to the Octotree sidebar.
|
||||
* @api protected
|
||||
*/
|
||||
getCssClass() {
|
||||
throw new Error('Not implemented')
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum width acceptable for the sidebar.
|
||||
* @api protected
|
||||
*/
|
||||
getMinWidth() {
|
||||
return 200
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the adapter is capable of loading the entire tree in
|
||||
* a single request. This is usually determined by the underlying the API.
|
||||
|
@ -247,7 +265,6 @@ class Adapter {
|
|||
window.location.href = path
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Selects a submodule.
|
||||
* @api public
|
||||
|
|
|
@ -14,6 +14,7 @@ const GH_PJAX_SEL = '#js-repo-pjax-container'
|
|||
const GH_CONTAINERS = '.container'
|
||||
|
||||
class GitHub extends Adapter {
|
||||
|
||||
// @override
|
||||
getCssClass() {
|
||||
return 'octotree_github_sidebar'
|
||||
|
|
|
@ -9,6 +9,7 @@ const GL_SHIFTED = 'h1.title'
|
|||
const GL_PROJECT_ID = '#project_id'
|
||||
|
||||
class GitLab extends Adapter {
|
||||
|
||||
constructor(store) {
|
||||
super()
|
||||
|
||||
|
@ -21,6 +22,11 @@ class GitLab extends Adapter {
|
|||
store.set(STORE.TOKEN, token, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @override
|
||||
init($sidebar) {
|
||||
super.init($sidebar)
|
||||
|
||||
// Triggers layout when the GL sidebar is toggled
|
||||
$('.toggle-nav-collapse').click(() => {
|
||||
|
@ -28,6 +34,22 @@ class GitLab extends Adapter {
|
|||
$(document).trigger(EVENT.LAYOUT_CHANGE)
|
||||
}, 10)
|
||||
})
|
||||
|
||||
// GitLab disables our submit buttons, re-enable them
|
||||
$('.octotree_view_body button[type="submit"]').click((event) => {
|
||||
setTimeout(() => {
|
||||
$(event.target).prop('disabled', false).removeClass('disabled')
|
||||
}, 100)
|
||||
})
|
||||
|
||||
// Reuses GitLab styles for inputs
|
||||
$('.octotree_view_body input[type="text"], .octotree_view_body textarea')
|
||||
.addClass('form-control')
|
||||
|
||||
// GitLab removes DOM, add back
|
||||
$(document).on(EVENT.LOC_CHANGE, () => {
|
||||
$sidebar.appendTo('body')
|
||||
})
|
||||
}
|
||||
|
||||
// @override
|
||||
|
@ -35,6 +57,11 @@ class GitLab extends Adapter {
|
|||
return 'octotree_gitlab_sidebar'
|
||||
}
|
||||
|
||||
// @override
|
||||
getMinWidth() {
|
||||
return 230 // just enough to hide the GitLab sidebar
|
||||
}
|
||||
|
||||
// @override
|
||||
getCreateTokenUrl() {
|
||||
return `${location.protocol}//${location.host}/profile/account`
|
||||
|
@ -42,16 +69,16 @@ class GitLab extends Adapter {
|
|||
|
||||
// @override
|
||||
updateLayout(sidebarVisible, sidebarWidth) {
|
||||
const useNewDesign = $('.navbar-gitlab.header-collapsed, .navbar-gitlab.header-expanded').length > 0
|
||||
const isNewDesign = $('.navbar-gitlab.header-collapsed, .navbar-gitlab.header-expanded').length > 0
|
||||
const glSidebarExpanded = $('.page-with-sidebar').hasClass('page-sidebar-expanded')
|
||||
let glSidebarWidth = glSidebarExpanded ? 230 : 62
|
||||
|
||||
if (useNewDesign) {
|
||||
if (isNewDesign) {
|
||||
const glSidebarWidth = glSidebarExpanded ? 230 : 62
|
||||
$(GL_SHIFTED).css('margin-left', sidebarVisible ? '' : 36)
|
||||
$('.octotree_toggle').css('right', sidebarVisible ? '' : -(glSidebarWidth + 50))
|
||||
}
|
||||
else {
|
||||
glSidebarWidth = glSidebarExpanded ? 230 : 52
|
||||
const glSidebarWidth = glSidebarExpanded ? 230 : 52
|
||||
$(GL_HEADER).css('z-index', 3)
|
||||
$(GL_SIDEBAR).css('z-index', 1)
|
||||
$(GL_SHIFTED).css('margin-left', sidebarVisible ? '' : 56)
|
||||
|
@ -61,7 +88,7 @@ class GitLab extends Adapter {
|
|||
})
|
||||
}
|
||||
|
||||
$(GL_HEADER).css({'z-index': 3, 'padding-left': sidebarVisible ? sidebarWidth : ''})
|
||||
$(GL_HEADER).css({'z-index': 3, 'margin-left': sidebarVisible ? sidebarWidth : ''})
|
||||
$('.page-with-sidebar').css('padding-left', sidebarVisible ? sidebarWidth : '')
|
||||
}
|
||||
|
||||
|
@ -138,25 +165,6 @@ class GitLab extends Adapter {
|
|||
}, cb)
|
||||
}
|
||||
|
||||
// @override
|
||||
setSideBar(sidebar) {
|
||||
this.sidebar = sidebar
|
||||
// GL disables our submit buttons, re-enable them
|
||||
const btns = $('.octotree_view_body button[type="submit"]')
|
||||
|
||||
btns.click((event) => {
|
||||
setTimeout(() => {
|
||||
$(event.target).prop('disabled', false).removeClass('disabled')
|
||||
}, 30)
|
||||
})
|
||||
// Make inputs consistent with GL style
|
||||
$('.octotree_view_body input[type="text"], .octotree_view_body textarea').addClass('form-control')
|
||||
|
||||
$(document).on(EVENT.LOC_CHANGE, () => {
|
||||
this.sidebar.appendTo('body')
|
||||
})
|
||||
}
|
||||
|
||||
// @override
|
||||
_getTree(path, opts, cb) {
|
||||
this._get(`/tree?path=${path}&ref_name=${opts.encodedBranch}`, opts, cb)
|
||||
|
|
|
@ -3,18 +3,6 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.page-sidebar-expanded {
|
||||
.octotree_gitlab_sidebar {
|
||||
left: 249px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-sidebar-collapsed {
|
||||
.octotree_gitlab_sidebar {
|
||||
left: 79px;
|
||||
}
|
||||
}
|
||||
|
||||
.octotree_gitlab_sidebar {
|
||||
a.octotree_toggle {
|
||||
right: 5px;
|
||||
|
@ -29,24 +17,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
html:not(.octotree) {
|
||||
.page-sidebar-expanded {
|
||||
.octotree_gitlab_sidebar {
|
||||
a.octotree_toggle {
|
||||
right: -294px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-sidebar-collapsed {
|
||||
.octotree_gitlab_sidebar {
|
||||
a.octotree_toggle {
|
||||
right: -110px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.octotree_gitlab_sidebar {
|
||||
transition-duration: .3s;
|
||||
padding-top: 58px;
|
|
@ -0,0 +1,21 @@
|
|||
(() => {
|
||||
const oldSet = Storage.prototype.set
|
||||
Storage.prototype.set = function (key, val, cb) {
|
||||
this._cache = this._cache || {}
|
||||
this._cache[key] = val
|
||||
|
||||
const shared = ~key.indexOf('.shared')
|
||||
if (shared) chrome.storage.local.set({[key]: val}, cb || Function())
|
||||
else oldSet.call(this, key, val, cb)
|
||||
}
|
||||
|
||||
const oldGet = Storage.prototype.get
|
||||
Storage.prototype.get = function (key, cb) {
|
||||
this._cache = this._cache || {}
|
||||
if (!cb) return this._cache[key]
|
||||
|
||||
const shared = ~key.indexOf('.shared')
|
||||
if (shared) chrome.storage.local.get(key, (item) => cb(item[key]))
|
||||
else oldGet.call(this, key, cb)
|
||||
}
|
||||
})()
|
|
@ -1,48 +0,0 @@
|
|||
function Storage() {
|
||||
var cache = this.cache = {}
|
||||
chrome.storage.onChanged.addListener(function(changes) {
|
||||
for (var key in changes) cache[key] = changes[key].newValue
|
||||
})
|
||||
}
|
||||
|
||||
Storage.prototype.set = function(key, val, local, cb) {
|
||||
if (typeof local === 'function') {
|
||||
cb = local
|
||||
local = false
|
||||
}
|
||||
|
||||
cb = cb || Function()
|
||||
this.cache[key] = val
|
||||
|
||||
if (local) {
|
||||
localStorage.setItem(key, JSON.stringify(val))
|
||||
cb()
|
||||
}
|
||||
else {
|
||||
var item = {}
|
||||
item[key] = val
|
||||
chrome.storage.local.set(item, cb)
|
||||
}
|
||||
}
|
||||
|
||||
Storage.prototype.get = function(key, local, cb) {
|
||||
if (typeof local === 'function') {
|
||||
cb = local
|
||||
local = false
|
||||
}
|
||||
|
||||
if (!cb) return this.cache[key]
|
||||
|
||||
if (local) cb(parse(localStorage.getItem(key)))
|
||||
else chrome.storage.local.get(key, function(item) {
|
||||
cb(item[key])
|
||||
})
|
||||
|
||||
function parse(val) {
|
||||
try {
|
||||
return JSON.parse(val)
|
||||
} catch (e) {
|
||||
return val
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
function Storage() {}
|
||||
|
||||
Storage.prototype.set = function(key, val, local, cb) {
|
||||
if (typeof local === 'function') cb = local
|
||||
|
||||
localStorage.setItem(key, JSON.stringify(val))
|
||||
if (cb) cb()
|
||||
}
|
||||
|
||||
Storage.prototype.get = function(key, local, cb) {
|
||||
if (typeof local === 'function') cb = local
|
||||
|
||||
var val = parse(localStorage.getItem(key))
|
||||
if (cb) cb(val)
|
||||
else return val
|
||||
|
||||
function parse(val) {
|
||||
try {
|
||||
return JSON.parse(val)
|
||||
} catch (e) {
|
||||
return val
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
function Storage() {}
|
||||
|
||||
Storage.prototype.set = function(key, val, local, cb) {
|
||||
if (typeof local === 'function') cb = local
|
||||
|
||||
localStorage.setItem(key, JSON.stringify(val))
|
||||
if (cb) cb()
|
||||
}
|
||||
|
||||
Storage.prototype.get = function(key, local, cb) {
|
||||
if (typeof local === 'function') cb = local
|
||||
|
||||
var val = parse(localStorage.getItem(key))
|
||||
if (cb) cb(val)
|
||||
else return val
|
||||
|
||||
function parse(val) {
|
||||
try {
|
||||
return JSON.parse(val)
|
||||
} catch (e) {
|
||||
return val
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,11 +6,11 @@ const STORE = {
|
|||
NONCODE : 'octotree.noncode_shown',
|
||||
HOTKEYS : 'octotree.hotkeys',
|
||||
LOADALL : 'octotree.loadall',
|
||||
GHEURLS : 'octotree.gheurls',
|
||||
GLEURLS : 'octotree.gleurls',
|
||||
WIDTH : 'octotree.sidebar_width',
|
||||
POPUP : 'octotree.popup_shown',
|
||||
SHOWN : 'octotree.sidebar_shown'
|
||||
WIDTH : 'octotree.sidebar_width',
|
||||
SHOWN : 'octotree.sidebar_shown',
|
||||
GHEURLS : 'octotree.gheurls.shared',
|
||||
GLEURLS : 'octotree.gleurls.shared'
|
||||
}
|
||||
|
||||
const DEFAULTS = {
|
||||
|
@ -26,7 +26,7 @@ const DEFAULTS = {
|
|||
// @endif
|
||||
GHEURLS : '',
|
||||
GLEURLS : '',
|
||||
WIDTH : 250,
|
||||
WIDTH : 232,
|
||||
POPUP : false,
|
||||
SHOWN : false
|
||||
}
|
||||
|
|
|
@ -5,10 +5,8 @@ $(document).ready(() => {
|
|||
|
||||
function setDefault(key, cb) {
|
||||
const storeKey = STORE[key]
|
||||
const local = storeKey === STORE.TOKEN
|
||||
|
||||
store.get(storeKey, local, (val) => {
|
||||
store.set(storeKey, val == null ? DEFAULTS[key] : val, local, cb)
|
||||
store.get(storeKey, (val) => {
|
||||
store.set(storeKey, val == null ? DEFAULTS[key] : val, cb)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -36,13 +34,11 @@ $(document).ready(() => {
|
|||
let hasError = false
|
||||
|
||||
$sidebar
|
||||
.width(parseFloat(store.get(STORE.WIDTH)))
|
||||
.resizable({ handles: 'e', minWidth: 230 }) // to hide GL sidebar
|
||||
.width(parseInt(store.get(STORE.WIDTH)))
|
||||
.resize(layoutChanged)
|
||||
.addClass(adapter.getCssClass())
|
||||
.appendTo($('body'))
|
||||
|
||||
adapter.setSideBar($sidebar)
|
||||
adapter.init($sidebar)
|
||||
layoutChanged()
|
||||
|
||||
$(window).resize((event) => { // handle zoom
|
||||
|
@ -170,7 +166,7 @@ $(document).ready(() => {
|
|||
}
|
||||
|
||||
function layoutChanged() {
|
||||
const width = $sidebar.width()
|
||||
const width = $sidebar.outerWidth()
|
||||
adapter.updateLayout(isSidebarVisible(), width)
|
||||
store.set(STORE.WIDTH, width)
|
||||
}
|
||||
|
|
|
@ -221,9 +221,7 @@ a.octotree_toggle {
|
|||
cursor: pointer;
|
||||
display: none;
|
||||
opacity: 0;
|
||||
top: 40px;
|
||||
left: 5px;
|
||||
z-index: 93;
|
||||
z-index: 999999999;
|
||||
width: 260px;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
|
@ -1,3 +1,3 @@
|
|||
@import "common";
|
||||
@import "github";
|
||||
@import "gitlab";
|
||||
@import "base";
|
||||
@import "../adapters/github";
|
||||
@import "../adapters/gitlab";
|
||||
|
|
|
@ -32,6 +32,26 @@
|
|||
<input type="text" data-store="TOKEN" data-perhost="true">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<label>Hotkeys</label>
|
||||
<a href="https://github.com/madrobby/keymaster#defining-shortcuts" target="_blank" tabIndex="-1">supported keys</a>
|
||||
</div>
|
||||
<input type="text" data-store="HOTKEYS">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label><input type="checkbox" data-store="REMEMBER"> Remember sidebar visibility</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label><input type="checkbox" data-store="NONCODE"> Show in non-code pages</label>
|
||||
</div>
|
||||
|
||||
<div class="octotree_github_only">
|
||||
<label><input type="checkbox" data-store="LOADALL"> Load entire tree at once</label>
|
||||
</div>
|
||||
|
||||
<!-- @ifdef CHROME -->
|
||||
<div class="octotree_github_only">
|
||||
<div>
|
||||
|
@ -40,6 +60,7 @@
|
|||
<textarea data-store="GHEURLS" placeholder="https://github.mysite1.com/ https://github.mysite2.com/">
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
<div class="octotree_gitlab_only">
|
||||
<div>
|
||||
<label>GitLab Enterprise URLs</label>
|
||||
|
@ -49,24 +70,6 @@
|
|||
</div>
|
||||
<!-- @endif -->
|
||||
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<label><input type="checkbox" data-store="REMEMBER"> Remember sidebar visibility</label>
|
||||
</div>
|
||||
<div>
|
||||
<label><input type="checkbox" data-store="NONCODE"> Show in non-code pages</label>
|
||||
</div>
|
||||
<div class="octotree_github_only">
|
||||
<label><input type="checkbox" data-store="LOADALL"> Load entire tree at once</label>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<label>Hotkeys</label>
|
||||
<a href="https://github.com/madrobby/keymaster#defining-shortcuts" target="_blank" tabIndex="-1">supported keys</a>
|
||||
</div>
|
||||
<input type="text" data-store="HOTKEYS">
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" class="btn">Save</button>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
class Storage {
|
||||
set(key, val, cb) {
|
||||
localStorage.setItem(key, JSON.stringify(val))
|
||||
if (cb) cb()
|
||||
}
|
||||
|
||||
get(key, cb) {
|
||||
var val = parse(localStorage.getItem(key))
|
||||
if (cb) cb(val)
|
||||
else return val
|
||||
|
||||
function parse(val) {
|
||||
try {
|
||||
return JSON.parse(val)
|
||||
} catch (e) {
|
||||
return val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,13 +5,27 @@ class HelpPopup {
|
|||
}
|
||||
|
||||
show() {
|
||||
const $view = this.$view
|
||||
const store = this.store
|
||||
const popupShown = store.get(STORE.POPUP)
|
||||
const sidebarVisible = $('html').hasClass(PREFIX)
|
||||
|
||||
if (popupShown) return
|
||||
if (popupShown || sidebarVisible) {
|
||||
store.set(STORE.POPUP, true)
|
||||
return
|
||||
}
|
||||
|
||||
$view.css('display', 'block').appendTo($('body'))
|
||||
const $view = this.$view
|
||||
const $toggler = $('.octotree_toggle')
|
||||
const offset = $toggler.offset()
|
||||
const height = $toggler.outerHeight()
|
||||
|
||||
$view
|
||||
.css({
|
||||
display: 'block',
|
||||
top: offset.top + height + 2,
|
||||
left: offset.left
|
||||
})
|
||||
$view.appendTo($('body'))
|
||||
|
||||
$(document).one(EVENT.TOGGLE, hide)
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class OptionsView {
|
|||
|
||||
_load() {
|
||||
this._eachOption(
|
||||
($elm, key, local, value, cb) => {
|
||||
($elm, key, value, cb) => {
|
||||
if ($elm.is(':checkbox')) $elm.prop('checked', value)
|
||||
else $elm.val(value)
|
||||
cb()
|
||||
|
@ -70,11 +70,11 @@ class OptionsView {
|
|||
_saveOptions() {
|
||||
const changes = {}
|
||||
this._eachOption(
|
||||
($elm, key, local, value, cb) => {
|
||||
($elm, key, value, cb) => {
|
||||
const newValue = $elm.is(':checkbox') ? $elm.is(':checked') : $elm.val()
|
||||
if (value === newValue) return cb()
|
||||
changes[key] = [value, newValue]
|
||||
this.store.set(key, newValue, local, cb)
|
||||
this.store.set(key, newValue, cb)
|
||||
},
|
||||
() => {
|
||||
this._toggle(false)
|
||||
|
@ -90,10 +90,9 @@ class OptionsView {
|
|||
(elm, cb) => {
|
||||
const $elm = $(elm)
|
||||
const key = STORE[$elm.data('store')]
|
||||
const local = !!$elm.data('perhost')
|
||||
|
||||
this.store.get(key, local, (value) => {
|
||||
processFn($elm, key, local, value, () => cb())
|
||||
this.store.get(key, (value) => {
|
||||
processFn($elm, key, value, () => cb())
|
||||
})
|
||||
},
|
||||
completeFn
|
||||
|
|
Loading…
Reference in New Issue