moved marking from 'selected' to 'marked' tag + added tag cloud...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2018-11-08 21:10:58 +03:00
parent 5cfc23b159
commit 700e953026
18 changed files with 179 additions and 74 deletions

View File

@ -1034,15 +1034,15 @@ stretching in width... */
} }
.mark.bookmark, .mark.bookmark,
.mark.selected { .mark.marked {
width: 0px; width: 0px;
margin-left: 0px; margin-left: 0px;
border: none; border: none;
overflow: visible; overflow: visible;
} }
.mark.bookmark:after, .mark.bookmark:after,
.mark.selected:before, .mark.marked:before,
.mark.selected:after { .mark.marked:after {
display: block; display: block;
position: absolute; position: absolute;
content: ""; content: "";
@ -1082,9 +1082,9 @@ stretching in width... */
} }
/* the selected tick... */ /* the marked tick... */
.mark.selected:before, .mark.marked:before,
.mark.selected:after { .mark.marked:after {
top: @image-tile-size/30; top: @image-tile-size/30;
left: -@image-tile-size/15; left: -@image-tile-size/15;
bottom: auto; bottom: auto;
@ -1093,11 +1093,11 @@ stretching in width... */
.rotate(-45deg); .rotate(-45deg);
} }
.mark.selected:before { .mark.marked:before {
width: @image-tile-size/100; width: @image-tile-size/100;
height: @image-tile-size/50; height: @image-tile-size/50;
} }
.mark.selected:after { .mark.marked:after {
width: @image-tile-size/25; width: @image-tile-size/25;
height: @image-tile-size/100; height: @image-tile-size/100;
} }
@ -1406,7 +1406,7 @@ stretching in width... */
} }
/* XXX REUSE: this is the same as selected/bookmarked image markers... */ /* XXX REUSE: this is the same as marked/bookmarked image markers... */
.overlay-info .marked, .overlay-info .marked,
.overlay-info .marked:after, .overlay-info .marked:after,
.overlay-info .marked:before, .overlay-info .marked:before,

View File

