├── .travis.yml
├── .coveralls.yml
├── src
├── css
│ ├── theme-dark.css
│ ├── theme-minimal-light.css
│ ├── theme-natural.css
│ ├── theme-minimal.css
│ └── base.css
├── sass
│ ├── theme-dark.scss
│ ├── theme-minimal-light.scss
│ ├── theme-natural.scss
│ ├── theme-minimal.scss
│ └── base.scss
├── img
│ ├── README.mkd
│ ├── email.svg
│ ├── facebook.svg
│ ├── twitter.svg
│ ├── pinterest.svg
│ ├── googleplus.svg
│ ├── whatsapp.svg
│ ├── telegram.svg
│ └── linkedin.svg
└── js
│ └── share.js
├── Gemfile
├── .gitignore
├── bower.json
├── Makefile
├── LICENSE
├── package.json
├── dist
├── img
│ └── icons.svg
├── css
│ ├── share.bar.min.css
│ └── share.bar.css
└── js
│ ├── share.bar.min.js
│ └── share.bar.js
├── demo
└── index.html
├── Gruntfile.js
├── README.md
└── tests
└── share.spec.js
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "4.5.0"
--------------------------------------------------------------------------------
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | service_name: travis-ci
2 | repo_token: STHQHehQyIEXzcZfkRIR4fHMx26kUYz9r
--------------------------------------------------------------------------------
/src/css/theme-dark.css:
--------------------------------------------------------------------------------
1 | .share-theme-dark .share-button a{background-color:#333333}
2 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | group :development do
4 | gem 'compass'
5 | end
--------------------------------------------------------------------------------
/src/sass/theme-dark.scss:
--------------------------------------------------------------------------------
1 | .share-theme-dark {
2 | .share-button a {
3 | background-color: #333333;
4 | }
5 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | Gemfile.lock
3 | .grunt/
4 | _SpecRunner.html
5 | tests/reports/*
6 | .sass-cache/
7 | src/fonts/
8 | dist/.DS_Store
9 | .DS_Store
10 |
--------------------------------------------------------------------------------
/src/img/README.mkd:
--------------------------------------------------------------------------------
1 | # Licensed images
2 |
3 | [telegram.svg](https://www.flaticon.com/free-icon/telegram-logo_14675) - Designerz Base - [CC 3.0 BY](https://creativecommons.org/licenses/by/3.0/)
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/img/email.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/img/facebook.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/img/twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/img/pinterest.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/img/googleplus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/img/whatsapp.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "share-bar",
3 | "version": "3.1.5",
4 | "homepage": "https://github.com/globocom/share-bar",
5 | "authors": [
6 | "globo.com"
7 | ],
8 | "description": "ShareBar is a plugin to create share bars. ShareBar is responsive, adaptable and easy to use.",
9 | "main": "dist/js/share.bar.js",
10 | "moduleType": [
11 | "globals"
12 | ],
13 | "keywords": [
14 | "sharebar",
15 | "twitter",
16 | "facebook",
17 | "pintereset",
18 | "share",
19 | "buttons"
20 | ],
21 | "license": "MIT",
22 | "ignore": [
23 | "**/.*",
24 | "node_modules",
25 | "bower_components",
26 | "test",
27 | "tests"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/src/css/theme-minimal-light.css:
--------------------------------------------------------------------------------
1 | .share-theme-minimal-light .share-button .svg-size .share-icon{top:50%;transform:translateY(-50%)}.share-theme-minimal-light .share-button{display:inline-block;min-width:34px}.share-theme-minimal-light .share-button a{background-color:transparent;padding:10px 15px 10px 5px;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-theme-minimal-light .share-button a .share-icon{fill:#FFF;color:#FFF}.share-theme-minimal-light .share-button a:active{padding-bottom:10px}.share-theme-minimal-light .share-button.share-small a,.share-theme-minimal-light .share-button.share-full a{padding:7px 7px 7px 7px}.share-theme-minimal-light .share-button.share-small a:active,.share-theme-minimal-light .share-button.share-full a:active{padding-bottom:7px}.share-theme-minimal-light .share-button a span,.share-theme-minimal-light .share-button.share-small a span,.share-theme-minimal-light .share-button.share-full a span{display:none}
2 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .SILENT:
2 | .DEFAULT_GOAL=help
3 |
4 | COLOR_RESET = \033[0m
5 | COLOR_GREEN = \033[32m
6 | COLOR_YELLOW = \033[33m
7 |
8 | PROJECT_NAME = `basename $(PWD)`
9 |
10 | ## prints this help
11 | help:
12 | printf "${COLOR_YELLOW}\n${PROJECT_NAME}\n\n${COLOR_RESET}"
13 | awk '/^[a-zA-Z\-\_0-9\.%]+:/ { \
14 | helpMessage = match(lastLine, /^## (.*)/); \
15 | if (helpMessage) { \
16 | helpCommand = substr($$1, 0, index($$1, ":")); \
17 | helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
18 | printf "${COLOR_GREEN}$$ make %s${COLOR_RESET} %s\n", helpCommand, helpMessage; \
19 | } \
20 | } \
21 | { lastLine = $$0 }' $(MAKEFILE_LIST)
22 | printf "\n"
23 |
24 | ## install project dependencies
25 | setup:
26 | @npm install
27 |
28 | ## run tests
29 | test:
30 | @grunt jasmine
31 |
32 | ## run a local server for local development use
33 | run:
34 | @grunt server
35 |
36 | ## build application
37 | build:
38 | @grunt default
39 |
40 | ## build and release
41 | release:
42 | @grunt bump-only
43 | @make build
44 | @grunt bump-commit
--------------------------------------------------------------------------------
/src/sass/theme-minimal-light.scss:
--------------------------------------------------------------------------------
1 | .share-theme-minimal-light .share-button .svg-size .share-icon {
2 | top: 50%;
3 | transform: translateY(-50%);
4 | }
5 |
6 | .share-theme-minimal-light {
7 | .share-button {
8 | display: inline-block;
9 | min-width: 34px;
10 |
11 | a {
12 | background-color: transparent;
13 | padding: 10px 15px 10px 5px;
14 | box-shadow: inset 0 0 0 rgba(0,0,0,0.25);
15 |
16 | .share-icon {
17 | fill: #FFF;
18 | color: #FFF;
19 | }
20 |
21 | &:active {
22 | padding-bottom: 10px;
23 | }
24 | }
25 | }
26 |
27 | .share-button.share-small a,
28 | .share-button.share-full a {
29 | padding: 7px 7px 7px 7px;
30 |
31 | &:active {
32 | padding-bottom: 7px;
33 | }
34 | }
35 |
36 | .share-button a span,
37 | .share-button.share-small a span,
38 | .share-button.share-full a span {
39 | display: none;
40 | }
41 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Globo.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/css/theme-natural.css:
--------------------------------------------------------------------------------
1 | .share-theme-natural .share-button a{transition:background 300ms ease}.share-theme-natural .share-facebook a{background-color:#325c99}.share-theme-natural .share-twitter a{background-color:#02acec}.share-theme-natural .share-googleplus a{background-color:#dd4b39}.share-theme-natural .share-linkedin a{background-color:#0077b5}.share-theme-natural .share-pinterest a{background-color:#cb2027}.share-theme-natural .share-email a{background-color:#8f9eb3}.share-theme-natural .share-whatsapp a{background-color:#58ad15}.share-theme-natural .share-telegram a{background-color:#2da4d7}.no-touch .share-theme-natural .share-facebook a:hover{background-color:#284a85}.no-touch .share-theme-natural .share-twitter a:hover{background-color:#029be8}.no-touch .share-theme-natural .share-googleplus a:hover{background-color:#d63c2e}.no-touch .share-theme-natural .share-linkedin a:hover{background-color:#0077b5}.no-touch .share-theme-natural .share-pinterest a:hover{background-color:#c11a1f}.no-touch .share-theme-natural .share-email a:hover{background-color:#798ba4}.no-touch .share-theme-natural .share-whatsapp a:hover{background-color:#469d11}.no-touch .share-theme-natural .share-telegram a:hover{background-color:#45abcc}
2 |
--------------------------------------------------------------------------------
/src/css/theme-minimal.css:
--------------------------------------------------------------------------------
1 | .share-theme-minimal .share-button .svg-size .share-icon{top:50%;transform:translateY(-50%)}.share-theme-minimal .share-button{display:inline-block;min-width:34px}.share-theme-minimal .share-button a{background-color:transparent;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-theme-minimal .share-button a:active{padding-bottom:11px}.share-theme-minimal .share-button .svg-size .share-icon{vertical-align:baseline}.share-theme-minimal .share-button.share-small a,.share-theme-minimal .share-button.share-full a{padding:7px 7px 7px 7px}.share-theme-minimal .share-button.share-small a:active,.share-theme-minimal .share-button.share-full a:active{padding-bottom:7px}.share-theme-minimal .share-button a span,.share-theme-minimal .share-button.share-small a span,.share-theme-minimal .share-button.share-full a span{display:none}.share-theme-minimal .share-facebook a .share-icon{fill:#325c99}.share-theme-minimal .share-twitter a .share-icon{fill:#02acec}.share-theme-minimal .share-googleplus a .share-icon{fill:#dd4b39}.share-theme-minimal .share-linkedin a .share-icon{fill:#0077b5}.share-theme-minimal .share-pinterest a .share-icon{fill:#cb2027}.share-theme-minimal .share-email a .share-icon{fill:#8f9eb3}.share-theme-minimal .share-whatsapp a .share-icon{fill:#58ad15}.share-theme-minimal .share-telegram a .share-icon{fill:#2da4d7}
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "share.bar",
3 | "title": "ShareBar",
4 | "version": "3.2.0",
5 | "description": "Plugin js que automatiza a criação de barra de share de acordo com as redes sociais desejadas.",
6 | "main": "dist/share.bar.js",
7 | "author": {
8 | "name": "Globo.com"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/globocom/share-bar.git"
13 | },
14 | "keywords": [
15 | "share",
16 | "responsive",
17 | "javascript"
18 | ],
19 | "licenses": [
20 | {
21 | "type": "MIT",
22 | "url": "https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt"
23 | }
24 | ],
25 | "devDependencies": {
26 | "grunt": "1.0.1",
27 | "grunt-bump": "0.8.0",
28 | "grunt-contrib-compass": "1.1.1",
29 | "grunt-contrib-concat": "1.0.1",
30 | "grunt-contrib-connect": "1.0.2",
31 | "grunt-contrib-cssmin": "1.0.1",
32 | "grunt-contrib-jasmine": "1.0.3",
33 | "grunt-contrib-uglify": "2.0.0",
34 | "grunt-contrib-watch": "1.0.0",
35 | "grunt-coveralls": "1.0.1",
36 | "grunt-jslint": "1.1.14",
37 | "grunt-string-replace": "1.3.0",
38 | "grunt-svgmin": "3.3.0",
39 | "grunt-svgstore": "1.0.0",
40 | "grunt-template-jasmine-istanbul": "0.5.0",
41 | "phantomjs-prebuilt": ""
42 | },
43 | "scripts": {
44 | "test": "grunt ci"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/img/telegram.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/sass/theme-natural.scss:
--------------------------------------------------------------------------------
1 | .share-theme-natural {
2 | .share-button a {
3 | transition: background 300ms ease;
4 | }
5 |
6 | .share-facebook a {
7 | background-color: #325c99;
8 | }
9 |
10 | .share-twitter a {
11 | background-color: #02acec;
12 | }
13 |
14 | .share-googleplus a {
15 | background-color: #dd4b39;
16 | }
17 |
18 | .share-linkedin a {
19 | background-color: #0077b5;
20 | }
21 |
22 | .share-pinterest a {
23 | background-color: #cb2027;
24 | }
25 |
26 | .share-email a {
27 | background-color: #8f9eb3;
28 | }
29 |
30 | .share-whatsapp a {
31 | background-color: #58ad15;
32 | }
33 |
34 | .share-telegram a {
35 | background-color: #2da4d7;
36 | }
37 | }
38 |
39 | .no-touch .share-theme-natural {
40 |
41 | .share-facebook a:hover {
42 | background-color: #284a85;
43 | }
44 |
45 | .share-twitter a:hover {
46 | background-color: #029be8;
47 | }
48 |
49 | .share-googleplus a:hover {
50 | background-color: #d63c2e;
51 | }
52 |
53 | .share-linkedin a:hover {
54 | background-color: #0077b5;
55 | }
56 |
57 | .share-pinterest a:hover {
58 | background-color: #c11a1f;
59 | }
60 |
61 | .share-email a:hover {
62 | background-color: #798ba4;
63 | }
64 |
65 | .share-whatsapp a:hover {
66 | background-color: #469d11;
67 | }
68 |
69 | .share-telegram a:hover {
70 | background-color: #45abcc;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/img/linkedin.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.15, written by Peter Selinger 2001-2017
9 |
10 |
12 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/sass/theme-minimal.scss:
--------------------------------------------------------------------------------
1 | .share-theme-minimal .share-button .svg-size .share-icon {
2 | top: 50%;
3 | transform: translateY(-50%);
4 | }
5 |
6 | .share-theme-minimal {
7 | .share-button {
8 | display: inline-block;
9 | min-width: 34px;
10 |
11 | a {
12 | background-color: transparent;
13 | box-shadow: inset 0 0 0 rgba(0,0,0,0.25);
14 |
15 | &:active {
16 | padding-bottom: 11px;
17 | }
18 | }
19 |
20 | .svg-size .share-icon {
21 | vertical-align: baseline;
22 | }
23 | }
24 |
25 | .share-button.share-small a,
26 | .share-button.share-full a {
27 | padding: 7px 7px 7px 7px;
28 |
29 | &:active {
30 | padding-bottom: 7px;
31 | }
32 | }
33 |
34 | .share-button a span,
35 | .share-button.share-small a span,
36 | .share-button.share-full a span {
37 | display: none;
38 | }
39 |
40 | .share-facebook a .share-icon {
41 | fill: #325c99;
42 | }
43 |
44 | .share-twitter a .share-icon {
45 | fill: #02acec;
46 | }
47 |
48 | .share-googleplus a .share-icon {
49 | fill: #dd4b39;
50 | }
51 |
52 | .share-linkedin a .share-icon {
53 | fill: #0077b5;
54 | }
55 |
56 | .share-pinterest a .share-icon {
57 | fill: #cb2027;
58 | }
59 |
60 | .share-email a .share-icon {
61 | fill: #8f9eb3;
62 | }
63 |
64 | .share-whatsapp a .share-icon {
65 | fill: #58ad15;
66 | }
67 |
68 | .share-telegram a .share-icon {
69 | fill: #2da4d7;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/css/base.css:
--------------------------------------------------------------------------------
1 | .share-bar-container{display:table;border-collapse:separate;width:100%}.share-bar-container .share-button{display:table-cell;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:ProximaNova-Bold, Arial;text-transform:uppercase;letter-spacing:0;min-width:40px;vertical-align:bottom;text-align:center;padding-left:4px}.share-bar-container .share-button:first-child{padding-left:0px}.share-bar-container .share-button a{display:block;padding:9px 10px 11px 10px;height:20px;border-radius:3px;text-decoration:none;box-shadow:inset 0 -2px 0 rgba(0,0,0,0.25);box-sizing:content-box}.share-bar-container .share-button a:active{padding-bottom:6px;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-bar-container .share-button span{display:none}.share-bar-container .share-button.share-full{display:inline-block}.share-bar-container .share-button.share-full a{padding:6px 10px 8px 10px}.share-bar-container .share-button.share-full span{line-height:21px;display:inline-block;vertical-align:middle;font-size:11px;color:white;width:70px;text-align:center}.share-bar-container .share-button.share-full .share-icon{top:inherit;transform:inherit}.share-bar-container .share-button.share-small{display:inline-block;min-width:34px}.share-bar-container .share-button.share-small a{padding:6px 7px 8px 7px}.share-bar-container .share-button.share-small a:active{padding-bottom:6px;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-bar-container .share-button.share-hidden{display:none}.share-bar-container .svg-size{width:20px;height:20px;display:inline-block}.share-bar-container .svg-size .share-icon{fill:white;max-width:16px;position:relative;top:50%;transform:translateY(-50%);display:inline-block;vertical-align:middle}.share-facebook .svg-size .share-icon{max-width:16px;max-height:16px}.share-twitter .svg-size .share-icon{max-width:20px;max-height:20px}.share-whatsapp .svg-size .share-icon{max-width:18px;max-height:18px}.share-telegram .svg-size .share-icon{max-width:18px;max-height:18px}.share-googleplus .svg-size .share-icon{max-width:18px;max-height:18px}.share-linkedin .svg-size .share-icon{max-width:18px;max-height:18px}.share-pinterest .svg-size .share-icon{max-width:18px;max-height:18px}.share-email .svg-size .share-icon{max-width:16px}
2 |
--------------------------------------------------------------------------------
/src/sass/base.scss:
--------------------------------------------------------------------------------
1 | .share-bar-container {
2 | display: table;
3 | border-collapse: separate;
4 | width: 100%;
5 |
6 | .share-button {
7 | display: table-cell;
8 | -webkit-font-smoothing: antialiased;
9 | -moz-osx-font-smoothing: grayscale;
10 | font-family: ProximaNova-Bold, Arial;
11 | text-transform: uppercase;
12 | letter-spacing: 0;
13 |
14 | min-width: 40px;
15 | vertical-align: bottom;
16 | text-align: center;
17 | padding-left: 4px;
18 |
19 | &:first-child {
20 | padding-left: 0px;
21 | }
22 |
23 | a {
24 | display: block;
25 | padding: 9px 10px 11px 10px;
26 | height: 20px;
27 | border-radius: 3px;
28 | text-decoration: none;
29 | box-shadow: inset 0 -2px 0 rgba(0,0,0,0.25);
30 | box-sizing: content-box;
31 |
32 | &:active {
33 | padding-bottom: 6px;
34 | box-shadow: inset 0 0 0 rgba(0,0,0,0.25);
35 | }
36 | }
37 |
38 | span {
39 | display: none;
40 |
41 | }
42 |
43 | &.share-full {
44 | display: inline-block;
45 |
46 | a {
47 | padding: 6px 10px 8px 10px;
48 | }
49 |
50 | span {
51 | line-height: 21px;
52 | display: inline-block;
53 | vertical-align: middle;
54 | font-size: 11px;
55 | color: white;
56 | width: 70px;
57 | text-align: center;
58 | }
59 |
60 | .share-icon {
61 | top: inherit;
62 | transform: inherit;
63 | }
64 |
65 | }
66 |
67 | &.share-small {
68 | display: inline-block;
69 | min-width: 34px;
70 |
71 | a {
72 | padding: 6px 7px 8px 7px;
73 |
74 | &:active {
75 | padding-bottom: 6px;
76 | box-shadow: inset 0 0 0 rgba(0,0,0,0.25);
77 | }
78 | }
79 | }
80 |
81 | &.share-hidden {
82 | display: none;
83 | }
84 | }
85 |
86 | .svg-size {
87 | width: 20px;
88 | height: 20px;
89 | display: inline-block;
90 |
91 | .share-icon {
92 | fill: white;
93 | max-width: 16px;
94 | position: relative;
95 | top: 50%;
96 | transform: translateY(-50%);
97 | display: inline-block;
98 | vertical-align: middle;
99 | }
100 | }
101 | }
102 |
103 |
104 | .share-facebook .svg-size .share-icon {
105 | max-width: 16px;
106 | max-height: 16px;
107 | }
108 |
109 | .share-twitter .svg-size .share-icon {
110 | max-width: 20px;
111 | max-height: 20px;
112 | }
113 |
114 | .share-whatsapp .svg-size .share-icon {
115 | max-width: 18px;
116 | max-height: 18px;
117 | }
118 |
119 | .share-telegram .svg-size .share-icon {
120 | max-width: 18px;
121 | max-height: 18px;
122 | }
123 |
124 | .share-googleplus .svg-size .share-icon {
125 | max-width: 18px;
126 | max-height: 18px;
127 | }
128 |
129 | .share-linkedin .svg-size .share-icon {
130 | max-width: 18px;
131 | max-height: 18px;
132 | }
133 |
134 | .share-pinterest .svg-size .share-icon {
135 | max-width: 18px;
136 | max-height: 18px;
137 | }
138 |
139 | .share-email .svg-size .share-icon {
140 | max-width: 16px;
141 | }
142 |
--------------------------------------------------------------------------------
/dist/img/icons.svg:
--------------------------------------------------------------------------------
1 | email facebook googleplus linkedin pinterest telegram whatsapp
--------------------------------------------------------------------------------
/dist/css/share.bar.min.css:
--------------------------------------------------------------------------------
1 | /*! ShareBar - v3.2.0 - 2018-11-08 - * Copyright (c) 2018 Globo.com; Licensed MIT */.share-bar-container{display:table;border-collapse:separate;width:100%}.share-bar-container .share-button{display:table-cell;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:ProximaNova-Bold,Arial;text-transform:uppercase;letter-spacing:0;min-width:40px;vertical-align:bottom;text-align:center;padding-left:4px}.share-bar-container .share-button:first-child{padding-left:0}.share-bar-container .share-button a{display:block;padding:9px 10px 11px;height:20px;border-radius:3px;text-decoration:none;box-shadow:inset 0 -2px 0 rgba(0,0,0,.25);box-sizing:content-box}.share-bar-container .share-button a:active{padding-bottom:6px;box-shadow:inset 0 0 0 rgba(0,0,0,.25)}.share-bar-container .share-button span{display:none}.share-bar-container .share-button.share-full{display:inline-block}.share-bar-container .share-button.share-full a{padding:6px 10px 8px}.share-bar-container .share-button.share-full span{line-height:21px;display:inline-block;vertical-align:middle;font-size:11px;color:#fff;width:70px;text-align:center}.share-bar-container .share-button.share-full .share-icon{top:inherit;transform:inherit}.share-bar-container .share-button.share-small{display:inline-block;min-width:34px}.share-bar-container .share-button.share-small a{padding:6px 7px 8px}.share-bar-container .share-button.share-small a:active{padding-bottom:6px;box-shadow:inset 0 0 0 rgba(0,0,0,.25)}.share-bar-container .share-button.share-hidden{display:none}.share-bar-container .svg-size{width:20px;height:20px;display:inline-block}.share-bar-container .svg-size .share-icon{fill:#fff;max-width:16px;position:relative;top:50%;transform:translateY(-50%);display:inline-block;vertical-align:middle}.share-facebook .svg-size .share-icon{max-width:16px;max-height:16px}.share-twitter .svg-size .share-icon{max-width:20px;max-height:20px}.share-googleplus .svg-size .share-icon,.share-linkedin .svg-size .share-icon,.share-pinterest .svg-size .share-icon,.share-telegram .svg-size .share-icon,.share-whatsapp .svg-size .share-icon{max-width:18px;max-height:18px}.share-email .svg-size .share-icon{max-width:16px}.share-theme-dark .share-button a{background-color:#333}.share-theme-minimal .share-button a,.share-theme-minimal-light .share-button a{background-color:transparent;box-shadow:inset 0 0 0 rgba(0,0,0,.25)}.share-theme-minimal-light .share-button .svg-size .share-icon{top:50%;transform:translateY(-50%)}.share-theme-minimal-light .share-button{display:inline-block;min-width:34px}.share-theme-minimal-light .share-button a{padding:10px 15px 10px 5px}.share-theme-minimal-light .share-button a .share-icon{fill:#FFF;color:#FFF}.share-theme-minimal-light .share-button a:active{padding-bottom:10px}.share-theme-minimal-light .share-button.share-full a,.share-theme-minimal-light .share-button.share-small a{padding:7px}.share-theme-minimal-light .share-button.share-full a:active,.share-theme-minimal-light .share-button.share-small a:active{padding-bottom:7px}.share-theme-minimal-light .share-button a span,.share-theme-minimal-light .share-button.share-full a span,.share-theme-minimal-light .share-button.share-small a span{display:none}.share-theme-minimal .share-button .svg-size .share-icon{top:50%;transform:translateY(-50%);vertical-align:baseline}.share-theme-minimal .share-button{display:inline-block;min-width:34px}.share-theme-minimal .share-button a:active{padding-bottom:11px}.share-theme-minimal .share-button.share-full a,.share-theme-minimal .share-button.share-small a{padding:7px}.share-theme-minimal .share-button.share-full a:active,.share-theme-minimal .share-button.share-small a:active{padding-bottom:7px}.share-theme-minimal .share-button a span,.share-theme-minimal .share-button.share-full a span,.share-theme-minimal .share-button.share-small a span{display:none}.share-theme-minimal .share-facebook a .share-icon{fill:#325c99}.share-theme-minimal .share-twitter a .share-icon{fill:#02acec}.share-theme-minimal .share-googleplus a .share-icon{fill:#dd4b39}.share-theme-minimal .share-linkedin a .share-icon{fill:#0077b5}.share-theme-minimal .share-pinterest a .share-icon{fill:#cb2027}.share-theme-minimal .share-email a .share-icon{fill:#8f9eb3}.share-theme-minimal .share-whatsapp a .share-icon{fill:#58ad15}.share-theme-minimal .share-telegram a .share-icon{fill:#2da4d7}.share-theme-natural .share-button a{transition:background .3s ease}.share-theme-natural .share-facebook a{background-color:#325c99}.share-theme-natural .share-twitter a{background-color:#02acec}.share-theme-natural .share-googleplus a{background-color:#dd4b39}.share-theme-natural .share-linkedin a{background-color:#0077b5}.share-theme-natural .share-pinterest a{background-color:#cb2027}.share-theme-natural .share-email a{background-color:#8f9eb3}.share-theme-natural .share-whatsapp a{background-color:#58ad15}.share-theme-natural .share-telegram a{background-color:#2da4d7}.no-touch .share-theme-natural .share-facebook a:hover{background-color:#284a85}.no-touch .share-theme-natural .share-twitter a:hover{background-color:#029be8}.no-touch .share-theme-natural .share-googleplus a:hover{background-color:#d63c2e}.no-touch .share-theme-natural .share-linkedin a:hover{background-color:#0077b5}.no-touch .share-theme-natural .share-pinterest a:hover{background-color:#c11a1f}.no-touch .share-theme-natural .share-email a:hover{background-color:#798ba4}.no-touch .share-theme-natural .share-whatsapp a:hover{background-color:#469d11}.no-touch .share-theme-natural .share-telegram a:hover{background-color:#45abcc}
--------------------------------------------------------------------------------
/dist/css/share.bar.css:
--------------------------------------------------------------------------------
1 | /*! ShareBar - v3.2.0 - 2018-11-08 - * Copyright (c) 2018 Globo.com; Licensed MIT */
2 | .share-bar-container{display:table;border-collapse:separate;width:100%}.share-bar-container .share-button{display:table-cell;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:ProximaNova-Bold, Arial;text-transform:uppercase;letter-spacing:0;min-width:40px;vertical-align:bottom;text-align:center;padding-left:4px}.share-bar-container .share-button:first-child{padding-left:0px}.share-bar-container .share-button a{display:block;padding:9px 10px 11px 10px;height:20px;border-radius:3px;text-decoration:none;box-shadow:inset 0 -2px 0 rgba(0,0,0,0.25);box-sizing:content-box}.share-bar-container .share-button a:active{padding-bottom:6px;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-bar-container .share-button span{display:none}.share-bar-container .share-button.share-full{display:inline-block}.share-bar-container .share-button.share-full a{padding:6px 10px 8px 10px}.share-bar-container .share-button.share-full span{line-height:21px;display:inline-block;vertical-align:middle;font-size:11px;color:white;width:70px;text-align:center}.share-bar-container .share-button.share-full .share-icon{top:inherit;transform:inherit}.share-bar-container .share-button.share-small{display:inline-block;min-width:34px}.share-bar-container .share-button.share-small a{padding:6px 7px 8px 7px}.share-bar-container .share-button.share-small a:active{padding-bottom:6px;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-bar-container .share-button.share-hidden{display:none}.share-bar-container .svg-size{width:20px;height:20px;display:inline-block}.share-bar-container .svg-size .share-icon{fill:white;max-width:16px;position:relative;top:50%;transform:translateY(-50%);display:inline-block;vertical-align:middle}.share-facebook .svg-size .share-icon{max-width:16px;max-height:16px}.share-twitter .svg-size .share-icon{max-width:20px;max-height:20px}.share-whatsapp .svg-size .share-icon{max-width:18px;max-height:18px}.share-telegram .svg-size .share-icon{max-width:18px;max-height:18px}.share-googleplus .svg-size .share-icon{max-width:18px;max-height:18px}.share-linkedin .svg-size .share-icon{max-width:18px;max-height:18px}.share-pinterest .svg-size .share-icon{max-width:18px;max-height:18px}.share-email .svg-size .share-icon{max-width:16px}
3 |
4 | .share-theme-dark .share-button a{background-color:#333333}
5 |
6 | .share-theme-minimal-light .share-button .svg-size .share-icon{top:50%;transform:translateY(-50%)}.share-theme-minimal-light .share-button{display:inline-block;min-width:34px}.share-theme-minimal-light .share-button a{background-color:transparent;padding:10px 15px 10px 5px;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-theme-minimal-light .share-button a .share-icon{fill:#FFF;color:#FFF}.share-theme-minimal-light .share-button a:active{padding-bottom:10px}.share-theme-minimal-light .share-button.share-small a,.share-theme-minimal-light .share-button.share-full a{padding:7px 7px 7px 7px}.share-theme-minimal-light .share-button.share-small a:active,.share-theme-minimal-light .share-button.share-full a:active{padding-bottom:7px}.share-theme-minimal-light .share-button a span,.share-theme-minimal-light .share-button.share-small a span,.share-theme-minimal-light .share-button.share-full a span{display:none}
7 |
8 | .share-theme-minimal .share-button .svg-size .share-icon{top:50%;transform:translateY(-50%)}.share-theme-minimal .share-button{display:inline-block;min-width:34px}.share-theme-minimal .share-button a{background-color:transparent;box-shadow:inset 0 0 0 rgba(0,0,0,0.25)}.share-theme-minimal .share-button a:active{padding-bottom:11px}.share-theme-minimal .share-button .svg-size .share-icon{vertical-align:baseline}.share-theme-minimal .share-button.share-small a,.share-theme-minimal .share-button.share-full a{padding:7px 7px 7px 7px}.share-theme-minimal .share-button.share-small a:active,.share-theme-minimal .share-button.share-full a:active{padding-bottom:7px}.share-theme-minimal .share-button a span,.share-theme-minimal .share-button.share-small a span,.share-theme-minimal .share-button.share-full a span{display:none}.share-theme-minimal .share-facebook a .share-icon{fill:#325c99}.share-theme-minimal .share-twitter a .share-icon{fill:#02acec}.share-theme-minimal .share-googleplus a .share-icon{fill:#dd4b39}.share-theme-minimal .share-linkedin a .share-icon{fill:#0077b5}.share-theme-minimal .share-pinterest a .share-icon{fill:#cb2027}.share-theme-minimal .share-email a .share-icon{fill:#8f9eb3}.share-theme-minimal .share-whatsapp a .share-icon{fill:#58ad15}.share-theme-minimal .share-telegram a .share-icon{fill:#2da4d7}
9 |
10 | .share-theme-natural .share-button a{transition:background 300ms ease}.share-theme-natural .share-facebook a{background-color:#325c99}.share-theme-natural .share-twitter a{background-color:#02acec}.share-theme-natural .share-googleplus a{background-color:#dd4b39}.share-theme-natural .share-linkedin a{background-color:#0077b5}.share-theme-natural .share-pinterest a{background-color:#cb2027}.share-theme-natural .share-email a{background-color:#8f9eb3}.share-theme-natural .share-whatsapp a{background-color:#58ad15}.share-theme-natural .share-telegram a{background-color:#2da4d7}.no-touch .share-theme-natural .share-facebook a:hover{background-color:#284a85}.no-touch .share-theme-natural .share-twitter a:hover{background-color:#029be8}.no-touch .share-theme-natural .share-googleplus a:hover{background-color:#d63c2e}.no-touch .share-theme-natural .share-linkedin a:hover{background-color:#0077b5}.no-touch .share-theme-natural .share-pinterest a:hover{background-color:#c11a1f}.no-touch .share-theme-natural .share-email a:hover{background-color:#798ba4}.no-touch .share-theme-natural .share-whatsapp a:hover{background-color:#469d11}.no-touch .share-theme-natural .share-telegram a:hover{background-color:#45abcc}
11 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Demonstração da Barra de Share - ShareBar
7 |
8 |
9 |
10 | Página de demonstração da barra de share
11 |
12 | Tema Natural
13 | 100% de largura
14 |
15 | 40% de largura
16 |
17 | 30% de largura
18 |
19 | 10% de largura
20 |
21 | 5% de largura
22 |
23 |
24 |
25 | Tema Dark
26 | 100% de largura
27 |
28 | 40% de largura
29 |
30 | 30% de largura
31 |
32 | 10% de largura
33 |
34 | 5% de largura
35 |
36 |
37 |
38 | Tema Minimal
39 | 100% de largura
40 |
41 | 40% de largura
42 |
43 | 30% de largura
44 |
45 | 10% de largura
46 |
47 | 5% de largura
48 |
49 |
50 |
51 | Tema Minimal Light
52 | 100% de largura
53 |
54 | 40% de largura
55 |
56 | 30% de largura
57 |
58 | 10% de largura
59 |
60 | 5% de largura
61 |
62 |
63 |
64 |
67 |
68 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*global require, module:false */
2 | module.exports = function (grunt) {
3 | 'use strict';
4 |
5 | var distJs = 'dist/js/',
6 | distCss = 'dist/css/';
7 |
8 | // Project configuration.
9 | grunt.initConfig({
10 | // Metadata.
11 | pkg: grunt.file.readJSON('package.json'),
12 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
13 | '<%= grunt.template.today("yyyy-mm-dd") %> - ' +
14 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
15 | ' Licensed <%= pkg.licenses[0].type %> */\n',
16 |
17 | // Task configuration.
18 | concat: {
19 | options: {
20 | banner: '<%= banner %>',
21 | stripBanners: true
22 | },
23 | js: {
24 | src: 'src/js/share.js',
25 | dest: distJs + '<%= pkg.name %>.js'
26 | },
27 | css: {
28 | src: ['src/css/*.css'],
29 | dest: distCss + '<%= pkg.name %>.css'
30 | }
31 | },
32 |
33 | uglify: {
34 | options: {
35 | banner: '<%= banner %>'
36 | },
37 | dist: {
38 | src: '<%= concat.js.dest %>',
39 | dest: distJs + '<%= pkg.name %>.min.js'
40 | }
41 | },
42 |
43 | cssmin: {
44 | minify: {
45 | src: 'dist/css/share.bar.css',
46 | dest: 'dist/css/share.bar.min.css',
47 | banner: '<%= banner %>'
48 | }
49 | },
50 |
51 | jslint: {
52 | client: {
53 | src: ['<%= concat.js.src %>', 'tests/*.spec.js', 'Gruntfile.js'],
54 | directives: {
55 | browser: true,
56 | unparam: true,
57 | regexp: true,
58 | nomen: true,
59 | plusplus: true
60 | }
61 | }
62 | },
63 |
64 | compass: {
65 | dist: {
66 | options: {
67 | sassDir: 'src/sass',
68 | cssDir: 'src/css',
69 | outputStyle: 'compressed',
70 | noLineComments: true,
71 | relativeAssets: true
72 |
73 | }
74 | }
75 | },
76 |
77 | svgstore: {
78 | options: {
79 | prefix : 'icon-'
80 | },
81 | default: {
82 | files: {
83 | 'dist/img/icons.svg': ['src/img/*.svg']
84 | }
85 | }
86 | },
87 |
88 | svgmin: {
89 | options: {
90 | plugins: [
91 | { removeViewBox: false },
92 | { cleanupIDs: false }
93 | ]
94 | },
95 | dist: {
96 | files: {
97 | 'dist/img/icons.svg': 'dist/img/icons.svg'
98 | }
99 | }
100 | },
101 |
102 | 'string-replace': {
103 | dist: {
104 | files: {
105 | 'dist/js/share.bar.js': 'dist/js/share.bar.js'
106 | },
107 | options: {
108 | replacements: [{
109 | pattern: '[[X_SVG_X]]',
110 | replacement: grunt.file.read('dist/img/icons.svg')
111 | }]
112 | }
113 | }
114 | },
115 |
116 | jasmine: {
117 | share: {
118 | src: 'src/js/share.js',
119 | options: {
120 | specs: 'tests/*.spec.js',
121 | vendor: [],
122 | junit: {
123 | path: 'tests/reports/',
124 | consolidate: true
125 | },
126 | keepRunner: true,
127 | template: require('grunt-template-jasmine-istanbul'),
128 | templateOptions: {
129 | coverage: 'tests/reports/conbertura.json',
130 | report: [{
131 | type: 'lcov',
132 | options: {
133 | dir: 'tests/reports/'
134 | }
135 | }]
136 | },
137 | // phantom options
138 | '--web-security' : false,
139 | '--local-to-remote-url-access' : true,
140 | '--ignore-ssl-errors' : true
141 | }
142 | }
143 | },
144 |
145 | coveralls: {
146 |
147 | options: {
148 | force: true
149 | },
150 | main_target: {
151 | src: "tests/reports/lcov.info"
152 | }
153 | },
154 |
155 | watch: {
156 | gruntfile: {
157 | files: 'Gruntfile.js',
158 | tasks: ['jslint']
159 | },
160 | test: {
161 | files: 'tests/*.spec.js',
162 | tasks: ['jstest']
163 | },
164 | buildJS: {
165 | files: ['<%= concat.js.src %>'],
166 | tasks: ['jstest', 'js']
167 | },
168 | buildCSS: {
169 | files: ['src/sass/*.scss'],
170 | tasks: ['css']
171 | },
172 | buildIcons: {
173 | files: ['src/img/*.svg'],
174 | tasks: ['icon']
175 | }
176 | },
177 |
178 | connect: {
179 | server: {
180 | options: {
181 | port: 9002,
182 | base: '.',
183 | livereload: true
184 | }
185 | }
186 | },
187 |
188 | bump: {
189 | options: {
190 | files: ['package.json'],
191 | updateConfigs: [],
192 | commit: true,
193 | commitMessage: 'Release version: %VERSION%',
194 | commitFiles: ['-a'],
195 | createTag: true,
196 | tagName: '%VERSION%',
197 | tagMessage: 'Version %VERSION%',
198 | push: true,
199 | pushTo: 'origin master',
200 | gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d'
201 | }
202 | }
203 | });
204 |
205 | // These plugins provide necessary tasks.
206 | grunt.loadNpmTasks('grunt-contrib-compass');
207 | grunt.loadNpmTasks('grunt-contrib-jasmine');
208 | grunt.loadNpmTasks('grunt-contrib-concat');
209 | grunt.loadNpmTasks('grunt-contrib-connect');
210 | grunt.loadNpmTasks('grunt-contrib-uglify');
211 | grunt.loadNpmTasks('grunt-contrib-cssmin');
212 | grunt.loadNpmTasks('grunt-contrib-watch');
213 | grunt.loadNpmTasks('grunt-jslint');
214 | grunt.loadNpmTasks('grunt-svgstore');
215 | grunt.loadNpmTasks('grunt-string-replace');
216 | grunt.loadNpmTasks('grunt-svgmin');
217 | grunt.loadNpmTasks('grunt-bump');
218 | grunt.loadNpmTasks('grunt-coveralls');
219 |
220 | // Custom tasks
221 | grunt.registerTask('icon', ['svgstore', 'svgmin', 'string-replace']);
222 | grunt.registerTask('jstest', ['jslint', 'jasmine']);
223 | grunt.registerTask('js', ['concat:js', 'string-replace', 'uglify']);
224 | grunt.registerTask('css', ['compass', 'concat:css', 'cssmin']);
225 | grunt.registerTask('server', ['connect:server', 'watch']);
226 | grunt.registerTask('ci', ['jasmine', 'coveralls']);
227 |
228 | // Default task.
229 | grunt.registerTask('default', ['icon', 'jstest', 'js', 'css']);
230 | };
231 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/globocom/share-bar)
2 | [](https://coveralls.io/r/globocom/share-bar)
3 |
4 | # share-bar
5 |
6 | > A pure JS plugin to generate a share bar for social media, used by Globo.com.
7 |
8 | ## Table of Contents
9 |
10 | - [share-bar](#share-bar)
11 | - [Table of Contents](#table-of-contents)
12 | - [Browser Support](#browser-support)
13 | - [How to Install](#how-to-install)
14 | - [How to Use](#how-to-use)
15 | - [Options](#options)
16 | - [Selector](#selector)
17 | - [Theme](#theme)
18 | - [classPopup](#classpopup)
19 | - [buttonWidth](#buttonwidth)
20 | - [buttonFullWidth](#buttonfullwidth)
21 | - [buttonPadding](#buttonpadding)
22 | - [maxSocialButtons](#maxsocialbuttons)
23 | - [networks](#networks)
24 | - [context](#context)
25 | - [campaign](#campaign)
26 | - [onCreateBar](#oncreatebar)
27 | - [onCreateButton](#oncreatebutton)
28 | - [onShare](#onshare)
29 | - [createBar](#createbar)
30 | - [Contributing](#contributing)
31 | - [Icons](#icons)
32 | - [Version](#version)
33 | - [License](#license)
34 |
35 | ## Browser Support
36 |
37 | |  |  |  |  |  |
38 | |:---:|:---:|:---:|:---:|:---:|
39 | | All ✔ | 3.6+ ✔ | 9+ ✔ | 29+ ✔ | 5+ ✔ |
40 |
41 | ## How to Install
42 |
43 | Install through NPM:
44 |
45 | ```bash
46 | npm install @globocom/share-bar
47 | ```
48 |
49 | ## How to Use
50 |
51 | Once you added the CSS and JS from the plugin on the page, you can simply do:
52 |
53 | ```javascript
54 | new ShareBar({'facebookAppId': 'APP_ID'});
55 | ```
56 |
57 | > `APP_ID` can be automatically pulled from the page if you're using Facebook meta tags ([meta tag open graph](https://developers.facebook.com/docs/sharing/webmasters#basic)), but we strongly recommend you to pass it manually.
58 |
59 | Also, place the following markup where you want the share-bar to be:
60 |
61 | ```html
62 |
67 |
68 | ```
69 |
70 | Take a look at our [demo](https://globocom.github.io/share-bar/).
71 |
72 | ## Options
73 |
74 | The plugin also offers a few options for customization.
75 |
76 | ### Selector
77 |
78 | Allows to alter the default selector.
79 |
80 | Default: `.share-bar`
81 |
82 | ```javascript
83 | new ShareBar({selector: '.meu-seletor'});
84 | ```
85 |
86 | ### Theme
87 |
88 | Allows to alter the default theme, using these options: `natural`, `dark`, `minimal` and `minimal light`.
89 |
90 | Default: `'natural'`
91 |
92 | ```javascript
93 | new ShareBar({theme: 'dark'});
94 | ```
95 |
96 | ### classPopup
97 |
98 | Allows to alter the CSS class when opening the share popup windows. This is only necessary when the default class is already in use.
99 |
100 | Default: `'share-popup'`
101 |
102 | ```javascript
103 | new ShareBar({classPopup: 'class-popup'});
104 | ```
105 |
106 | ### buttonWidth
107 |
108 | Allows to alter the reserved width for small buttons. This property does not change the actual button width, it only uses it to calculate how many buttons can fit in the share bar.
109 |
110 | Default: `34`
111 |
112 | ```javascript
113 | new ShareBar({buttonWidth: 50});
114 | ```
115 |
116 | ### buttonFullWidth
117 |
118 | Allows to alter the reserved width for expanded buttons. This property does not change the actual button width, it only uses it to calculate how many buttons can fit in the share bar.
119 |
120 | Default: `110`
121 |
122 | ```javascript
123 | new ShareBar({buttonFullWidth: 150});
124 | ```
125 |
126 | ### buttonPadding
127 |
128 | Allows to alter the reserved left padding for buttons. This property does not change the actual button width, it only uses it to calculate how many buttons can fit in the share bar.
129 |
130 | Default: `4`
131 |
132 | ```javascript
133 | new ShareBar({buttonPadding: 4});
134 | ```
135 |
136 | ### maxSocialButtons
137 |
138 | Allows to alter the maximum quantity of social networks visible in the share bar. This is only necessary if you want to show more than 6 social networks in the bar.
139 |
140 | Default: `6`
141 |
142 | ```javascript
143 | new ShareBar({maxSocialButtons: 10});
144 | ```
145 |
146 | ### networks
147 |
148 | Allows to alter the visible social networks in the share bar. This is the property you use to show or hide social network buttons in the share bar.
149 |
150 | Default:
151 |
152 | ```javascript
153 | [
154 | 'facebook',
155 | 'twitter',
156 | 'whatsapp',
157 | 'google',
158 | 'linkedin',
159 | 'pinterest',
160 | 'email'
161 | ]
162 | ```
163 |
164 | Customize it like this:
165 |
166 | ```javascript
167 | new ShareBar({
168 | 'networks': [
169 | 'facebook',
170 | 'twitter',
171 | function createSampleButton(container, buttonClass) {
172 | var data = this.getMetadataFromElement(container);
173 | buttonClass = buttonClass || '';
174 |
175 | this.createButton(
176 | container, 'sample', buttonClass,
177 | 'http://www.sample.com/sample-sharer.php?u=' + data['url']
178 | );
179 | }
180 | ]
181 | });
182 | ```
183 |
184 | > Note: The WhatsApp icon is only visible on screens with less than 768px of width and are touch capable.
185 |
186 | ### context
187 |
188 | Allows to alter the render context of the bar. This information is sent via `utm_medium` in the URL. This is useful when you have more than one sharebar on the page and you want to filter the actions on Google Analytics.
189 |
190 | Default: `'desktop'`
191 |
192 | ```javascript
193 | new ShareBar({context: 'mobile'});
194 | ```
195 |
196 | ### campaign
197 |
198 | Allows to alter the campaign metadata of the bar. This information is sent via `utm_campaign` in the URL. This is useful when you have more than one sharebar on the page and you want to filter the actions on Google Analytics.
199 |
200 | Default: `'share-bar'`
201 |
202 | ```javascript
203 | new ShareBar({campaign: 'custom-campaign'});
204 | ```
205 |
206 | ### onCreateBar
207 |
208 | A callback that fires when you create the bar. It receives the created bar as a parameter.
209 |
210 | Default: `function (bar) { return false; }`
211 |
212 | ```javascript
213 | new ShareBar({
214 | onCreateBar: function (bar) {
215 | alert(bar.innerHTML);
216 | }
217 | });
218 | ```
219 |
220 | ### onCreateButton
221 |
222 | A callback that fires after a share button is created. It receives the created button as a parameter.
223 |
224 | Default: `function (button) { return false; }`
225 |
226 | ```javascript
227 | new ShareBar({
228 | onCreateBar: function (button) {
229 | alert(button.innerHTML);
230 | }
231 | });
232 | ```
233 |
234 | ### onShare
235 |
236 | A callback that fires after a share button is clicked. It receives the clicked button as a parameter.
237 |
238 | Default: `function (button) { return false; }`
239 |
240 | ```javascript
241 | new ShareBar({
242 | onShare: function (button) {
243 | alert(button.innerHTML);
244 | }
245 | });
246 | ```
247 |
248 | ### createBar
249 |
250 | It's possible to call `createBar` to create the bar manually anytime you want.
251 |
252 | ```javascript
253 | const sharebar = new ShareBar({maxSocialButtons: 10});
254 | sharebar.createBar(document.querySelector('.minha-barra'));
255 | ```
256 |
257 | > Note: For this to work, you need to have the HTML element shown above with the data-attributes already set.
258 |
259 | ## Contributing
260 |
261 | This project depends on NodeJS and NPM.
262 |
263 | To install the project dependencies use:
264 |
265 | ```bash
266 | $ make setup
267 | ```
268 |
269 | To run the tests:
270 |
271 | ```bash
272 | $ make test
273 | ```
274 |
275 | To run a local server for local development use:
276 |
277 | ```bash
278 | $ make run
279 | ```
280 |
281 | ### Icons
282 |
283 | The icons used in this project are SVGs embedded in the JavaScript.
284 |
285 | Adding more icons to the project:
286 |
287 | 1 - Add your SVG to the image path
288 |
289 | ```bash
290 | $ mv ~/caminho/da/imagem.svg caminho/do/share/src/img/
291 | ```
292 |
293 | 2 - Generate the SVG icons again with Grunt
294 |
295 | ```bash
296 | $ grunt icon
297 | ```
298 |
299 | 3 - Alter the CSS and Fonts to accomplish the desired look
300 |
301 | 4 - If you want, add a callback function to the button
302 |
303 |
304 | ## Version
305 |
306 | To generate a new tag version, use this:
307 |
308 | ```bash
309 | $ grunt bump
310 | ```
311 |
312 | ## License
313 |
314 | The MIT License (MIT)
315 |
316 | Copyright (c) 2019 globo.com
317 |
318 | Permission is hereby granted, free of charge, to any person obtaining a copy
319 | of this software and associated documentation files (the "Software"), to deal
320 | in the Software without restriction, including without limitation the rights
321 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
322 | copies of the Software, and to permit persons to whom the Software is
323 | furnished to do so, subject to the following conditions:
324 |
325 | The above copyright notice and this permission notice shall be included in
326 | all copies or substantial portions of the Software.
327 |
328 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
329 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
330 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
331 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
332 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
333 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
334 | THE SOFTWARE.
335 |
--------------------------------------------------------------------------------
/dist/js/share.bar.min.js:
--------------------------------------------------------------------------------
1 | /*! ShareBar - v3.2.0 - 2018-11-08 - * Copyright (c) 2018 Globo.com; Licensed MIT */
2 | function ShareBar(a){"use strict";return this.init(a)}!function(a,b){"use strict";function c(a){a&&a.preventDefault&&a.preventDefault()}function d(){if(void 0===a&&"function"==typeof a.addEventListener){var b=!1,c=Function,d=Object.defineProperty({},"passive",{get:function(){b=!0}});return a.addEventListener("testPassiveEventSupport",c,d),a.removeEventListener("testPassiveEventSupport",c,d),b}}function e(a,b,c){var e=!!d()&&{passive:!0};return a.addEventListener(b,c,e)}var f="facebook",g="twitter",h="whatsapp",i="telegram",j="google",k="linkedin",l="pinterest",m="email",n=34,o=110,p=4,q=6,r="share-button",s="sharebar-svg-container";ShareBar.prototype={init:function(a){this.activeNetworks=[],this.eventName=this.getActionName(),this.verifyTouch(),this.createSVG(),this.mergeOptions(a),this.containers=b.querySelectorAll(this.selector),this.createBars()},destroy:function(){this.containers.forEach(function(a){var b,c=0;for(a.classList.remove("share-bar-container"),c;cemail facebook googleplus linkedin pinterest telegram whatsapp ',a.classList.add(s),a.style.display="none",b.body.appendChild(a))},mergeOptions:function(a){var b,c={selector:".share-bar",campaign:"share-bar",classPopup:"share-popup",facebookAppId:"",networks:[f,g,h,i,j,k,l,m],theme:"natural",buttonWidth:n,buttonFullWidth:o,buttonPadding:p,maxSocialButtons:q,context:"desktop",onCreateBar:function(a){return!1},onCreateButton:function(a){return!1},onShare:function(a){return!1}};a||(a={});for(b in c)c.hasOwnProperty(b)&&(this[b]=a[b]||c[b])},validateNetworks:function(a){var b="The list of networks passed on initialization is wrong",c=0,d="",e="";if("[object Array]"!==Object.prototype.toString.call(a))throw new Error(b+" [Should be an Array]");for(c;ca?this.getButtonsSmall(b,d,a):e?["","","","","",""]:this.getButtonsFull(b,c,d,a)},getButtonsSmall:function(a,b,c){var d=[],e=1,f=0,g=this.isSmallScreen();for(e;e<=a;e++)f=e*b,f<=c?d[e-1]=g?"":" share-small":d[e-1]=" share-hidden";return d},getButtonsFull:function(a,b,c,d){var e=[],f=1,g=0,h=0;for(f;f<=a;f++)g=f*b,h=(a-f)*c,h+g<=d?e[f-1]=" share-full":e[f-1]=" share-small";return e},bindOpenPopup:function(a){var b=a.querySelectorAll("."+this.classPopup),d=0,f=this,g=function(a){f.openPopup.call(this,a)};for(d;d1?f[0]+g+""+f[1]:e+g,{url:d(c),title:d(b.getAttribute("data-title")||""),imageUrl:d(b.getAttribute("data-image-url")||""),hashtags:d(b.getAttribute("data-hashtags")||"")}},isSmallScreen:function(){var b=768,c=a.innerWidth||screen.width;return c',this.createContentButton(c,f),""].join(""),a.appendChild(h),this.onCreateButton(h),h},createContentButton:function(a,b){var c;return b=b||a,c=[' ',' ',' '," ","
",""+b+" "].join("")},createFacebookButton:function(b,d){var g="",h="",i=this.getMetadataFromElement(b),j=i.url.replace("%23source%23",f);h=this.createButton(b,f,d,"http://www.facebook.com/","",!0),this.getFacebookUi(),g=function(){var b=a.decodeURIComponent;FB.ui({method:"feed",display:"popup",link:b(j),name:b(i.title),picture:b(i.imageUrl)})},e(h,this.eventName,g),e(h,"click",c)},getFacebookUi:function(){var c=this.facebookAppId||this.getOgFbAppId();return!a.FB&&void(c&&(a.fbAsyncInit=function(){FB.init({appId:c,xfbml:!0,version:"v2.8"})},function(a,b,c){var d,e=a.getElementsByTagName(b)[0];a.getElementById(c)||(d=a.createElement(b),d.id=c,d.src="//connect.facebook.net/en_US/sdk.js",e.parentNode.insertBefore(d,e))}(b,"script","facebook-jssdk")))},getOgFbAppId:function(){var a=b.querySelector("meta[property='fb:app_id']");if(null!==a)return a.getAttribute("content")},createTwitterButton:function(a,b){var c=this.getMetadataFromElement(a);this.createButton(a,g,b,"https://twitter.com/share?url="+c.url+"&text="+c.title+" "+c.hashtags)},createGoogleButton:function(a,b){var c=this.getMetadataFromElement(a);this.createButton(a,j+"plus",b,"https://plus.google.com/share?url="+c.url,j+"+")},createLinkedinButton:function(a,b){var c=this.getMetadataFromElement(a);this.createButton(a,k,b,"http://www.linkedin.com/shareArticle?mini=true&url="+c.url)},createPinterestButton:function(a,b){var c=this.getMetadataFromElement(a);this.createButton(a,l,b,"http://br.pinterest.com/pin/create/button/?url="+c.url+"&media="+c.imageUrl+"&description="+c.title)},createWhatsappButton:function(a,b){var c=this.getMetadataFromElement(a);return!(!this.isSmallScreen()||!this.isTouch())&&void this.createButton(a,h,b,"whatsapp://send?text="+c.title+"%20"+c.url,"",!0)},createTelegramButton:function(a,b){var c=this.getMetadataFromElement(a);this.createButton(a,i,b,"https://telegram.me/share/url?url="+c.url+"&text="+c.title,"",!0)},createEmailButton:function(a,b){var c=this.getMetadataFromElement(a);return!!this.isTouch()&&void this.createButton(a,m,b,"mailto:?subject="+c.title+"&body="+c.url,"e-mail",!0)}}}(window,document);
--------------------------------------------------------------------------------
/src/js/share.js:
--------------------------------------------------------------------------------
1 | /*global DocumentTouch, FB */
2 |
3 | function ShareBar(options) {
4 | 'use strict';
5 | return this.init(options);
6 | }
7 |
8 | (function (window, document) {
9 | 'use strict';
10 |
11 | var FACEBOOK = 'facebook',
12 | TWITTER = 'twitter',
13 | WHATSAPP = 'whatsapp',
14 | TELEGRAM = 'telegram',
15 | GOOGLE = 'google',
16 | LINKEDIN = 'linkedin',
17 | PINTEREST = 'pinterest',
18 | EMAIL = 'email',
19 | BUTTON_WIDTH = 34,
20 | BUTTON_FULL_WIDTH = 110,
21 | BUTTON_PADDING = 4,
22 | MAX_SOCIAL_BUTTONS = 6,
23 | SHARE_BUTTON = 'share-button',
24 | SVG_CONTAINER = 'sharebar-svg-container';
25 |
26 | function preventDefault(e) {
27 | if (e && e.preventDefault) {
28 | e.preventDefault();
29 | }
30 | }
31 |
32 | function supportPassiveEvents() {
33 | if (window === undefined && typeof window.addEventListener === 'function') {
34 | var support = false,
35 | noop = Function,
36 | options = Object.defineProperty({}, 'passive', {
37 | get: function () { support = true; }
38 | });
39 |
40 | window.addEventListener('testPassiveEventSupport', noop, options);
41 | window.removeEventListener('testPassiveEventSupport', noop, options);
42 | return support;
43 | }
44 | }
45 |
46 | function addEventListener(element, event, handler) {
47 | var useCapture = supportPassiveEvents() ? { passive: true } : false;
48 | return element.addEventListener(event, handler, useCapture);
49 | }
50 |
51 | ShareBar.prototype = {
52 | init: function init(options) {
53 | this.activeNetworks = [];
54 | this.eventName = this.getActionName();
55 | this.verifyTouch();
56 | this.createSVG();
57 | this.mergeOptions(options);
58 | this.containers = document.querySelectorAll(this.selector);
59 | this.createBars();
60 | },
61 |
62 | destroy: function destroy() {
63 | this.containers.forEach(function (container) {
64 | var i = 0, item;
65 |
66 | container.classList.remove('share-bar-container');
67 |
68 | for (i; i < container.classList.length; i++) {
69 | item = container.classList.item(i);
70 |
71 | if (item.indexOf('share-theme') !== -1) {
72 | container.setAttribute('data-theme', item.split('-')[2]);
73 | container.classList.remove(item);
74 | }
75 | }
76 | while (container.firstChild) {
77 | container.removeChild(container.firstChild);
78 | }
79 | });
80 | },
81 |
82 | getActionName: function getActionName() {
83 | return this.isTouch() ? 'mouseup' : 'click';
84 | },
85 |
86 | // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
87 | verifyTouch: function verifyTouch() {
88 | var html = document.querySelector('html'),
89 | isTouch = this.isTouch(),
90 | touch = ' touch',
91 | noTouch = ' no-touch';
92 |
93 | if (isTouch && html.className.indexOf(touch) === -1) {
94 | html.className += touch;
95 |
96 | } else if (!isTouch && html.className.indexOf(noTouch) === -1) {
97 | html.className += noTouch;
98 | }
99 | },
100 |
101 | isTouch: function isTouch() {
102 | var bool = false;
103 |
104 | if (window.ontouchstart !== undefined || (window.DocumentTouch && document instanceof DocumentTouch)) {
105 | bool = true;
106 | }
107 | return bool;
108 | },
109 |
110 | createSVG: function createSVG() {
111 | var hasSvg = document.querySelector('.sharebar-svg-container'),
112 | svg;
113 |
114 | if (!hasSvg) {
115 | svg = document.createElement('div');
116 | svg.innerHTML = '[[X_SVG_X]]';
117 | svg.classList.add(SVG_CONTAINER);
118 | svg.style.display = 'none';
119 |
120 | document.body.appendChild(svg);
121 | }
122 | },
123 |
124 | mergeOptions: function mergeOptions(options) {
125 | var option,
126 | defaultOptions = {
127 | // Selector to open lightbox
128 | selector: '.share-bar',
129 | campaign: 'share-bar',
130 | classPopup: 'share-popup',
131 | facebookAppId: '',
132 | networks: [
133 | FACEBOOK, TWITTER, WHATSAPP, TELEGRAM, GOOGLE, LINKEDIN, PINTEREST, EMAIL
134 | ],
135 | theme: 'natural',
136 | buttonWidth: BUTTON_WIDTH,
137 | buttonFullWidth: BUTTON_FULL_WIDTH,
138 | buttonPadding: BUTTON_PADDING,
139 | maxSocialButtons: MAX_SOCIAL_BUTTONS,
140 | context: 'desktop',
141 | onCreateBar: function (bar) { return false; },
142 | onCreateButton: function (button) { return false; },
143 | onShare: function (button) { return false; }
144 | };
145 |
146 | if (!options) {
147 | options = {};
148 | }
149 |
150 | for (option in defaultOptions) {
151 | if (defaultOptions.hasOwnProperty(option)) {
152 | this[option] = options[option] || defaultOptions[option];
153 | }
154 | }
155 | },
156 |
157 | validateNetworks: function validateNetworks(networks) {
158 | var msg = 'The list of networks passed on initialization is wrong',
159 | i = 0,
160 | networkName = '',
161 | method = '';
162 |
163 | if (Object.prototype.toString.call(networks) !== '[object Array]') {
164 | throw new Error(msg + ' [Should be an Array]');
165 | }
166 |
167 | for (i; i < networks.length; i++) {
168 | if (typeof networks[i] === 'string') {
169 | networkName = networks[i];
170 | networkName = networkName.substr(0, 1).toUpperCase() + networkName.substr(1);
171 | method = ShareBar.prototype['create' + networkName + 'Button'];
172 |
173 | if (method) {
174 | if (this.activeNetworks.indexOf(networks[i]) === -1) {
175 | this.activeNetworks.push(networks[i]);
176 | }
177 |
178 | networks[i] = method;
179 | } else {
180 | throw new Error(msg + ' [Network name "' + networks[i] + '" is wrong, should be ' + FACEBOOK + ' or ' + TWITTER + ' or ' + WHATSAPP + ' or ' + GOOGLE + ' or ' + LINKEDIN + ' or ' + PINTEREST + ' or ' + EMAIL + ']');
181 | }
182 |
183 | } else if (typeof networks[i] !== 'function') {
184 | throw new Error(msg + ' [Should be string or function]');
185 | }
186 | }
187 |
188 | return networks;
189 | },
190 |
191 | createBars: function createBars() {
192 | var items = this.containers,
193 | element = 0;
194 |
195 | for (element = 0; element < items.length; element++) {
196 | this.createBar(items[element]);
197 | }
198 |
199 | },
200 |
201 | createBar: function createBar(element, networks) {
202 | var theme = ' share-theme-',
203 | i = 0,
204 | count = 0,
205 | buttonClasses = [];
206 |
207 | networks = this.validateNetworks(networks || this.networks);
208 | networks = networks.slice(0, this.maxSocialButtons);
209 |
210 | count = networks.length;
211 | buttonClasses = this.getButtonsSize(element.offsetWidth, count);
212 |
213 | for (i; i < count; i++) {
214 | networks[i].call(this, element, buttonClasses[i]);
215 | }
216 |
217 | theme += element.getAttribute('data-theme') || this.theme;
218 | element.className += ' share-bar-container' + theme;
219 | this.bindOpenPopup(element);
220 | this.bindShare(element);
221 | this.onCreateBar(element);
222 | },
223 |
224 | getButtonsSize: function getButtonsSize(containerWidth, numberOfButtons) {
225 | var fullButtonWidth = this.buttonFullWidth + this.buttonPadding,
226 | smallButtonWidth = this.buttonWidth + this.buttonPadding,
227 | isSmallScreen = this.isSmallScreen();
228 |
229 | if ((numberOfButtons * smallButtonWidth) > containerWidth) {
230 | return this.getButtonsSmall(
231 | numberOfButtons,
232 | smallButtonWidth,
233 | containerWidth
234 | );
235 | }
236 |
237 | if (isSmallScreen) {
238 | return ['', '', '', '', '', ''];
239 | }
240 |
241 | return this.getButtonsFull(
242 | numberOfButtons,
243 | fullButtonWidth,
244 | smallButtonWidth,
245 | containerWidth
246 | );
247 | },
248 |
249 | getButtonsSmall: function getButtonsSmall(numberOfButtons, smallButtonWidth, containerWidth) {
250 | var result = [],
251 | i = 1,
252 | totalOfSmallButtons = 0,
253 | isSmallScreen = this.isSmallScreen();
254 |
255 | for (i; i <= numberOfButtons; i++) {
256 | totalOfSmallButtons = i * smallButtonWidth;
257 |
258 | if (totalOfSmallButtons <= containerWidth) {
259 | result[i - 1] = isSmallScreen ? '' : ' share-small';
260 | } else {
261 | result[i - 1] = ' share-hidden';
262 | }
263 | }
264 |
265 | return result;
266 | },
267 |
268 | getButtonsFull: function getButtonsFull(numberOfButtons, fullButtonWidth, smallButtonWidth, containerWidth) {
269 | var result = [],
270 | i = 1,
271 | totalOfFullButtons = 0,
272 | totalOfSmallButtons = 0;
273 |
274 | for (i; i <= numberOfButtons; i++) {
275 | totalOfFullButtons = i * fullButtonWidth;
276 | totalOfSmallButtons = (numberOfButtons - i) * smallButtonWidth;
277 |
278 | if ((totalOfSmallButtons + totalOfFullButtons) <= containerWidth) {
279 | result[i - 1] = ' share-full';
280 | } else {
281 | result[i - 1] = ' share-small';
282 | }
283 | }
284 |
285 | return result;
286 | },
287 |
288 | bindOpenPopup: function bindOpenPopup(element) {
289 | var linksPopup = element.querySelectorAll('.' + this.classPopup),
290 | i = 0,
291 | self = this,
292 | onShareClick = function (e) {
293 | self.openPopup.call(this, e);
294 | };
295 |
296 | for (i; i < linksPopup.length; i++) {
297 | addEventListener(linksPopup[i], this.eventName, onShareClick);
298 | addEventListener(linksPopup[i], 'click', preventDefault);
299 | }
300 | },
301 |
302 | bindShare: function bindShare(element) {
303 | var shareButtons = element.querySelectorAll('.' + SHARE_BUTTON),
304 | i = 0,
305 | self = this,
306 | onShareClick = function (e) {
307 | self.onShare(this);
308 | };
309 |
310 | for (i; i < shareButtons.length; i++) {
311 | addEventListener(shareButtons[i], this.eventName, onShareClick);
312 | }
313 | },
314 |
315 | openPopup: function openPopup(e) {
316 | var win = window.open(
317 | this.getAttribute('href'),
318 | 'popup',
319 | 'height=400,width=500,left=10,top=10,resizable=yes,scrollbars=no,toolbar=no,menubar=no,location=no,directories=no,status=no'
320 | );
321 |
322 | win.focus();
323 | },
324 |
325 | getMetadataFromElement: function getMetadataFromElement(element) {
326 | var encode = window.encodeURIComponent,
327 | url = element.getAttribute('data-url') || '',
328 | urlToShare,
329 | splitUrl = url.split('#'),
330 | queryString = '?utm_source=#source#&utm_medium=share-bar-' + this.context + '&utm_campaign=' + this.campaign;
331 |
332 | if (splitUrl.length > 1) {
333 | urlToShare = splitUrl[0] + queryString + '' + splitUrl[1];
334 | } else {
335 | urlToShare = url + queryString;
336 | }
337 |
338 | return {
339 | 'url': encode(urlToShare),
340 | 'title': encode(element.getAttribute('data-title') || ''),
341 | 'imageUrl': encode(element.getAttribute('data-image-url') || ''),
342 | 'hashtags': encode(element.getAttribute('data-hashtags') || '')
343 | };
344 | },
345 |
346 | isSmallScreen: function isSmallScreen() {
347 | var desktopMinWidth = 768,
348 | width = window.innerWidth || screen.width;
349 | return width < desktopMinWidth;
350 | },
351 |
352 | createButton: function createButton(container, socialNetworkClass, className, url, socialNetworkTitle, openInPage) {
353 | var shareContainer = document.createElement('div'),
354 | classPopup = '';
355 | socialNetworkTitle = socialNetworkTitle || socialNetworkClass;
356 | className = className || '';
357 | shareContainer.className = SHARE_BUTTON + ' share-' + socialNetworkClass + className;
358 | socialNetworkTitle = socialNetworkTitle[0].toUpperCase() + socialNetworkTitle.slice(1);
359 | url = url.replace('%23source%23', socialNetworkClass);
360 |
361 | if (!openInPage) {
362 | classPopup = this.classPopup;
363 | }
364 |
365 | shareContainer.innerHTML = [
366 | ''
369 | ].join('');
370 |
371 | container.appendChild(shareContainer);
372 | this.onCreateButton(shareContainer);
373 |
374 | return shareContainer;
375 | },
376 |
377 | createContentButton: function createContentButton(name, title) {
378 | var iconElement;
379 | title = title || name;
380 |
381 | iconElement = [
382 | ' ',
383 | ' ',
384 | ' ',
385 | ' ',
386 | '
',
387 | '' + title + ' '
388 | ].join('');
389 |
390 | return iconElement;
391 | },
392 |
393 | createFacebookButton: function createFacebookButton(container, buttonClass) {
394 | var onShare = '',
395 | button = '',
396 | data = this.getMetadataFromElement(container),
397 | url = data.url.replace('%23source%23', FACEBOOK);
398 |
399 | button = this.createButton(
400 | container,
401 | FACEBOOK,
402 | buttonClass,
403 | 'http://www.facebook.com/',
404 | '',
405 | true
406 | );
407 |
408 | this.getFacebookUi();
409 |
410 | onShare = function () {
411 | var decode = window.decodeURIComponent;
412 |
413 | FB.ui({
414 | method: 'feed',
415 | display: 'popup',
416 | link: decode(url),
417 | name: decode(data.title),
418 | picture: decode(data.imageUrl)
419 | });
420 | };
421 |
422 | addEventListener(button, this.eventName, onShare);
423 | addEventListener(button, 'click', preventDefault);
424 | },
425 |
426 | getFacebookUi: function getFacebookUi() {
427 | var facebookAppId = this.facebookAppId || this.getOgFbAppId();
428 |
429 | if (window.FB) {
430 | return false;
431 | }
432 |
433 | if (facebookAppId) {
434 | window.fbAsyncInit = function () {
435 | FB.init({
436 | appId: facebookAppId,
437 | xfbml: true,
438 | version: 'v2.8'
439 | });
440 | };
441 | (function (d, s, id) {
442 | var js, fjs = d.getElementsByTagName(s)[0];
443 | if (d.getElementById(id)) { return; }
444 | js = d.createElement(s);
445 | js.id = id;
446 | js.src = "//connect.facebook.net/en_US/sdk.js";
447 | fjs.parentNode.insertBefore(js, fjs);
448 | }(document, 'script', 'facebook-jssdk'));
449 | }
450 |
451 | },
452 |
453 | getOgFbAppId: function () {
454 | var el = document.querySelector("meta[property='fb:app_id']");
455 |
456 | if (el !== null) {
457 | return el.getAttribute('content');
458 | }
459 | return;
460 | },
461 |
462 | createTwitterButton: function createTwitterButton(container, buttonClass) {
463 | var data = this.getMetadataFromElement(container);
464 |
465 | this.createButton(
466 | container,
467 | TWITTER,
468 | buttonClass,
469 | 'https://twitter.com/share?url=' + data.url + '&text=' + data.title + ' ' + data.hashtags
470 | );
471 | },
472 |
473 | createGoogleButton: function createGoogleButton(container, buttonClass) {
474 | var data = this.getMetadataFromElement(container);
475 |
476 | this.createButton(
477 | container,
478 | GOOGLE + 'plus',
479 | buttonClass,
480 | 'https://plus.google.com/share?url=' + data.url,
481 | GOOGLE + '+'
482 | );
483 | },
484 |
485 | createLinkedinButton: function createLinkedinButton(container, buttonClass) {
486 | var data = this.getMetadataFromElement(container);
487 |
488 | this.createButton(
489 | container,
490 | LINKEDIN,
491 | buttonClass,
492 | 'http://www.linkedin.com/shareArticle?mini=true&url=' + data.url
493 | );
494 | },
495 |
496 | createPinterestButton: function createPinterestButton(container, buttonClass) {
497 | var data = this.getMetadataFromElement(container);
498 |
499 | this.createButton(
500 | container,
501 | PINTEREST,
502 | buttonClass,
503 | 'http://br.pinterest.com/pin/create/button/?url=' + data.url + '&media=' + data.imageUrl + '&description=' + data.title
504 | );
505 | },
506 |
507 | createWhatsappButton: function createWhatsappButton(container, buttonClass) {
508 | var data = this.getMetadataFromElement(container);
509 |
510 | if (!this.isSmallScreen() || !this.isTouch()) {
511 | return false;
512 | }
513 |
514 | this.createButton(
515 | container,
516 | WHATSAPP,
517 | buttonClass,
518 | 'whatsapp://send?text=' + data.title + '%20' + data.url,
519 | '',
520 | true
521 | );
522 | },
523 |
524 | createTelegramButton: function createTelegramButton(container, buttonClass) {
525 | var data = this.getMetadataFromElement(container);
526 |
527 | this.createButton(
528 | container,
529 | TELEGRAM,
530 | buttonClass,
531 | 'https://telegram.me/share/url?url=' + data.url + '&text=' + data.title,
532 | '',
533 | true
534 | );
535 | },
536 |
537 | createEmailButton: function createEmailButton(container, buttonClass) {
538 | var data = this.getMetadataFromElement(container);
539 |
540 | if (!this.isTouch()) {
541 | return false;
542 | }
543 |
544 | this.createButton(
545 | container,
546 | EMAIL,
547 | buttonClass,
548 | 'mailto:?subject=' + data.title + '&body=' + data.url,
549 | 'e-mail',
550 | true
551 | );
552 | }
553 | };
554 |
555 | }(window, document));
556 |
--------------------------------------------------------------------------------
/dist/js/share.bar.js:
--------------------------------------------------------------------------------
1 | /*! ShareBar - v3.2.0 - 2018-11-08 - * Copyright (c) 2018 Globo.com; Licensed MIT */
2 | function ShareBar(options) {
3 | 'use strict';
4 | return this.init(options);
5 | }
6 |
7 | (function (window, document) {
8 | 'use strict';
9 |
10 | var FACEBOOK = 'facebook',
11 | TWITTER = 'twitter',
12 | WHATSAPP = 'whatsapp',
13 | TELEGRAM = 'telegram',
14 | GOOGLE = 'google',
15 | LINKEDIN = 'linkedin',
16 | PINTEREST = 'pinterest',
17 | EMAIL = 'email',
18 | BUTTON_WIDTH = 34,
19 | BUTTON_FULL_WIDTH = 110,
20 | BUTTON_PADDING = 4,
21 | MAX_SOCIAL_BUTTONS = 6,
22 | SHARE_BUTTON = 'share-button',
23 | SVG_CONTAINER = 'sharebar-svg-container';
24 |
25 | function preventDefault(e) {
26 | if (e && e.preventDefault) {
27 | e.preventDefault();
28 | }
29 | }
30 |
31 | function supportPassiveEvents() {
32 | if (window === undefined && typeof window.addEventListener === 'function') {
33 | var support = false,
34 | noop = Function,
35 | options = Object.defineProperty({}, 'passive', {
36 | get: function () { support = true; }
37 | });
38 |
39 | window.addEventListener('testPassiveEventSupport', noop, options);
40 | window.removeEventListener('testPassiveEventSupport', noop, options);
41 | return support;
42 | }
43 | }
44 |
45 | function addEventListener(element, event, handler) {
46 | var useCapture = supportPassiveEvents() ? { passive: true } : false;
47 | return element.addEventListener(event, handler, useCapture);
48 | }
49 |
50 | ShareBar.prototype = {
51 | init: function init(options) {
52 | this.activeNetworks = [];
53 | this.eventName = this.getActionName();
54 | this.verifyTouch();
55 | this.createSVG();
56 | this.mergeOptions(options);
57 | this.containers = document.querySelectorAll(this.selector);
58 | this.createBars();
59 | },
60 |
61 | destroy: function destroy() {
62 | this.containers.forEach(function (container) {
63 | var i = 0, item;
64 |
65 | container.classList.remove('share-bar-container');
66 |
67 | for (i; i < container.classList.length; i++) {
68 | item = container.classList.item(i);
69 |
70 | if (item.indexOf('share-theme') !== -1) {
71 | container.setAttribute('data-theme', item.split('-')[2]);
72 | container.classList.remove(item);
73 | }
74 | }
75 | while (container.firstChild) {
76 | container.removeChild(container.firstChild);
77 | }
78 | });
79 | },
80 |
81 | getActionName: function getActionName() {
82 | return this.isTouch() ? 'mouseup' : 'click';
83 | },
84 |
85 | // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
86 | verifyTouch: function verifyTouch() {
87 | var html = document.querySelector('html'),
88 | isTouch = this.isTouch(),
89 | touch = ' touch',
90 | noTouch = ' no-touch';
91 |
92 | if (isTouch && html.className.indexOf(touch) === -1) {
93 | html.className += touch;
94 |
95 | } else if (!isTouch && html.className.indexOf(noTouch) === -1) {
96 | html.className += noTouch;
97 | }
98 | },
99 |
100 | isTouch: function isTouch() {
101 | var bool = false;
102 |
103 | if (window.ontouchstart !== undefined || (window.DocumentTouch && document instanceof DocumentTouch)) {
104 | bool = true;
105 | }
106 | return bool;
107 | },
108 |
109 | createSVG: function createSVG() {
110 | var hasSvg = document.querySelector('.sharebar-svg-container'),
111 | svg;
112 |
113 | if (!hasSvg) {
114 | svg = document.createElement('div');
115 | svg.innerHTML = 'email facebook googleplus linkedin pinterest telegram whatsapp ';
116 | svg.classList.add(SVG_CONTAINER);
117 | svg.style.display = 'none';
118 |
119 | document.body.appendChild(svg);
120 | }
121 | },
122 |
123 | mergeOptions: function mergeOptions(options) {
124 | var option,
125 | defaultOptions = {
126 | // Selector to open lightbox
127 | selector: '.share-bar',
128 | campaign: 'share-bar',
129 | classPopup: 'share-popup',
130 | facebookAppId: '',
131 | networks: [
132 | FACEBOOK, TWITTER, WHATSAPP, TELEGRAM, GOOGLE, LINKEDIN, PINTEREST, EMAIL
133 | ],
134 | theme: 'natural',
135 | buttonWidth: BUTTON_WIDTH,
136 | buttonFullWidth: BUTTON_FULL_WIDTH,
137 | buttonPadding: BUTTON_PADDING,
138 | maxSocialButtons: MAX_SOCIAL_BUTTONS,
139 | context: 'desktop',
140 | onCreateBar: function (bar) { return false; },
141 | onCreateButton: function (button) { return false; },
142 | onShare: function (button) { return false; }
143 | };
144 |
145 | if (!options) {
146 | options = {};
147 | }
148 |
149 | for (option in defaultOptions) {
150 | if (defaultOptions.hasOwnProperty(option)) {
151 | this[option] = options[option] || defaultOptions[option];
152 | }
153 | }
154 | },
155 |
156 | validateNetworks: function validateNetworks(networks) {
157 | var msg = 'The list of networks passed on initialization is wrong',
158 | i = 0,
159 | networkName = '',
160 | method = '';
161 |
162 | if (Object.prototype.toString.call(networks) !== '[object Array]') {
163 | throw new Error(msg + ' [Should be an Array]');
164 | }
165 |
166 | for (i; i < networks.length; i++) {
167 | if (typeof networks[i] === 'string') {
168 | networkName = networks[i];
169 | networkName = networkName.substr(0, 1).toUpperCase() + networkName.substr(1);
170 | method = ShareBar.prototype['create' + networkName + 'Button'];
171 |
172 | if (method) {
173 | if (this.activeNetworks.indexOf(networks[i]) === -1) {
174 | this.activeNetworks.push(networks[i]);
175 | }
176 |
177 | networks[i] = method;
178 | } else {
179 | throw new Error(msg + ' [Network name "' + networks[i] + '" is wrong, should be ' + FACEBOOK + ' or ' + TWITTER + ' or ' + WHATSAPP + ' or ' + GOOGLE + ' or ' + LINKEDIN + ' or ' + PINTEREST + ' or ' + EMAIL + ']');
180 | }
181 |
182 | } else if (typeof networks[i] !== 'function') {
183 | throw new Error(msg + ' [Should be string or function]');
184 | }
185 | }
186 |
187 | return networks;
188 | },
189 |
190 | createBars: function createBars() {
191 | var items = this.containers,
192 | element = 0;
193 |
194 | for (element = 0; element < items.length; element++) {
195 | this.createBar(items[element]);
196 | }
197 |
198 | },
199 |
200 | createBar: function createBar(element, networks) {
201 | var theme = ' share-theme-',
202 | i = 0,
203 | count = 0,
204 | buttonClasses = [];
205 |
206 | networks = this.validateNetworks(networks || this.networks);
207 | networks = networks.slice(0, this.maxSocialButtons);
208 |
209 | count = networks.length;
210 | buttonClasses = this.getButtonsSize(element.offsetWidth, count);
211 |
212 | for (i; i < count; i++) {
213 | networks[i].call(this, element, buttonClasses[i]);
214 | }
215 |
216 | theme += element.getAttribute('data-theme') || this.theme;
217 | element.className += ' share-bar-container' + theme;
218 | this.bindOpenPopup(element);
219 | this.bindShare(element);
220 | this.onCreateBar(element);
221 | },
222 |
223 | getButtonsSize: function getButtonsSize(containerWidth, numberOfButtons) {
224 | var fullButtonWidth = this.buttonFullWidth + this.buttonPadding,
225 | smallButtonWidth = this.buttonWidth + this.buttonPadding,
226 | isSmallScreen = this.isSmallScreen();
227 |
228 | if ((numberOfButtons * smallButtonWidth) > containerWidth) {
229 | return this.getButtonsSmall(
230 | numberOfButtons,
231 | smallButtonWidth,
232 | containerWidth
233 | );
234 | }
235 |
236 | if (isSmallScreen) {
237 | return ['', '', '', '', '', ''];
238 | }
239 |
240 | return this.getButtonsFull(
241 | numberOfButtons,
242 | fullButtonWidth,
243 | smallButtonWidth,
244 | containerWidth
245 | );
246 | },
247 |
248 | getButtonsSmall: function getButtonsSmall(numberOfButtons, smallButtonWidth, containerWidth) {
249 | var result = [],
250 | i = 1,
251 | totalOfSmallButtons = 0,
252 | isSmallScreen = this.isSmallScreen();
253 |
254 | for (i; i <= numberOfButtons; i++) {
255 | totalOfSmallButtons = i * smallButtonWidth;
256 |
257 | if (totalOfSmallButtons <= containerWidth) {
258 | result[i - 1] = isSmallScreen ? '' : ' share-small';
259 | } else {
260 | result[i - 1] = ' share-hidden';
261 | }
262 | }
263 |
264 | return result;
265 | },
266 |
267 | getButtonsFull: function getButtonsFull(numberOfButtons, fullButtonWidth, smallButtonWidth, containerWidth) {
268 | var result = [],
269 | i = 1,
270 | totalOfFullButtons = 0,
271 | totalOfSmallButtons = 0;
272 |
273 | for (i; i <= numberOfButtons; i++) {
274 | totalOfFullButtons = i * fullButtonWidth;
275 | totalOfSmallButtons = (numberOfButtons - i) * smallButtonWidth;
276 |
277 | if ((totalOfSmallButtons + totalOfFullButtons) <= containerWidth) {
278 | result[i - 1] = ' share-full';
279 | } else {
280 | result[i - 1] = ' share-small';
281 | }
282 | }
283 |
284 | return result;
285 | },
286 |
287 | bindOpenPopup: function bindOpenPopup(element) {
288 | var linksPopup = element.querySelectorAll('.' + this.classPopup),
289 | i = 0,
290 | self = this,
291 | onShareClick = function (e) {
292 | self.openPopup.call(this, e);
293 | };
294 |
295 | for (i; i < linksPopup.length; i++) {
296 | addEventListener(linksPopup[i], this.eventName, onShareClick);
297 | addEventListener(linksPopup[i], 'click', preventDefault);
298 | }
299 | },
300 |
301 | bindShare: function bindShare(element) {
302 | var shareButtons = element.querySelectorAll('.' + SHARE_BUTTON),
303 | i = 0,
304 | self = this,
305 | onShareClick = function (e) {
306 | self.onShare(this);
307 | };
308 |
309 | for (i; i < shareButtons.length; i++) {
310 | addEventListener(shareButtons[i], this.eventName, onShareClick);
311 | }
312 | },
313 |
314 | openPopup: function openPopup(e) {
315 | var win = window.open(
316 | this.getAttribute('href'),
317 | 'popup',
318 | 'height=400,width=500,left=10,top=10,resizable=yes,scrollbars=no,toolbar=no,menubar=no,location=no,directories=no,status=no'
319 | );
320 |
321 | win.focus();
322 | },
323 |
324 | getMetadataFromElement: function getMetadataFromElement(element) {
325 | var encode = window.encodeURIComponent,
326 | url = element.getAttribute('data-url') || '',
327 | urlToShare,
328 | splitUrl = url.split('#'),
329 | queryString = '?utm_source=#source#&utm_medium=share-bar-' + this.context + '&utm_campaign=' + this.campaign;
330 |
331 | if (splitUrl.length > 1) {
332 | urlToShare = splitUrl[0] + queryString + '' + splitUrl[1];
333 | } else {
334 | urlToShare = url + queryString;
335 | }
336 |
337 | return {
338 | 'url': encode(urlToShare),
339 | 'title': encode(element.getAttribute('data-title') || ''),
340 | 'imageUrl': encode(element.getAttribute('data-image-url') || ''),
341 | 'hashtags': encode(element.getAttribute('data-hashtags') || '')
342 | };
343 | },
344 |
345 | isSmallScreen: function isSmallScreen() {
346 | var desktopMinWidth = 768,
347 | width = window.innerWidth || screen.width;
348 | return width < desktopMinWidth;
349 | },
350 |
351 | createButton: function createButton(container, socialNetworkClass, className, url, socialNetworkTitle, openInPage) {
352 | var shareContainer = document.createElement('div'),
353 | classPopup = '';
354 | socialNetworkTitle = socialNetworkTitle || socialNetworkClass;
355 | className = className || '';
356 | shareContainer.className = SHARE_BUTTON + ' share-' + socialNetworkClass + className;
357 | socialNetworkTitle = socialNetworkTitle[0].toUpperCase() + socialNetworkTitle.slice(1);
358 | url = url.replace('%23source%23', socialNetworkClass);
359 |
360 | if (!openInPage) {
361 | classPopup = this.classPopup;
362 | }
363 |
364 | shareContainer.innerHTML = [
365 | ''
368 | ].join('');
369 |
370 | container.appendChild(shareContainer);
371 | this.onCreateButton(shareContainer);
372 |
373 | return shareContainer;
374 | },
375 |
376 | createContentButton: function createContentButton(name, title) {
377 | var iconElement;
378 | title = title || name;
379 |
380 | iconElement = [
381 | ' ',
382 | ' ',
383 | ' ',
384 | ' ',
385 | '
',
386 | '' + title + ' '
387 | ].join('');
388 |
389 | return iconElement;
390 | },
391 |
392 | createFacebookButton: function createFacebookButton(container, buttonClass) {
393 | var onShare = '',
394 | button = '',
395 | data = this.getMetadataFromElement(container),
396 | url = data.url.replace('%23source%23', FACEBOOK);
397 |
398 | button = this.createButton(
399 | container,
400 | FACEBOOK,
401 | buttonClass,
402 | 'http://www.facebook.com/',
403 | '',
404 | true
405 | );
406 |
407 | this.getFacebookUi();
408 |
409 | onShare = function () {
410 | var decode = window.decodeURIComponent;
411 |
412 | FB.ui({
413 | method: 'feed',
414 | display: 'popup',
415 | link: decode(url),
416 | name: decode(data.title),
417 | picture: decode(data.imageUrl)
418 | });
419 | };
420 |
421 | addEventListener(button, this.eventName, onShare);
422 | addEventListener(button, 'click', preventDefault);
423 | },
424 |
425 | getFacebookUi: function getFacebookUi() {
426 | var facebookAppId = this.facebookAppId || this.getOgFbAppId();
427 |
428 | if (window.FB) {
429 | return false;
430 | }
431 |
432 | if (facebookAppId) {
433 | window.fbAsyncInit = function () {
434 | FB.init({
435 | appId: facebookAppId,
436 | xfbml: true,
437 | version: 'v2.8'
438 | });
439 | };
440 | (function (d, s, id) {
441 | var js, fjs = d.getElementsByTagName(s)[0];
442 | if (d.getElementById(id)) { return; }
443 | js = d.createElement(s);
444 | js.id = id;
445 | js.src = "//connect.facebook.net/en_US/sdk.js";
446 | fjs.parentNode.insertBefore(js, fjs);
447 | }(document, 'script', 'facebook-jssdk'));
448 | }
449 |
450 | },
451 |
452 | getOgFbAppId: function () {
453 | var el = document.querySelector("meta[property='fb:app_id']");
454 |
455 | if (el !== null) {
456 | return el.getAttribute('content');
457 | }
458 | return;
459 | },
460 |
461 | createTwitterButton: function createTwitterButton(container, buttonClass) {
462 | var data = this.getMetadataFromElement(container);
463 |
464 | this.createButton(
465 | container,
466 | TWITTER,
467 | buttonClass,
468 | 'https://twitter.com/share?url=' + data.url + '&text=' + data.title + ' ' + data.hashtags
469 | );
470 | },
471 |
472 | createGoogleButton: function createGoogleButton(container, buttonClass) {
473 | var data = this.getMetadataFromElement(container);
474 |
475 | this.createButton(
476 | container,
477 | GOOGLE + 'plus',
478 | buttonClass,
479 | 'https://plus.google.com/share?url=' + data.url,
480 | GOOGLE + '+'
481 | );
482 | },
483 |
484 | createLinkedinButton: function createLinkedinButton(container, buttonClass) {
485 | var data = this.getMetadataFromElement(container);
486 |
487 | this.createButton(
488 | container,
489 | LINKEDIN,
490 | buttonClass,
491 | 'http://www.linkedin.com/shareArticle?mini=true&url=' + data.url
492 | );
493 | },
494 |
495 | createPinterestButton: function createPinterestButton(container, buttonClass) {
496 | var data = this.getMetadataFromElement(container);
497 |
498 | this.createButton(
499 | container,
500 | PINTEREST,
501 | buttonClass,
502 | 'http://br.pinterest.com/pin/create/button/?url=' + data.url + '&media=' + data.imageUrl + '&description=' + data.title
503 | );
504 | },
505 |
506 | createWhatsappButton: function createWhatsappButton(container, buttonClass) {
507 | var data = this.getMetadataFromElement(container);
508 |
509 | if (!this.isSmallScreen() || !this.isTouch()) {
510 | return false;
511 | }
512 |
513 | this.createButton(
514 | container,
515 | WHATSAPP,
516 | buttonClass,
517 | 'whatsapp://send?text=' + data.title + '%20' + data.url,
518 | '',
519 | true
520 | );
521 | },
522 |
523 | createTelegramButton: function createTelegramButton(container, buttonClass) {
524 | var data = this.getMetadataFromElement(container);
525 |
526 | this.createButton(
527 | container,
528 | TELEGRAM,
529 | buttonClass,
530 | 'https://telegram.me/share/url?url=' + data.url + '&text=' + data.title,
531 | '',
532 | true
533 | );
534 | },
535 |
536 | createEmailButton: function createEmailButton(container, buttonClass) {
537 | var data = this.getMetadataFromElement(container);
538 |
539 | if (!this.isTouch()) {
540 | return false;
541 | }
542 |
543 | this.createButton(
544 | container,
545 | EMAIL,
546 | buttonClass,
547 | 'mailto:?subject=' + data.title + '&body=' + data.url,
548 | 'e-mail',
549 | true
550 | );
551 | }
552 | };
553 |
554 | }(window, document));
555 |
--------------------------------------------------------------------------------
/tests/share.spec.js:
--------------------------------------------------------------------------------
1 | /*global describe, it, expect, spyOn,
2 | beforeEach, afterEach, jasmine, xit, ShareBar, FB */
3 |
4 | function createBar(options) {
5 | 'use strict';
6 | return new ShareBar(options);
7 | }
8 |
9 | function click(element) {
10 | 'use strict';
11 | var event = document.createEvent('MouseEvents');
12 | event.initMouseEvent('click', true, true, window, 1, 0, 0);
13 | element.dispatchEvent(event);
14 | return event;
15 | }
16 |
17 | function createShareContainer(hashUrl) {
18 | 'use strict';
19 | var element = document.createElement('div');
20 | element.className = 'share-bar';
21 |
22 | if (hashUrl) {
23 | element.setAttribute('data-url', 'http://globo.com' + hashUrl);
24 | } else {
25 | element.setAttribute('data-url', 'http://globo.com');
26 | }
27 | element.setAttribute('data-title', 'Test title');
28 | element.setAttribute('data-image-url', 'http://g1.globo.com');
29 | element.setAttribute('data-hashtags', '#test #g1');
30 | document.body.appendChild(element);
31 | return element;
32 | }
33 |
34 | function createPopupElement() {
35 | 'use strict';
36 | var element = document.createElement('a');
37 | element.className = 'share-button share-popup';
38 | element.setAttribute('href', '#');
39 | document.body.appendChild(element);
40 | return element;
41 | }
42 |
43 | describe('ShareBar - Setup Test Case', function () {
44 | 'use strict';
45 |
46 | describe('setup', function () {
47 | it('should have ShareBar plugin on page', function () {
48 | expect(ShareBar).not.toBe(undefined);
49 | });
50 |
51 | it('should call init method on instance new bar', function () {
52 | var spy = spyOn(ShareBar.prototype, 'init');
53 | createBar();
54 | expect(spy).toHaveBeenCalled();
55 | });
56 | });
57 |
58 | describe('init', function () {
59 | it('should call createSVG method', function () {
60 | var spy = spyOn(ShareBar.prototype, 'createSVG');
61 | createBar();
62 | expect(spy).toHaveBeenCalled();
63 | });
64 |
65 | it('should call mergeOptions method', function () {
66 | var spy = spyOn(ShareBar.prototype, 'mergeOptions'),
67 | options = {'selector': '.test'};
68 | createBar(options);
69 | expect(spy).toHaveBeenCalledWith(options);
70 | });
71 |
72 | it('should call createBars method', function () {
73 | var spy = spyOn(ShareBar.prototype, 'createBars');
74 | createBar();
75 | expect(spy).toHaveBeenCalled();
76 | });
77 |
78 | it('should set containers atribute with selected elements', function () {
79 | var newBar;
80 | spyOn(ShareBar.prototype, 'createBars');
81 | newBar = createBar();
82 | expect(newBar.containers[0]).toEqual(this.el);
83 | });
84 | });
85 | });
86 |
87 | describe('ShareBar - Methods Test Case', function () {
88 | 'use strict';
89 | var facebookAppId = "1234";
90 |
91 | beforeEach(function () {
92 | this.el = createShareContainer();
93 |
94 | this.newBar = createBar({
95 | 'selector': '.no-elements',
96 | 'buttonWidth': 21,
97 | 'buttonFullWidth': 46,
98 | 'buttonPadding': 4
99 | });
100 | this.newBar.containers = [];
101 | this.newBar.supportSvg = true;
102 | });
103 |
104 | afterEach(function () {
105 | document.body.removeChild(this.el);
106 | });
107 |
108 | describe('destroy', function () {
109 | it('should remove class \'share-bar-container\' and \'share-theme\' ', function () {
110 | this.newBar.containers = [this.el];
111 | this.newBar.createBars();
112 | this.newBar.destroy();
113 | expect(this.newBar.containers[0].classList.toString()).toEqual('share-bar');
114 | });
115 |
116 | it('should remove all childdren from container', function () {
117 | this.newBar.containers = [this.el];
118 | this.newBar.createBars();
119 | this.newBar.destroy();
120 | expect(this.newBar.containers[0].childElementCount).toEqual(0);
121 | });
122 | });
123 |
124 | describe('mergeOptions', function () {
125 | it('should create properties with defaultOptions', function () {
126 | this.newBar.mergeOptions();
127 |
128 | expect(this.newBar.selector).toEqual('.share-bar');
129 | expect(this.newBar.classPopup).toEqual('share-popup');
130 | expect(this.newBar.facebookAppId).toEqual('');
131 | expect(this.newBar.networks).toEqual([
132 | 'facebook',
133 | 'twitter',
134 | 'whatsapp',
135 | 'telegram',
136 | 'google',
137 | 'linkedin',
138 | 'pinterest',
139 | 'email'
140 | ]);
141 | expect(this.newBar.theme).toEqual('natural');
142 | });
143 |
144 | it('should merge options with defaultOptions', function () {
145 | this.newBar.mergeOptions({'selector': 'test'});
146 | expect(this.newBar.selector).toEqual('test');
147 | });
148 |
149 | it('should not create options when not exists in defaultOptions', function () {
150 | this.newBar.mergeOptions({'selectorEspecial': 'test'});
151 | expect(this.newBar.selectorEspecial).toBe(undefined);
152 | });
153 | });
154 |
155 | describe('validateNetworks', function () {
156 | it('should throw an error when networks is not an array', function () {
157 | var self = this;
158 |
159 | expect(
160 | function () {self.newBar.validateNetworks('facebook'); }
161 | ).toThrow(
162 | new Error('The list of networks passed on initialization is wrong [Should be an Array]')
163 | );
164 | });
165 |
166 | it('should find method to create network button by name', function () {
167 | var networks = this.newBar.validateNetworks(['facebook']);
168 | expect(networks).toEqual([this.newBar.createFacebookButton]);
169 | });
170 |
171 | it('should find methods to create any networks button by names', function () {
172 | var networks = this.newBar.validateNetworks(['facebook', 'twitter']);
173 | expect(networks).toEqual([this.newBar.createFacebookButton, this.newBar.createTwitterButton]);
174 | });
175 |
176 | it('should throw an error when can not find method by name', function () {
177 | var self = this;
178 |
179 | expect(
180 | function () {self.newBar.validateNetworks(['facebrrk']); }
181 | ).toThrow(
182 | new Error('The list of networks passed on initialization is wrong [Network name "facebrrk" is wrong, should be facebook or twitter or whatsapp or google or linkedin or pinterest or email]')
183 | );
184 | });
185 |
186 | it('should set a function when function is passed', function () {
187 | var myNetworkFunction = function () { return true; },
188 | networks = this.newBar.validateNetworks([myNetworkFunction]);
189 | expect(networks).toEqual([myNetworkFunction]);
190 | });
191 |
192 | it('should throw an error when something other than string or function', function () {
193 | var self = this;
194 |
195 | expect(
196 | function () {self.newBar.validateNetworks([{'object': 'error'}]); }
197 | ).toThrow(
198 | new Error('The list of networks passed on initialization is wrong [Should be string or function]')
199 | );
200 | });
201 |
202 | it('should keep available networks in an instance var activeNetworks', function () {
203 | this.newBar.validateNetworks(['facebook', 'twitter']);
204 | expect(this.newBar.activeNetworks).toEqual(['facebook', 'twitter']);
205 | });
206 | });
207 |
208 | describe('bindOpenPopup', function () {
209 | beforeEach(function () {
210 | this.newBar.eventName = 'click';
211 | });
212 |
213 | it('should call addEventListener function for each popup element', function () {
214 | var popups = [createPopupElement(), createPopupElement()],
215 | spies = [];
216 |
217 | this.el.appendChild(popups[0]);
218 | this.el.appendChild(popups[1]);
219 |
220 | spies[0] = spyOn(popups[0], 'addEventListener');
221 | spies[1] = spyOn(popups[1], 'addEventListener');
222 |
223 | this.newBar.bindOpenPopup(this.el);
224 |
225 | expect(spies[0]).toHaveBeenCalledWith('click', jasmine.any(Function), false);
226 | expect(spies[1]).toHaveBeenCalledWith('click', jasmine.any(Function), false);
227 | });
228 |
229 | it('should call openPopup on click in popup element', function () {
230 | var popup = createPopupElement(),
231 | spy = spyOn(ShareBar.prototype, 'openPopup'),
232 | eventClick = '';
233 |
234 | this.el.appendChild(popup);
235 |
236 | this.newBar.bindOpenPopup(this.el);
237 | eventClick = click(popup);
238 |
239 | expect(spy).toHaveBeenCalledWith(eventClick);
240 | });
241 | });
242 |
243 | describe('bindShare', function () {
244 | beforeEach(function () {
245 | this.newBar.eventName = 'click';
246 | });
247 |
248 | it('should call onShare callback on click in share button', function () {
249 | var popup = createPopupElement(),
250 | spy = spyOn(this.newBar, 'onShare');
251 |
252 | this.el.appendChild(popup);
253 |
254 | this.newBar.bindShare(this.el);
255 | click(popup);
256 |
257 | expect(spy).toHaveBeenCalledWith(popup);
258 | });
259 |
260 | it('should call onShare callback on click in any element in share button', function () {
261 | var popup = createPopupElement(),
262 | span = document.createElement('span'),
263 | spy = spyOn(this.newBar, 'onShare');
264 |
265 | popup.appendChild(span);
266 | this.el.appendChild(popup);
267 |
268 | this.newBar.bindShare(this.el);
269 | click(span);
270 |
271 | expect(spy).toHaveBeenCalledWith(popup);
272 | });
273 |
274 | it('should call onShare callback on click in share button only once', function () {
275 | var popup = createPopupElement(),
276 | spy = spyOn(this.newBar, 'onShare'),
277 | el1 = createShareContainer(),
278 | el2 = createShareContainer();
279 |
280 | el1.appendChild(popup);
281 |
282 | this.newBar.createBar(el1);
283 | this.newBar.createBar(el2);
284 |
285 | click(popup);
286 | expect(spy.calls.count()).toEqual(1);
287 | });
288 | });
289 |
290 | describe('openPopup', function () {
291 | beforeEach(function () {
292 | this.popup = createPopupElement();
293 | this.eventClick = click(this.popup);
294 | this.spyWindowsOpen = spyOn(window, 'open').and.returnValue(window);
295 | this.spyWindowsFocus = spyOn(window, 'focus').and.returnValue(window);
296 | });
297 |
298 | it('should call window.open to open popup', function () {
299 | this.newBar.openPopup.call(this.popup, this.eventClick);
300 |
301 | expect(this.spyWindowsOpen).toHaveBeenCalledWith(
302 | this.popup.getAttribute("href"),
303 | 'popup',
304 | 'height=400,width=500,left=10,top=10,resizable=yes,scrollbars=no,toolbar=no,menubar=no,location=no,directories=no,status=no'
305 | );
306 | });
307 |
308 | it('should call window.focus to set focus on popup', function () {
309 | this.newBar.openPopup.call(this.popup, this.eventClick);
310 | expect(this.spyWindowsFocus).toHaveBeenCalled();
311 | });
312 | });
313 |
314 | describe('createBars', function () {
315 | it('should call createBar method for each selected element', function () {
316 | var otherEl = createShareContainer(),
317 | spy = spyOn(ShareBar.prototype, 'createBar');
318 |
319 | this.newBar.containers = [otherEl, this.el];
320 | this.newBar.createBars();
321 |
322 | expect(spy).toHaveBeenCalledWith(otherEl);
323 | expect(spy).toHaveBeenCalledWith(this.el);
324 | });
325 | });
326 |
327 | describe('createBar', function () {
328 | it('should call validateNetworks method', function () {
329 | var spy = spyOn(ShareBar.prototype, 'validateNetworks').and.callThrough();
330 | this.newBar.createBar(this.el);
331 | expect(spy).toHaveBeenCalledWith(this.newBar.networks);
332 | });
333 |
334 | it('should call validateNetworks method with custom networks', function () {
335 | var spy = spyOn(ShareBar.prototype, 'validateNetworks').and.callThrough(),
336 | network = ['facebook'];
337 | this.newBar.createBar(this.el, network);
338 | expect(spy).toHaveBeenCalledWith(network);
339 | });
340 |
341 | it('should call createFacebookButton method', function () {
342 | var spy = spyOn(ShareBar.prototype, 'createFacebookButton');
343 | this.newBar.networks = [this.newBar.createFacebookButton];
344 | this.newBar.createBar(this.el);
345 |
346 | expect(spy).toHaveBeenCalled();
347 | });
348 |
349 | it('should create a maximum of 6 buttons', function () {
350 | var spy = jasmine.createSpy('test');
351 | this.newBar.networks = [spy, spy, spy, spy, spy, spy, spy];
352 | this.newBar.createBar(this.el);
353 |
354 | expect(spy.calls.count()).toEqual(6);
355 | });
356 |
357 | it('should set class share-bar-container on container element', function () {
358 | this.newBar.createBar(this.el);
359 | expect(this.el.classList.contains('share-bar-container')).toBe(true);
360 | });
361 |
362 | it('should set theme default on container element', function () {
363 | this.newBar.createBar(this.el);
364 | expect(this.el.classList.contains('share-theme-natural')).toBe(true);
365 | });
366 |
367 | it('should set customized theme on container element', function () {
368 | this.el.setAttribute('data-theme', 'test');
369 | this.newBar.createBar(this.el);
370 | expect(this.el.classList.contains('share-theme-test')).toBe(true);
371 | });
372 |
373 | it('should call method passed as parameter', function () {
374 | var spy = spyOn(ShareBar.prototype, 'createFacebookButton'),
375 | spyNetworks = [jasmine.createSpy('test')];
376 |
377 | this.newBar.networks = [this.newBar.createFacebookButton];
378 | this.newBar.createBar(this.el, spyNetworks);
379 |
380 | expect(spy).not.toHaveBeenCalled();
381 | expect(spyNetworks[0]).toHaveBeenCalled();
382 | });
383 |
384 | it('should call bindOpenPopup method', function () {
385 | var spy = spyOn(ShareBar.prototype, 'bindOpenPopup');
386 | this.newBar.createBar(this.el);
387 | expect(spy).toHaveBeenCalled();
388 | });
389 |
390 | it('should call bindShare callback', function () {
391 | var spy = spyOn(this.newBar, 'bindShare');
392 | this.newBar.createBar(this.el);
393 | expect(spy).toHaveBeenCalledWith(this.el);
394 | });
395 |
396 | it('should call onCreateBar callback', function () {
397 | var spy = spyOn(this.newBar, 'onCreateBar');
398 | this.newBar.createBar(this.el);
399 | expect(spy).toHaveBeenCalledWith(this.el);
400 | });
401 | });
402 |
403 | describe('getButtonsSize', function () {
404 | it('should call getButtonsSmall when container is small', function () {
405 | var spy = spyOn(ShareBar.prototype, 'getButtonsSmall');
406 | spyOn(this.newBar, 'isSmallScreen').and.returnValue(false);
407 | this.newBar.getButtonsSize(20, 6);
408 |
409 | expect(spy).toHaveBeenCalledWith(6, 25, 20);
410 | });
411 |
412 | it('should return all elements as is when container is big and is small sreen', function () {
413 | var result = [];
414 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(true);
415 |
416 | result = this.newBar.getButtonsSize(200, 6);
417 |
418 | expect(result).toEqual(
419 | ['', '', '', '', '', '']
420 | );
421 | });
422 |
423 | it('should call getButtonsFull when container is big', function () {
424 | var spy = spyOn(ShareBar.prototype, 'getButtonsFull');
425 | spyOn(this.newBar, 'isSmallScreen').and.returnValue(false);
426 | this.newBar.getButtonsSize(150, 6);
427 |
428 | expect(spy).toHaveBeenCalledWith(6, 50, 25, 150);
429 | });
430 | });
431 |
432 | describe('getButtonsSmall', function () {
433 | it('should return all elements as hidden when container is smallest than button', function () {
434 | var result = [];
435 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(false);
436 | result = this.newBar.getButtonsSmall(6, 25, 20);
437 |
438 | expect(result).toEqual(
439 | [' share-hidden', ' share-hidden', ' share-hidden', ' share-hidden', ' share-hidden', ' share-hidden']
440 | );
441 | });
442 |
443 | it('should return some elements as small when container is small', function () {
444 | var result = [];
445 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(false);
446 | result = this.newBar.getButtonsSmall(6, 25, 75);
447 |
448 | expect(result).toEqual(
449 | [' share-small', ' share-small', ' share-small', ' share-hidden', ' share-hidden', ' share-hidden']
450 | );
451 | });
452 |
453 | it('should return some elements as is when container is small and is small sreen', function () {
454 | var result = [];
455 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(true);
456 | result = this.newBar.getButtonsSmall(6, 25, 75);
457 |
458 | expect(result).toEqual(
459 | ['', '', '', ' share-hidden', ' share-hidden', ' share-hidden']
460 | );
461 | });
462 | });
463 |
464 | describe('getButtonsFull', function () {
465 | it('should return all elements as small when container is a little bigger', function () {
466 | var result = [];
467 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(false);
468 |
469 | result = this.newBar.getButtonsFull(6, 50, 25, 160);
470 |
471 | expect(result).toEqual(
472 | [' share-small', ' share-small', ' share-small', ' share-small', ' share-small', ' share-small']
473 | );
474 | });
475 |
476 | it('should return some elements as full when container is big', function () {
477 | var result = [];
478 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(false);
479 |
480 | result = this.newBar.getButtonsFull(6, 50, 25, 225);
481 |
482 | expect(result).toEqual(
483 | [' share-full', ' share-full', ' share-full', ' share-small', ' share-small', ' share-small']
484 | );
485 | });
486 |
487 | it('should return all elements as full when container is very big', function () {
488 | var result = [];
489 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(false);
490 |
491 | result = this.newBar.getButtonsFull(6, 50, 25, 300);
492 |
493 | expect(result).toEqual(
494 | [' share-full', ' share-full', ' share-full', ' share-full', ' share-full', ' share-full']
495 | );
496 | });
497 | });
498 |
499 | describe('getMetadataFromElement', function () {
500 | it('should return a dictionary with metadata from element', function () {
501 | var data = this.newBar.getMetadataFromElement(this.el),
502 | expectedData = {
503 | 'url': window.encodeURIComponent('http://globo.com?utm_source=#source#&utm_medium=share-bar-desktop&utm_campaign=share-bar'),
504 | 'title': window.encodeURIComponent('Test title'),
505 | 'imageUrl': window.encodeURIComponent('http://g1.globo.com'),
506 | 'hashtags': window.encodeURIComponent('#test #g1')
507 | };
508 |
509 | expect(data).toEqual(expectedData);
510 | });
511 | it('should return a hash in the end of url', function () {
512 | document.body.removeChild(this.el);
513 | this.el = createShareContainer("#12345");
514 |
515 | var newBar = createBar({
516 | 'selector': '.no-elements',
517 | 'buttonWidth': 21,
518 | 'buttonFullWidth': 46,
519 | 'buttonPadding': 4
520 | }),
521 |
522 | data = newBar.getMetadataFromElement(this.el),
523 |
524 | expectedData = {
525 | 'url': window.encodeURIComponent('http://globo.com?utm_source=#source#&utm_medium=share-bar-desktop&utm_campaign=share-bar〹'),
526 | 'title': window.encodeURIComponent('Test title'),
527 | 'imageUrl': window.encodeURIComponent('http://g1.globo.com'),
528 | 'hashtags': window.encodeURIComponent('#test #g1')
529 | };
530 |
531 | expect(data.url).toEqual(expectedData.url);
532 | });
533 | });
534 |
535 | describe('createButton', function () {
536 | it('should create share button', function () {
537 | this.newBar.createButton(this.el, 'test', '', 'urltest');
538 | expect(this.el.querySelector('.share-test a')).not.toBe(null);
539 | });
540 |
541 | it('should call createContentButton method', function () {
542 | var spy = spyOn(ShareBar.prototype, 'createContentButton');
543 |
544 | this.newBar.createButton(this.el, 'test', '', 'urltest');
545 | expect(spy).toHaveBeenCalledWith('test', 'Test');
546 | });
547 |
548 | it('should call createContentButton method when title was passed', function () {
549 | var spy = spyOn(ShareBar.prototype, 'createContentButton');
550 |
551 | this.newBar.createButton(this.el, 'test', '', 'urltest', 'title');
552 | expect(spy).toHaveBeenCalledWith('test', 'Title');
553 | });
554 |
555 | it('should return share button', function () {
556 | var button = this.newBar.createButton(this.el, 'test', '', 'test ');
557 | expect(button.className).toEqual('share-button share-test');
558 | });
559 |
560 | it('should be class share-popup when openInPage is undefined', function () {
561 | var button = this.newBar.createButton(this.el, 'test', '', 'test ');
562 | expect(button.querySelector('a').className).toEqual('share-popup');
563 | });
564 |
565 | it('should not be class share-popup when openInPage is true', function () {
566 | var button = this.newBar.createButton(this.el, 'test', '', 'test ', '', true);
567 | expect(button.querySelector('a').className).toEqual('');
568 | });
569 |
570 | it('should call onCreateButton callback', function () {
571 | var spy = spyOn(this.newBar, 'onCreateButton'),
572 | button = this.newBar.createButton(this.el, 'test', '', 'test ');
573 |
574 | expect(spy).toHaveBeenCalledWith(button);
575 | });
576 |
577 | it('should set href with url', function () {
578 | this.newBar.createButton(this.el, 'test', '', 'urltest');
579 | expect(this.el.querySelector('.share-test a').getAttribute("href")).toEqual('urltest');
580 | });
581 |
582 | it('should set title of social share', function () {
583 | this.newBar.createButton(this.el, 'test', '', 'urltest');
584 | expect(this.el.querySelector('.share-test a').getAttribute("title")).toEqual('Compartilhar via Test');
585 | });
586 |
587 | it('should set data-social-network', function () {
588 | this.newBar.createButton(this.el, 'test', '', 'urltest');
589 | expect(this.el.querySelector('.share-test a').getAttribute("data-social-network")).toEqual('test');
590 | });
591 |
592 | it('should set rel=external', function () {
593 | this.newBar.createButton(this.el, 'test', '', 'urltest');
594 | expect(this.el.querySelector('.share-test a').getAttribute("rel")).toEqual('external');
595 | });
596 |
597 | it('should set target=_blank', function () {
598 | this.newBar.createButton(this.el, 'test', '', 'urltest');
599 | expect(this.el.querySelector('.share-test a').getAttribute("target")).toEqual('_blank');
600 | });
601 | });
602 |
603 | describe('createContentButton', function () {
604 | it('should return SVG element when SVG is enabled', function () {
605 | var result;
606 | result = this.newBar.createContentButton('test');
607 |
608 | expect(result).toContain('');
609 | expect(result).toContain('test ');
610 | });
611 | });
612 |
613 | describe('createFacebookButton', function () {
614 | beforeEach(function () {
615 | this.newBar.eventName = 'click';
616 | });
617 |
618 | it('should create facebook button', function () {
619 | this.newBar.createFacebookButton(this.el);
620 | expect(this.el.querySelector('.share-button.share-facebook a span')).not.toBe(null);
621 | });
622 |
623 | it('should set link href with only facebook url', function () {
624 | var link = '';
625 | this.newBar.createFacebookButton(this.el);
626 |
627 | link = this.el.querySelector('.share-button.share-facebook a');
628 | expect(link.href).toEqual(
629 | 'http://www.facebook.com/'
630 | );
631 | });
632 |
633 | it('should call getFacebookUi method', function () {
634 | var spy = spyOn(this.newBar, 'getFacebookUi');
635 | this.newBar.createFacebookButton(this.el);
636 | expect(spy).toHaveBeenCalled();
637 | });
638 |
639 | it('should call FB.ui method when click in button', function () {
640 | window.FB = jasmine.createSpyObj('FB', ['ui']);
641 | this.newBar.createFacebookButton(this.el);
642 |
643 | click(this.el.querySelector('.share-button.share-facebook a'));
644 | expect(window.FB.ui).toHaveBeenCalledWith({
645 | method: 'feed',
646 | display: 'popup',
647 | link: 'http://globo.com?utm_source=facebook&utm_medium=share-bar-desktop&utm_campaign=share-bar',
648 | name: 'Test title',
649 | picture: 'http://g1.globo.com'
650 | });
651 | });
652 | });
653 |
654 | describe('getFacebookUi', function () {
655 | beforeEach(function () {
656 | delete window.FB;
657 | this.oldFacebookAppId = this.newBar.facebookAppId;
658 | });
659 |
660 | afterEach(function () {
661 | this.newBar.facebookAppId = this.oldFacebookAppId;
662 | delete window.FB;
663 | var node = document.getElementById('facebook-jssdk');
664 | if (node !== null) {
665 | node.parentNode.removeChild(node);
666 | }
667 | });
668 |
669 | it('should call pass facebookAppId to the FB SDK', function () {
670 | this.newBar.facebookAppId = facebookAppId;
671 | this.newBar.getFacebookUi();
672 | window.FB = jasmine.createSpyObj('FB', ['init']);
673 | window.fbAsyncInit();
674 | expect(window.FB.init).toHaveBeenCalledWith(jasmine.objectContaining({appId: facebookAppId}));
675 | });
676 |
677 | it('should call getOgFbAppId when facebookAppId is not defined or empty', function () {
678 | this.newBar.facebookAppId = '';
679 | spyOn(this.newBar, 'getOgFbAppId').and.returnValue(facebookAppId);
680 | this.newBar.getFacebookUi();
681 | window.FB = jasmine.createSpyObj('FB', ['init']);
682 | window.fbAsyncInit();
683 | expect(window.FB.init).toHaveBeenCalledWith(jasmine.objectContaining({appId: facebookAppId}));
684 | });
685 |
686 | it('should not apply fbAsyncInit when facebookAppId not defined', function () {
687 | delete window.fbAsyncInit;
688 | this.newBar.facebookAppId = '';
689 | spyOn(this.newBar, 'getOgFbAppId').and.returnValue('');
690 | this.newBar.getFacebookUi();
691 | expect(window.fbAsyncInit).toBeUndefined();
692 | });
693 |
694 | it('should include the facebook script tag when facebookAppId is available', function () {
695 | this.newBar.facebookAppId = facebookAppId;
696 | this.newBar.getFacebookUi();
697 | expect(document.getElementById('facebook-jssdk')).not.toBeNull(null);
698 | });
699 |
700 | it('should not include the facebook script tag when facebookAppId is empty', function () {
701 | this.newBar.facebookAppId = '';
702 | spyOn(this.newBar, 'getOgFbAppId').and.returnValue('');
703 | this.newBar.getFacebookUi();
704 | expect(document.getElementById('facebook-jssdk')).toBeNull();
705 | });
706 | });
707 |
708 | describe('getOgFbAppId', function () {
709 | it('should return the facebook app id from meta tag', function () {
710 | var fbId,
711 | metaEl = document.createElement('META');
712 | metaEl.setAttribute('property', 'fb:app_id');
713 | metaEl.setAttribute('content', facebookAppId);
714 | document.head.appendChild(metaEl);
715 | fbId = this.newBar.getOgFbAppId();
716 | document.head.removeChild(metaEl);
717 | expect(fbId).toEqual(facebookAppId);
718 | });
719 |
720 | it('should return null when element is not defined', function () {
721 | var fbId = this.newBar.getOgFbAppId();
722 | expect(fbId).toBeUndefined();
723 | });
724 | });
725 |
726 | describe('createTwitterButton', function () {
727 | it('should create twitter button', function () {
728 | this.newBar.createTwitterButton(this.el);
729 | expect(this.el.querySelector('.share-button.share-twitter a.share-popup span')).not.toBe(null);
730 | });
731 |
732 | it('should set link href with metadata of container', function () {
733 | var link = '';
734 | this.newBar.createTwitterButton(this.el);
735 |
736 | link = this.el.querySelector('.share-button.share-twitter a');
737 | expect(link.href).toEqual(
738 | 'https://twitter.com/share?url=http%3A%2F%2Fglobo.com%3Futm_source%3Dtwitter%26utm_medium%3Dshare-bar-desktop%26utm_campaign%3Dshare-bar&text=Test%20title%20%23test%20%23g1'
739 | );
740 | });
741 | });
742 |
743 | describe('createGoogleButton', function () {
744 | it('should create googleplus button', function () {
745 | this.newBar.createGoogleButton(this.el);
746 | expect(this.el.querySelector('.share-button.share-googleplus a.share-popup span')).not.toBe(null);
747 | });
748 |
749 | it('should set link href with metadata of container', function () {
750 | var link = '';
751 | this.newBar.createGoogleButton(this.el);
752 |
753 | link = this.el.querySelector('.share-button.share-googleplus a');
754 | expect(link.href).toEqual(
755 | 'https://plus.google.com/share?url=http%3A%2F%2Fglobo.com%3Futm_source%3Dgoogleplus%26utm_medium%3Dshare-bar-desktop%26utm_campaign%3Dshare-bar'
756 | );
757 | });
758 | });
759 |
760 | describe('createPinterestButton', function () {
761 | it('should create pinterest button', function () {
762 | this.newBar.createPinterestButton(this.el);
763 | expect(this.el.querySelector('.share-button.share-pinterest a.share-popup span')).not.toBe(null);
764 | });
765 |
766 | it('should set link href with metadata of container', function () {
767 | var link = '';
768 | this.newBar.createPinterestButton(this.el);
769 |
770 | link = this.el.querySelector('.share-button.share-pinterest a');
771 | expect(link.href).toEqual(
772 | 'http://br.pinterest.com/pin/create/button/?url=http%3A%2F%2Fglobo.com%3Futm_source%3Dpinterest%26utm_medium%3Dshare-bar-desktop%26utm_campaign%3Dshare-bar&media=http%3A%2F%2Fg1.globo.com&description=Test%20title'
773 | );
774 | });
775 | });
776 |
777 | describe('createWhatsappButton', function () {
778 | it('should create whatsapp button when device is iphone', function () {
779 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(true);
780 | spyOn(ShareBar.prototype, 'isTouch').and.returnValue(true);
781 | this.newBar.createWhatsappButton(this.el);
782 | expect(this.el.querySelector('.share-button.share-whatsapp a span')).not.toBe(null);
783 | });
784 |
785 | it('should set link href with metadata of container', function () {
786 | var link = '';
787 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(true);
788 | spyOn(ShareBar.prototype, 'isTouch').and.returnValue(true);
789 | this.newBar.createWhatsappButton(this.el);
790 |
791 | link = this.el.querySelector('.share-button.share-whatsapp a');
792 | expect(link.href).toEqual(
793 | 'whatsapp://send?text=Test%20title%20http%3A%2F%2Fglobo.com%3Futm_source%3Dwhatsapp%26utm_medium%3Dshare-bar-desktop%26utm_campaign%3Dshare-bar'
794 | );
795 | });
796 |
797 | it('should not create whatsapp button when is not mobile device', function () {
798 | spyOn(ShareBar.prototype, 'isSmallScreen').and.returnValue(false);
799 | spyOn(ShareBar.prototype, 'isTouch').and.returnValue(false);
800 | this.newBar.createWhatsappButton(this.el);
801 | expect(this.el.querySelector('.share-button.share-whatsapp a span')).toBe(null);
802 | });
803 |
804 | it('should not open in popup', function () {
805 | this.newBar.createWhatsappButton(this.el);
806 | expect(this.el.querySelector('.share-whatsapp a').className).toEqual('');
807 | });
808 | });
809 |
810 | describe('createEmailButton', function () {
811 | it('should create email button', function () {
812 | this.newBar.createEmailButton(this.el);
813 | expect(this.el.querySelector('.share-button.share-email a span')).not.toBe(null);
814 | });
815 |
816 | it('should set link href with metadata of container', function () {
817 | var link = '';
818 | this.newBar.createEmailButton(this.el);
819 |
820 | link = this.el.querySelector('.share-email a');
821 | expect(link.href).toEqual(
822 | 'mailto:?subject=Test%20title&body=http%3A%2F%2Fglobo.com%3Futm_source%3Demail%26utm_medium%3Dshare-bar-desktop%26utm_campaign%3Dshare-bar'
823 | );
824 | });
825 |
826 | it('should not create email button when is not mobile device', function () {
827 | spyOn(ShareBar.prototype, 'isTouch').and.returnValue(false);
828 | this.newBar.createEmailButton(this.el);
829 | expect(this.el.querySelector('.share-button.share-email a span')).toBe(null);
830 | });
831 |
832 | it('should not open in popup', function () {
833 | this.newBar.createEmailButton(this.el);
834 | expect(this.el.querySelector('.share-email a').className).toEqual('');
835 | });
836 | });
837 |
838 | describe('createSVG', function () {
839 | it('should only create one svg container', function () {
840 | var element = '',
841 | elements = [];
842 |
843 | this.newBar.createSVG();
844 | this.newBar.createSVG();
845 | this.newBar.createSVG();
846 |
847 | elements = document.querySelectorAll('div.sharebar-svg-container');
848 | element = elements[elements.length - 1];
849 |
850 | expect(elements.length).toEqual(1);
851 | expect(element.style.display).toEqual('none');
852 | expect(element.innerHTML).toEqual('[[X_SVG_X]]');
853 | });
854 | });
855 |
856 | describe('verifyTouch', function () {
857 | beforeEach(function () {
858 | document.querySelector('html').className = '';
859 | });
860 |
861 | it('should add class no-touch for desktop', function () {
862 | var html;
863 |
864 | spyOn(ShareBar.prototype, 'isTouch').and.returnValue(false);
865 | this.newBar.verifyTouch();
866 |
867 | html = document.querySelector('html');
868 | expect(html.className).toEqual(' no-touch');
869 | });
870 |
871 | it('should add class touch for touch devices', function () {
872 | var html;
873 |
874 | spyOn(ShareBar.prototype, 'isTouch').and.returnValue(true);
875 | this.newBar.verifyTouch();
876 |
877 | html = document.querySelector('html');
878 | expect(html.className).toEqual(' touch');
879 | });
880 | });
881 | describe('define a specific campaign', function () {
882 | describe('uses a custom campaign', function () {
883 | it('should call with custom options', function () {
884 | var customCampaign = 'custom-campaign',
885 | options = {
886 | 'selector': '.share-bar',
887 | 'campaign': customCampaign
888 | },
889 | data,
890 | expectedData;
891 |
892 | this.newBar = createBar(options);
893 | data = this.newBar.getMetadataFromElement(this.el);
894 | expectedData = {
895 | 'url': window.encodeURIComponent('http://globo.com?utm_source=#source#&utm_medium=share-bar-desktop&utm_campaign=' + customCampaign),
896 | 'title': window.encodeURIComponent('Test title'),
897 | 'imageUrl': window.encodeURIComponent('http://g1.globo.com'),
898 | 'hashtags': window.encodeURIComponent('#test #g1')
899 | };
900 |
901 | expect(data).toEqual(expectedData);
902 | });
903 | });
904 | describe('using a unspecified campaign', function () {
905 | it('should call with default options', function () {
906 | var defaultCampaign = 'share-bar',
907 | options = {
908 | 'selector': '.share-bar'
909 | },
910 | data,
911 | expectedData;
912 |
913 | this.newBar = createBar(options);
914 | data = this.newBar.getMetadataFromElement(this.el);
915 | expectedData = {
916 | 'url': window.encodeURIComponent('http://globo.com?utm_source=#source#&utm_medium=share-bar-desktop&utm_campaign=' + defaultCampaign),
917 | 'title': window.encodeURIComponent('Test title'),
918 | 'imageUrl': window.encodeURIComponent('http://g1.globo.com'),
919 | 'hashtags': window.encodeURIComponent('#test #g1')
920 | };
921 |
922 | expect(data).toEqual(expectedData);
923 | });
924 | });
925 | });
926 | });
927 |
--------------------------------------------------------------------------------