• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2025 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {defer} from './deferred';
16
17const DEFAULT_TIMEOUT_MS = 30_000;
18
19export interface PopupArgs {
20  url: string;
21  width?: number;
22  height?: number;
23  timeoutMs?: number; // Defaults to DEFAULT_TIMEOUT_MS.
24}
25
26/**
27 * Opens a URL in a new popup-style tab.
28 * @returns A promise for a result that is resolved successfully if the popup
29 * closes, or unsuccessfully if popups are blocked or the timeout expires.
30 */
31export function showPopupWindow(args: PopupArgs): Promise<boolean> {
32  const popup = window.open(
33    args.url,
34    '_blank',
35    `width=${args.width ?? 500},height=${args.height ?? 500},` +
36      'scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no',
37  );
38  const promise = defer<boolean>();
39  if (popup === null) {
40    promise.resolve(false);
41    return promise;
42  }
43  const deadline = performance.now() + (args.timeoutMs ?? DEFAULT_TIMEOUT_MS);
44  const interval = setInterval(() => {
45    if (popup.closed) {
46      clearInterval(interval);
47      promise.resolve(true);
48    }
49    if (performance.now() >= deadline) {
50      clearInterval(interval);
51      promise.resolve(false);
52    }
53  }, 500);
54  return promise;
55}
56