| // Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| @JS() |
| library; |
| |
| import 'dart:async'; |
| // TODO: https://github.com/dart-lang/webdev/issues/2508 |
| // ignore: deprecated_member_use |
| import 'dart:js_util'; |
| |
| // TODO: https://github.com/dart-lang/webdev/issues/2508 |
| // ignore: deprecated_member_use |
| import 'package:js/js.dart'; |
| |
| import 'chrome_api.dart'; |
| |
| Future<Tab> createTab(String url, {bool inNewWindow = false}) { |
| final completer = Completer<Tab>(); |
| if (inNewWindow) { |
| chrome.windows.create( |
| WindowInfo(focused: true, url: url), |
| allowInterop((WindowObj windowObj) { |
| completer.complete(windowObj.tabs.first); |
| }), |
| ); |
| } else { |
| chrome.tabs.create( |
| TabInfo(active: true, url: url), |
| allowInterop(completer.complete), |
| ); |
| } |
| return completer.future; |
| } |
| |
| Future<Tab?> getTab(int tabId) { |
| final completer = Completer<Tab?>(); |
| chrome.tabs.get(tabId, allowInterop(completer.complete)); |
| return completer.future; |
| } |
| |
| Future<Tab?> get activeTab { |
| final completer = Completer<Tab?>(); |
| final query = QueryInfo(active: true, currentWindow: true); |
| chrome.tabs.query( |
| query, |
| allowInterop((List<Tab> tabs) { |
| completer.complete(tabs.firstOrNull); |
| }), |
| ); |
| return completer.future; |
| } |
| |
| Future<bool> removeTab(int tabId) { |
| final completer = Completer<bool>(); |
| chrome.tabs.remove( |
| tabId, |
| allowInterop(() { |
| completer.complete(true); |
| }), |
| ); |
| return completer.future; |
| } |
| |
| void displayNotification( |
| String message, { |
| bool isError = false, |
| Function? callback, |
| }) { |
| chrome.notifications.create( |
| // notificationId |
| null, |
| NotificationOptions( |
| title: '${isError ? '[Error] ' : ''}Dart Debug Extension', |
| message: message, |
| iconUrl: |
| isError ? 'static_assets/dart_warning.png' : 'static_assets/dart.png', |
| type: 'basic', |
| ), |
| callback, |
| ); |
| } |
| |
| void setExtensionIcon(IconInfo info) { |
| if (isMV3) { |
| _setExtensionIconMV3( |
| info, |
| // callback |
| null, |
| ); |
| } else { |
| _setExtensionIconMV2( |
| info, |
| // callback |
| null, |
| ); |
| } |
| } |
| |
| void setExtensionPopup(PopupDetails details) { |
| if (isMV3) { |
| _setExtensionPopupMV3( |
| details, |
| // callback |
| null, |
| ); |
| } else { |
| _setExtensionPopupMV2( |
| details, |
| // callback |
| null, |
| ); |
| } |
| } |
| |
| final bool isDevMode = () { |
| final extensionManifest = chrome.runtime.getManifest(); |
| final extensionName = getProperty<String?>(extensionManifest, 'name') ?? ''; |
| return extensionName.contains('DEV'); |
| }(); |
| |
| final bool isMV3 = () { |
| final extensionManifest = chrome.runtime.getManifest(); |
| final manifestVersion = |
| getProperty(extensionManifest, 'manifest_version') ?? 2; |
| return manifestVersion == 3; |
| }(); |
| |
| String addQueryParameters( |
| String uri, { |
| required Map<String, String> queryParameters, |
| }) { |
| final originalUri = Uri.parse(uri); |
| final newUri = originalUri.replace( |
| path: '', // Replace the /debugger path so that the inspector url works. |
| queryParameters: {...originalUri.queryParameters, ...queryParameters}, |
| ); |
| return newUri.toString(); |
| } |
| |
| @JS('chrome.browserAction.setIcon') |
| external void _setExtensionIconMV2(IconInfo iconInfo, Function? callback); |
| |
| @JS('chrome.action.setIcon') |
| external void _setExtensionIconMV3(IconInfo iconInfo, Function? callback); |
| |
| @JS('chrome.browserAction.setPopup') |
| external void _setExtensionPopupMV2(PopupDetails details, Function? callback); |
| |
| @JS('chrome.action.setPopup') |
| external void _setExtensionPopupMV3(PopupDetails details, Function? callback); |
| |
| @JS() |
| @anonymous |
| class IconInfo { |
| external String get path; |
| external factory IconInfo({required String path}); |
| } |
| |
| @JS() |
| @anonymous |
| class PopupDetails { |
| external int get tabId; |
| external String get popup; |
| external factory PopupDetails({required int tabId, required String popup}); |
| } |