2013-11-24 21:50:46 +01:00
|
|
|
function setCookie(name, value, exdays)
|
|
|
|
{
|
|
|
|
var exdate = new Date();
|
|
|
|
exdate.setDate(exdate.getDate() + exdays);
|
|
|
|
value = escape(value) + '; path=/' + ((exdays == null) ? '' : '; expires=' + exdate.toUTCString());
|
|
|
|
document.cookie = name + '=' + value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCookie(name)
|
|
|
|
{
|
|
|
|
var value = document.cookie;
|
|
|
|
var start = value.indexOf(' ' + name + '=');
|
|
|
|
|
|
|
|
if (start == -1)
|
|
|
|
start = value.indexOf(name + '=');
|
|
|
|
|
|
|
|
if (start == -1)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
start = value.indexOf('=', start) + 1;
|
2013-11-25 21:51:31 +01:00
|
|
|
var end = value.indexOf(';', start);
|
2013-11-24 21:50:46 +01:00
|
|
|
if (end == -1)
|
|
|
|
end = value.length;
|
|
|
|
|
|
|
|
return unescape(value.substring(start, end));
|
|
|
|
}
|
|
|
|
|
|
|
|
function rememberLastSearchQuery()
|
|
|
|
{
|
|
|
|
//lastSearchQuery variable is obtained from layout
|
|
|
|
setCookie('last-search-query', lastSearchQuery);
|
|
|
|
}
|
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
//core functionalities, prototypes
|
2014-05-15 23:11:53 +02:00
|
|
|
function getJSON(data)
|
|
|
|
{
|
|
|
|
if (typeof(data.headers) === 'undefined')
|
|
|
|
data.headers = {};
|
|
|
|
data.headers['X-Ajax'] = '1';
|
|
|
|
data.type = 'GET';
|
|
|
|
return $.ajax(data);
|
|
|
|
};
|
|
|
|
|
|
|
|
function postJSON(data)
|
|
|
|
{
|
|
|
|
if (typeof(data.headers) === 'undefined')
|
|
|
|
data.headers = {};
|
|
|
|
data.headers['X-Ajax'] = '1';
|
|
|
|
data.type = 'POST';
|
|
|
|
return $.ajax(data);
|
|
|
|
};
|
|
|
|
|
2013-10-21 14:24:34 +02:00
|
|
|
$.fn.hasAttr = function(name)
|
|
|
|
{
|
2013-10-15 13:14:48 +02:00
|
|
|
return this.attr(name) !== undefined;
|
|
|
|
};
|
|
|
|
|
2014-02-19 20:46:37 +01:00
|
|
|
$.fn.bindOnce = function(name, eventName, callback)
|
|
|
|
{
|
|
|
|
$.each(this, function(i, item)
|
|
|
|
{
|
|
|
|
if ($(item).data(name) == name)
|
|
|
|
return;
|
|
|
|
$(item).data(name, name);
|
|
|
|
$(item).on(eventName, callback);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
//basic event listeners
|
|
|
|
$(function()
|
|
|
|
{
|
|
|
|
$('body').bind('dom-update', function()
|
2013-10-15 13:14:48 +02:00
|
|
|
{
|
2013-11-24 21:50:46 +01:00
|
|
|
//event confirmations
|
2013-11-05 09:17:44 +01:00
|
|
|
function confirmEvent(e)
|
2013-10-15 13:14:48 +02:00
|
|
|
{
|
2013-11-05 09:17:44 +01:00
|
|
|
if (!confirm($(this).attr('data-confirm-text')))
|
|
|
|
{
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
2013-10-15 13:14:48 +02:00
|
|
|
}
|
|
|
|
|
2014-02-19 20:46:37 +01:00
|
|
|
$('form.confirmable').bindOnce('confirmation', 'submit', confirmEvent);
|
|
|
|
$('a.confirmable').bindOnce('confirmation', 'click', confirmEvent);
|
2013-10-15 13:14:48 +02:00
|
|
|
|
2013-11-24 21:50:46 +01:00
|
|
|
|
|
|
|
//simple action buttons
|
2014-02-19 20:46:37 +01:00
|
|
|
$('a.simple-action').bindOnce('simple-action', 'click', function(e)
|
2013-11-05 09:17:44 +01:00
|
|
|
{
|
2014-02-19 20:46:37 +01:00
|
|
|
if (e.isPropagationStopped())
|
2013-11-05 09:17:44 +01:00
|
|
|
return;
|
2013-10-15 13:14:48 +02:00
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
e.preventDefault();
|
2013-11-24 21:50:46 +01:00
|
|
|
rememberLastSearchQuery();
|
2013-10-15 13:14:48 +02:00
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
var aDom = $(this);
|
|
|
|
if (aDom.hasClass('inactive'))
|
|
|
|
return;
|
|
|
|
aDom.addClass('inactive');
|
2013-10-15 13:14:48 +02:00
|
|
|
|
2014-05-15 23:11:53 +02:00
|
|
|
var url = $(this).attr('href');
|
|
|
|
postJSON({ url: url }).success(function(data)
|
2013-10-15 13:14:48 +02:00
|
|
|
{
|
2014-05-01 22:29:36 +02:00
|
|
|
if (aDom.hasAttr('data-redirect-url'))
|
|
|
|
window.location.href = aDom.attr('data-redirect-url');
|
|
|
|
else if (aDom.data('callback'))
|
|
|
|
aDom.data('callback')();
|
2013-10-15 13:14:48 +02:00
|
|
|
else
|
2014-05-01 22:29:36 +02:00
|
|
|
window.location.reload();
|
|
|
|
}).error(function(xhr)
|
|
|
|
{
|
|
|
|
alert(xhr.responseJSON
|
|
|
|
? xhr.responseJSON.message
|
|
|
|
: 'Fatal error');
|
|
|
|
aDom.removeClass('inactive');
|
2013-11-05 09:17:44 +01:00
|
|
|
});
|
2013-10-15 13:14:48 +02:00
|
|
|
});
|
2013-10-17 22:57:32 +02:00
|
|
|
|
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
//attach data from submit buttons to forms before .submit() gets called
|
2013-11-30 14:22:49 +01:00
|
|
|
$('.submit').each(function()
|
2013-10-17 22:57:32 +02:00
|
|
|
{
|
2014-02-19 20:46:37 +01:00
|
|
|
$(this).bindOnce('submit-faux-input', 'click', function()
|
2013-11-05 09:17:44 +01:00
|
|
|
{
|
|
|
|
var form = $(this).closest('form');
|
|
|
|
form.find('.faux-submit').remove();
|
|
|
|
var input = $('<input class="faux-submit" type="hidden"/>').attr({
|
|
|
|
name: $(this).attr('name'),
|
|
|
|
value: $(this).val()
|
|
|
|
});
|
|
|
|
form.append(input);
|
2013-10-17 22:57:32 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2013-11-24 21:50:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
//try to remember last search query
|
|
|
|
window.onbeforeunload = rememberLastSearchQuery;
|
2013-10-19 22:56:56 +02:00
|
|
|
});
|
|
|
|
|
2013-10-20 15:55:29 +02:00
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
|
2013-10-20 15:55:29 +02:00
|
|
|
//modify DOM on small viewports
|
2013-11-16 22:37:43 +01:00
|
|
|
function processSidebar()
|
2013-10-19 22:56:56 +02:00
|
|
|
{
|
2014-01-06 19:25:27 +01:00
|
|
|
if ($('#small-screen').is(':visible'))
|
2013-10-19 22:56:56 +02:00
|
|
|
$('#sidebar').insertAfter($('#inner-content'));
|
|
|
|
else
|
2013-10-20 15:55:29 +02:00
|
|
|
$('#sidebar').insertBefore($('#inner-content'));
|
2013-11-16 22:37:43 +01:00
|
|
|
}
|
2013-10-21 14:24:34 +02:00
|
|
|
$(function()
|
|
|
|
{
|
2013-11-16 22:37:43 +01:00
|
|
|
$(window).resize(function()
|
|
|
|
{
|
2014-02-16 12:33:31 +01:00
|
|
|
fixSize();
|
2013-11-16 22:37:43 +01:00
|
|
|
if ($('body').width() == $('body').data('last-width'))
|
|
|
|
return;
|
2013-11-19 20:20:16 +01:00
|
|
|
$('body').data('last-width', $('body').width());
|
|
|
|
$('body').trigger('dom-update');
|
2013-11-16 22:37:43 +01:00
|
|
|
});
|
|
|
|
$('body').bind('dom-update', processSidebar);
|
2014-02-16 12:33:31 +01:00
|
|
|
fixSize();
|
2013-10-21 14:24:34 +02:00
|
|
|
});
|
|
|
|
|
2014-02-16 12:33:31 +01:00
|
|
|
var fixedEvenOnce = false;
|
|
|
|
function fixSize()
|
|
|
|
{
|
2014-04-08 17:06:00 +02:00
|
|
|
if ($('#small-screen').is(':visible'))
|
|
|
|
return;
|
2014-02-16 12:33:31 +01:00
|
|
|
var multiply = 168;
|
|
|
|
var oldWidth = $('.main-wrapper:eq(0)').width();
|
|
|
|
$('.main-wrapper:eq(0)').width('');
|
|
|
|
var newWidth = $('.main-wrapper:eq(0)').width();
|
|
|
|
if (oldWidth != newWidth || !fixedEvenOnce)
|
|
|
|
{
|
|
|
|
$('.main-wrapper').width(multiply * Math.floor(newWidth / multiply));
|
|
|
|
fixedEvenOnce = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-21 14:24:34 +02:00
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
|
2013-10-21 14:24:34 +02:00
|
|
|
//autocomplete
|
|
|
|
function split(val)
|
|
|
|
{
|
|
|
|
return val.split(/\s+/);
|
|
|
|
}
|
|
|
|
|
2014-02-18 21:15:00 +01:00
|
|
|
function retrieveTags(searchTerm, cb)
|
|
|
|
{
|
2014-05-15 23:11:53 +02:00
|
|
|
var options =
|
2014-02-18 21:15:00 +01:00
|
|
|
{
|
2014-05-15 23:11:53 +02:00
|
|
|
url: '/tags-autocomplete',
|
|
|
|
data: { search: searchTerm }
|
|
|
|
};
|
|
|
|
getJSON(options)
|
|
|
|
.success(function(data)
|
2014-02-18 21:15:00 +01:00
|
|
|
{
|
2014-05-15 23:11:53 +02:00
|
|
|
var tags = $.map(data.tags.slice(0, 15), function(tag)
|
2014-02-18 21:15:00 +01:00
|
|
|
{
|
2014-05-15 23:11:53 +02:00
|
|
|
var ret =
|
|
|
|
{
|
|
|
|
label: tag.name + ' (' + tag.count + ')',
|
|
|
|
value: tag.name,
|
|
|
|
};
|
|
|
|
return ret;
|
|
|
|
});
|
2014-02-18 21:15:00 +01:00
|
|
|
|
2014-05-15 23:11:53 +02:00
|
|
|
cb(tags);
|
|
|
|
});
|
2014-02-18 21:15:00 +01:00
|
|
|
}
|
|
|
|
|
2013-10-21 14:24:34 +02:00
|
|
|
$(function()
|
|
|
|
{
|
2013-11-24 23:30:06 +01:00
|
|
|
$('.autocomplete').each(function()
|
2013-10-29 09:04:42 +01:00
|
|
|
{
|
2013-11-27 17:44:52 +01:00
|
|
|
var options =
|
2013-10-21 14:24:34 +02:00
|
|
|
{
|
2013-10-21 15:07:27 +02:00
|
|
|
minLength: 1,
|
2013-10-21 14:24:34 +02:00
|
|
|
source: function(request, response)
|
|
|
|
{
|
2014-03-10 00:13:10 +01:00
|
|
|
var terms = split(request.term);
|
|
|
|
var term = terms.pop();
|
2013-10-27 23:14:48 +01:00
|
|
|
if (term != '')
|
2014-02-18 21:15:00 +01:00
|
|
|
retrieveTags(term, response);
|
2013-10-21 14:24:34 +02:00
|
|
|
},
|
2013-11-30 00:09:15 +01:00
|
|
|
focus: function(e)
|
2013-10-21 14:24:34 +02:00
|
|
|
{
|
|
|
|
// prevent value inserted on focus
|
2013-11-30 00:09:15 +01:00
|
|
|
e.preventDefault();
|
2013-10-21 14:24:34 +02:00
|
|
|
},
|
2013-11-30 00:09:15 +01:00
|
|
|
select: function(e, ui)
|
2013-10-21 14:24:34 +02:00
|
|
|
{
|
2013-11-30 00:09:15 +01:00
|
|
|
e.preventDefault();
|
2013-10-21 14:24:34 +02:00
|
|
|
var terms = split(this.value);
|
|
|
|
terms.pop();
|
|
|
|
terms.push(ui.item.value);
|
|
|
|
terms.push('');
|
|
|
|
this.value = terms.join(' ');
|
|
|
|
}
|
2013-11-27 17:44:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
if ($(this).parents('#top-nav').length != 0)
|
|
|
|
{
|
|
|
|
options['position'] =
|
|
|
|
{
|
|
|
|
my: 'right top',
|
|
|
|
at: 'right bottom'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
var searchInput = $(this);
|
|
|
|
searchInput
|
|
|
|
// don't navigate away from the field on tab when selecting an item
|
2013-11-30 00:09:15 +01:00
|
|
|
.bind('keydown', function(e)
|
2013-11-27 17:44:52 +01:00
|
|
|
{
|
2013-11-30 00:09:15 +01:00
|
|
|
if (e.keyCode === $.ui.keyCode.TAB && $(this).data('autocomplete').menu.active)
|
|
|
|
e.preventDefault();
|
2013-11-27 17:44:52 +01:00
|
|
|
}).autocomplete(options);
|
2013-10-29 09:04:42 +01:00
|
|
|
});
|
2013-10-21 14:24:34 +02:00
|
|
|
});
|
2013-10-21 14:48:28 +02:00
|
|
|
|
2014-03-10 01:15:33 +01:00
|
|
|
function attachTagIt(target)
|
2013-10-21 14:48:28 +02:00
|
|
|
{
|
2014-02-18 21:15:00 +01:00
|
|
|
var tagItOptions =
|
|
|
|
{
|
2013-10-21 14:48:28 +02:00
|
|
|
caseSensitive: false,
|
2014-03-10 01:15:33 +01:00
|
|
|
onTagClicked: function(e, ui)
|
|
|
|
{
|
|
|
|
var targetTagit = ui.tag.parents('.tagit');
|
2014-03-10 16:14:00 +01:00
|
|
|
var context = target.tagit('assignedTags');
|
2014-05-15 23:11:53 +02:00
|
|
|
var options =
|
|
|
|
{
|
|
|
|
url: '/tags-related',
|
|
|
|
data:
|
|
|
|
{
|
|
|
|
context: context,
|
|
|
|
tag: ui.tagLabel
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if (targetTagit.siblings('.related-tags:eq(0)').data('for') == options.data.tag)
|
2014-03-10 01:15:33 +01:00
|
|
|
{
|
|
|
|
targetTagit.siblings('.related-tags').slideUp(function()
|
|
|
|
{
|
|
|
|
$(this).remove();
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-05-15 23:11:53 +02:00
|
|
|
getJSON(options).success(function(data)
|
2014-03-10 01:15:33 +01:00
|
|
|
{
|
|
|
|
var list = $('<ul>');
|
2014-03-10 16:14:00 +01:00
|
|
|
$.each(data.tags, function(i, tag)
|
2014-03-10 01:15:33 +01:00
|
|
|
{
|
|
|
|
var link = $('<a>');
|
2014-03-10 01:37:26 +01:00
|
|
|
link.attr('href', '/posts/' + tag.name + '/');
|
2014-03-10 01:15:33 +01:00
|
|
|
link.text('#' + tag.name);
|
|
|
|
link.click(function(e)
|
|
|
|
{
|
|
|
|
e.preventDefault();
|
|
|
|
target.tagit('createTag', tag.name);
|
|
|
|
});
|
|
|
|
list.append(link.wrap('<li/>').parent());
|
|
|
|
});
|
|
|
|
targetTagit.siblings('.related-tags').slideUp(function()
|
|
|
|
{
|
|
|
|
$(this).remove();
|
|
|
|
});
|
|
|
|
var div = $('<div>');
|
|
|
|
div.data('for', options.tag);
|
|
|
|
div.addClass('related-tags');
|
|
|
|
div.append('<p>Related tags:</p>');
|
|
|
|
div.append(list);
|
2014-03-10 01:37:26 +01:00
|
|
|
div.append('<div class="clear"></div>');
|
2014-03-10 01:15:33 +01:00
|
|
|
div.insertAfter(targetTagit).hide().slideDown();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2013-10-21 14:48:28 +02:00
|
|
|
autocomplete:
|
|
|
|
{
|
|
|
|
source:
|
|
|
|
function(request, response)
|
|
|
|
{
|
2014-02-18 21:15:00 +01:00
|
|
|
var tagit = this;
|
2014-03-10 00:13:10 +01:00
|
|
|
//var context = tagit.element.tagit('assignedTags');
|
2014-02-18 21:15:00 +01:00
|
|
|
retrieveTags(request.term.toLowerCase(), function(tags)
|
2013-10-21 14:48:28 +02:00
|
|
|
{
|
2014-02-18 21:15:00 +01:00
|
|
|
if (!tagit.options.allowDuplicates)
|
|
|
|
{
|
|
|
|
tags = $.grep(tags, function(tag)
|
|
|
|
{
|
|
|
|
return tagit.assignedTags().indexOf(tag.value) == -1;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
response(tags);
|
2013-10-21 14:48:28 +02:00
|
|
|
});
|
|
|
|
},
|
|
|
|
}
|
|
|
|
};
|
2014-02-18 21:15:00 +01:00
|
|
|
|
2014-03-10 01:15:33 +01:00
|
|
|
tagItOptions.placeholderText = target.attr('placeholder');
|
|
|
|
target.tagit(tagItOptions);
|
2013-10-21 14:48:28 +02:00
|
|
|
}
|
2013-10-25 15:41:09 +02:00
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
|
|
|
|
|
2014-03-05 22:14:30 +01:00
|
|
|
//prevent keybindings from executing when flash posts are focused
|
|
|
|
var oldMousetrapBind = Mousetrap.bind;
|
|
|
|
Mousetrap.bind = function(key, func, args)
|
|
|
|
{
|
|
|
|
oldMousetrapBind(key, function()
|
|
|
|
{
|
|
|
|
if ($(document.activeElement).parents('.post-type-flash').length > 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
func();
|
|
|
|
}, args);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-05 09:17:44 +01:00
|
|
|
//hotkeys
|
2013-10-25 15:41:09 +02:00
|
|
|
$(function()
|
|
|
|
{
|
2014-03-05 22:14:30 +01:00
|
|
|
Mousetrap.bind('q', function()
|
|
|
|
{
|
|
|
|
$('#top-nav input').focus();
|
|
|
|
return false;
|
|
|
|
}, 'keyup');
|
|
|
|
|
|
|
|
Mousetrap.bind('w', function()
|
|
|
|
{
|
|
|
|
$('body,html').animate({scrollTop: '-=150px'}, 200);
|
|
|
|
});
|
|
|
|
|
|
|
|
Mousetrap.bind('s', function()
|
|
|
|
{
|
|
|
|
$('body,html').animate({scrollTop: '+=150px'}, 200);
|
|
|
|
});
|
|
|
|
|
|
|
|
Mousetrap.bind('a', function()
|
|
|
|
{
|
|
|
|
var url = $('.paginator:visible .prev:not(.disabled) a').attr('href');
|
|
|
|
if (typeof url !== 'undefined')
|
|
|
|
window.location.href = url;
|
|
|
|
}, 'keyup');
|
|
|
|
|
|
|
|
Mousetrap.bind('d', function()
|
|
|
|
{
|
|
|
|
var url = $('.paginator:visible .next:not(.disabled) a').attr('href');
|
|
|
|
if (typeof url !== 'undefined')
|
|
|
|
window.location.href = url;
|
|
|
|
}, 'keyup');
|
|
|
|
|
|
|
|
Mousetrap.bind('p', function()
|
|
|
|
{
|
|
|
|
$('.post a').eq(0).focus();
|
|
|
|
return false;
|
|
|
|
}, 'keyup');
|
2013-10-25 15:41:09 +02:00
|
|
|
});
|
2014-02-01 10:10:09 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function enableExitConfirmation()
|
|
|
|
{
|
|
|
|
$(window).bind('beforeunload', function(e)
|
|
|
|
{
|
2014-02-16 18:57:37 +01:00
|
|
|
return 'There are unsaved changes.';
|
2014-02-01 10:10:09 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function disableExitConfirmation()
|
|
|
|
{
|
|
|
|
$(window).unbind('beforeunload');
|
|
|
|
}
|