OLD | NEW |
(Empty) | |
| 1 <link rel="import" href="../polymer/polymer.html"> |
| 2 <link rel="import" href="google-signin-aware.html"> |
| 3 <link rel="import" href="../iron-icon/iron-icon.html"> |
| 4 <link rel="import" href="../iron-icons/iron-icons.html"> |
| 5 <link rel="import" href="../font-roboto/roboto.html"> |
| 6 <link rel="import" href="../google-apis/google-js-api.html"> |
| 7 <link rel="import" href="../paper-ripple/paper-ripple.html"> |
| 8 <link rel="import" href="../paper-material/paper-material.html"> |
| 9 <link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html"> |
| 10 <link rel="import" href="google-icons.html"> |
| 11 |
| 12 <dom-module id="google-signin"> |
| 13 <link rel="import" type="css" href="google-signin.css"> |
| 14 <template> |
| 15 <google-signin-aware id="aware" |
| 16 app-package-name="{{appPackageName}}" |
| 17 client-id="{{clientId}}" |
| 18 cookie-policy="{{cookiePolicy}}" |
| 19 request-visible-actions="{{requestVisibleActions}}" |
| 20 scopes="{{scopes}}" |
| 21 signed-in="{{signedIn}}" |
| 22 is-authorized="{{isAuthorized}}" |
| 23 need-additional-auth="{{needAdditionalAuth}}" |
| 24 has-plus-scopes="{{hasPlusScopes}}"></google-signin-aware> |
| 25 <template is="dom-if" if="{{raised}}"> |
| 26 <paper-material id="shadow" class="fit" elevation="2" animated></paper-mat
erial> |
| 27 </template> |
| 28 <div id="button" |
| 29 class$="[[_computeButtonClass(height, width, theme, signedIn, _brand, need
AdditionalAuth)]]"> |
| 30 |
| 31 <paper-ripple id="ripple" class="fit"></paper-ripple> |
| 32 <!-- this div is needed to position the ripple behind text content --> |
| 33 <div relative layout horizontal center-center> |
| 34 <template is="dom-if" if="{{_computeButtonIsSignIn(signedIn, needAdditio
nalAuth)}}"> |
| 35 <div class="button-content signIn" tabindex="0" |
| 36 on-click="signIn" on-keydown="_signInKeyPress"> |
| 37 <span class="icon"><iron-icon icon="[[_brandIcon]]"></iron-icon></sp
an> |
| 38 <span class="buttonText">{{_labelSignin}}</span> |
| 39 </div> |
| 40 </template> |
| 41 <template is="dom-if" if="{{_computeButtonIsSignOut(signedIn, needAdditi
onalAuth) }}"> |
| 42 <div class="button-content signOut" tabindex="0" |
| 43 on-click="signOut" on-keydown="_signOutKeyPress"> |
| 44 <span class="icon"><iron-icon icon="[[_brandIcon]]"></iron-icon></sp
an> |
| 45 <span class="buttonText">{{labelSignout}}</span> |
| 46 </div> |
| 47 </template> |
| 48 <template is="dom-if" if="{{_computeButtonIsSignOutAddl(signedIn, needAd
ditionalAuth) }}"> |
| 49 <div class="button-content signIn" tabindex="0" |
| 50 on-click="signIn" on-keydown="_signInKeyPress"> |
| 51 <span class="icon"><iron-icon icon="[[_brandIcon]]"></iron-icon></sp
an> |
| 52 <span class="buttonText">{{labelAdditional}}</span> |
| 53 </div> |
| 54 </template> |
| 55 </div> |
| 56 |
| 57 </div> |
| 58 </template> |
| 59 </dom-module> |
| 60 <script> |
| 61 (function() { |
| 62 |
| 63 /** |
| 64 * Enum brand values. |
| 65 * @readonly |
| 66 * @enum {string} |
| 67 */ |
| 68 var BrandValue = { |
| 69 GOOGLE: 'google', |
| 70 PLUS: 'google-plus' |
| 71 }; |
| 72 |
| 73 /** |
| 74 * Enum height values. |
| 75 * @readonly |
| 76 * @enum {string} |
| 77 */ |
| 78 var HeightValue = { |
| 79 SHORT: 'short', |
| 80 STANDARD: 'standard', |
| 81 TALL: 'tall' |
| 82 }; |
| 83 |
| 84 /** |
| 85 * Enum button label default values. |
| 86 * @readonly |
| 87 * @enum {string} |
| 88 */ |
| 89 var LabelValue = { |
| 90 STANDARD: 'Sign in', |
| 91 WIDE: 'Sign in with Google', |
| 92 WIDE_PLUS: 'Sign in with Google+' |
| 93 }; |
| 94 |
| 95 /** |
| 96 * Enum theme values. |
| 97 * @readonly |
| 98 * @enum {string} |
| 99 */ |
| 100 var ThemeValue = { |
| 101 LIGHT: 'light', |
| 102 DARK: 'dark' |
| 103 }; |
| 104 |
| 105 /** |
| 106 * Enum width values. |
| 107 * @readonly |
| 108 * @enum {string} |
| 109 */ |
| 110 var WidthValue = { |
| 111 ICON_ONLY: 'iconOnly', |
| 112 STANDARD: 'standard', |
| 113 WIDE: 'wide' |
| 114 }; |
| 115 |
| 116 /** |
| 117 <google-signin> is used to authenticate with Google, allowing you to inter
act |
| 118 with other Google APIs such as Drive and Google+. |
| 119 |
| 120 <img style="max-width:100%;" src="https://cloud.githubusercontent.com/assets/107
076/6791176/5c868822-d16a-11e4-918c-ec9b84a2db45.png"/> |
| 121 |
| 122 If you do not need to show the button, use companion `<google-signin-aware>` ele
ment to declare scopes, check authentication state. |
| 123 |
| 124 #### Examples |
| 125 |
| 126 <google-signin client-id="..." scopes="https://www.googleapis.com/auth/drive
"></google-signin> |
| 127 |
| 128 <google-signin label-signin="Sign-in" client-id="..." scopes="https://www.go
ogleapis.com/auth/drive"></google-signin> |
| 129 |
| 130 <google-signin theme="dark" width="iconOnly" client-id="..." scopes="https:/
/www.googleapis.com/auth/drive"></google-signin> |
| 131 |
| 132 |
| 133 #### Notes |
| 134 |
| 135 The attribute `clientId` is provided in your Google Developers Console |
| 136 (https://console.developers.google.com). |
| 137 |
| 138 The `scopes` attribute allows you to specify which scope permissions are require
d |
| 139 (e.g do you want to allow interaction with the Google Drive API). Many APIs also |
| 140 need to be enabled in the Google Developers Console before you can use them. |
| 141 |
| 142 The `requestVisibleActions` attribute is necessary if you want to write app |
| 143 activities (https://developers.google.com/+/web/app-activities/) on behalf of |
| 144 the user. Please note that this attribute is only valid in combination with the |
| 145 plus.login scope (https://www.googleapis.com/auth/plus.login). |
| 146 |
| 147 Use label properties to customize prompts. |
| 148 |
| 149 The button can be styled in using the `height`, `width`, and `theme` attributes. |
| 150 These attributes help you follow the Google+ Sign-In button branding guidelines |
| 151 (https://developers.google.com/+/branding-guidelines). |
| 152 |
| 153 The `google-signin-success` event is triggered when a user successfully authenti
cates |
| 154 and `google-signed-out` is triggered when user signeds out. |
| 155 You can also use `isAuthorized` attribute to observe user's authentication state
. |
| 156 |
| 157 Additional events, such as `google-signout-attempted` are |
| 158 triggered when the user attempts to sign-out and successfully signs out. |
| 159 |
| 160 The `google-signin-necessary` event is fired when scopes requested via |
| 161 google-signin-aware elements require additional user permissions. |
| 162 |
| 163 #### Testing |
| 164 |
| 165 By default, the demo accompanying this element is setup to work on localhost wit
h |
| 166 port 8080. That said, you *should* update the `clientId` to your own one for |
| 167 any apps you're building. See the Google Developers Console |
| 168 (https://console.developers.google.com) for more info. |
| 169 |
| 170 @demo |
| 171 */ |
| 172 |
| 173 Polymer({ |
| 174 |
| 175 is: 'google-signin', |
| 176 |
| 177 /** |
| 178 * Fired when user is signed in. |
| 179 * You can use auth2 api to retrieve current user: `gapi.auth2.getAuthInstan
ce().currentUser.get();` |
| 180 * @event google-signin-success |
| 181 */ |
| 182 |
| 183 /** |
| 184 * Fired when the user is signed-out. |
| 185 * @event google-signed-out |
| 186 */ |
| 187 |
| 188 /** |
| 189 * Fired if user requires additional authorization |
| 190 * @event google-signin-necessary |
| 191 */ |
| 192 |
| 193 /** |
| 194 * Fired when signed in, and scope has been authorized |
| 195 * @param {Object} result Authorization result. |
| 196 * @event google-signin-aware-success |
| 197 */ |
| 198 |
| 199 /** |
| 200 * Fired when this scope is not authorized |
| 201 * @event google-signin-aware-signed-out |
| 202 */ |
| 203 properties: { |
| 204 /** |
| 205 * App package name for android over-the-air installs. |
| 206 * See the relevant [docs](https://developers.google.com/+/web/signin/an
droid-app-installs) |
| 207 */ |
| 208 appPackageName: { |
| 209 type: String, |
| 210 value: '' |
| 211 }, |
| 212 |
| 213 /** |
| 214 * The brand being used for logo and styling. |
| 215 * |
| 216 * @default 'google' |
| 217 */ |
| 218 brand: { |
| 219 type: String, |
| 220 value: '' |
| 221 }, |
| 222 |
| 223 /** @private */ |
| 224 _brand: { |
| 225 type: String, |
| 226 computed: '_computeBrand(brand, hasPlusScopes)' |
| 227 }, |
| 228 |
| 229 /** |
| 230 * a Google Developers clientId reference |
| 231 */ |
| 232 clientId: { |
| 233 type: String, |
| 234 value: '' |
| 235 }, |
| 236 |
| 237 /** |
| 238 * The cookie policy defines what URIs have access to the session cookie |
| 239 * remembering the user's sign-in state. |
| 240 * See the relevant [docs](https://developers.google.com/+/web/signin/re
ference#determining_a_value_for_cookie_policy) for more information. |
| 241 * |
| 242 * @default 'single_host_origin' |
| 243 */ |
| 244 cookiePolicy: { |
| 245 type: String, |
| 246 value: '' |
| 247 }, |
| 248 |
| 249 /** |
| 250 * The height to use for the button. |
| 251 * |
| 252 * Available options: short, standard, tall. |
| 253 * |
| 254 * @type {HeightValue} |
| 255 */ |
| 256 height: { |
| 257 type: String, |
| 258 value: 'standard' |
| 259 }, |
| 260 |
| 261 /** |
| 262 * By default the ripple expands to fill the button. Set this to true to |
| 263 * constrain the ripple to a circle within the button. |
| 264 */ |
| 265 fill: { |
| 266 type: Boolean, |
| 267 value: true |
| 268 }, |
| 269 |
| 270 /** |
| 271 * An optional label for the button for additional permissions. |
| 272 */ |
| 273 labelAdditional: { |
| 274 type: String, |
| 275 value: 'Additional permissions required' |
| 276 }, |
| 277 |
| 278 /** |
| 279 * An optional label for the sign-in button. |
| 280 */ |
| 281 labelSignin: { |
| 282 type: String, |
| 283 value: '' |
| 284 }, |
| 285 |
| 286 _labelSignin: { |
| 287 type: String, |
| 288 computed: '_computeSigninLabel(labelSignin, width, _brand)' |
| 289 }, |
| 290 /** |
| 291 * An optional label for the sign-out button. |
| 292 */ |
| 293 labelSignout: { |
| 294 type: String, |
| 295 value: 'Sign out' |
| 296 }, |
| 297 |
| 298 /** |
| 299 * If true, the button will be styled with a shadow. |
| 300 */ |
| 301 raised: { |
| 302 type: Boolean, |
| 303 value: false |
| 304 }, |
| 305 |
| 306 /** |
| 307 * The app activity types you want to write on behalf of the user |
| 308 * (e.g http://schemas.google.com/AddActivity) |
| 309 */ |
| 310 requestVisibleActions: { |
| 311 type: String, |
| 312 value: '' |
| 313 }, |
| 314 |
| 315 /** |
| 316 * The scopes to provide access to (e.g https://www.googleapis.com/auth/
drive) |
| 317 * and should be space-delimited. |
| 318 */ |
| 319 scopes: { |
| 320 type: String, |
| 321 value: '' |
| 322 }, |
| 323 |
| 324 /** |
| 325 * The theme to use for the button. |
| 326 * |
| 327 * Available options: light, dark. |
| 328 * |
| 329 * @attribute theme |
| 330 * @type {ThemeValue} |
| 331 * @default 'dark' |
| 332 */ |
| 333 theme: { |
| 334 type: String, |
| 335 value: 'dark' |
| 336 }, |
| 337 |
| 338 /** |
| 339 * The width to use for the button. |
| 340 * |
| 341 * Available options: iconOnly, standard, wide. |
| 342 * |
| 343 * @type {WidthValue} |
| 344 */ |
| 345 width: { |
| 346 type: String, |
| 347 value: 'standard' |
| 348 }, |
| 349 |
| 350 _brandIcon: { |
| 351 type: String, |
| 352 computed: '_computeIcon(_brand)' |
| 353 }, |
| 354 |
| 355 /** |
| 356 * True if *any* element has google+ scopes |
| 357 */ |
| 358 hasPlusScopes: { |
| 359 type: Boolean, |
| 360 notify: true, |
| 361 value: false |
| 362 }, |
| 363 |
| 364 /** |
| 365 * True if additional authorization required globally |
| 366 */ |
| 367 needAdditionalAuth: { |
| 368 type: Boolean, |
| 369 value: false |
| 370 }, |
| 371 |
| 372 /** |
| 373 * Is user signed in? |
| 374 */ |
| 375 signedIn: { |
| 376 type: Boolean, |
| 377 notify: true, |
| 378 value: false, |
| 379 observer: '_observeSignedIn' |
| 380 }, |
| 381 |
| 382 /** |
| 383 * True if authorizations for *this* element have been granted |
| 384 */ |
| 385 isAuthorized: { |
| 386 type: Boolean, |
| 387 notify: true, |
| 388 value: false |
| 389 } |
| 390 |
| 391 }, |
| 392 |
| 393 _computeButtonClass: function(height, width, theme, signedIn, brand, needA
dditionalAuth) { |
| 394 return "height-" + height + " width-" + width + " theme-" + theme + " si
gnedIn-" + signedIn + " brand-" + brand + " additionalAuth-" + needAdditionalAu
th; |
| 395 }, |
| 396 |
| 397 _computeIcon: function(brand) { |
| 398 return "google:" + brand; |
| 399 }, |
| 400 |
| 401 /* Button state computed */ |
| 402 _computeButtonIsSignIn: function(signedIn, additionalAuth) { |
| 403 return !signedIn; |
| 404 }, |
| 405 |
| 406 _computeButtonIsSignOut: function(signedIn, additionalAuth) { |
| 407 return signedIn && !additionalAuth; |
| 408 }, |
| 409 |
| 410 _computeButtonIsSignOutAddl: function(signedIn, additionalAuth) { |
| 411 return signedIn && additionalAuth; |
| 412 }, |
| 413 |
| 414 _computeBrand: function(attrBrand, hasPlusScopes) { |
| 415 var newBrand; |
| 416 if (attrBrand) { |
| 417 newBrand = attrBrand; |
| 418 } else if (hasPlusScopes) { |
| 419 newBrand = BrandValue.PLUS; |
| 420 } else { |
| 421 newBrand = BrandValue.GOOGLE; |
| 422 }; |
| 423 return newBrand; |
| 424 }, |
| 425 |
| 426 _observeSignedIn: function(newVal, oldVal) { |
| 427 if (newVal) { |
| 428 if (this.needAdditionalAuth) |
| 429 this.fire('google-signin-necessary'); |
| 430 this.fire('google-signin-success'); |
| 431 } |
| 432 else |
| 433 this.fire('google-signed-out'); |
| 434 }, |
| 435 |
| 436 /** |
| 437 * Determines the proper label based on the attributes. |
| 438 */ |
| 439 _computeSigninLabel: function(labelSignin, width, _brand) { |
| 440 if (labelSignin) { |
| 441 return labelSignin; |
| 442 } else { |
| 443 switch(width) { |
| 444 |
| 445 case WidthValue.WIDE: |
| 446 return (_brand == BrandValue.PLUS) ? |
| 447 LabelValue.WIDE_PLUS : LabelValue.WIDE; |
| 448 |
| 449 case WidthValue.STANDARD: |
| 450 return LabelValue.STANDARD; |
| 451 |
| 452 case WidthValue.ICON_ONLY: |
| 453 return ''; |
| 454 |
| 455 default: |
| 456 console.warn("bad width value: ", width); |
| 457 return LabelValue.STANDARD; |
| 458 } |
| 459 } |
| 460 }, |
| 461 |
| 462 /** Sign in user. Opens the authorization dialog for signing in. |
| 463 * The dialog will be blocked by a popup blocker unless called inside clic
k handler. |
| 464 */ |
| 465 signIn: function () { |
| 466 this.$.aware.signIn(); |
| 467 }, |
| 468 |
| 469 _signInKeyPress: function (e) { |
| 470 if (e.which == 13 || e.keyCode == 13 || e.which == 32 || e.keyCode == 32
) { |
| 471 e.preventDefault(); |
| 472 this.signIn(); |
| 473 } |
| 474 }, |
| 475 |
| 476 /** Sign out the user */ |
| 477 signOut: function () { |
| 478 this.fire('google-signout-attempted'); |
| 479 this.$.aware.signOut(); |
| 480 }, |
| 481 |
| 482 _signOutKeyPress: function (e) { |
| 483 if (e.which == 13 || e.keyCode == 13 || e.which == 32 || e.keyCode == 32
) { |
| 484 e.preventDefault(); |
| 485 this.signOut(); |
| 486 } |
| 487 } |
| 488 }); |
| 489 }()); |
| 490 </script> |
OLD | NEW |