stomping-grounds/server/templates/spytext-toolbar.bak.dust
2015-09-02 11:04:34 +02:00

333 lines
9.2 KiB
Plaintext

module.exports = function() {
events: {
'click button': 'command'
},
template: 'spytext-toolbar',
command: function() {
var command = $(e.currentTarget).attr('data-command');
}
};
var SpytextButton = function(config, spytext) {
this.spytext = spytext;
this.config = typeof config.preset === 'string' ? merge(this.presets[config.preset], config) : config;
this.element = $('<button class="spytext-button" st-button-type="' + config.preset + '" tabindex="' + -1 + '">')[0];
for(var property in this.events)
$(this.element).on(property, this.events[property].bind(this));
this.disable();
};
SpytextButton.prototype = {
setActive: function() {
$(this.element).addClass('active');
},
unsetActive: function() {
$(this.element).removeClass('active');
},
enable: function() {
this.element.disabled = false;
},
disable: function() {
this.element.disabled = true;
this.unsetActive();
},
events: {
click: function(e) {
e.preventDefault();
this.spytext.execute(this.config.action, this.config.options);
}
},
presets: {
alignLeft: { title: 'Align Left', action: 'align', options: { alignment: 'left' }},
alignRight: { title: 'Align Right', action: 'align', options: { alignment: 'right' }},
alignCenter: { title: 'Align Center', action: 'align', options: { alignment: 'center' }},
alignJustify: { title: 'Align Justify', action: 'align', options: { alignment: 'justify' }},
bold: { title: 'Bold', action: 'format', options: { tag: 'B' }},
strikeThrough: { title: 'Strike Through', action: 'format', options: { tag: 'STRIKE' }},
underline: { title: 'Underline', action: 'format', options: { tag: 'U' }},
italic: { title: 'Italic', action: 'format', options: { tag: 'I' }},
removeFormat: { action: 'removeFormat' },
typeHeading1: { title: 'Heading 1', action: 'block', options: { tag: 'H1' }},
typeHeading2: { title: 'Heading 2', action: 'block', options: { tag: 'H2' }},
typeHeading3: { title: 'Heading 3', action: 'block', options: { tag: 'H3' }},
typeHeading4: { title: 'Heading 4', action: 'block', options: { tag: 'H4' }},
typeHeading5: { title: 'Heading 5', action: 'block', options: { tag: 'H5' }},
typeHeading6: { title: 'Heading 6', action: 'block', options: { tag: 'H6' }},
typeParagraph: { title: 'Paragraph', action: 'block', options: { tag: 'P' }},
orderedList: { title: 'Ordered List', action: 'list', options: { tag: 'OL' }},
unorderedList: { title: 'Unordered List', action: 'list', options: { tag: 'UL' }},
indent: { title: 'Indent', action: 'indent', options: { outdent: false }},
outdent: { title: 'Outdent', action: 'indent', options: { outdent: true }}
}
};
var SpytextDropdown = function(config, spytext) {
this.spytext = spytext;
this.config = typeof config.preset === 'string' ? merge(this.presets[config.preset], config) : config;
this.items = [];
this.element = $('<ul class="spytext-dropdown">')[0];
var property;
this.config.items.forEach(function(item) {
var $el = $('<li><span>' + item.title + '</span></li>');
$(this.element).append($el);
for(property in this.events.item)
$el.on(property, this.events.item[property].bind(this));
this.items.push(item);
}.bind(this));
for(property in this.events.dropdown)
$(this.element).on(property, this.events.dropdown[property].bind(this));
this.index = 0;
this.length = $(this.element).children().length;
this.disable();
};
SpytextDropdown.prototype = {
setIndex: function(index) {
this.index = index;
var liHeight = this.element.children[0].offsetHeight;
var children = this.element.children;
for(var i = 0; i < children.length; i++) {
$(children[i]).css('top', '-' + (index * liHeight) + 'px');
if(i === index) $(children[i]).addClass('active');
else $(children[i]).removeClass('active');
}
},
setNoActive: function() {
this.index = 0;
var children = this.element.children;
for(var i = 0; i < children.length; i++) {
$(children[i]).css('top', '0');
$(children[i]).removeClass('active');
}
},
setActive: function(options) {
for(var i = 0; i < this.items.length; i++)
for(var prop in options)
if(options[prop] === this.items[i].options[prop])
return this.setIndex(i);
},
enable: function() {
$(this.element).removeClass('disabled');
},
disable: function() {
$(this.element).addClass('disabled').removeClass('expanded');
this.setNoActive();
},
events: {
dropdown: {
click: function(e) {
if(this.spytext.currentField) {
$(this.element).toggleClass('expanded');
}
}
},
item: {
click: function(e) {
if($(this.element).hasClass('expanded')) {
var index = $(this.element).children().index(e.currentTarget);
this.spytext.execute(this.config.action, this.items[index].options);
}
}
}
},
presets: {
type: {
action: 'block',
items: [
{ title: 'Heading 1', options: { tag: 'H1' }},
{ title: 'Heading 2', options: { tag: 'H2' }},
{ title: 'Heading 3', options: { tag: 'H3' }},
{ title: 'Heading 4', options: { tag: 'H4' }},
{ title: 'Heading 5', options: { tag: 'H5' }},
{ title: 'Heading 6', options: { tag: 'H6' }},
{ title: 'Paragraph', options: { tag: 'P' }}
]
}
}
};
var SpytextToolbar = function(config, spytext) {
this.dropdowns = [];
this.buttons = [];
this.spytext = spytext;
this.config = typeof config.preset === 'string' ? merge(this.presets[config.preset], config) : config;
this.element = $('<div class="spytext-toolbar">')[0];
for(var property in this.config.dropdowns)
this.addDropdown.call(this, this.config.dropdowns[property], property);
for(property in this.config.buttonGroups)
this.addButtonGroup.call(this, this.config.buttonGroups[property], property);
for(property in this.events)
$(this.element).on(property, this.events[property].bind(this));
};
SpytextToolbar.prototype = {
addButtonGroup: function(group) {
var $ul = $('<UL>').addClass('spytext-button-group ' + group.name);
group.buttons.forEach(function(buttonType) {
var $li = $('<LI>');
var button = this.addButton({ preset: buttonType }, this.spytext);
$ul.append($li);
$li.append(button.element);
}.bind(this));
$(this.element).append($ul);
},
addButton: function(config) {
var button = new SpytextButton(config, this.spytext);
this.buttons[config.preset] = button;
return button;
},
addDropdown: function(config) {
config = typeof config === 'string' ? { preset: config } : config;
var dropdown = new SpytextDropdown(config, this.spytext);
this.dropdowns[config.preset] = dropdown;
$(this.element).append(dropdown.element);
return dropdown;
},
enable: function() {
for(var i in this.buttons) {
var button = this.buttons[i];
//button.element.setAttribute('disabled');
button.enable();
}
for(var j in this.dropdowns) {
this.dropdowns[j].enable();
//button.element.setAttribute('disabled');
}
$(this.element).addClass('active');
},
disable: function() {
for(var i in this.buttons) {
this.buttons[i].disable();
}
for(var j in this.dropdowns) {
this.dropdowns[j].disable();
}
$(this.element).removeClass('active');
},
setActiveStyles: function() {
function setBlock(tag) {
switch(tag) {
case 'P':
case 'H1':
case 'H2':
case 'H3':
case 'H4':
case 'H5':
case 'H6':
if(that.dropdowns.type) {
that.dropdowns.type.setActive({ tag: tag });
}
break;
case 'UL':
that.buttons.unorderedList.setActive();
that.dropdowns.type.setNoActive();
break;
case 'OL':
that.buttons.orderedList.setActive();
that.dropdowns.type.setNoActive();
break;
}
}
var that = this;
var tags = [];
var blocks = [];
var rng;
var s = 0;
while(!rng) {
rng = this.spytext.currentField.selectron.range();
if(s++ > 10000) return;
}
if(!rng) return;
if(rng.collapsed) {
tags = ancestors(rng.startContainer, null, this.spytext.currentField.element);
// The last element should always be the block element, such as P or UL.
} else {
var el = rng.commonAncestorContainer;
tags = ancestors(el, null, this.spytext.element);
}
if(tags.length > 0) blocks.push(tags.pop());
for(var i in this.buttons) {
var button = this.buttons[i];
if(button.config.options && $(tags).is(button.config.options.tag).length > 0) {
button.setActive();
} else button.unsetActive();
}
var blockTag;
for(var j = 0; j < blocks.length; j++) {
if(blockTag && blockTag !== blocks[j].tagName) {
blockTag = null;
break;
} else {
blockTag = blocks[j].tagName || null;
}
}
if(blockTag) setBlock(blockTag);
},
presets: {
standard: {
dropdowns: [ 'type' ],
buttonGroups: [
//{ name: 'block', buttons: ['typeHeading1', 'typeHeading2', 'typeHeading3', 'typeHeading4', 'typeHeading5', 'typeHeading6', 'typeParagraph']},
{ name: 'format', buttons: ['bold', 'italic', 'underline', 'strikeThrough', 'removeFormat']},
{ name: 'align', buttons: ['alignLeft', 'alignCenter', 'alignRight', 'alignJustify']},
{ name: 'list', buttons: ['unorderedList', 'orderedList']},
{ name: 'indent', buttons: ['indent', 'outdent']}
]
},
format: {
buttonGroups: [
{ name: 'format', buttons: ['bold', 'underline', 'strikeThrough', 'removeFormat']},
]
}
},
events: {
mousedown: function(e) {
// this is needed to prevent toolbar from stealing focus
e.preventDefault();
}
}
};