blob: d6be21a805617847d38964cd063147d12aada768 [file] [log] [blame]
// 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});
}