UNPKG

quodolores

Version:

Monorepo for the Firebase JavaScript SDK

138 lines (118 loc) 3.46 kB
/** * @license * Copyright 2020 Google LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { getUA } from '@firebase/util'; import { AuthErrorCode } from '../../core/errors'; import { _assert } from '../../core/util/assert'; import { _isChromeIOS, _isFirefox, _isIOSStandalone } from '../../core/util/browser'; import { AuthInternal } from '../../model/auth'; const BASE_POPUP_OPTIONS = { location: 'yes', resizable: 'yes', statusbar: 'yes', toolbar: 'no' }; const DEFAULT_WIDTH = 500; const DEFAULT_HEIGHT = 600; const TARGET_BLANK = '_blank'; const FIREFOX_EMPTY_URL = 'http://localhost'; export class AuthPopup { associatedEvent: string | null = null; constructor(readonly window: Window | null) {} close(): void { if (this.window) { try { this.window.close(); } catch (e) {} } } } export function _open( auth: AuthInternal, url?: string, name?: string, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT ): AuthPopup { const top = Math.min((window.screen.availHeight - height) / 2, 0).toString(); const left = Math.min((window.screen.availWidth - width) / 2, 0).toString(); let target = ''; const options: { [key: string]: string } = { ...BASE_POPUP_OPTIONS, width: width.toString(), height: height.toString(), top, left }; // Chrome iOS 7 and 8 is returning an undefined popup win when target is // specified, even though the popup is not necessarily blocked. const ua = getUA().toLowerCase(); if (name) { target = _isChromeIOS(ua) ? TARGET_BLANK : name; } if (_isFirefox(ua)) { // Firefox complains when invalid URLs are popped out. Hacky way to bypass. url = url || FIREFOX_EMPTY_URL; // Firefox disables by default scrolling on popup windows, which can create // issues when the user has many Google accounts, for instance. options.scrollbars = 'yes'; } const optionsString = Object.entries(options).reduce( (accum, [key, value]) => `${accum}${key}=${value},`, '' ); if (_isIOSStandalone(ua) && target !== '_self') { openAsNewWindowIOS(url || '', target); return new AuthPopup(null); } // about:blank getting sanitized causing browsers like IE/Edge to display // brief error message before redirecting to handler. const newWin = window.open(url || '', target, optionsString); _assert(newWin, auth, AuthErrorCode.POPUP_BLOCKED); // Flaky on IE edge, encapsulate with a try and catch. try { newWin.focus(); } catch (e) {} return new AuthPopup(newWin); } function openAsNewWindowIOS(url: string, target: string): void { const el = document.createElement('a'); el.href = url; el.target = target; const click = document.createEvent('MouseEvent'); click.initMouseEvent( 'click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 1, null ); el.dispatchEvent(click); }