widgets/Share.js
define([
'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'gis/dijit/_FloatingWidgetMixin',
'dojo/_base/lang',
'dojo/on',
'dojo/topic',
'dojo/dom-attr',
'dojo/dom-construct',
'dojo/number',
'dojo/_base/event',
'esri/request',
'esri/urlUtils',
'esri/geometry/Extent',
// template
'dojo/text!./Share/templates/Share.html',
//i18n
'dojo/i18n!./Share/nls/Share',
//template widgets
'dijit/form/CheckBox',
// css
'xstyle/css!./Share/css/Share.css'
], function (
declare,
_WidgetBase,
_TemplatedMixin,
_WidgetsInTemplateMixin,
_FloatingWidgetMixin,
lang,
on,
topic,
domAttr,
domConstruct,
number,
event,
esriRequest,
urlUtils,
Extent,
template,
i18n
) {
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], {
name: 'Share',
baseClass: 'cmvShareWidget',
widgetsInTemplate: true,
templateString: template,
mapClickMode: null,
// i18n
i18n: i18n,
url: window.location.href,
mailURL: 'mailto:%20?subject={title}&body={summary}%20{url}',
facebookURL: 'https://www.facebook.com/sharer/sharer.php?s=100&p[url]={url}&p[images][0]={image}&p[title]={title}&p[summary]={summary}',
twitterURL: 'https://twitter.com/intent/tweet?url={url}&text={title}&hashtags={hashtags}',
googlePlusURL: 'https://plus.google.com/share?url={url}',
bitlyAPI: location.protocol === 'https:' ? 'https://api-ssl.bitly.com/v3/shorten' : 'http://api.bit.ly/v3/shorten',
bitlyLogin: '',
bitlyKey: '',
title: '',
image: '',
summary: '',
hashtags: '',
windowSpecs: 'height=500, width=700, scrollbars=false',
embedHeight: null,
embedWidth: null,
embedSizes: [
{
'width': '100%',
'height': '640px'
}, {
'width': '100%',
'height': '480px'
}, {
'width': '100%',
'height': '320px'
}, {
'width': '800px',
'height': '600px'
}, {
'width': '640px',
'height': '480px'
}, {
'width': '480px',
'height': '320px'
}
],
useExtent: false,
extentEvt: null,
draggable: true,
postCreate: function () {
this.inherited(arguments);
if (!this.parentWidget.toggleable) {
this.parentWidget.draggable = this.draggable;
}
this.own(on(this.extentInput, 'click', lang.hitch(this, this.useExtentUpdate)));
this.setExtentChecked();
this.watch('url', this.updateUrl);
this.watch('embedSizes', this.setSizeOptions);
this.watch('embed', this.updateEmbed);
this.watch('bitlyUrl', this.updateBitlyUrl);
this.watch('useExtent', this.useExtentChanged);
this.updateUrl();
this.shareLink();
},
startup: function () {
this.inherited(arguments);
// set sizes for select box
this.setSizeOptions();
// handle any query string parameters
// like zoom to extent
this.handeQueryParameters();
// set embed url
this.updateUrl();
// update the widget user interface
this.updateUI();
},
handeQueryParameters: function () {
var urlObject = urlUtils.urlToObject(window.location.href);
urlObject.query = urlObject.query || {};
if (urlObject.query.extent) {
var vals = urlObject.query.extent.split(',');
if (vals.length === 4 && !isNaN(vals[0]) && !isNaN(vals[1]) && !isNaN(vals[2]) && !isNaN(vals[3])) {
// assumes lat/lng
var extent = new Extent({
xmin: number.parse(vals[0]),
ymin: number.parse(vals[1]),
xmax: number.parse(vals[2]),
ymax: number.parse(vals[3]),
spatialReference: {
wkid: 4326
}
});
this.map.setExtent(extent);
}
}
},
updateUI: function () {
// select menu change
this.own(on(this.comboBoxNode, 'change', lang.hitch(this, function (evt) {
this.set('embedWidth', this.get('embedSizes')[parseInt(evt.currentTarget.value, 10)].width);
this.set('embedHeight', this.get('embedSizes')[parseInt(evt.currentTarget.value, 10)].height);
this.setEmbedCode();
})));
// facebook click
this.own(on(this.facebookButton, 'click', lang.hitch(this, function () {
this.configureShareLink(this.get('facebookURL'));
})));
// twitter click
this.own(on(this.twitterButton, 'click', lang.hitch(this, function () {
this.configureShareLink(this.get('twitterURL'));
})));
// google plus click
this.own(on(this.gplusButton, 'click', lang.hitch(this, function () {
this.configureShareLink(this.get('googlePlusURL'));
})));
// email click
this.own(on(this.emailButton, 'click', lang.hitch(this, function () {
this.configureShareLink(this.get('mailURL'), true);
})));
// link click
this.own(on(this.linkButton, 'click', lang.hitch(this, function () {
this.configureShareLink(this.get('url'), false, true);
})));
// link box click
this.own(on(this.shareMapUrlText, 'click', lang.hitch(this, function () {
this.shareMapUrlText.setSelectionRange(0, 9999);
})));
// link box mouseup stop for touch devices
this.own(on(this.shareMapUrlText, 'mouseup', function (evt) {
event.stop(evt);
}));
// embed box click
this.own(on(this.embedNode, 'click', lang.hitch(this, function () {
this.embedNode.setSelectionRange(0, 9999);
})));
// embed box mouseup stop for touch devices
this.own(on(this.embedNode, 'mouseup', function (evt) {
event.stop(evt);
}));
},
updateUrl: function () {
// nothing currently shortened
this.shortened = null;
// no bitly shortened
this.set('bitlyUrl', null);
// vars
var map = this.get('map'),
url = this.get('url'),
useSeparator = null;
// get url params
var urlObject = urlUtils.urlToObject(window.location.href);
urlObject.query = urlObject.query || {};
// include extent in url
if (this.get('useExtent') && map) {
// get map extent in geographic
var gExtent = map.geographicExtent;
// set extent string
urlObject.query.extent = gExtent.xmin.toFixed(6) + ',' + gExtent.ymin.toFixed(6) + ',' + gExtent.xmax.toFixed(6) + ',' + gExtent.ymax.toFixed(6);
} else {
urlObject.query.extent = null;
}
// create base url
url = window.location.protocol + '//' + window.location.host + window.location.pathname;
// each param
for (var i in urlObject.query) {
if (urlObject.query[i] && urlObject.query[i] !== 'config') {
// use separator
if (useSeparator) {
url += '&';
} else {
url += '?';
useSeparator = true;
}
url += i + '=' + urlObject.query[i];
}
}
// update url
this.set('url', url);
// reset embed code
this.setEmbedCode();
// set url value
domAttr.set(this.shareMapUrlText, 'value', url);
},
updateEmbed: function () {
domAttr.set(this.embedNode, 'value', this.get('embed'));
},
setEmbedCode: function () {
var es = '<iframe width=\'' + this.get('embedWidth') + '\' height=\'' + this.get('embedHeight') + '\' src=\'' + this.get('url') + '\' frameborder=\'0\' scrolling=\'no\'></iframe>';
this.set('embed', es);
},
setExtentChecked: function () {
this.extentInput.setValue(this.useExtent);
if (this.useExtent) {
this.extentEvt = this.own(this.map.on('extent-change', lang.hitch(this, function () {
this.updateUrl();
})));
} else if (this.extentEvt && this.extentEvt.remove) {
this.extentEvt.remove();
}
},
useExtentUpdate: function () {
this.set('useExtent', this.extentInput.getValue());
},
useExtentChanged: function () {
this.updateUrl();
this.shareLink();
this.setExtentChecked();
},
setSizeOptions: function () {
// clear select menu
this.comboBoxNode.innerHTML = '';
// if embed sizes exist
if (this.get('embedSizes') && this.get('embedSizes').length) {
// map sizes
for (var i = 0; i < this.get('embedSizes').length; i++) {
if (i === 0) {
this.set('embedWidth', this.get('embedSizes')[i].width);
this.set('embedHeight', this.get('embedSizes')[i].height);
}
var option = domConstruct.create('option', {
value: i,
innerHTML: this.get('embedSizes')[i].width + ' x ' + this.get('embedSizes')[i].height
});
domConstruct.place(option, this.comboBoxNode, 'last');
}
}
},
updateBitlyUrl: function () {
var bitly = this.get('bitlyUrl');
if (bitly) {
domAttr.set(this.shareMapUrlText, 'value', bitly);
domAttr.set(this.linkButton, 'href', bitly);
}
},
shareLink: function () {
if (this.get('bitlyAPI') && this.get('bitlyLogin') && this.get('bitlyKey')) {
var currentUrl = this.get('url');
// not already shortened
if (currentUrl !== this.shortened) {
// set shortened
this.shortened = currentUrl;
// make request
esriRequest({
url: this.get('bitlyAPI'),
callbackParamName: 'callback',
content: {
uri: currentUrl,
login: this.get('bitlyLogin'),
apiKey: this.get('bitlyKey'),
f: 'json'
},
load: lang.hitch(this, function (response) {
if (response && response.data && response.data.url) {
this.set('bitlyUrl', response.data.url);
}
}),
error: function (error) {
topic.publish('viewer/handerError', {
error: error
});
}
});
}
}
},
configureShareLink: function (Link, isMail, isLink) {
// replace strings
var fullLink = lang.replace(Link, {
url: encodeURIComponent(this.get('bitlyUrl') ? this.get('bitlyUrl') : this.get('url')),
image: encodeURIComponent(this.get('image')),
title: encodeURIComponent(this.get('title')),
summary: encodeURIComponent(this.get('summary')),
hashtags: encodeURIComponent(this.get('hashtags'))
});
// email link
if (isMail) {
window.location.href = fullLink;
// just a normal link
} else if (isLink) {
window.open(fullLink);
} else {
window.open(fullLink, 'cmvShare', this.get('windowSpecs'));
}
}
});
});