diff --git a/CHANGELOG.md b/CHANGELOG.md
index a1cd9e6..048075f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+
+# [2.2.0](https://github.com/nicolasbeauvais/vue-social-sharing/compare/2.1.5...2.2.0) (2017-03-29)
+- Internal methods refactor
+- Rename `social_shares_click` event to `social_shares_open`
+- Add `social_shares_change` and `social_shares_close` event
+
# [2.1.5](https://github.com/nicolasbeauvais/vue-social-sharing/compare/2.1.4...2.1.5) (2017-03-18)
- Vue 2.2.4 compatibility
diff --git a/README.md b/README.md
index 523cedc..6ae2f64 100644
--- a/README.md
+++ b/README.md
@@ -101,6 +101,25 @@ Prop | Data Type | Default | Description
`twitter-user` | String | | Twitter user (Twitter only).
`media` | String | | Url to a media (Pinterest only).
+#### Available events
+
+Events are emitted on the vue $root instance:
+
+Name | Data | Description
+---------------------- | -------------------------- | --------------------------------------------------------------------------
+`social_shares_open` | Network object, shared url | Fired when a sharing popup is open
+`social_shares_change` | Network object, shared url | Fired when the user open a new sharing popup while another is already open
+`social_shares_close` | Network object, shared url | Fired when a sharing popup is closed or changed by another popup
+
+You can listen to a `vue-social-sharing` event by using the following code:
+```javascript
+Vue.$root.$on('social_shares_open', function (network, url) {
+ // your event code
+});
+```
+
+> Note that the `social_shares_close` event is not fired for Whatsapp.
+
## Feature request
Feel free to open an issue to ask for a new social network support.
diff --git a/bower.json b/bower.json
index f0023d3..e718cc6 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "vue-social-sharing",
- "version": "2.1.4",
+ "version": "2.2.0",
"homepage": "https://github.com/nicolasbeauvais/vue-social-sharing",
"authors": [
"nicolasbeauvais "
diff --git a/dist/vue-social-sharing.common.js b/dist/vue-social-sharing.common.js
index 17b970f..a6b45ae 100644
--- a/dist/vue-social-sharing.common.js
+++ b/dist/vue-social-sharing.common.js
@@ -1,5 +1,5 @@
/*!
- * vue-social-sharing v2.1.4
+ * vue-social-sharing v2.2.0
* (c) 2017 nicolasbeauvais
* Released under the MIT License.
*/
@@ -46,7 +46,7 @@ var SocialSharingNetwork = {
id: context.data.attrs.id || null,
'data-link': network.type === 'popup'
? '#share-' + context.props.network
- : context.parent._getSharer(context.props.network),
+ : context.parent.createSharingUrl(context.props.network),
'data-action': network.type === 'popup' ? null : network.action
},
on: {
@@ -181,7 +181,8 @@ var SocialSharing = {
height: 436,
top: 0,
left: 0,
- window: undefined
+ window: undefined,
+ interval: null
}
};
},
@@ -192,7 +193,7 @@ var SocialSharing = {
*
* @param network Social network key.
*/
- _getSharer: function (network) {
+ createSharingUrl: function createSharingUrl (network) {
return this.networks[network].sharer
.replace(/@url/g, encodeURIComponent(this.url))
.replace(/@title/g, encodeURIComponent(this.title))
@@ -208,9 +209,9 @@ var SocialSharing = {
*
* @param string network Social network key.
*/
- share: function (network) {
- this._openSharer(this._getSharer(network));
- this.$root.$emit('social_shares_click', network, this.url);
+ share: function share (network) {
+ this.openSharer(network, this.createSharingUrl(network));
+ this.$root.$emit('social_shares_open', network, this.url);
},
/**
@@ -218,9 +219,9 @@ var SocialSharing = {
*
* @param string network Social network key.
*/
- touch: function (network) {
- window.open(this._getSharer(network), '_self');
- this.$root.$emit('social_shares_click', network, this.url);
+ touch: function touch (network) {
+ window.open(this.createSharingUrl(network), '_self');
+ this.$root.$emit('social_shares_open', network, this.url);
},
/**
@@ -228,7 +229,16 @@ var SocialSharing = {
*
* @param string url Url to share.
*/
- _openSharer: function (url) {
+ openSharer: function openSharer (network, url) {
+ var this$1 = this;
+
+ // If a popup window already exist it will be replaced, trigger a close event.
+ if (this.popup.window && this.popup.interval) {
+ clearInterval(this.popup.interval);
+ this.popup.window.close();// Force close (for Facebook)
+ this.$root.$emit('social_shares_change', network, this.url);
+ }
+
this.popup.window = window.open(
url,
'sharer',
@@ -246,13 +256,24 @@ var SocialSharing = {
',location=' + (this.popup.location ? 'yes' : 'no') +
',directories=' + (this.popup.directories ? 'yes' : 'no')
);
+
+ this.popup.window.focus();
+
+ // Create an interval to detect popup closing event
+ this.popup.interval = setInterval(function () {
+ if (this$1.popup.window.closed) {
+ clearInterval(this$1.popup.interval);
+ this$1.popup.window = undefined;
+ this$1.$root.$emit('social_shares_close', network, this$1.url);
+ }
+ }, 500);
}
},
/**
* Sets popup default dimensions.
*/
- mounted: function () {
+ mounted: function mounted () {
if (!inBrowser) {
return;
}
@@ -279,7 +300,7 @@ var SocialSharing = {
}
};
-SocialSharing.version = '2.1.4';
+SocialSharing.version = '2.2.0';
SocialSharing.install = function (Vue) {
Vue.component('social-sharing', SocialSharing);
diff --git a/dist/vue-social-sharing.js b/dist/vue-social-sharing.js
index b3cd618..e96b75b 100644
--- a/dist/vue-social-sharing.js
+++ b/dist/vue-social-sharing.js
@@ -1,5 +1,5 @@
/*!
- * vue-social-sharing v2.1.4
+ * vue-social-sharing v2.2.0
* (c) 2017 nicolasbeauvais
* Released under the MIT License.
*/
@@ -50,7 +50,7 @@ var SocialSharingNetwork = {
id: context.data.attrs.id || null,
'data-link': network.type === 'popup'
? '#share-' + context.props.network
- : context.parent._getSharer(context.props.network),
+ : context.parent.createSharingUrl(context.props.network),
'data-action': network.type === 'popup' ? null : network.action
},
on: {
@@ -185,7 +185,8 @@ var SocialSharing = {
height: 436,
top: 0,
left: 0,
- window: undefined
+ window: undefined,
+ interval: null
}
};
},
@@ -196,7 +197,7 @@ var SocialSharing = {
*
* @param network Social network key.
*/
- _getSharer: function (network) {
+ createSharingUrl: function createSharingUrl (network) {
return this.networks[network].sharer
.replace(/@url/g, encodeURIComponent(this.url))
.replace(/@title/g, encodeURIComponent(this.title))
@@ -212,9 +213,9 @@ var SocialSharing = {
*
* @param string network Social network key.
*/
- share: function (network) {
- this._openSharer(this._getSharer(network));
- this.$root.$emit('social_shares_click', network, this.url);
+ share: function share (network) {
+ this.openSharer(network, this.createSharingUrl(network));
+ this.$root.$emit('social_shares_open', network, this.url);
},
/**
@@ -222,9 +223,9 @@ var SocialSharing = {
*
* @param string network Social network key.
*/
- touch: function (network) {
- window.open(this._getSharer(network), '_self');
- this.$root.$emit('social_shares_click', network, this.url);
+ touch: function touch (network) {
+ window.open(this.createSharingUrl(network), '_self');
+ this.$root.$emit('social_shares_open', network, this.url);
},
/**
@@ -232,7 +233,16 @@ var SocialSharing = {
*
* @param string url Url to share.
*/
- _openSharer: function (url) {
+ openSharer: function openSharer (network, url) {
+ var this$1 = this;
+
+ // If a popup window already exist it will be replaced, trigger a close event.
+ if (this.popup.window && this.popup.interval) {
+ clearInterval(this.popup.interval);
+ this.popup.window.close();// Force close (for Facebook)
+ this.$root.$emit('social_shares_change', network, this.url);
+ }
+
this.popup.window = window.open(
url,
'sharer',
@@ -250,13 +260,24 @@ var SocialSharing = {
',location=' + (this.popup.location ? 'yes' : 'no') +
',directories=' + (this.popup.directories ? 'yes' : 'no')
);
+
+ this.popup.window.focus();
+
+ // Create an interval to detect popup closing event
+ this.popup.interval = setInterval(function () {
+ if (this$1.popup.window.closed) {
+ clearInterval(this$1.popup.interval);
+ this$1.popup.window = undefined;
+ this$1.$root.$emit('social_shares_close', network, this$1.url);
+ }
+ }, 500);
}
},
/**
* Sets popup default dimensions.
*/
- mounted: function () {
+ mounted: function mounted () {
if (!inBrowser) {
return;
}
@@ -283,7 +304,7 @@ var SocialSharing = {
}
};
-SocialSharing.version = '2.1.4';
+SocialSharing.version = '2.2.0';
SocialSharing.install = function (Vue) {
Vue.component('social-sharing', SocialSharing);
diff --git a/dist/vue-social-sharing.min.js b/dist/vue-social-sharing.min.js
index 5c850f3..6f13e84 100644
--- a/dist/vue-social-sharing.min.js
+++ b/dist/vue-social-sharing.min.js
@@ -1,6 +1,6 @@
/*!
- * vue-social-sharing v2.1.4
+ * vue-social-sharing v2.2.0
* (c) 2017 nicolasbeauvais
* Released under the MIT License.
*/
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.VueSocialSharing=e()}(this,function(){"use strict";var t={sharer:"https://www.facebook.com/sharer/sharer.php?u=@url&title=@title&description=@description"e=@quote",type:"popup"},e={sharer:"https://plus.google.com/share?url=@url",type:"popup"},i={sharer:"https://www.linkedin.com/shareArticle?mini=true&url=@url&title=@title&summary=@description",type:"popup"},o={sharer:"https://pinterest.com/pin/create/button/?url=@url&media=@media&description=@title",type:"popup"},r={sharer:"https://www.reddit.com/submit?url=@url&title=@title",type:"popup"},p={sharer:"https://twitter.com/intent/tweet?text=@title&url=@url&hashtags=@hashtags@twitteruser",type:"popup"},n={sharer:"https://vk.com/share.php?url=@url&title=@title&description=@description&image=@media&noparse=true",type:"popup"},s={sharer:"http://service.weibo.com/share/share.php?url=@url&title=@title",type:"popup"},a={sharer:"whatsapp://send?text=@url",type:"direct",action:"share/whatsapp/share"},u={facebook:t,googleplus:e,linkedin:i,pinterest:o,reddit:r,twitter:p,vk:n,weibo:s,whatsapp:a},l={functional:!0,props:{network:{type:String,default:""}},render:function(t,e){var i=u[e.props.network];return t(e.parent.networkTag,{class:e.data.staticClass||null,style:e.data.staticStyle||null,attrs:{id:e.data.attrs.id||null,"data-link":"popup"===i.type?"#share-"+e.props.network:e.parent._getSharer(e.props.network),"data-action":"popup"===i.type?null:i.action},on:{click:"popup"===i.type?function(){e.parent.share(e.props.network)}:function(){e.parent.touch(e.props.network)}}},e.children)}},h="undefined"!=typeof window,c=h?window:null,d={props:{url:{type:String,default:h?window.location.href:""},title:{type:String,default:""},description:{type:String,default:""},quote:{type:String,default:""},hashtags:{type:String,default:""},twitterUser:{type:String,default:""},withCounts:{type:[String,Boolean],default:!1},googleKey:{type:String,default:void 0},media:{type:String,default:""},networkTag:{type:String,default:"span"}},data:function(){return{networks:u,popup:{status:!1,resizable:!0,toolbar:!1,menubar:!1,scrollbars:!1,location:!1,directories:!1,width:626,height:436,top:0,left:0,window:void 0}}},methods:{_getSharer:function(t){return this.networks[t].sharer.replace(/@url/g,encodeURIComponent(this.url)).replace(/@title/g,encodeURIComponent(this.title)).replace(/@description/g,encodeURIComponent(this.description)).replace(/@quote/g,encodeURIComponent(this.quote)).replace(/@hashtags/g,this.hashtags).replace(/@media/g,this.media).replace(/@twitteruser/g,this.twitterUser?"&via="+this.twitterUser:"")},share:function(t){this._openSharer(this._getSharer(t)),this.$root.$emit("social_shares_click",t,this.url)},touch:function(t){window.open(this._getSharer(t),"_self"),this.$root.$emit("social_shares_click",t,this.url)},_openSharer:function(t){this.popup.window=window.open(t,"sharer","status="+(this.popup.status?"yes":"no")+",height="+this.popup.height+",width="+this.popup.width+",resizable="+(this.popup.resizable?"yes":"no")+",left="+this.popup.left+",top="+this.popup.top+",screenX="+this.popup.left+",screenY="+this.popup.top+",toolbar="+(this.popup.toolbar?"yes":"no")+",menubar="+(this.popup.menubar?"yes":"no")+",scrollbars="+(this.popup.scrollbars?"yes":"no")+",location="+(this.popup.location?"yes":"no")+",directories="+(this.popup.directories?"yes":"no"))}},mounted:function(){if(h){var t=void 0!==c.screenLeft?c.screenLeft:screen.left,e=void 0!==c.screenTop?c.screenTop:screen.top,i=c.innerWidth?c.innerWidth:document.documentElement.clientWidth?document.documentElement.clientWidth:screen.width,o=c.innerHeight?c.innerHeight:document.documentElement.clientHeight?document.documentElement.clientHeight:screen.height;this.popup.left=i/2-this.popup.width/2+t,this.popup.top=o/2-this.popup.height/2+e}},components:{network:l}};return d.version="2.1.4",d.install=function(t){t.component("social-sharing",d)},"undefined"!=typeof window&&(window.SocialSharing=d),d});
\ No newline at end of file
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.VueSocialSharing=e()}(this,function(){"use strict";var t={sharer:"https://www.facebook.com/sharer/sharer.php?u=@url&title=@title&description=@description"e=@quote",type:"popup"},e={sharer:"https://plus.google.com/share?url=@url",type:"popup"},i={sharer:"https://www.linkedin.com/shareArticle?mini=true&url=@url&title=@title&summary=@description",type:"popup"},o={sharer:"https://pinterest.com/pin/create/button/?url=@url&media=@media&description=@title",type:"popup"},p={sharer:"https://www.reddit.com/submit?url=@url&title=@title",type:"popup"},r={sharer:"https://twitter.com/intent/tweet?text=@title&url=@url&hashtags=@hashtags@twitteruser",type:"popup"},n={sharer:"https://vk.com/share.php?url=@url&title=@title&description=@description&image=@media&noparse=true",type:"popup"},s={sharer:"http://service.weibo.com/share/share.php?url=@url&title=@title",type:"popup"},a={sharer:"whatsapp://send?text=@url",type:"direct",action:"share/whatsapp/share"},l={facebook:t,googleplus:e,linkedin:i,pinterest:o,reddit:p,twitter:r,vk:n,weibo:s,whatsapp:a},u={functional:!0,props:{network:{type:String,default:""}},render:function(t,e){var i=l[e.props.network];return t(e.parent.networkTag,{class:e.data.staticClass||null,style:e.data.staticStyle||null,attrs:{id:e.data.attrs.id||null,"data-link":"popup"===i.type?"#share-"+e.props.network:e.parent.createSharingUrl(e.props.network),"data-action":"popup"===i.type?null:i.action},on:{click:"popup"===i.type?function(){e.parent.share(e.props.network)}:function(){e.parent.touch(e.props.network)}}},e.children)}},h="undefined"!=typeof window,c=h?window:null,d={props:{url:{type:String,default:h?window.location.href:""},title:{type:String,default:""},description:{type:String,default:""},quote:{type:String,default:""},hashtags:{type:String,default:""},twitterUser:{type:String,default:""},withCounts:{type:[String,Boolean],default:!1},googleKey:{type:String,default:void 0},media:{type:String,default:""},networkTag:{type:String,default:"span"}},data:function(){return{networks:l,popup:{status:!1,resizable:!0,toolbar:!1,menubar:!1,scrollbars:!1,location:!1,directories:!1,width:626,height:436,top:0,left:0,window:void 0,interval:null}}},methods:{createSharingUrl:function(t){return this.networks[t].sharer.replace(/@url/g,encodeURIComponent(this.url)).replace(/@title/g,encodeURIComponent(this.title)).replace(/@description/g,encodeURIComponent(this.description)).replace(/@quote/g,encodeURIComponent(this.quote)).replace(/@hashtags/g,this.hashtags).replace(/@media/g,this.media).replace(/@twitteruser/g,this.twitterUser?"&via="+this.twitterUser:"")},share:function(t){this.openSharer(t,this.createSharingUrl(t)),this.$root.$emit("social_shares_open",t,this.url)},touch:function(t){window.open(this.createSharingUrl(t),"_self"),this.$root.$emit("social_shares_open",t,this.url)},openSharer:function(t,e){var i=this;this.popup.window&&this.popup.interval&&(clearInterval(this.popup.interval),this.popup.window.close(),this.$root.$emit("social_shares_change",t,this.url)),this.popup.window=window.open(e,"sharer","status="+(this.popup.status?"yes":"no")+",height="+this.popup.height+",width="+this.popup.width+",resizable="+(this.popup.resizable?"yes":"no")+",left="+this.popup.left+",top="+this.popup.top+",screenX="+this.popup.left+",screenY="+this.popup.top+",toolbar="+(this.popup.toolbar?"yes":"no")+",menubar="+(this.popup.menubar?"yes":"no")+",scrollbars="+(this.popup.scrollbars?"yes":"no")+",location="+(this.popup.location?"yes":"no")+",directories="+(this.popup.directories?"yes":"no")),this.popup.window.focus(),this.popup.interval=setInterval(function(){i.popup.window.closed&&(clearInterval(i.popup.interval),i.popup.window=void 0,i.$root.$emit("social_shares_close",t,i.url))},500)}},mounted:function(){if(h){var t=void 0!==c.screenLeft?c.screenLeft:screen.left,e=void 0!==c.screenTop?c.screenTop:screen.top,i=c.innerWidth?c.innerWidth:document.documentElement.clientWidth?document.documentElement.clientWidth:screen.width,o=c.innerHeight?c.innerHeight:document.documentElement.clientHeight?document.documentElement.clientHeight:screen.height;this.popup.left=i/2-this.popup.width/2+t,this.popup.top=o/2-this.popup.height/2+e}},components:{network:u}};return d.version="2.2.0",d.install=function(t){t.component("social-sharing",d)},"undefined"!=typeof window&&(window.SocialSharing=d),d});
\ No newline at end of file
diff --git a/examples/vue2-example.html b/examples/vue2-example.html
index 0c82681..aef65d1 100644
--- a/examples/vue2-example.html
+++ b/examples/vue2-example.html
@@ -5,6 +5,17 @@
Vue social sharing example
+
+
@@ -21,47 +32,47 @@
-
- Facebook
+ Facebook
-
- Google +
+ Google +
-
- LinkedIn
+ LinkedIn
-
- Pinterest
+ Pinterest
-
- Reddit
+ Reddit
-
-
- VKontakte
+ VKontakte
-
- Weibo
+ Weibo
-
- Whatsapp
+ Whatsapp
diff --git a/package.json b/package.json
index cd97d11..1699e3e 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "vue-social-sharing",
"description": "A Vue.js component for sharing links to social networks",
- "version": "2.1.5",
+ "version": "2.2.0",
"author": {
"name": "nicolasbeauvais",
"email": "nicolasbeauvais1@gmail.com"
diff --git a/src/index.js b/src/index.js
index 7e09afd..04aacfb 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,6 @@
import SocialSharing from './social-sharing';
-SocialSharing.version = '2.1.4';
+SocialSharing.version = '2.2.0';
SocialSharing.install = (Vue) => {
Vue.component('social-sharing', SocialSharing);
diff --git a/src/social-sharing-network.js b/src/social-sharing-network.js
index 6d9bbe5..d94034d 100644
--- a/src/social-sharing-network.js
+++ b/src/social-sharing-network.js
@@ -20,7 +20,7 @@ export default {
id: context.data.attrs.id || null,
'data-link': network.type === 'popup'
? '#share-' + context.props.network
- : context.parent._getSharer(context.props.network),
+ : context.parent.createSharingUrl(context.props.network),
'data-action': network.type === 'popup' ? null : network.action
},
on: {
diff --git a/src/social-sharing.js b/src/social-sharing.js
index 4cfac8f..599026b 100644
--- a/src/social-sharing.js
+++ b/src/social-sharing.js
@@ -126,7 +126,8 @@ export default {
height: 436,
top: 0,
left: 0,
- window: undefined
+ window: undefined,
+ interval: null
}
};
},
@@ -137,7 +138,7 @@ export default {
*
* @param network Social network key.
*/
- _getSharer: function (network) {
+ createSharingUrl (network) {
return this.networks[network].sharer
.replace(/@url/g, encodeURIComponent(this.url))
.replace(/@title/g, encodeURIComponent(this.title))
@@ -153,9 +154,9 @@ export default {
*
* @param string network Social network key.
*/
- share: function (network) {
- this._openSharer(this._getSharer(network));
- this.$root.$emit('social_shares_click', network, this.url);
+ share (network) {
+ this.openSharer(network, this.createSharingUrl(network));
+ this.$root.$emit('social_shares_open', network, this.url);
},
/**
@@ -163,9 +164,9 @@ export default {
*
* @param string network Social network key.
*/
- touch: function (network) {
- window.open(this._getSharer(network), '_self');
- this.$root.$emit('social_shares_click', network, this.url);
+ touch (network) {
+ window.open(this.createSharingUrl(network), '_self');
+ this.$root.$emit('social_shares_open', network, this.url);
},
/**
@@ -173,7 +174,14 @@ export default {
*
* @param string url Url to share.
*/
- _openSharer: function (url) {
+ openSharer (network, url) {
+ // If a popup window already exist it will be replaced, trigger a close event.
+ if (this.popup.window && this.popup.interval) {
+ clearInterval(this.popup.interval);
+ this.popup.window.close();// Force close (for Facebook)
+ this.$root.$emit('social_shares_change', network, this.url);
+ }
+
this.popup.window = window.open(
url,
'sharer',
@@ -191,13 +199,24 @@ export default {
',location=' + (this.popup.location ? 'yes' : 'no') +
',directories=' + (this.popup.directories ? 'yes' : 'no')
);
+
+ this.popup.window.focus();
+
+ // Create an interval to detect popup closing event
+ this.popup.interval = setInterval(() => {
+ if (this.popup.window.closed) {
+ clearInterval(this.popup.interval);
+ this.popup.window = undefined;
+ this.$root.$emit('social_shares_close', network, this.url);
+ }
+ }, 500);
}
},
/**
* Sets popup default dimensions.
*/
- mounted: function () {
+ mounted () {
if (!inBrowser) {
return;
}
diff --git a/test/unit/test.js b/test/unit/test.js
index 1e65f08..e49df2a 100644
--- a/test/unit/test.js
+++ b/test/unit/test.js
@@ -5,7 +5,7 @@ import Networks from '../../src/networks';
describe('SocialSharing', () => {
const createComponent = (propsData = {}, attr = {}) => {
- const Ctor = Vue.extend({
+ const Comp = Vue.extend({
template: `
@@ -39,7 +39,7 @@ describe('SocialSharing', () => {
}
});
- return new Ctor({
+ return new Comp({
propsData,
data () {
return {
@@ -137,4 +137,16 @@ describe('SocialSharing', () => {
expect(typeof SocialSharingNetwork.props).toBe('object');
expect(SocialSharingNetwork.functional).toBe(true);
});
+
+ it('it create a popup', () => {
+ const vm = createComponent();
+ const network = Object.keys(Networks)[0];
+
+ vm.$on('social_shares_open', (sharedNetwork, url) => {
+ expect(sharedNetwork).toBe(network);
+ expect(url).toBe('https://vuejs.org/');
+ });
+
+ vm.$children[0].share(network);
+ });
});