279 lines
10 KiB
JavaScript
279 lines
10 KiB
JavaScript
(function(Site) {
|
|
|
|
var Snipt = snipt.module('snipt');
|
|
|
|
Backbone.oldSync = Backbone.sync;
|
|
Backbone.Model.prototype.idAttribute = 'resource_uri';
|
|
var addSlash = function(str) {
|
|
return str + ((str.length > 0 && str.charAt(str.length - 1) === '/') ? '' : '/');
|
|
};
|
|
Backbone.sync = function(method, model, options) {
|
|
options.headers = _.extend({
|
|
'Authorization': 'ApiKey ' + window.user + ':' + window.api_key
|
|
}, options.headers);
|
|
return Backbone.oldSync(method, model, options);
|
|
};
|
|
Backbone.Model.prototype.url = function() {
|
|
var url = this.id;
|
|
if (!url) {
|
|
url = this.urlRoot;
|
|
url = url || this.collection && (_.isFunction(this.collection.url) ? this.collection.url() : this.collection.url);
|
|
|
|
if (url && this.has('id')) {
|
|
url = addSlash(url) + this.get('id');
|
|
}
|
|
}
|
|
url = url && addSlash(url);
|
|
|
|
if (typeof url === 'undefined') {
|
|
url = '/api/private/snipt/';
|
|
this.unset('id', {'silent': true});
|
|
this.unset('user', {'silent': true});
|
|
}
|
|
return url || null;
|
|
};
|
|
|
|
Site.SiteView = Backbone.View.extend({
|
|
el: 'body',
|
|
|
|
initialize: function(opts) {
|
|
this.$body = $(this.el);
|
|
this.$html = $('html');
|
|
this.$html_body = this.$body.add(this.$html);
|
|
this.$aside_main = $('aside.main', this.$body);
|
|
this.$aside_nav = $('aside.nav', this.$body);
|
|
this.$teams_nav = $('li.teams-nav', this.$body);
|
|
this.$add_snipt = $('li.add-snipt', this.$body);
|
|
this.$aside_nav_ul = $('ul', this.$aside_nav);
|
|
this.$search_form = $('form.search', this.$body);
|
|
this.$search_query = $('input#search-query', this.$body);
|
|
this.$search_page_query = $('input.search-query', this.$body);
|
|
this.$search_queries = this.$search_query.add(this.$search_page_query);
|
|
this.$snipts = $('section#snipts article.snipt', this.$body);
|
|
this.$modals = $('div.modal', this.$snipts);
|
|
this.$main_edit = $('section#main-edit');
|
|
this.$main = $('section#main');
|
|
this.$keyboard_shortcuts = $('#keyboard-shortcuts', this.$body);
|
|
|
|
this.keyboardShortcuts();
|
|
this.inFieldLabels();
|
|
|
|
var SniptListView = Snipt.SniptListView;
|
|
this.snipt_list = new SniptListView({ 'snipts': this.$snipts });
|
|
|
|
var that = this;
|
|
|
|
this.$body.click(function() {
|
|
if (!window.ui_halted && !window.from_modal && window.$selected) {
|
|
window.$selected.trigger('deselect');
|
|
}
|
|
if (window.from_modal) {
|
|
window.from_modal = false;
|
|
}
|
|
that.$aside_nav.removeClass('open');
|
|
that.$teams_nav.removeClass('open');
|
|
that.$add_snipt.removeClass('open');
|
|
});
|
|
|
|
this.$aside_nav_ul.click(function(e) {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
$search_queries = this.$search_queries;
|
|
$search_queries.focus(function() {
|
|
if (window.$selected) {
|
|
$selected.trigger('deselect');
|
|
}
|
|
});
|
|
|
|
this.$body.on('click', 'a.close', function() {
|
|
$(this).parent().parent().modal('hide');
|
|
window.ui_halted = false;
|
|
return false;
|
|
});
|
|
|
|
this.$keyboard_shortcuts.on('hidden', function() {
|
|
window.ui_halted = false;
|
|
});
|
|
|
|
if (this.$body.hasClass('pro-signup')) {
|
|
var $form = $('form#pro-signup');
|
|
var $submit = $('button[type="submit"]', $form);
|
|
|
|
var $cardNumber = $('input#number');
|
|
var $expMonth = $('select#exp-month');
|
|
var $expYear = $('select#exp-year');
|
|
var $cvc = $('input#cvc');
|
|
|
|
$form.submit(function() {
|
|
|
|
$submit.attr('disabled', 'disabled');
|
|
|
|
var errors = false;
|
|
|
|
if (!Stripe.validateCardNumber($cardNumber.val())) {
|
|
$cardNumber.parents('div.control-group').addClass('error');
|
|
errors = true;
|
|
} else {
|
|
$cardNumber.parents('div.control-group').removeClass('error');
|
|
}
|
|
|
|
if (!Stripe.validateExpiry($expMonth.val(), $expYear.val())) {
|
|
$expMonth.parents('div.control-group').addClass('error');
|
|
errors = true;
|
|
} else {
|
|
$expMonth.parents('div.control-group').removeClass('error');
|
|
}
|
|
|
|
if (!Stripe.validateCVC($cvc.val())) {
|
|
$cvc.parents('div.control-group').addClass('error');
|
|
errors = true;
|
|
} else {
|
|
$cvc.parents('div.control-group').removeClass('error');
|
|
}
|
|
|
|
if (!errors) {
|
|
|
|
$('.payment-errors').hide();
|
|
$('.payment-loading').show();
|
|
|
|
Stripe.createToken({
|
|
number: $cardNumber.val(),
|
|
cvc: $cvc.val(),
|
|
exp_month: $expMonth.val(),
|
|
exp_year: $expYear.val()
|
|
}, that.stripeResponseHandler);
|
|
|
|
} else {
|
|
$submit.removeAttr('disabled');
|
|
}
|
|
|
|
return false;
|
|
});
|
|
}
|
|
|
|
if (this.$body.hasClass('login')) {
|
|
$('input#id_username').focus();
|
|
}
|
|
|
|
// Populate any GitTip widgets.
|
|
if (window.gittip_username) {
|
|
this.$aside_main.html(this.$aside_main.html().replace(
|
|
/\[\[.*gittip.*\]\]/,
|
|
'<iframe style="border: 0; margin: 0; padding: 0;" src="https://www.gittip.com/' + window.gittip_username + '/widget.html" width="48pt" height="22pt"></iframe>')
|
|
);
|
|
$('iframe', this.$aside_main).parent('p').prev('p').css('margin-bottom', '10px');
|
|
}
|
|
|
|
// Highlight any Markdown code.
|
|
$('div.markdown pre code').each(function(i, e) {
|
|
hljs.highlightBlock(e);
|
|
});
|
|
|
|
// Populate any embedded tweets.
|
|
var $embeddedTweets = $('div.embedded-tweet');
|
|
if ($embeddedTweets.length) {
|
|
$.each($embeddedTweets, function() {
|
|
var $tweetPlaceholder = $(this);
|
|
var tweetID = $tweetPlaceholder.attr('data-tweet-id');
|
|
|
|
$.ajax({
|
|
url: 'https://api.twitter.com/1/statuses/oembed.json?id=' + tweetID + '&align=center',
|
|
dataType: 'jsonp',
|
|
type: 'get',
|
|
success: function(resp) {
|
|
$tweetPlaceholder.replaceWith($(resp.html));
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
window.ui_halted = false;
|
|
},
|
|
events: {
|
|
'showKeyboardShortcuts': 'showKeyboardShortcuts',
|
|
'click a.mini-profile': 'toggleMiniProfile',
|
|
'click a.teams-nav': 'toggleTeamsNav'
|
|
},
|
|
|
|
keyboardShortcuts: function() {
|
|
var $body = this.$body;
|
|
|
|
var that = this;
|
|
|
|
$search_queries = this.$search_queries;
|
|
$search_page_query = this.$search_page_query;
|
|
$search_query = this.$search_query;
|
|
$document = $(document);
|
|
|
|
$document.bind('keydown', '/', function(e) {
|
|
if (!window.ui_halted) {
|
|
e.preventDefault();
|
|
if ($body.hasClass('search')) {
|
|
$search_page_query.focus();
|
|
} else {
|
|
$search_query.focus();
|
|
}
|
|
}
|
|
});
|
|
$document.bind('keydown', 'Ctrl+h', function(e) {
|
|
if (!window.ui_halted) {
|
|
window.ui_halted = true;
|
|
$body.trigger('showKeyboardShortcuts');
|
|
} else {
|
|
if (that.$keyboard_shortcuts.is(':visible')) {
|
|
that.$keyboard_shortcuts.modal('hide');
|
|
}
|
|
}
|
|
});
|
|
this.$search_queries.bind('keydown', 'esc', function(e) {
|
|
if (!window.ui_halted) {
|
|
e.preventDefault();
|
|
this.blur();
|
|
}
|
|
});
|
|
},
|
|
showKeyboardShortcuts: function() {
|
|
this.$keyboard_shortcuts.modal('toggle');
|
|
},
|
|
toggleMiniProfile: function(e) {
|
|
this.$aside_nav.toggleClass('open');
|
|
return false;
|
|
},
|
|
toggleTeamsNav: function(e) {
|
|
this.$teams_nav.toggleClass('open');
|
|
return false;
|
|
},
|
|
inFieldLabels: function () {
|
|
$('div.infield label', this.$body).inFieldLabels({
|
|
fadeDuration: 200
|
|
});
|
|
},
|
|
stripeResponseHandler: function(status, response) {
|
|
|
|
var $form = $('form#pro-signup');
|
|
|
|
if (response.error) {
|
|
$('button[type="submit"]', $form).removeAttr('disabled');
|
|
$('.payment-loading').hide();
|
|
$('.payment-errors').text(response.error.message).show();
|
|
} else {
|
|
var token = response.id;
|
|
|
|
// Kill all of the form details so none of it touches our server.
|
|
// Note, this is unnecessary, because the inputs themselves do not
|
|
// have a name attr, meaning they'll never get sent to begin with.
|
|
$('input#name').val('');
|
|
$('input#number').val('');
|
|
$('select#exp-month').val('');
|
|
$('select#exp-year').val('');
|
|
$('input#cvc').val('');
|
|
|
|
$form.append("<input type='hidden' name='token' value='" + token + "'/>");
|
|
$form.get(0).submit();
|
|
}
|
|
}
|
|
});
|
|
|
|
})(snipt.module('site'));
|