app/assets/javascripts/widgets/views/ShareWidgetView.js
/**
* The ShareWidgetView selector view.
*
* @return ShareWidgetView instance (extends Backbone.View).
*/
define(
[
'backbone',
'underscore',
'handlebars',
'mps',
'text!templates/share-widget.handlebars',
'widgets/presenters/ShareWidgetPresenter'
],
function(Backbonoe, _, Handlebars, mps, tpl, Presenter) {
'use strict';
var ShareModel = Backbone.Model.extend({
defaults: {
hidden: true,
type: 'link',
url: null,
widget: null
}
});
var ShareWidgetView = Backbone.View.extend({
el: '#shareWidgetView',
className: 'share-modal mini-modal',
template: Handlebars.compile(tpl),
events: {
'click .js-close-share': 'hide',
'click .js-type-share': 'changeType',
'click .js-copy-share': 'copyUrl',
'focus .js-input-share': 'selectUrl',
'click .js-social-share': 'openPopup'
},
initialize: function(parent) {
this.presenter = new Presenter();
this.model = new ShareModel();
this.render();
this.listeners();
},
// Render & cache & listeners //
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.cache();
this.setOptions();
// Reset the interval
this.resetIframeInterval();
},
cache: function() {
this.$body = $('body');
this.$input = this.$el.find('#share-field');
this.$iframeBox = this.$el.find('#share-iframe-box');
// Social links
this.$twitterLink = this.$('.twitter');
this.$facebookLink = this.$('.facebook');
this.$googleplusLink = this.$('.google_plus');
},
listeners: function() {
this.model.on('change:hidden', this.toggle, this);
this.model.on('change:type', this.render, this);
this.model.on('change:url', this.setInput, this);
// Everytime we click inside an .js-open-share we will show the modal
this.$body.on('click', '.js-open-share', _.bind(this.show, this));
},
// Show, hide and toggle //
show: function(e) {
e && e.preventDefault();
this.model.set('widget', $(e.currentTarget).data('widget'));
this.model.set('slugshare', $(e.currentTarget).data('slugshare'));
this.model.set('hidden', false);
},
hide: function(e) {
e && e.preventDefault();
this.model.set('hidden', true);
this.model.set('type', 'link');
},
toggle: function() {
var is_hidden = this.model.get('hidden');
if (is_hidden) {
this.$el.hide(0);
this.unbindings();
} else {
this.$el.show(0);
this.bindings();
}
// Iframe height interval
this.resetIframeInterval();
},
// Bindings //
bindings: function() {
$(document).on(
'keyup.share',
function(e) {
if (e.keyCode === 27) {
this.hide();
}
}.bind(this)
);
},
unbindings: function() {
$(document).off('keyup.share');
},
// SETTERS
// Set options
setOptions: function(e) {
this.setUrl(e);
},
setUrl: function(e) {
switch (this.model.get('type')) {
case 'link':
this.setUrlLink();
break;
case 'embed':
this.setUrlEmbed(e);
break;
}
},
setInput: function() {
this.$input.val(this.model.get('url'));
if (this.model.get('type') == 'embed') {
this.$iframeBox.append(this.model.get('url'));
this.resizeIframeHeight();
}
},
// LINK
setUrlLink: function() {
this.getBitlyLink(
window.location.href,
function(url) {
this.model.set('url', url);
this.setSocialLinks();
}.bind(this)
);
ga('send', 'event', 'Map', 'Share', 'Share Link clicked');
},
getBitlyLink: function(url, callback) {
$.ajax({
url:
'https://api-ssl.bitly.com/v3/shorten?longUrl=' +
encodeURIComponent(url) +
'&login=simbiotica&apiKey=R_33ced8db36b545829eefeb644f4c3d19',
type: 'GET',
async: false,
dataType: 'jsonp',
success: function(r) {
if (!r.data.url) {
callback && callback(url);
throw new Error(
"BITLY doesn't allow localhost alone as domain, use localhost.lan for example"
);
} else {
callback && callback(r.data.url);
}
},
error: function() {
callback && callback(url);
}
});
},
// EMBED
setUrlEmbed: function(e) {
var url = this.getEmbedLink();
this.model.set('url', url);
},
getEmbedLink: function() {
var width = 500;
var height = 600;
var url =
window.location.protocol +
'//' +
window.location.host +
'/embed/countries/' +
this.model.get('slugshare') +
'/' +
this.model.get('widget');
return (
'<iframe id="share-iframe" width="' +
width +
'" height="' +
height +
'" frameborder="0" src="' +
url +
'"></iframe>'
);
},
// SOCIAL
setSocialLinks: function() {
this.$twitterLink.attr(
'href',
'https://twitter.com/share?url=' + this.model.get('url')
);
this.$facebookLink.attr(
'href',
'https://www.facebook.com/sharer.php?u=' + this.model.get('url')
);
this.$googleplusLink.attr(
'href',
'https://plus.google.com/share?url=' + this.model.get('url')
);
},
// UI EVENTS
changeType: function(e) {
e && e.preventDefault();
this.model.set('type', $(e.currentTarget).data('type'));
},
copyUrl: function(e) {
this.$input.select();
try {
var successful = document.execCommand('copy');
$(e.currentTarget).html('copied');
} catch (err) {
mps.publish('Notification/open', ['not-clipboard-support']);
}
},
selectUrl: function(e) {
this.$input.select();
},
openPopup: function(e) {
e && e.preventDefault();
var width = 575,
height = 400,
left = ($(window).width() - width) / 2,
top = ($(window).height() - height) / 2,
url = $(e.currentTarget).attr('href'),
opts =
'status=1' +
',width=' +
width +
',height=' +
height +
',top=' +
top +
',left=' +
left;
window.open(url, 'Share this map view', opts);
},
resizeIframeHeight: function() {
var iframe = document.getElementById('share-iframe');
// For other good browsers.
this.$iframeBox.find('iframe').load(
function() {
// Set inline style to equal the body height of the iframed content.
var iPrevHeight = 0;
this.iframeInterval = setInterval(
function() {
var iHeight = iframe.contentWindow.document.body.offsetHeight;
if (iHeight > 100 && iPrevHeight != iHeight) {
iframe.style.height = iHeight + 'px';
iPrevHeight = iHeight;
}
}.bind(this),
500
);
}.bind(this)
);
},
resetIframeInterval: function() {
if (!!this.iframeInterval) {
clearInterval(this.iframeInterval);
}
}
});
return ShareWidgetView;
}
);