Switched to spaces

This commit is contained in:
rr-
2015-06-28 10:07:11 +02:00
parent 79df9b56d3
commit 2702518e31
265 changed files with 14902 additions and 14902 deletions

View File

@ -2,273 +2,273 @@ var App = App || {};
App.Controls = App.Controls || {};
App.Controls.AutoCompleteInput = function($input) {
var _ = App.DI.get('_');
var jQuery = App.DI.get('jQuery');
var tagList = App.DI.get('tagList');
var _ = App.DI.get('_');
var jQuery = App.DI.get('jQuery');
var tagList = App.DI.get('tagList');
var KEY_TAB = 9;
var KEY_RETURN = 13;
var KEY_DELETE = 46;
var KEY_ESCAPE = 27;
var KEY_UP = 38;
var KEY_DOWN = 40;
var KEY_TAB = 9;
var KEY_RETURN = 13;
var KEY_DELETE = 46;
var KEY_ESCAPE = 27;
var KEY_UP = 38;
var KEY_DOWN = 40;
var options = {
caseSensitive: false,
source: null,
maxResults: 15,
minLengthToArbitrarySearch: 3,
onApply: null,
onDelete: null,
onRender: null,
additionalFilter: null,
};
var showTimeout = null;
var cachedSource = null;
var results = [];
var activeResult = -1;
var monitorInputHidingInterval = null;
var options = {
caseSensitive: false,
source: null,
maxResults: 15,
minLengthToArbitrarySearch: 3,
onApply: null,
onDelete: null,
onRender: null,
additionalFilter: null,
};
var showTimeout = null;
var cachedSource = null;
var results = [];
var activeResult = -1;
var monitorInputHidingInterval = null;
if ($input.length === 0) {
throw new Error('Input element was not found');
}
if ($input.length > 1) {
throw new Error('Cannot add autocompletion to more than one element at once');
}
if ($input.attr('data-autocomplete')) {
throw new Error('Autocompletion was already added for this element');
}
$input.attr('data-autocomplete', true);
$input.attr('autocomplete', 'off');
if ($input.length === 0) {
throw new Error('Input element was not found');
}
if ($input.length > 1) {
throw new Error('Cannot add autocompletion to more than one element at once');
}
if ($input.attr('data-autocomplete')) {
throw new Error('Autocompletion was already added for this element');
}
$input.attr('data-autocomplete', true);
$input.attr('autocomplete', 'off');
var $div = jQuery('<div>');
var $list = jQuery('<ul>');
$div.addClass('autocomplete');
$div.append($list);
jQuery(document.body).append($div);
var $div = jQuery('<div>');
var $list = jQuery('<ul>');
$div.addClass('autocomplete');
$div.append($list);
jQuery(document.body).append($div);
function getSource() {
if (cachedSource) {
return cachedSource;
} else {
var source = tagList.getTags();
source = _.sortBy(source, function(a) { return -a.usages; });
source = _.filter(source, function(a) { return a.usages >= 0; });
source = _.map(source, function(a) {
return {
tag: a.name,
caption: a.name + ' (' + a.usages + ')',
};
});
cachedSource = source;
return source;
}
}
function getSource() {
if (cachedSource) {
return cachedSource;
} else {
var source = tagList.getTags();
source = _.sortBy(source, function(a) { return -a.usages; });
source = _.filter(source, function(a) { return a.usages >= 0; });
source = _.map(source, function(a) {
return {
tag: a.name,
caption: a.name + ' (' + a.usages + ')',
};
});
cachedSource = source;
return source;
}
}
$input.bind('keydown', function(e) {
var func = null;
if (isShown() && e.which === KEY_ESCAPE) {
func = hide;
} else if (isShown() && e.which === KEY_TAB) {
if (e.shiftKey) {
func = selectPrevious;
} else {
func = selectNext;
}
} else if (isShown() && e.which === KEY_DOWN) {
func = selectNext;
} else if (isShown() && e.which === KEY_UP) {
func = selectPrevious;
} else if (isShown() && e.which === KEY_RETURN && activeResult >= 0) {
func = function() { applyAutocomplete(); hide(); };
} else if (isShown() && e.which === KEY_DELETE && activeResult >= 0) {
func = function() { applyDelete(); hide(); };
}
$input.bind('keydown', function(e) {
var func = null;
if (isShown() && e.which === KEY_ESCAPE) {
func = hide;
} else if (isShown() && e.which === KEY_TAB) {
if (e.shiftKey) {
func = selectPrevious;
} else {
func = selectNext;
}
} else if (isShown() && e.which === KEY_DOWN) {
func = selectNext;
} else if (isShown() && e.which === KEY_UP) {
func = selectPrevious;
} else if (isShown() && e.which === KEY_RETURN && activeResult >= 0) {
func = function() { applyAutocomplete(); hide(); };
} else if (isShown() && e.which === KEY_DELETE && activeResult >= 0) {
func = function() { applyDelete(); hide(); };
}
if (func !== null) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
func();
} else {
window.clearTimeout(showTimeout);
showTimeout = window.setTimeout(showOrHide, 250);
}
});
if (func !== null) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
func();
} else {
window.clearTimeout(showTimeout);
showTimeout = window.setTimeout(showOrHide, 250);
}
});
$input.blur(function(e) {
window.clearTimeout(showTimeout);
window.setTimeout(function() { hide(); }, 50);
});
$input.blur(function(e) {
window.clearTimeout(showTimeout);
window.setTimeout(function() { hide(); }, 50);
});
function getSelectionStart(){
var input = $input.get(0);
if (!input) {
return;
}
if ('selectionStart' in input) {
return input.selectionStart;
} else if (document.selection) {
input.focus();
var sel = document.selection.createRange();
var selLen = document.selection.createRange().text.length;
sel.moveStart('character', -input.value.length);
return sel.text.length - selLen;
} else {
return 0;
}
}
function getSelectionStart(){
var input = $input.get(0);
if (!input) {
return;
}
if ('selectionStart' in input) {
return input.selectionStart;
} else if (document.selection) {
input.focus();
var sel = document.selection.createRange();
var selLen = document.selection.createRange().text.length;
sel.moveStart('character', -input.value.length);
return sel.text.length - selLen;
} else {
return 0;
}
}
function getTextToFind() {
var val = $input.val();
var start = getSelectionStart();
return val.substring(0, start).replace(/.*\s/, '');
}
function getTextToFind() {
var val = $input.val();
var start = getSelectionStart();
return val.substring(0, start).replace(/.*\s/, '');
}
function showOrHide() {
var textToFind = getTextToFind();
if (textToFind.length === 0) {
hide();
} else {
updateResults(textToFind);
refreshList();
}
}
function showOrHide() {
var textToFind = getTextToFind();
if (textToFind.length === 0) {
hide();
} else {
updateResults(textToFind);
refreshList();
}
}
function isShown() {
return $div.is(':visible');
}
function isShown() {
return $div.is(':visible');
}
function hide() {
$div.hide();
window.clearInterval(monitorInputHidingInterval);
}
function hide() {
$div.hide();
window.clearInterval(monitorInputHidingInterval);
}
function selectPrevious() {
select(activeResult === -1 ? results.length - 1 : activeResult - 1);
}
function selectPrevious() {
select(activeResult === -1 ? results.length - 1 : activeResult - 1);
}
function selectNext() {
select(activeResult === -1 ? 0 : activeResult + 1);
}
function selectNext() {
select(activeResult === -1 ? 0 : activeResult + 1);
}
function select(newActiveResult) {
if (newActiveResult >= 0 && newActiveResult < results.length) {
activeResult = newActiveResult;
refreshActiveResult();
} else {
activeResult = - 1;
refreshActiveResult();
}
}
function select(newActiveResult) {
if (newActiveResult >= 0 && newActiveResult < results.length) {
activeResult = newActiveResult;
refreshActiveResult();
} else {
activeResult = - 1;
refreshActiveResult();
}
}
function getResultsFilter(textToFind) {
if (textToFind.length < options.minLengthToArbitrarySearch) {
return options.caseSensitive ?
function(resultItem) { return resultItem.tag.indexOf(textToFind) === 0; } :
function(resultItem) { return resultItem.tag.toLowerCase().indexOf(textToFind.toLowerCase()) === 0; };
} else {
return options.caseSensitive ?
function(resultItem) { return resultItem.tag.indexOf(textToFind) >= 0; } :
function(resultItem) { return resultItem.tag.toLowerCase().indexOf(textToFind.toLowerCase()) >= 0; };
}
}
function getResultsFilter(textToFind) {
if (textToFind.length < options.minLengthToArbitrarySearch) {
return options.caseSensitive ?
function(resultItem) { return resultItem.tag.indexOf(textToFind) === 0; } :
function(resultItem) { return resultItem.tag.toLowerCase().indexOf(textToFind.toLowerCase()) === 0; };
} else {
return options.caseSensitive ?
function(resultItem) { return resultItem.tag.indexOf(textToFind) >= 0; } :
function(resultItem) { return resultItem.tag.toLowerCase().indexOf(textToFind.toLowerCase()) >= 0; };
}
}
function updateResults(textToFind) {
var oldResults = results.slice();
var source = getSource();
var filter = getResultsFilter(textToFind);
results = _.filter(source, filter);
if (options.additionalFilter) {
results = options.additionalFilter(results);
}
results = results.slice(0, options.maxResults);
if (!_.isEqual(oldResults, results)) {
activeResult = -1;
}
}
function updateResults(textToFind) {
var oldResults = results.slice();
var source = getSource();
var filter = getResultsFilter(textToFind);
results = _.filter(source, filter);
if (options.additionalFilter) {
results = options.additionalFilter(results);
}
results = results.slice(0, options.maxResults);
if (!_.isEqual(oldResults, results)) {
activeResult = -1;
}
}
function applyDelete() {
if (options.onDelete) {
options.onDelete(results[activeResult].tag);
}
}
function applyDelete() {
if (options.onDelete) {
options.onDelete(results[activeResult].tag);
}
}
function applyAutocomplete() {
if (options.onApply) {
options.onApply(results[activeResult].tag);
} else {
var val = $input.val();
var start = getSelectionStart();
var prefix = '';
var suffix = val.substring(start);
var middle = val.substring(0, start);
var index = middle.lastIndexOf(' ');
if (index !== -1) {
prefix = val.substring(0, index + 1);
middle = val.substring(index + 1);
}
$input.val(prefix + results[activeResult].tag + ' ' + suffix.trimLeft());
$input.focus();
}
}
function applyAutocomplete() {
if (options.onApply) {
options.onApply(results[activeResult].tag);
} else {
var val = $input.val();
var start = getSelectionStart();
var prefix = '';
var suffix = val.substring(start);
var middle = val.substring(0, start);
var index = middle.lastIndexOf(' ');
if (index !== -1) {
prefix = val.substring(0, index + 1);
middle = val.substring(index + 1);
}
$input.val(prefix + results[activeResult].tag + ' ' + suffix.trimLeft());
$input.focus();
}
}
function refreshList() {
if (results.length === 0) {
hide();
return;
}
function refreshList() {
if (results.length === 0) {
hide();
return;
}
$list.empty();
_.each(results, function(resultItem, resultIndex) {
var $listItem = jQuery('<li/>');
$listItem.text(resultItem.caption);
$listItem.attr('data-key', resultItem.tag);
$listItem.hover(function(e) {
e.preventDefault();
activeResult = resultIndex;
refreshActiveResult();
});
$listItem.mousedown(function(e) {
e.preventDefault();
activeResult = resultIndex;
applyAutocomplete();
hide();
});
$list.append($listItem);
});
if (options.onRender) {
options.onRender($list);
}
refreshActiveResult();
$list.empty();
_.each(results, function(resultItem, resultIndex) {
var $listItem = jQuery('<li/>');
$listItem.text(resultItem.caption);
$listItem.attr('data-key', resultItem.tag);
$listItem.hover(function(e) {
e.preventDefault();
activeResult = resultIndex;
refreshActiveResult();
});
$listItem.mousedown(function(e) {
e.preventDefault();
activeResult = resultIndex;
applyAutocomplete();
hide();
});
$list.append($listItem);
});
if (options.onRender) {
options.onRender($list);
}
refreshActiveResult();
var x = $input.offset().left;
var y = $input.offset().top + $input.outerHeight() - 2;
if (y + $div.height() > window.innerHeight) {
y = $input.offset().top - $div.height();
}
$div.css({
left: x + 'px',
top: y + 'px',
});
$div.show();
monitorInputHiding();
}
var x = $input.offset().left;
var y = $input.offset().top + $input.outerHeight() - 2;
if (y + $div.height() > window.innerHeight) {
y = $input.offset().top - $div.height();
}
$div.css({
left: x + 'px',
top: y + 'px',
});
$div.show();
monitorInputHiding();
}
function refreshActiveResult() {
$list.find('li.active').removeClass('active');
if (activeResult >= 0) {
$list.find('li').eq(activeResult).addClass('active');
}
}
function refreshActiveResult() {
$list.find('li.active').removeClass('active');
if (activeResult >= 0) {
$list.find('li').eq(activeResult).addClass('active');
}
}
function monitorInputHiding() {
monitorInputHidingInterval = window.setInterval(function() {
if (!$input.is(':visible')) {
hide();
}
}, 100);
}
function monitorInputHiding() {
monitorInputHidingInterval = window.setInterval(function() {
if (!$input.is(':visible')) {
hide();
}
}, 100);
}
return options;
return options;
};

