// console.log("Loading TopBar...")
Spontaneous.TopBar = (function($, S) {
var dom = S.Dom;
var RootNode = function(page) {
this.page = page;
this.id = page.id;
this.url = page.url;
this.title = S.site_domain;
}
RootNode.prototype = {
element: function() {
var li = dom.li('.root');
var link = dom.a({'href': this.url}).text(this.title).data('page', this.page);
link.click(function() {
var page = $(this).data('page');
S.Location.load_id(page.id);
return false;
});
li.append(link);
this.link = link;
return li;
},
set_title: function(new_title) {
this.link.text(new_title);
}
}
var AncestorNode = function(page) {
this.page = page;
this.id = page.id;
this.title = page.slug;
this.path = page.path;
};
AncestorNode.prototype = {
element: function() {
var link = dom.li().append($('').data('page', this.page).click(function() {
var page = $(this).data('page');
S.Location.load_id(page.id);
}).text(this.title));
return link;
}
};
var CurrentNode = function(page) {
this.page = page;
this.id = page.id;
this.path = page.path;
this.title = page.slug;
this.pages = page.generation.sort(function(p1, p2) {
var a = p1.title, b = p2.title;
if (a == b) return 0;
return (a < b ? -1 : 1);
});
for (var i = 0, ii = this.pages.length; i < ii; i++) {
var p = this.pages[i];
if (p.id === this.id) {
this.selected = i;
break;
}
}
}
CurrentNode.prototype = {
element: function() {
var li = dom.li();
var select = dom.select();
select.change(function() {
var page = $(this.options[this.selectedIndex]).data('page');
S.Location.load_id(page.id);
return false;
});
for (var i = 0, ii = this.pages.length; i < ii; i++) {
var p = this.pages[i],
option = dom.option({'value': p.id, 'selected':(i == this.selected) }).text(p.slug).data('page', p);
if (p.id === this.id) {
this.title_option = option;
}
select.append(option);
};
li.append(select);
// select.hide();
// var link = $(dom.li).append($('').data('page', this.page).click(function() {
// // var page = $(this).data('page');
// // S.Location.load_id(page.id);
// select.toggle().trigger('click');
// }).text(this.title));
//
// link.append(select);
// return link;
return li;
},
set_title: function(new_title) {
this.title_option.text(new_title);
}
}
var ChildrenNode = function(children) {
this.children = children;
}
ChildrenNode.prototype = {
element: function() {
var li = dom.li('.children');
var select = dom.select('.unselected');
this.li = li;
this.select = select;
select.append(dom.option().text(this.status_text()));
select.change(function() {
var p = $(this.options[this.selectedIndex]).data('page');
if (p) {
S.Location.load_id(p.id());
}
return false;
});
for (var i = 0, ii = this.children.length; i < ii; i++) {
var p = this.children[i];
select.append(this.option_for_entry(p));
};
li.append(select);
return li;
}.cache(),
status_text: function() {
if (this.children.length === 0) {
this.select.hide();
} else {
this.select.show();
}
return '('+(this.children.length)+' pages)';
},
option_for_entry: function(p) {
var opt = dom.option({'value': p.id()}).text(p.slug()).data('page', p);
if (p.watch) {
p.watch('slug', function(value) {
opt.text(value);
}.bind(this));
}
return opt;
},
update_status: function() {
var first = this.select.find('option:first-child');
first.text(this.status_text());
return first;
},
add_page: function(page, position) {
var option = this.option_for_entry(page);
if (position === -1) {
this.children.push(page)
this.select.append(option);
} else {
this.children.splice(0, 0, page)
var first = this.update_status();
first.after(option);
}
},
remove_page: function(page) {
var index = 0;
for (var i = 0, ii = this.children.length; i < ii; i++) {
if (this.children[i].id() === page.id()) { index = i; break; };
}
this.children.splice(index, 1);
this.update_status();
var options = this.select.find('option:gt(0)'), remove;
options.each(function() {
if ($(this).data('page').id() === page.id()) {
$(this).remove();
}
});
}
}
var PublishButton = new JS.Class({
rapid_check: 2000,
normal_check: 10000,
initialize: function() {
this.status = false;
this.set_interval(this.normal_check);
// this.check_status();
var update_status = this.update_status.bind(this);
S.EventSource.addEventListener('publish_progress', function(event) {
update_status($.parseJSON(event.data))
});
},
check_status: function() {
S.Ajax.get('/publish/status', this.status_recieved.bind(this));
},
status_recieved: function(status, response_code) {
if (response_code === 'success' && status != this.status) {
this.update_status(status);
}
window.setTimeout(this.check_status.bind(this), this.timer_interval);
},
update_status: function(status) {
if (status === null || status === '') { return; }
var state = status.state, progress = status.progress
// if (this.in_progress && (state == this.current_action && progress == this.current_progress)) { return; }
this.current_action = state;
this.current_progress = progress;
if (state === 'complete' || state === 'error') {
// if (this.in_progress) {
this.in_progress = false;
this.progress().stop();
// this.set_interval(this.normal_check);
this.set_label("Publish");
this.button().switchClass('progress', '')
this.current_action = this.current_progress = null;
// }
if (state === 'error') {
alert('There was a problem publishing: ' + progress)
}
} else {
this.publishing_state();
if (state === 'rendering') {
this.progress().update(progress);
} else {
this.progress().indeterminate();
}
}
},
publishing_started: function() {
this.publishing_state();
this.progress().indeterminate();
},
publishing_state: function() {
// this.set_interval(this.rapid_check);
this.set_label("Publishing");
var b = this.button();
this.current_action = this.current_progress = null;
if (!b.hasClass('progress')) { b.switchClass('', 'progress'); }
this.in_progress = true;
},
set_label: function(label) {
if (label !== this._label_text) {
this._label_text = label;
this._label.text(label);
}
},
button: function() {
if (!this._button) {
this._progress_container = dom.span('#publish-progress');
this._label = dom.span();
this._button = dom.a('#open-publish').append(this._progress_container).append(this._label);
this.set_label("Publish");
this._button.click(function() {
if (!this.in_progress) {
S.Publishing.open_dialogue();
}
}.bind(this));
}
return this._button
},
progress: function() {
if (!this._progress) {
this._progress = Spontaneous.Progress('publish-progress', 15, {
spinner_fg_color: '#ccc',
progress_fg_color: '#fff'
});
this._progress.init();
}
return this._progress;
},
set_interval: function(milliseconds) {
this.timer_interval = milliseconds;
}
});
var LocationChildProxy = new JS.Class({
initialize: function(child) {
this.child = child;
},
id: function() { return this.child.id; },
title: function() { return this.child.title; },
slug: function() { return this.child.slug; }
})
var TopBar = new JS.Singleton({
include: Spontaneous.Properties,
location: "/",
panel: function() {
this.wrap = dom.div('#top');
this.location = dom.ul('#navigation');
this.location.append(dom.li().append(dom.a()))
this.mode_switch = dom.a('#switch-mode').
text(this.opposite_mode(S.ContentArea.mode)).
click(function() {
S.TopBar.toggle_modes();
});
this.publish_button = new PublishButton();
this.wrap.append(this.location);
this.wrap.append(this.publish_button.button());
this.wrap.append(this.mode_switch);
return this.wrap;
},
init: function() {
if (!this.get('mode')) {
this.set('mode', S.ContentArea.mode);
}
S.Editing.watch('page', this.page_loaded.bind(this));
S.Location.watch('location', this.location_loaded.bind(this));
},
location_loaded: function(location) {
// clear the loaded page so that it forces a reload of the nav when we switch back to edit mode
this.set('page', undefined);
var children = [];
for (var i = 0, cc = location.children, ii = cc.length; i < ii; i++) {
children.push(new LocationChildProxy(cc[i]));
}
var children_node = new ChildrenNode(children);
this.location.append(children_node.element());
this.children_node = children_node;
},
page_loaded: function(page) {
var loaded_page = this.get('page'), loaded_id = (loaded_page ? loaded_page.id() : undefined);
if (page && (page.id() !== loaded_id)) {
if (this.children_node) {
this.children_node.element().remove();
}
this.set('page', page);
var children_node = new ChildrenNode(page.children());
this.location.append(children_node.element());
page.bind('entry_added', function(entry, position) {
if (entry.is_page()) {
children_node.add_page(entry, position);
}
});
page.bind('removed_entry', function(entry) {
if (entry.is_page()) {
children_node.remove_page(entry);
}
});
page.watch('slug', function(title) {
this.navigation_current.set_title(title);
}.bind(this));
page.title_field().watch('value', function(title) {
this.set_browser_title(title);
}.bind(this));
this.children_node = children_node;
}
},
set_mode: function(mode) {
this.set('mode', mode);
this.mode_switch.text(this.opposite_mode(mode));
},
toggle_modes: function() {
this.set_mode(this.opposite_mode(this.get('mode')));
},
opposite_mode: function(to_mode) {
if (to_mode === 'preview') {
return 'edit';
} else if (to_mode === 'edit') {
return 'preview';
}
},
publishing_started: function() {
this.publish_button.publishing_started();
},
set_browser_title: function(page_title) {
document.title = S.site_domain + " | Editing: '"+page_title+"'";
},
location_changed: function(new_location) {
this.set_browser_title(new_location.title)
this.set('location', new_location);
this.update_navigation();
},
update_navigation: function() {
var nodes = [];
var location = this.get('location');
var $location_bar = this.location;
var ancestors = location.ancestors;
var root, is_root = false, root_node, children_node, current_node;
if (ancestors.length === 0) {
root = location;
is_root = true;
} else {
root = ancestors.shift();
}
root_node = new RootNode(root);
nodes.push(root_node);
for (var i=0, ii=ancestors.length; i < ii; i++) {
var page = ancestors[i];
var node = new AncestorNode(page)
nodes.push(node);
};
if (!is_root) {
current_node = new CurrentNode(location)
nodes.push(current_node);
} else {
current_node = root_node;
}
$('li:gt(0)', $location_bar).remove();
var children_node;
if (location.children.length > 0) {
// children_node = new ChildrenNode(location.children);
// $location_bar.append(children_node.element())
}
for (var i = 0, ii = nodes.length; i < ii; i++) {
var node = nodes[i];
$location_bar.append(node.element())
}
this.navigation_current = current_node;
this.page_loaded = function(page) {
};
}
});
return TopBar;
})(jQuery, Spontaneous);