@ -1290,7 +1290,7 @@ module.TagsEditActions = actions.Actions({
// NOTE: setting source to 'both' and mode to 'reset' is the same as // NOTE: setting source to 'both' and mode to 'reset' is the same as
// 'images' and 'reset' as all .data tags will be lost on first // 'images' and 'reset' as all .data tags will be lost on first
// pass... // pass...
syncTags: ['Tag/Synchoronize tags between data and images', syncTags: ['Tag/-10:Synchoronize tags between data and images',
{journal: true}, {journal: true},
function(source, mode){ function(source, mode){
// can't do anything if either .data or .images are not // can't do anything if either .data or .images are not
@ -1350,8 +1350,8 @@ module.TagsEdit = core.ImageGridFeatures.Feature({
if(tags.length > 0){ if(tags.length > 0){
this.markChanged('tags') this.markChanged('tags')
tags.indexOf('selected') >= 0 tags.indexOf('marked') >= 0
&& this.markChanged('selected') && this.markChanged('marked')
tags.indexOf('bookmark') >= 0 tags.indexOf('bookmark') >= 0
&& this.markChanged('bookmarked') && this.markChanged('bookmarked')
@ -1360,7 +1360,7 @@ module.TagsEdit = core.ImageGridFeatures.Feature({
this.markChanged('images', gids) this.markChanged('images', gids)
}], }],
// store .tags and .tags.selected / .tags.bookmark separately from .data... // store .tags and .tags.marked / .tags.bookmark separately from .data...
// //
// XXX see if this can be automated... // XXX see if this can be automated...
['prepareIndexForWrite', ['prepareIndexForWrite',
@ -1375,9 +1375,9 @@ module.TagsEdit = core.ImageGridFeatures.Feature({
res.index.tags = res.raw.data.tags res.index.tags = res.raw.data.tags
} }
// XXX should we save an empty list *iff* changes.selected is true??? // XXX should we save an empty list *iff* changes.marked is true???
if(changes === true || changes.selected){ if(changes === true || changes.marked){
res.index.marked = (res.raw.data.tags || {}).selected || [] res.index.marked = (res.raw.data.tags || {}).marked || []
} }
// XXX should we save an empty list *iff* changes.bookmarked is true??? // XXX should we save an empty list *iff* changes.bookmarked is true???
if(changes === true || changes.bookmarked){ if(changes === true || changes.bookmarked){
@ -1389,7 +1389,7 @@ module.TagsEdit = core.ImageGridFeatures.Feature({
// cleanup... // cleanup...
if(res.index.data && res.index.data.tags){ if(res.index.data && res.index.data.tags){
delete res.index.data.tags.selected delete res.index.data.tags.marked
delete res.index.data.tags.bookmark delete res.index.data.tags.bookmark
//delete res.index.data.tags.bookmark_data //delete res.index.data.tags.bookmark_data
delete res.index.data.tags delete res.index.data.tags
@ -1399,7 +1399,7 @@ module.TagsEdit = core.ImageGridFeatures.Feature({
function(res, json){ function(res, json){
res.data.tags = json.tags || {} res.data.tags = json.tags || {}
res.data.tags.selected = json.marked || [] res.data.tags.marked = json.marked || []
res.data.tags.bookmark = json.bookmarked ? json.bookmarked[0] : [] res.data.tags.bookmark = json.bookmarked ? json.bookmarked[0] : []
//res.data.tags.bookmark_data = json.bookmarked ? json.bookmarked[1] : {} //res.data.tags.bookmark_data = json.bookmarked ? json.bookmarked[1] : {}

View File

@ -2865,7 +2865,7 @@ var CollectionMarksActions = actions.Actions({
CollectionTagsActions.config['collection-local-tags'] CollectionTagsActions.config['collection-local-tags']
.concat([ .concat([
'bookmark', 'bookmark',
'selected', 'marked',
]), ]),
'collection-transfer-changes': 'collection-transfer-changes':
@ -2875,7 +2875,7 @@ var CollectionMarksActions = actions.Actions({
CollectionActions.config['collection-transfer-changes'] CollectionActions.config['collection-transfer-changes']
.concat([ .concat([
'bookmarked', 'bookmarked',
'selected', 'marked',
]), ]),
}, },
@ -2883,13 +2883,13 @@ var CollectionMarksActions = actions.Actions({
collectMarked: ['- Collections|Mark/', collectMarked: ['- Collections|Mark/',
function(collection){ function(collection){
return this.collect(this.marked, collection) }], return this.collect(this.marked, collection) }],
//return this.collectTagged('selected', collection) }], //return this.collectTagged('marked', collection) }],
uncollectMarked: ['Collections|Mark/Remove marked from collection', uncollectMarked: ['Collections|Mark/Remove marked from collection',
{browseMode: function(){ {browseMode: function(){
return (!this.collection || this.marked.length == 0) && 'disabled' }}, return (!this.collection || this.marked.length == 0) && 'disabled' }},
function(collection){ function(collection){
return this.uncollect(this.marked, collection) }], return this.uncollect(this.marked, collection) }],
//return this.uncollectTagged('selected', collection) }], //return this.uncollectTagged('marked', collection) }],
// bookmarked... // bookmarked...
collectBookmarked: ['- Collections|Bookmark/', collectBookmarked: ['- Collections|Bookmark/',

View File

@ -37,7 +37,7 @@ module.demo_data = {
}, },
tags: { tags: {
selected: ['b', 'z'], marked: ['b', 'z'],
bookmark: ['1', 'c', 'z'], bookmark: ['1', 'c', 'z'],
}, },

View File

@ -351,7 +351,7 @@ var ExampleUIActions = actions.Actions({
}) })
make('do nothing') make('do nothing')
.addClass('selected') .addClass('marked')
make('nested dialog...', make('nested dialog...',
{ {
@ -767,8 +767,8 @@ var ExampleUIActions = actions.Actions({
}], }],
showBookmarkedInDrawer: ['Test/Show bookmarked in drawer', showBookmarkedInDrawer: ['Test/Show bookmarked in drawer',
function(){ this.showTaggedInDrawer('bookmark') }], function(){ this.showTaggedInDrawer('bookmark') }],
showSelectedInDrawer: ['Test/Show selected in drawer', showSelectedInDrawer: ['Test/Show marked in drawer',
function(){ this.showTaggedInDrawer('selected') }], function(){ this.showTaggedInDrawer('marked') }],
makePartitionAfter: ['Test/Make Partition after image', makePartitionAfter: ['Test/Make Partition after image',

View File

@ -2083,7 +2083,7 @@ var FileSystemWriterActions = actions.Actions({
// tags... // tags...
// XXX test: %n%(b)b%(m)m%e // XXX test: %n%(b)b%(m)m%e
.replace( .replace(
/%\(([^)]*)\)m/, tags.indexOf('selected') >= 0 ? '$1' : '') /%\(([^)]*)\)m/, tags.indexOf('marked') >= 0 ? '$1' : '')
.replace( .replace(
/%\(([^)]*)\)b/, tags.indexOf('bookmark') >= 0 ? '$1' : '') /%\(([^)]*)\)b/, tags.indexOf('bookmark') >= 0 ? '$1' : '')
@ -2369,7 +2369,7 @@ var FileSystemWriterUIActions = actions.Actions({
['Marked:', ['Marked:',
actions.formatImageName(pattern, actions.formatImageName(pattern,
img, img,
{tags: ['selected']})], {tags: ['marked']})],
['Bookmarked:', ['Bookmarked:',
actions.formatImageName(pattern, actions.formatImageName(pattern,
img, img,
@ -2383,7 +2383,7 @@ var FileSystemWriterUIActions = actions.Actions({
img, img,
{ {
tags: [ tags: [
'selected', 'marked',
'bookmark', 'bookmark',
], ],
conflicts: { conflicts: {

View File

@ -208,6 +208,7 @@ module.GLOBAL_KEYBOARD = {
alt_F: 'browseActions: "/File/" -- File menu...', alt_F: 'browseActions: "/File/" -- File menu...',
alt_E: 'browseActions: "/Edit/" -- Edit menu...', alt_E: 'browseActions: "/Edit/" -- Edit menu...',
alt_N: 'browseActions: "/Navigate/" -- Navigate menu...', alt_N: 'browseActions: "/Navigate/" -- Navigate menu...',
alt_T: 'browseActions: "/Tag/" -- Tag menu...',
//alt_S: 'browseActions: "/Sort/" -- Sort menu...', //alt_S: 'browseActions: "/Sort/" -- Sort menu...',
alt_shift_A: 'listActions', alt_shift_A: 'listActions',
@ -398,6 +399,9 @@ module.GLOBAL_KEYBOARD = {
I: 'showMetadata', I: 'showMetadata',
//ctrl_shift_I: 'showMetadata: "current" "full" -- Show full metadata', //ctrl_shift_I: 'showMetadata: "current" "full" -- Show full metadata',
// XXX
ctrl_T: 'showTagCloud',
// marking... // marking...
M: 'toggleMark', M: 'toggleMark',

View File

@ -230,11 +230,11 @@ var ImageMarkActions = actions.Actions({
get marked(){ get marked(){
if(this.data == null if(this.data == null
|| this.data.tags == null || this.data.tags == null
|| !('selected' in this.data.tags)){ || !('marked' in this.data.tags)){
return [] return []
} }
//return this.data.tags['selected'].slice() //return this.data.tags['marked'].slice()
return this.data.getImages(this.data.tags['selected']) return this.data.getImages(this.data.tags['marked'])
}, },
markedInRibbon: ['- Mark|Ribbon/', markedInRibbon: ['- Mark|Ribbon/',
@ -250,16 +250,16 @@ var ImageMarkActions = actions.Actions({
prevMarked: ['Mark|Navigate/Previous marked image', prevMarked: ['Mark|Navigate/Previous marked image',
{browseMode: function(target){ {browseMode: function(target){
return this.data.getImage('current', 'before', this.marked) == null && 'disabled' }}, return this.data.getImage('current', 'before', this.marked) == null && 'disabled' }},
function(mode){ this.prevTagged('selected', mode) }], function(mode){ this.prevTagged('marked', mode) }],
nextMarked: ['Mark|Navigate/Next marked image', nextMarked: ['Mark|Navigate/Next marked image',
{browseMode: function(target){ {browseMode: function(target){
return this.data.getImage('current', 'after', this.marked) == null && 'disabled' }}, return this.data.getImage('current', 'after', this.marked) == null && 'disabled' }},
function(mode){ this.nextTagged('selected', mode) }], function(mode){ this.nextTagged('marked', mode) }],
cropMarked: ['Mark|Crop/Crop $marked images', cropMarked: ['Mark|Crop/Crop $marked images',
{browseMode: function(target){ {browseMode: function(target){
return this.marked.length == 0 && 'disabled' }}, return this.marked.length == 0 && 'disabled' }},
function(flatten){ this.cropTagged('selected', 'any', flatten) }], function(flatten){ this.cropTagged('marked', 'any', flatten) }],
removeMarkedFromCrop: ['Mark|Crop/Remove marked from crop', removeMarkedFromCrop: ['Mark|Crop/Remove marked from crop',
{browseMode: function(target){ {browseMode: function(target){
@ -320,7 +320,7 @@ var ImageMarkEditActions = actions.Actions({
// //
toggleMark: ['Mark|Image/Image $mark', toggleMark: ['Mark|Image/Image $mark',
undoTag('toggleMark'), undoTag('toggleMark'),
makeTagTogglerAction('selected')], makeTagTogglerAction('marked')],
toggleMarkBlock: ['Mark/Invert $block marks', toggleMarkBlock: ['Mark/Invert $block marks',
core.doc`A block is a set of adjacent images either marked on unmarked core.doc`A block is a set of adjacent images either marked on unmarked
in the same way in the same way
@ -485,8 +485,8 @@ module.ImageMarksUI = core.ImageGridFeatures.Feature({
&& this.ribbons && this.ribbons
.toggleImageMark( .toggleImageMark(
gid, gid,
'selected', 'marked',
this.data.hasTag(gid, 'selected') ? 'on' : 'off') this.data.hasTag(gid, 'marked') ? 'on' : 'off')
}], }],
], ],
}) })
@ -563,7 +563,7 @@ var ImageBookmarkEditActions = actions.Actions({
toggleBookmarkOnMarked: ['Bookmark|Mark/-70:Toggle bookmark on maked images', toggleBookmarkOnMarked: ['Bookmark|Mark/-70:Toggle bookmark on maked images',
{browseMode: 'cropMarked'}, {browseMode: 'cropMarked'},
function(action){ function(action){
return this.toggleBookmark(this.data.getTaggedByAny('selected'), action) return this.toggleBookmark(this.data.getTaggedByAny('marked'), action)
}], }],
}) })

View File

@ -66,6 +66,8 @@ core.ImageGridFeatures.Feature('imagegrid-ui-minimal', [
'ui-bounds-indicators', 'ui-bounds-indicators',
'ui-current-image-indicator', 'ui-current-image-indicator',
'ui-tags',
]) ])

View File

@ -11,6 +11,9 @@ var actions = require('lib/actions')
var features = require('lib/features') var features = require('lib/features')
var core = require('features/core') var core = require('features/core')
var widgets = require('features/ui-widgets')
var browse = require('lib/widget/browse')
@ -32,7 +35,6 @@ module.PersistentTags = core.ImageGridFeatures.Feature({
depends: [ depends: [
'base', 'base',
], ],
actions: PersistentTagsActions, actions: PersistentTagsActions,
handlers: [], handlers: [],
@ -53,6 +55,100 @@ module.PersistentTags = core.ImageGridFeatures.Feature({
// //
var TagUIActions = actions.Actions({ var TagUIActions = actions.Actions({
// XXX use global tag list... (???)
showTagCloud: ['Tag|Edit|Image/$Tags...',
core.doc`
`,
{dialogTitle: function(_, gids){
return (gids.length == 1 && gids[0] == 'marked') ?
'Marked image tags'
: gids.length > 1 ?
'Tags of: '+ gids.join(', ')
: 'Tags' }},
widgets.makeUIDialog(function(...gids){
var that = this
gids = gids.length == 0 ? ['current'] : gids
// handle 'marked' keyword...
gids = gids
.map(function(gid){
return gid == 'marked' ? that.marked : gid })
.reduce(function(res, cur){
return res.concat(cur instanceof Array ? cur : [cur]) }, [])
.unique()
// XXX
var removeTag = function(tag){
console.log('REMOVE TAG:', tag)
}
return browse.makeLister(null, function(path, make){
var tags = that.data.getTags(gids)
// tags...
// XXX make this a group...
// XXX indicate if some of the gids are tagged...
// ...need three states per tag:
// - on - all are tagged
// - partial - some are tagged
// - off - none are tagged
// XXX add key binding to delete a tag...
Object.keys(that.data.tags || {})
.sort()
.map(function(tag){
return make(tag, {
cls: tags.indexOf(tag) >= 0 ? 'tagged' : '',
style: {
opacity: tags.indexOf(tag) >= 0 ? '' : '0.3'
},
open: function(){
var e = $(this)
var on = e.css('opacity')
on = on == '' || on == '1'
e.css('opacity', on ? 0.3 : '')
on ?
that.data.untag(tag, gids)
: that.data.tag(tag, gids)
},
buttons: [
// remove tag button...
['&times;', removeTag.bind(that, tag) ],
],
})
})
make.Separator()
make.Editable('$New...', {
clear_on_edit: true,
editdone: function(evt, tag){
tag = tag.trim()
// no empty tags...
if(tag == ''){
return
}
that.data.tag(tag, gids)
// update tag list...
make.dialog
.update()
// select the new tag...
.then(function(){
make.dialog.select(tag) })
},
})
}, {
cloudView: true,
close: function(){ that.refresh() },
})
})],
showMakedTagCoud: ['Tag|Mark/$Tags of marked images...',
'showTagCloud: "marked"'],
// XXX crop/filter by tags...
// XXX
}) })

View File

@ -22,7 +22,7 @@ var PreCacheActions = actions.Actions({
'preload-radius': 5, 'preload-radius': 5,
// Sources to preload... // Sources to preload...
'preload-sources': ['bookmark', 'selected'], 'preload-sources': ['bookmark', 'marked'],
}, },
// NOTE: this will not work from chrome when loading from a local fs... // NOTE: this will not work from chrome when loading from a local fs...
@ -75,7 +75,7 @@ var PreCacheActions = actions.Actions({
// //
// Sources supported: // Sources supported:
// <tag> - pre-load images tagged with <tag> // <tag> - pre-load images tagged with <tag>
// (default: ['bookmark', 'selected']) // (default: ['bookmark', 'marked'])
// <ribbon-gid> - pre-cache from a specific ribbon // <ribbon-gid> - pre-cache from a specific ribbon
// 'ribbon' - pre-cache from current ribbon // 'ribbon' - pre-cache from current ribbon
// 'order' - pre-cache from images in order // 'order' - pre-cache from images in order
@ -115,7 +115,7 @@ var PreCacheActions = actions.Actions({
: (this.data.getImage(target) : (this.data.getImage(target)
|| this.data.getImage(target, 'after')) || this.data.getImage(target, 'after'))
sources = sources || this.config['preload-sources'] || ['bookmark', 'selected'] sources = sources || this.config['preload-sources'] || ['bookmark', 'marked']
sources = sources.constructor !== Array ? [sources] : sources sources = sources.constructor !== Array ? [sources] : sources
radius = radius || this.config['preload-radius'] || 9 radius = radius || this.config['preload-radius'] || 9

View File

@ -76,7 +76,7 @@ class IGRibbon extends preact.Component {
var images = data.ribbons[ribbon] var images = data.ribbons[ribbon]
.map(function(gid){ .map(function(gid){
var marks = data.tags.selected.indexOf(gid) >= 0 ? var marks = data.tags.marked.indexOf(gid) >= 0 ?
h(IGImageMark, { h(IGImageMark, {
gid: gid, gid: gid,
type: 'selected', type: 'selected',

View File

@ -477,7 +477,7 @@ var StatusBarActions = actions.Actions({
// ...this also simpler than handling '?' and other // ...this also simpler than handling '?' and other
// special toggler args in the handler... // special toggler args in the handler...
var tags = this.data ? this.data.getTags(gid) : [] var tags = this.data ? this.data.getTags(gid) : []
var tag = type == 'mark' ? 'selected' : 'bookmark' var tag = type == 'mark' ? 'marked' : 'bookmark'
var on = item.hasClass('on') var on = item.hasClass('on')
item[tags.indexOf(tag) < 0 ? item[tags.indexOf(tag) < 0 ?
'removeClass' 'removeClass'

View File

@ -236,8 +236,8 @@ var VirtualDOMRibbonsPrototype = {
// XXX STUB: make this extensible... // XXX STUB: make this extensible...
tags.indexOf('bookmark') >= 0 tags.indexOf('bookmark') >= 0
&& marks.push('bookmark') && marks.push('bookmark')
tags.indexOf('selected') >= 0 tags.indexOf('marked') >= 0
&& marks.push('selected') && marks.push('marked')
return marks return marks
.map(function(type){ .map(function(type){

View File

@ -895,7 +895,7 @@ module.Dialogs = core.ImageGridFeatures.Feature({
&& this.toggleOverlayBlur(this.config['ui-overlay-blur']) && this.toggleOverlayBlur(this.config['ui-overlay-blur'])
}], }],
['__call__', ['__call__',
function(res, action){ function(res, action, args){
//if(res instanceof jQuery || res instanceof widget.Widget){ //if(res instanceof jQuery || res instanceof widget.Widget){
// var elem = (res.dom || res) // var elem = (res.dom || res)
if(res instanceof widget.Widget){ if(res instanceof widget.Widget){
@ -904,7 +904,10 @@ module.Dialogs = core.ImageGridFeatures.Feature({
var title = this.getActionAttr(action, 'dialogTitle') var title = this.getActionAttr(action, 'dialogTitle')
title ? title ?
elem.attr('dialog-title', title) elem.attr('dialog-title',
title instanceof Function ?
title.call(this, action, args)
: title)
: !elem.attr('keep-dialog-title') : !elem.attr('keep-dialog-title')
&& !this.getActionAttr(action, 'keepDialogTitle') && !this.getActionAttr(action, 'keepDialogTitle')
&& elem.attr('dialog-title', this.getDocTitle(action)) && elem.attr('dialog-title', this.getDocTitle(action))

View File

@ -2885,6 +2885,15 @@ var DataPrototype = {
var DataWithTagsPrototype = { var DataWithTagsPrototype = {
// tags store...
//
// Format:
// {
// <tag>: [<gid>, ...],
// ...
// }
tags: null,
// XXX hate manual super calls... // XXX hate manual super calls...
// ....is there a way not to say DataPrototype here??? // ....is there a way not to say DataPrototype here???
__gid_lists: DataPrototype.__gid_lists.concat(['tags']), __gid_lists: DataPrototype.__gid_lists.concat(['tags']),

View File

@ -129,35 +129,14 @@ function(data){
/* This is best kept as a separate entity... /* XXX template...
// XXX EXPERIMENTAL...
module.VERSIONS['3.1'] = module.VERSIONS['3.1'] =
function(data){ function(data){
res = module.VERSIONS['3.0'](data) var res = data.version < '3.0' ? module.VERSIONS['3.0'](data) : data
res.version = '3.1'
res.order_list = data.order_list != null ? JSON.parse(JSON.stringify(data.order_list)) : null
return res
}
*/
/* XXX we do not have a ref to images...
module.VERSIONS['3.1'] =
function(data){
res = module.VERSIONS['3.0'](data)
res.version = '3.1' res.version = '3.1'
// XXX we do not have a ref to images here... // XXX
Object.values(res.images || {})
.forEach(function(img){
Object.keys(img.preview)
.forEach(function(res){
var p = img.preview[res]
img.preview[res] = p.indexOf('%20') >= 0 ? decodeURI(p) : p
})
})
return res return res
} }

View File

@ -290,7 +290,7 @@ function(text, options){
// stop_propagation: 'open', // stop_propagation: 'open',
// //
// // Called when editing is abrted... // // Called when editing is abrted...
// editaborted: <func>, // editaborted: <func(new-text)>,
// //
// // Called when editing is done... // // Called when editing is done...
// editdone: <func>, // editdone: <func>,
@ -2253,10 +2253,16 @@ var BrowserPrototype = {
// ... // ...
// }, // },
// //
// // element attributes...
// attrs: { // attrs: {
// <attr>: <value>, // <attr>: <value>,
// ... // ...
// }, // },
//
// // element css style...
// style: {
// <attr>: <value>,
// }
// } // }
// //
// <buttons> format (optional): // <buttons> format (optional):
@ -2658,6 +2664,8 @@ var BrowserPrototype = {
opts.attrs opts.attrs
&& res.attr(opts.attrs) && res.attr(opts.attrs)
opts.style
&& res.css(opts.style)
//--------------------------------------------- buttons --- //--------------------------------------------- buttons ---
// button container... // button container...
@ -4027,6 +4035,10 @@ var BrowserPrototype = {
var dom = this.dom var dom = this.dom
options = this.options options = this.options
// handle close event...
options.close
&& this.close(options.close)
// basic permanent interactions... // basic permanent interactions...
dom.find('.path') dom.find('.path')
// NOTE: these are used for full-path editing and are defined // NOTE: these are used for full-path editing and are defined