View File

@ -2,64 +2,64 @@ var App = App || {};
App.Controls = App.Controls || {};
App.Controls.FileDropper = function($fileInput) {
var _ = App.DI.get('_');
var jQuery = App.DI.get('jQuery');
var _ = App.DI.get('_');
var jQuery = App.DI.get('jQuery');
var options = {
onChange: null,
setNames: false,
};
var options = {
onChange: null,
setNames: false,
};
var $dropDiv = jQuery('<button type="button" class="file-handler"></button>');
var allowMultiple = $fileInput.attr('multiple');
$dropDiv.html((allowMultiple ? 'Drop files here!' : 'Drop file here!') + '<br/>Or just click on this box.');
$dropDiv.insertBefore($fileInput);
$fileInput.attr('multiple', allowMultiple);
$fileInput.hide();
var $dropDiv = jQuery('<button type="button" class="file-handler"></button>');
var allowMultiple = $fileInput.attr('multiple');
$dropDiv.html((allowMultiple ? 'Drop files here!' : 'Drop file here!') + '<br/>Or just click on this box.');
$dropDiv.insertBefore($fileInput);
$fileInput.attr('multiple', allowMultiple);
$fileInput.hide();
$fileInput.change(function(e) {
addFiles(this.files);
});
$fileInput.change(function(e) {
addFiles(this.files);
});
$dropDiv.on('dragenter', function(e) {
$dropDiv.addClass('active');
}).on('dragleave', function(e) {
$dropDiv.removeClass('active');
}).on('dragover', function(e) {
e.preventDefault();
}).on('drop', function(e) {
e.preventDefault();
addFiles(e.originalEvent.dataTransfer.files);
}).on('click', function(e) {
$fileInput.show().focus().trigger('click').hide();
$dropDiv.addClass('active');
});
$dropDiv.on('dragenter', function(e) {
$dropDiv.addClass('active');
}).on('dragleave', function(e) {
$dropDiv.removeClass('active');
}).on('dragover', function(e) {
e.preventDefault();
}).on('drop', function(e) {
e.preventDefault();
addFiles(e.originalEvent.dataTransfer.files);
}).on('click', function(e) {
$fileInput.show().focus().trigger('click').hide();
$dropDiv.addClass('active');
});
function addFiles(files) {
$dropDiv.removeClass('active');
if (!allowMultiple && files.length > 1) {
window.alert('Cannot select multiple files.');
return;
}
if (typeof(options.onChange) !== 'undefined') {
options.onChange(files);
}
if (options.setNames && !allowMultiple) {
$dropDiv.text(files[0].name);
}
}
function addFiles(files) {
$dropDiv.removeClass('active');
if (!allowMultiple && files.length > 1) {
window.alert('Cannot select multiple files.');
return;
}
if (typeof(options.onChange) !== 'undefined') {
options.onChange(files);
}
if (options.setNames && !allowMultiple) {
$dropDiv.text(files[0].name);
}
}
function readAsDataURL(file, callback) {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
};
reader.readAsDataURL(file);
}
function readAsDataURL(file, callback) {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
};
reader.readAsDataURL(file);
}
_.extend(options, {
readAsDataURL: readAsDataURL,
});
_.extend(options, {
readAsDataURL: readAsDataURL,
});
return options;
return options;
};

View File

@ -2,419 +2,419 @@ var App = App || {};
App.Controls = App.Controls || {};
App.Controls.TagInput = function($underlyingInput) {
var _ = App.DI.get('_');
var jQuery = App.DI.get('jQuery');
var promise = App.DI.get('promise');
var api = App.DI.get('api');
var tagList = App.DI.get('tagList');
var _ = App.DI.get('_');
var jQuery = App.DI.get('jQuery');
var promise = App.DI.get('promise');
var api = App.DI.get('api');
var tagList = App.DI.get('tagList');
var KEY_RETURN = 13;
var KEY_SPACE = 32;
var KEY_BACKSPACE = 8;
var tagConfirmKeys = [KEY_RETURN, KEY_SPACE];
var inputConfirmKeys = [KEY_RETURN];
var KEY_RETURN = 13;
var KEY_SPACE = 32;
var KEY_BACKSPACE = 8;
var tagConfirmKeys = [KEY_RETURN, KEY_SPACE];
var inputConfirmKeys = [KEY_RETURN];
var SOURCE_INITIAL_TEXT = 1;
var SOURCE_AUTOCOMPLETION = 2;
var SOURCE_PASTE = 3;
var SOURCE_IMPLICATIONS = 4;
var SOURCE_INPUT_BLUR = 5;
var SOURCE_INPUT_ENTER = 6;
var SOURCE_SUGGESTIONS = 7;
var SOURCE_INITIAL_TEXT = 1;
var SOURCE_AUTOCOMPLETION = 2;
var SOURCE_PASTE = 3;
var SOURCE_IMPLICATIONS = 4;
var SOURCE_INPUT_BLUR = 5;
var SOURCE_INPUT_ENTER = 6;
var SOURCE_SUGGESTIONS = 7;
var tags = [];
var options = {
beforeTagAdded: null,
beforeTagRemoved: null,
inputConfirmed: null,
};
var tags = [];
var options = {
beforeTagAdded: null,
beforeTagRemoved: null,
inputConfirmed: null,
};
var $wrapper = jQuery('<div class="tag-input">');
var $tagList = jQuery('<ul class="tags">');
var tagInputId = 'tags' + Math.random();
var $label = jQuery('<label for="' + tagInputId + '" style="display: none">Tags:</label>');
var $input = jQuery('<input class="tag-real-input" type="text" id="' + tagInputId + '"/>');
var $siblings = jQuery('<div class="related-tags"><span>Sibling tags:</span><ul>');
var $suggestions = jQuery('<div class="related-tags"><span>Suggested tags:</span><ul>');
init();
render();
initAutoComplete();
var $wrapper = jQuery('<div class="tag-input">');
var $tagList = jQuery('<ul class="tags">');
var tagInputId = 'tags' + Math.random();
var $label = jQuery('<label for="' + tagInputId + '" style="display: none">Tags:</label>');
var $input = jQuery('<input class="tag-real-input" type="text" id="' + tagInputId + '"/>');
var $siblings = jQuery('<div class="related-tags"><span>Sibling tags:</span><ul>');
var $suggestions = jQuery('<div class="related-tags"><span>Suggested tags:</span><ul>');
init();
render();
initAutoComplete();
function init() {
if ($underlyingInput.length === 0) {
throw new Error('Tag input element was not found');
}
if ($underlyingInput.length > 1) {
throw new Error('Cannot set tag input to more than one element at once');
}
if ($underlyingInput.attr('data-tagged')) {
throw new Error('Tag input was already initialized for this element');
}
$underlyingInput.attr('data-tagged', true);
}
function init() {
if ($underlyingInput.length === 0) {
throw new Error('Tag input element was not found');
}
if ($underlyingInput.length > 1) {
throw new Error('Cannot set tag input to more than one element at once');
}
if ($underlyingInput.attr('data-tagged')) {
throw new Error('Tag input was already initialized for this element');
}
$underlyingInput.attr('data-tagged', true);
}
function render() {
$underlyingInput.hide();
$wrapper.append($tagList);
$wrapper.append($label);
$wrapper.append($input);
$wrapper.insertAfter($underlyingInput);
$wrapper.click(function(e) {
if (e.target.nodeName === 'LI') {
return;
}
e.preventDefault();
$input.focus();
});
$input.attr('placeholder', $underlyingInput.attr('placeholder'));
$siblings.insertAfter($wrapper);
$suggestions.insertAfter($wrapper);
function render() {
$underlyingInput.hide();
$wrapper.append($tagList);
$wrapper.append($label);
$wrapper.append($input);
$wrapper.insertAfter($underlyingInput);
$wrapper.click(function(e) {
if (e.target.nodeName === 'LI') {
return;
}
e.preventDefault();
$input.focus();
});
$input.attr('placeholder', $underlyingInput.attr('placeholder'));
$siblings.insertAfter($wrapper);
$suggestions.insertAfter($wrapper);
processText($underlyingInput.val(), SOURCE_INITIAL_TEXT);
processText($underlyingInput.val(), SOURCE_INITIAL_TEXT);
$underlyingInput.val('');
}
$underlyingInput.val('');
}
function initAutoComplete() {
var autoComplete = new App.Controls.AutoCompleteInput($input);
autoComplete.onDelete = function(text) {
removeTag(text);
$input.val('');
};
autoComplete.onApply = function(text) {
processText(text, SOURCE_AUTOCOMPLETION);
$input.val('');
};
autoComplete.additionalFilter = function(results) {
return _.filter(results, function(resultItem) {
return !_.contains(getTags(), resultItem[0]);
});
};
autoComplete.onRender = function($list) {
$list.find('li').each(function() {
var $li = jQuery(this);
if (isTaggedWith($li.attr('data-key'))) {
$li.css('opacity', '0.5');
}
});
};
}
function initAutoComplete() {
var autoComplete = new App.Controls.AutoCompleteInput($input);
autoComplete.onDelete = function(text) {
removeTag(text);
$input.val('');
};
autoComplete.onApply = function(text) {
processText(text, SOURCE_AUTOCOMPLETION);
$input.val('');
};
autoComplete.additionalFilter = function(results) {
return _.filter(results, function(resultItem) {
return !_.contains(getTags(), resultItem[0]);
});
};
autoComplete.onRender = function($list) {
$list.find('li').each(function() {
var $li = jQuery(this);
if (isTaggedWith($li.attr('data-key'))) {
$li.css('opacity', '0.5');
}
});
};
}
$input.bind('focus', function(e) {
$wrapper.addClass('focused');
});
$input.bind('blur', function(e) {
$wrapper.removeClass('focused');
var tagName = $input.val();
addTag(tagName, SOURCE_INPUT_BLUR);
$input.val('');
});
$input.bind('focus', function(e) {
$wrapper.addClass('focused');
});
$input.bind('blur', function(e) {
$wrapper.removeClass('focused');
var tagName = $input.val();
addTag(tagName, SOURCE_INPUT_BLUR);
$input.val('');
});
$input.bind('paste', function(e) {
e.preventDefault();
var pastedText;
if (window.clipboardData) {
pastedText = window.clipboardData.getData('Text');
} else {
pastedText = (e.originalEvent || e).clipboardData.getData('text/plain');
}
$input.bind('paste', function(e) {
e.preventDefault();
var pastedText;
if (window.clipboardData) {
pastedText = window.clipboardData.getData('Text');
} else {
pastedText = (e.originalEvent || e).clipboardData.getData('text/plain');
}
if (pastedText.length > 2000) {
window.alert('Pasted text is too long.');
return;
}
if (pastedText.length > 2000) {
window.alert('Pasted text is too long.');
return;
}
processTextWithoutLast(pastedText, SOURCE_PASTE);
});
processTextWithoutLast(pastedText, SOURCE_PASTE);
});
$input.bind('keydown', function(e) {
if (_.contains(inputConfirmKeys, e.which) && !$input.val()) {
e.preventDefault();
if (typeof(options.inputConfirmed) !== 'undefined') {
options.inputConfirmed();
}
} else if (_.contains(tagConfirmKeys, e.which)) {
var tagName = $input.val();
e.preventDefault();
$input.val('');
addTag(tagName, SOURCE_INPUT_ENTER);
} else if (e.which === KEY_BACKSPACE && jQuery(this).val().length === 0) {
e.preventDefault();
removeLastTag();
}
});
$input.bind('keydown', function(e) {
if (_.contains(inputConfirmKeys, e.which) && !$input.val()) {
e.preventDefault();
if (typeof(options.inputConfirmed) !== 'undefined') {
options.inputConfirmed();
}
} else if (_.contains(tagConfirmKeys, e.which)) {
var tagName = $input.val();
e.preventDefault();
$input.val('');
addTag(tagName, SOURCE_INPUT_ENTER);
} else if (e.which === KEY_BACKSPACE && jQuery(this).val().length === 0) {
e.preventDefault();
removeLastTag();
}
});
function explodeText(text) {
return _.filter(text.trim().split(/\s+/), function(item) {
return item.length > 0;
});
}
function explodeText(text) {
return _.filter(text.trim().split(/\s+/), function(item) {
return item.length > 0;
});
}
function processText(text, source) {
var tagNamesToAdd = explodeText(text);
_.map(tagNamesToAdd, function(tagName) { addTag(tagName, source); });
}
function processText(text, source) {
var tagNamesToAdd = explodeText(text);
_.map(tagNamesToAdd, function(tagName) { addTag(tagName, source); });
}
function processTextWithoutLast(text, source) {
var tagNamesToAdd = explodeText(text);
var lastTagName = tagNamesToAdd.pop();
_.map(tagNamesToAdd, function(tagName) { addTag(tagName, source); });
$input.val(lastTagName);
}
function processTextWithoutLast(text, source) {
var tagNamesToAdd = explodeText(text);
var lastTagName = tagNamesToAdd.pop();
_.map(tagNamesToAdd, function(tagName) { addTag(tagName, source); });
$input.val(lastTagName);
}
function addTag(tagName, source) {
tagName = tagName.trim();
if (tagName.length === 0) {
return;
}
function addTag(tagName, source) {
tagName = tagName.trim();
if (tagName.length === 0) {
return;
}
if (tagName.length > 64) {
//showing alert inside keydown event leads to mysterious behaviors
//in some browsers, hence the timeout
window.setTimeout(function() {
window.alert('Tag is too long.');
}, 10);
return;
}
if (tagName.length > 64) {
//showing alert inside keydown event leads to mysterious behaviors
//in some browsers, hence the timeout
window.setTimeout(function() {
window.alert('Tag is too long.');
}, 10);
return;
}
if (isTaggedWith(tagName)) {
flashTagRed(tagName);
} else {
beforeTagAdded(tagName, source);
if (isTaggedWith(tagName)) {
flashTagRed(tagName);
} else {
beforeTagAdded(tagName, source);
var exportedTag = getExportedTag(tagName);
if (!exportedTag || !exportedTag.banned) {
tags.push(tagName);
var $elem = createListElement(tagName);
$tagList.append($elem);
}
var exportedTag = getExportedTag(tagName);
if (!exportedTag || !exportedTag.banned) {
tags.push(tagName);
var $elem = createListElement(tagName);
$tagList.append($elem);
}
afterTagAdded(tagName, source);
}
}
afterTagAdded(tagName, source);
}
}
function beforeTagRemoved(tagName) {
if (typeof(options.beforeTagRemoved) === 'function') {
options.beforeTagRemoved(tagName);
}
}
function beforeTagRemoved(tagName) {
if (typeof(options.beforeTagRemoved) === 'function') {
options.beforeTagRemoved(tagName);
}
}
function afterTagRemoved(tagName) {
refreshShownSiblings();
}
function afterTagRemoved(tagName) {
refreshShownSiblings();
}
function beforeTagAdded(tagName, source) {
if (typeof(options.beforeTagAdded) === 'function') {
options.beforeTagAdded(tagName);
}
}
function beforeTagAdded(tagName, source) {
if (typeof(options.beforeTagAdded) === 'function') {
options.beforeTagAdded(tagName);
}
}
function afterTagAdded(tagName, source) {
if (source === SOURCE_IMPLICATIONS) {
flashTagYellow(tagName);
} else if (source !== SOURCE_INITIAL_TEXT) {
var tag = getExportedTag(tagName);
if (tag) {
_.each(tag.implications, function(impliedTagName) {
if (!isTaggedWith(impliedTagName)) {
addTag(impliedTagName, SOURCE_IMPLICATIONS);
}
});
if (source !== SOURCE_IMPLICATIONS && source !== SOURCE_SUGGESTIONS) {
showOrHideSuggestions(tagName);
refreshShownSiblings();
}
} else {
flashTagGreen(tagName);
}
}
}
function afterTagAdded(tagName, source) {
if (source === SOURCE_IMPLICATIONS) {
flashTagYellow(tagName);
} else if (source !== SOURCE_INITIAL_TEXT) {
var tag = getExportedTag(tagName);
if (tag) {
_.each(tag.implications, function(impliedTagName) {
if (!isTaggedWith(impliedTagName)) {
addTag(impliedTagName, SOURCE_IMPLICATIONS);
}
});
if (source !== SOURCE_IMPLICATIONS && source !== SOURCE_SUGGESTIONS) {
showOrHideSuggestions(tagName);
refreshShownSiblings();
}
} else {
flashTagGreen(tagName);
}
}
}
function getExportedTag(tagName) {
return _.first(_.filter(
tagList.getTags(),
function(t) {
return t.name.toLowerCase() === tagName.toLowerCase();
}));
}
function getExportedTag(tagName) {
return _.first(_.filter(
tagList.getTags(),
function(t) {
return t.name.toLowerCase() === tagName.toLowerCase();
}));
}
function removeTag(tagName) {
var oldTagNames = getTags();
var newTagNames = _.without(oldTagNames, tagName);
if (newTagNames.length !== oldTagNames.length) {
beforeTagRemoved(tagName);
setTags(newTagNames);
afterTagRemoved(tagName);
}
}
function removeTag(tagName) {
var oldTagNames = getTags();
var newTagNames = _.without(oldTagNames, tagName);
if (newTagNames.length !== oldTagNames.length) {
beforeTagRemoved(tagName);
setTags(newTagNames);
afterTagRemoved(tagName);
}
}
function isTaggedWith(tagName) {
var tagNames = _.map(getTags(), function(tagName) {
return tagName.toLowerCase();
});
return _.contains(tagNames, tagName.toLowerCase());
}
function isTaggedWith(tagName) {
var tagNames = _.map(getTags(), function(tagName) {
return tagName.toLowerCase();
});
return _.contains(tagNames, tagName.toLowerCase());
}
function removeLastTag() {
removeTag(_.last(getTags()));
}
function removeLastTag() {
removeTag(_.last(getTags()));
}
function flashTagRed(tagName) {
flashTag(tagName, 'rgba(255, 200, 200, 1)');
}
function flashTagRed(tagName) {
flashTag(tagName, 'rgba(255, 200, 200, 1)');
}
function flashTagYellow(tagName) {
flashTag(tagName, 'rgba(255, 255, 200, 1)');
}
function flashTagYellow(tagName) {
flashTag(tagName, 'rgba(255, 255, 200, 1)');
}
function flashTagGreen(tagName) {
flashTag(tagName, 'rgba(200, 255, 200, 1)');
}
function flashTagGreen(tagName) {
flashTag(tagName, 'rgba(200, 255, 200, 1)');
}
function flashTag(tagName, color) {
var $elem = getListElement(tagName);
$elem.css({backgroundColor: color});
}
function flashTag(tagName, color) {
var $elem = getListElement(tagName);
$elem.css({backgroundColor: color});
}
function getListElement(tagName) {
return $tagList.find('li[data-tag="' + tagName.toLowerCase() + '"]');
}
function getListElement(tagName) {
return $tagList.find('li[data-tag="' + tagName.toLowerCase() + '"]');
}
function setTags(newTagNames) {
tags = newTagNames.slice();
$tagList.empty();
$underlyingInput.val(newTagNames.join(' '));
_.each(newTagNames, function(tagName) {
var $elem = createListElement(tagName);
$tagList.append($elem);
});
}
function setTags(newTagNames) {
tags = newTagNames.slice();
$tagList.empty();
$underlyingInput.val(newTagNames.join(' '));
_.each(newTagNames, function(tagName) {
var $elem = createListElement(tagName);
$tagList.append($elem);
});
}
function createListElement(tagName) {
var $elem = jQuery('<li/>');
$elem.attr('data-tag', tagName.toLowerCase());
function createListElement(tagName) {
var $elem = jQuery('<li/>');
$elem.attr('data-tag', tagName.toLowerCase());
var $tagLink = jQuery('<a class="tag">');
$tagLink.text(tagName + ' ' /* for easy copying */);
$tagLink.click(function(e) {
e.preventDefault();
showOrHideSiblings(tagName);
showOrHideSuggestions(tagName);
});
$elem.append($tagLink);
var $tagLink = jQuery('<a class="tag">');
$tagLink.text(tagName + ' ' /* for easy copying */);
$tagLink.click(function(e) {
e.preventDefault();
showOrHideSiblings(tagName);
showOrHideSuggestions(tagName);
});
$elem.append($tagLink);
var $deleteButton = jQuery('<a class="close"><i class="fa fa-remove"></i></a>');
$deleteButton.click(function(e) {
e.preventDefault();
removeTag(tagName);
$input.focus();
});
$elem.append($deleteButton);
return $elem;
}
var $deleteButton = jQuery('<a class="close"><i class="fa fa-remove"></i></a>');
$deleteButton.click(function(e) {
e.preventDefault();
removeTag(tagName);
$input.focus();
});
$elem.append($deleteButton);
return $elem;
}
function showOrHideSuggestions(tagName) {
var tag = getExportedTag(tagName);
var suggestions = tag ? tag.suggestions : [];
updateSuggestions($suggestions, suggestions);
}
function showOrHideSuggestions(tagName) {
var tag = getExportedTag(tagName);
var suggestions = tag ? tag.suggestions : [];
updateSuggestions($suggestions, suggestions);
}
function showOrHideSiblings(tagName) {
if ($siblings.data('lastTag') === tagName && $siblings.is(':visible')) {
$siblings.slideUp('fast');
$siblings.data('lastTag', null);
return;
}
function showOrHideSiblings(tagName) {
if ($siblings.data('lastTag') === tagName && $siblings.is(':visible')) {
$siblings.slideUp('fast');
$siblings.data('lastTag', null);
return;
}
promise.wait(getSiblings(tagName), promise.make(function(resolve, reject) {
$siblings.slideUp('fast', resolve);
})).then(function(siblings) {
siblings = _.pluck(siblings, 'name');
$siblings.data('lastTag', tagName);
$siblings.data('siblings', siblings);
updateSuggestions($siblings, siblings);
}).fail(function() {
});
}
promise.wait(getSiblings(tagName), promise.make(function(resolve, reject) {
$siblings.slideUp('fast', resolve);
})).then(function(siblings) {
siblings = _.pluck(siblings, 'name');
$siblings.data('lastTag', tagName);
$siblings.data('siblings', siblings);
updateSuggestions($siblings, siblings);
}).fail(function() {
});
}
function refreshShownSiblings() {
updateSuggestions($siblings, $siblings.data('siblings'));
}
function refreshShownSiblings() {
updateSuggestions($siblings, $siblings.data('siblings'));
}
function updateSuggestions($target, suggestedTagNames) {
function filterSuggestions(sourceTagNames) {
if (!sourceTagNames) {
return [];
}
var tagNames = _.filter(sourceTagNames.slice(), function(tagName) {
return !isTaggedWith(tagName);
});
tagNames = tagNames.slice(0, 20);
return tagNames;
}
function updateSuggestions($target, suggestedTagNames) {
function filterSuggestions(sourceTagNames) {
if (!sourceTagNames) {
return [];
}
var tagNames = _.filter(sourceTagNames.slice(), function(tagName) {
return !isTaggedWith(tagName);
});
tagNames = tagNames.slice(0, 20);
return tagNames;
}
function attachTagsToSuggestionList($list, tagNames) {
$list.empty();
_.each(tagNames, function(tagName) {
var $li = jQuery('<li>');
var $a = jQuery('<a href="#/posts/query=' + tagName + '">');
$a.text(tagName);
$a.click(function(e) {
e.preventDefault();
addTag(tagName, SOURCE_SUGGESTIONS);
$li.fadeOut('fast', function() {
$li.remove();
if ($list.children().length === 0) {
$list.parent('div').slideUp('fast');
}
});
});
$li.append($a);
$list.append($li);
});
}
function attachTagsToSuggestionList($list, tagNames) {
$list.empty();
_.each(tagNames, function(tagName) {
var $li = jQuery('<li>');
var $a = jQuery('<a href="#/posts/query=' + tagName + '">');
$a.text(tagName);
$a.click(function(e) {
e.preventDefault();
addTag(tagName, SOURCE_SUGGESTIONS);
$li.fadeOut('fast', function() {
$li.remove();
if ($list.children().length === 0) {
$list.parent('div').slideUp('fast');
}
});
});
$li.append($a);
$list.append($li);
});
}
var suggestions = filterSuggestions(suggestedTagNames);
if (suggestions.length > 0) {
attachTagsToSuggestionList($target.find('ul'), suggestions);
$target.slideDown('fast');
} else {
$target.slideUp('fast');
}
}
var suggestions = filterSuggestions(suggestedTagNames);
if (suggestions.length > 0) {
attachTagsToSuggestionList($target.find('ul'), suggestions);
$target.slideDown('fast');
} else {
$target.slideUp('fast');
}
}
function getSiblings(tagName) {
return promise.make(function(resolve, reject) {
promise.wait(api.get('/tags/' + tagName + '/siblings'))
.then(function(response) {
resolve(response.json.data);
}).fail(function() {
reject();
});
});
}
function getSiblings(tagName) {
return promise.make(function(resolve, reject) {
promise.wait(api.get('/tags/' + tagName + '/siblings'))
.then(function(response) {
resolve(response.json.data);
}).fail(function() {
reject();
});
});
}
function getTags() {
return tags;
}
function getTags() {
return tags;
}
function focus() {
$input.focus();
}
function focus() {
$input.focus();
}
function hideSuggestions() {
$siblings.hide();
$suggestions.hide();
$siblings.data('siblings', []);
}
function hideSuggestions() {
$siblings.hide();
$suggestions.hide();
$siblings.data('siblings', []);
}
_.extend(options, {
setTags: setTags,
getTags: getTags,
removeTag: removeTag,
addTag: addTag,
focus: focus,
hideSuggestions: hideSuggestions,
});
return options;
_.extend(options, {
setTags: setTags,
getTags: getTags,
removeTag: removeTag,
addTag: addTag,
focus: focus,
hideSuggestions: hideSuggestions,
});
return options;
};