From 9c22847e3fb3d407e6e0ad4c0efdcf2d8e192ed3 Mon Sep 17 00:00:00 2001 From: Brendan Date: Sat, 28 Jul 2018 22:41:17 -0500 Subject: [PATCH 1/7] Port to edge There's something wrong with me --- .gitignore | 1 + README.md | 20 +- edge-files/AppXManifest.xml | 50 + edge-files/backgroundScriptsAPIBridge.js | 1068 ++++++++++++++++++++++ edge-files/contentScriptsAPIBridge.js | 484 ++++++++++ edge-files/icon_150.png | Bin 0 -> 15971 bytes edge-files/icon_44.png | Bin 0 -> 5467 bytes edge-files/icon_50.png | Bin 0 -> 5622 bytes manifest-edge.json | 70 ++ package.json | 9 +- src/background.ts | 3 + src/popup.ts | 16 +- src/ui/entry.ts | 114 ++- src/ui/menu.ts | 31 +- view/popup.html | 2 +- 15 files changed, 1798 insertions(+), 70 deletions(-) create mode 100644 edge-files/AppXManifest.xml create mode 100644 edge-files/backgroundScriptsAPIBridge.js create mode 100644 edge-files/contentScriptsAPIBridge.js create mode 100644 edge-files/icon_150.png create mode 100644 edge-files/icon_44.png create mode 100644 edge-files/icon_50.png create mode 100644 manifest-edge.json diff --git a/.gitignore b/.gitignore index 42727e223..06abdbcfb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules build chrome firefox +edge .vscode .atom-build.yml ci/authenticator-build-key.enc diff --git a/README.md b/README.md index 3b1212291..0075e4aab 100644 --- a/README.md +++ b/README.md @@ -13,18 +13,14 @@ Authenticator is one of the [featured extensions on Firefox Add-ons this month]( ## Build Setup ``` bash -# install typescript -npm install -g typescript -#install gts -npm install -g gts -# install dependencies +# install typescript and gts +npm install -g typescript gts +# install development dependencies npm install -# check typescript style -gts check -# try to auto fix style issue +# fix code style issues gts fix -# compile for Chrome -npm run chrome -# compile for Firefox -npm run firefox +# compile +npm run [chrome, firefox, edge] ``` + +Note that Windows users should download [Cygwin](http://cygwin.com/) to build. Building for Edge requires the [Windows App Certification Kit](https://developer.microsoft.com/en-us/windows/develop/app-certification-kit) \ No newline at end of file diff --git a/edge-files/AppXManifest.xml b/edge-files/AppXManifest.xml new file mode 100644 index 000000000..5e5594711 --- /dev/null +++ b/edge-files/AppXManifest.xml @@ -0,0 +1,50 @@ + + + + + + + Authenticator Extension + mymindstorm + Assets/icon_50.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/edge-files/backgroundScriptsAPIBridge.js b/edge-files/backgroundScriptsAPIBridge.js new file mode 100644 index 000000000..3947f31bb --- /dev/null +++ b/edge-files/backgroundScriptsAPIBridge.js @@ -0,0 +1,1068 @@ +try { + if (!Range.prototype.hasOwnProperty("intersectsNode")) { + Range.prototype["intersectsNode"] = function (node) { + let range = document.createRange(); + range.selectNode(node); + return 0 > this.compareBoundaryPoints(Range.END_TO_START, range) + && 0 < this.compareBoundaryPoints(Range.START_TO_END, range); + }; + } +} +catch (e) { } +try { + if (!Navigator.prototype.hasOwnProperty("languages")) { + Navigator.prototype["languages"] = [navigator.language]; + } +} +catch (e) { } +var getExtensionProtocol = function () { + if (typeof browser == "undefined") { + if (typeof chrome !== "undefined") + return "chrome-extension://"; + } + else { + return "ms-browser-extension://"; + } +}; +class BridgeAlarmEvent { + constructor() { + this.listeners = new Array(); + } + addListener(callback) { + this.listeners.push(callback); + } + addRules(rules, callback) { } + getRules(ruleIdentifiers, callback) { } + hasListener(callback) { return false; } + hasListeners() { return this.listeners.length > 0; } + removeRules(ruleIdentifiers, callback) { } + removeListener(callback) { } +} +class EdgeBridgeAlarms { + constructor() { + this.alarms = {}; + this.onAlarm = new BridgeAlarmEvent(); + } + create(name, alarmInfo) { + if (arguments.length < 1 || arguments.length > 2) { + throw "Unexpected set of arguments. Expecting (alarmInfo) or (name, alarmInfo)"; + } + var alarmName = ""; + var startMilliseconds = 0; + var startSet = false; + if (typeof name === "string") { + alarmName = name; + } + else if (typeof name === "object") { + alarmInfo = name; + } + else + throw "Unexpected set of arguments. Expecting (alarmInfo) or (name, alarmInfo)"; + if (!alarmInfo) { + throw "You must specify an alarmInfo argument!!"; + } + if (!alarmInfo.when && !alarmInfo.delayInMinutes && !alarmInfo.periodInMinutes) { + throw "Invalid alarmInfo argument!!"; + } + else if (alarmInfo.when && alarmInfo.delayInMinutes) { + throw "Invalid alarmInfo argument!! Either 'when' or 'delayInMinutes' but not both!!"; + } + else if (alarmInfo.when) { + startMilliseconds = alarmInfo.when; + startSet = true; + } + else if (alarmInfo.delayInMinutes) { + startMilliseconds = alarmInfo.delayInMinutes * 60 * 1000; + startSet = true; + } + else if (alarmInfo.periodInMinutes) { + startMilliseconds = alarmInfo.periodInMinutes * 60 * 1000; + startSet = true; + } + else + throw "Invalid alarmInfo argument!!"; + var timerHandle; + if (startSet) { + if (this.alarms[alarmName]) { + this.clearAlarm(alarmName); + } + var alarm = { name: alarmName, scheduledTime: Date.now() + startMilliseconds }; + var alarmAndHandle = { alarm: alarm, timerHandle: 0, startedInterval: false }; + this.alarms[alarmName] = alarmAndHandle; + if (alarmInfo.periodInMinutes) { + this.alarms[alarmName].alarm.periodInMinutes = alarmInfo.periodInMinutes; + this.alarms[alarmName].timerHandle = window.setTimeout(function (alarmName, that) { + that.soundAlarm(alarmName, that); + that.alarms[alarmName].timerHandle = window.setInterval(that.soundAlarm, alarmInfo.periodInMinutes * 60 * 1000, alarmName, that); + that.alarms[alarmName].startedInterval = true; + }, startMilliseconds, alarmName, this); + } + else { + this.alarms[alarmName].timerHandle = window.setTimeout(this.soundAlarm, startMilliseconds, alarmName, this); + } + } + } + getAll(callback) { + for (var key in this.alarms) { + if (this.alarms.hasOwnProperty(key)) { + var alarm = this.alarms[key].alarm; + callback(alarm); + } + } + } + clearAll(callback) { + var clearedAll = true; + for (var key in this.alarms) { + if (this.alarms.hasOwnProperty(key)) { + var alarm = this.alarms[key].alarm; + if (!this.clearAlarm(alarm.name)) { + clearedAll = false; + } + } + } + if (callback) { + callback(clearedAll); + } + } + clear(name, callback) { + var alarmName = ""; + if (typeof name === "string") { + alarmName = name; + } + else if (typeof name === "function") { + callback = name; + } + var wasCleared = this.clearAlarm(alarmName); + if (callback) { + callback(wasCleared); + } + } + get(name, callback) { + if (this.alarms.hasOwnProperty(name)) { + var alarm = this.alarms[name].alarm; + callback(alarm); + } + } + clearAlarm(name) { + var wasCleared = false; + if (this.alarms[name]) { + if (this.alarms[name].alarm.startedInterval) { + window.clearInterval(this.alarms[name].timerHandle); + } + else { + window.clearTimeout(this.alarms[name].timerHandle); + } + delete this.alarms[name]; + wasCleared = true; + } + return wasCleared; + } + soundAlarm(name, that) { + for (var index = 0; index < that.onAlarm.listeners.length; index++) { + var listener = that.onAlarm.listeners[index]; + listener({ name: name }); + } + } +} +class FakeEvent { + addListener(callback) { } + addRules(rules, callback) { } + getRules(ruleIdentifiers, callback) { } + hasListener(callback) { return false; } + hasListeners() { return false; } + removeRules(ruleIdentifiers, callback) { } + removeListener(callback) { } +} +class EdgeBridgeHelper { + constructor() { + this.fakeEvent = new FakeEvent(); + this.alarms = new EdgeBridgeAlarms(); + } + toAbsolutePath(relativePath) { + if (relativePath.indexOf("ms-browser-extension://") == 0) { + return relativePath.replace(myBrowser.runtime.getURL(""), ""); + } + else if (relativePath.indexOf("/") != 0) { + var absolutePath = ""; + var documentPath = document.location.pathname; + absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1); + absolutePath += relativePath; + return absolutePath; + } + return relativePath; + } +} +var bridgeHelper = new EdgeBridgeHelper(); +class EdgeBridgeDebugLog { + constructor() { + this.CatchOnException = true; + this.VerboseLogging = true; + this.FailedCalls = {}; + this.SuccededCalls = {}; + this.DeprecatedCalls = {}; + this.BridgedCalls = {}; + this.UnavailableApis = {}; + this.EdgeIssues = {}; + } + log(message) { + try { + if (this.VerboseLogging) { + console.log(message); + } + } + catch (e) { + } + } + info(message) { + try { + if (this.VerboseLogging) { + console.info(message); + } + } + catch (e) { + } + } + warn(message) { + try { + if (this.VerboseLogging) { + console.warn(message); + } + } + catch (e) { + } + } + error(message) { + try { + if (this.VerboseLogging) { + console.error(message); + } + } + catch (e) { + } + } + DoActionAndLog(action, name, deprecatedTo, bridgedTo) { + var result; + try { + result = action(); + this.AddToCalledDictionary(this.SuccededCalls, name); + if (typeof deprecatedTo !== "undefined") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + if (typeof bridgedTo !== "undefined") { + this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo); + this.AddToCalledDictionary(this.BridgedCalls, name); + } + this.info("API Call: '" + name + "'"); + return result; + } + catch (ex) { + this.AddToCalledDictionary(this.FailedCalls, name); + if (this.CatchOnException) + this.error("API Call Failed: " + name + " - " + ex); + else + throw ex; + } + } + LogEdgeIssue(name, message) { + this.warn(message); + this.AddToCalledDictionary(this.EdgeIssues, name); + } + LogUnavailbleApi(name, deprecatedTo) { + this.warn("API Call '" + name + "' is not supported in Edge"); + this.AddToCalledDictionary(this.UnavailableApis, name); + if (typeof deprecatedTo !== "undefined") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + } + AddToCalledDictionary(dictionary, name) { + if (typeof dictionary[name] !== "undefined") { + dictionary[name]++; + } + else { + dictionary[name] = 1; + } + } +} +var bridgeLog = new EdgeBridgeDebugLog(); +class EdgeChromeAlarmBridge { + get onAlarm() { + return bridgeLog.DoActionAndLog(() => { + return bridgeHelper.alarms.onAlarm; + }, "alarms.onAlarm", undefined, "bridgeHelper.alarms.onAlarm"); + } + create(name, alarmInfo) { + bridgeLog.DoActionAndLog(() => { + bridgeHelper.alarms.create.apply(null, arguments); + }, "alarms.create", undefined, "bridgeHelper.alarms.create"); + } + getAll(callback) { + bridgeLog.DoActionAndLog(() => { + bridgeHelper.alarms.getAll.apply(null, arguments); + }, "alarms.getAll", undefined, "bridgeHelper.alarms.getAll"); + } + clearAll(callback) { + bridgeLog.DoActionAndLog(() => { + bridgeHelper.alarms.clearAll.apply(null, arguments); + }, "alarms.clearAll", undefined, "bridgeHelper.alarms.clearAll"); + } + clear(name, callback) { + bridgeLog.DoActionAndLog(() => { + bridgeHelper.alarms.clear.apply(null, arguments); + }, "alarms.clear", undefined, "bridgeHelper.alarms.clear"); + } + get(name, callback) { + bridgeLog.DoActionAndLog(() => { + bridgeHelper.alarms.get.apply(null, arguments); + }, "alarms.get", undefined, "bridgeHelper.alarms.get"); + } +} +class EdgeChromeAppBridge { + getDetails() { + return bridgeLog.DoActionAndLog(() => { + return EdgeChromeRuntimeBridge.prototype.getManifest.apply(null, arguments); + }, "app.getManifest", undefined, "runtime.getManifest"); + } + get isInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.isInstalled is not available in Edge"; }, "app.isInstalled"); } + getIsInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.getIsInstalled is not available in the Edge"; }, "app.getIsInstalled"); } + installState() { return bridgeLog.DoActionAndLog(() => { throw "app.installState is not available in Edge"; }, "app.installState"); } + runningState() { return bridgeLog.DoActionAndLog(() => { throw "app.runningState is not available in Edge"; }, "app.runningState"); } +} +class EdgeBookmarksBridge { + create(bookmark, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.bookmarks.create.apply(null, arguments); + }, "bookmarks.create"); + } + getTree(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.bookmarks.getTree.apply(null, arguments); + }, "bookmarks.getTree"); + } + move(id, destination, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.bookmarks.move.apply(null, arguments); + }, "bookmarks.move"); + } + remove(id, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.bookmarks.remove.apply(null, arguments); + }, "bookmarks.remove"); + } + removeTree(id, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.bookmarks.removeTree.apply(null, arguments); + }, "bookmarks.removeTree"); + } + update(id, changes, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.bookmarks.update.apply(null, arguments); + }, "bookmarks.update"); + } +} +class EdgeChromeBookmarksBridge extends EdgeBookmarksBridge { + get onRemoved() { bridgeLog.LogUnavailbleApi("bookmarks.onRemoved"); return bridgeHelper.fakeEvent; } + get onImportEnded() { bridgeLog.LogUnavailbleApi("bookmarks.onImportEnded"); return bridgeHelper.fakeEvent; } + get onImportBegan() { bridgeLog.LogUnavailbleApi("bookmarks.onImportBegan"); return bridgeHelper.fakeEvent; } + get onChanged() { bridgeLog.LogUnavailbleApi("bookmarks.onChanged"); return bridgeHelper.fakeEvent; } + get onMoved() { bridgeLog.LogUnavailbleApi("bookmarks.onMoved"); return bridgeHelper.fakeEvent; } + get onCreated() { bridgeLog.LogUnavailbleApi("bookmarks.onCreated"); return bridgeHelper.fakeEvent; } + get onChildrenReordered() { bridgeLog.LogUnavailbleApi("bookmarks.onChildrenReordered"); return bridgeHelper.fakeEvent; } + getRecent(numberOfItems, callback) { + bridgeLog.LogUnavailbleApi("bookmarks.getRecent"); + } + get(idList, callback) { + bridgeLog.LogUnavailbleApi("bookmarks.get"); + } + getChildren(id, callback) { + bridgeLog.LogUnavailbleApi("bookmarks.getChildren"); + } + getSubTree(id, callback) { + bridgeLog.LogUnavailbleApi("bookmarks.getSubTree"); + } + search(query, callback) { + bridgeLog.LogUnavailbleApi("bookmarks.search"); + } +} +class EdgeBrowserActionBridge { + get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.browserAction.onClicked; }, "browserAction.onClicked"); } + disable(tabId) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.disable.apply(null, arguments); + }, "browserAction.disable"); + } + enable(tabId) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.enable.apply(null, arguments); + }, "browserAction.Enable"); + } + getBadgeBackgroundColor(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.getBadgeBackgroundColor.apply(null, arguments); + }, "browserAction.getBadgeBackgroundColor"); + } + getBadgeText(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.getBadgeText.apply(null, arguments); + ; + }, "browserAction.getBadgeText"); + } + getPopup(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.getPopup.apply(null, arguments); + }, "browserAction.getPopup"); + } + getTitle(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.getTitle.apply(null, arguments); + }, "browserAction.getTitle"); + } + setBadgeBackgroundColor(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setBadgeBackgroundColor.apply(null, arguments); + }, "browserAction.setBadgeBackgroundColor"); + } + setBadgeText(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setBadgeText.apply(null, arguments); + }, "browserAction.setBadgeText"); + } + setIcon(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setIcon.apply(null, arguments); + }, "browserAction.setIcon"); + } + setPopup(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setPopup.apply(null, arguments); + }, "browserAction.setPopup"); + } + setTitle(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.browserAction.setTitle.apply(null, arguments); + }, "browserAction.setTitle"); + } +} +class EdgeChromeBrowserActionBridge extends EdgeBrowserActionBridge { + getPopup(details, callback) { + if (myBrowser.browserAction.getPopup) { + EdgeBrowserActionBridge.prototype.getPopup.apply(null, arguments); + } + else { + bridgeLog.LogUnavailbleApi("browserAction.getPopup"); + } + } + getTitle(details, callback) { + if (myBrowser.browserAction.getTitle) { + EdgeBrowserActionBridge.prototype.getTitle.apply(null, arguments); + } + else { + bridgeLog.LogUnavailbleApi("browserAction.getTitle"); + } + } + setTitle(details) { + if (myBrowser.browserAction.setTitle) { + EdgeBrowserActionBridge.prototype.setTitle.apply(null, arguments); + } + else { + bridgeLog.LogUnavailbleApi("browserAction.setTitle"); + } + } +} +class EdgeChromeCommandsBridge { + get onCommand() { bridgeLog.LogUnavailbleApi("commands.onCommand"); return bridgeHelper.fakeEvent; } + getAll(callback) { + bridgeLog.LogUnavailbleApi("commands.getAll"); + } +} +class EdgeContextMenusBridge { + get ACTION_MENU_TOP_LEVEL_LIMIT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT; }, "contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT"); } + get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.onClicked; }, "contextMenus.onClicked"); } + create(createProperties, callback) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.contextMenus.create.apply(null, arguments); + }, "contextMenus.create"); + } + remove(menuItemId, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.contextMenus.remove.apply(null, arguments); + }, "contextMenus.remove"); + } + removeAll(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.contextMenus.removeAll.apply(null, arguments); + }, "contextMenus.removeAll"); + } + update(id, updateProperties, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.contextMenus.update.apply(null, arguments); + }, "contextMenus.update"); + } +} +class EdgeCookiesBridge { + get(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.cookies.get.apply(null, arguments); + }, "cookies.get"); + } + getAll(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.cookies.getAll.apply(null, arguments); + }, "cookies.getAll"); + } + remove(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.cookies.remove.apply(null, arguments); + }, "cookies.remove"); + } + set(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.cookies.set.apply(null, arguments); + }, "cookies.set"); + } +} +class EdgeChromeCookiesBridge extends EdgeCookiesBridge { + get onChanged() { bridgeLog.LogUnavailbleApi("cookies.onChanged"); return bridgeHelper.fakeEvent; } +} +class EdgeExtensionBridge { + get inIncognitoContext() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.inIncognitoContext; + }, "extension.inIncognitoContext"); + } + getBackgroundPage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getBackgroundPage.apply(null, arguments); + }, "extension.getBackgroundPage"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getURL.apply(null, arguments); + }, "extension.getURL"); + } + getViews(fetchProperties) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getViews.apply(null, arguments); + }, "extension.getViews"); + } + isAllowedIncognitoAccess(callback) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.isAllowedIncognitoAccess.apply(null, arguments); + }, "extension.isAllowedIncognitoAccess"); + } +} +class EdgeChromeExtensionBridge extends EdgeExtensionBridge { + get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); } + get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); } + get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.connect.apply(null, arguments); + }, "extension.connect", "runtime.connect", "runtime.connect"); + } + sendMessage(message, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage.apply(null, arguments); + }, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage"); + } + sendRequest(extensionId, message, options, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage.apply(null, arguments); + }, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage"); + } + isAllowedFileSchemeAccess(callback) { + bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess"); + } + setUpdateUrlData(data) { + bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData"); + } +} +class EdgeHistoryBridge { + get onVisited() { bridgeLog.LogUnavailbleApi("history.onVisited"); return bridgeHelper.fakeEvent; } + get onVisitRemoved() { bridgeLog.LogUnavailbleApi("history.onVisitRemoved"); return bridgeHelper.fakeEvent; } + addUrl(details, callback) { + bridgeLog.LogUnavailbleApi("history.addUrl"); + } + deleteAll(callback) { + bridgeLog.LogUnavailbleApi("history.deleteAll"); + } + deleteRange(range, callback) { + bridgeLog.LogUnavailbleApi("history.deleteRange"); + } + deleteUrl(details, callback) { + bridgeLog.LogUnavailbleApi("history.deleteUrl"); + } + getVisits(details, callback) { + bridgeLog.LogUnavailbleApi("history.getVisits"); + } + search(query, callback) { + bridgeLog.LogUnavailbleApi("history.search"); + } +} +class EdgeI18nBridge { + getAcceptLanguages(callback) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getAcceptLanguages.apply(null, arguments); + }, "i18n.getAcceptLanguages"); + } + getMessage(messageName, substitutions) { + return bridgeLog.DoActionAndLog(() => { + if (messageName.indexOf("@@extension_id") > -1) { + return myBrowser.runtime.id; + } + return myBrowser.i18n.getMessage.apply(null, arguments); + }, "i18n.getMessage"); + } + getUILanguage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getUILanguage.apply(null, arguments); + }, "i18n.getUILanguage"); + } +} +class EdgeChromeIdleBridge { + get onStateChanged() { bridgeLog.LogUnavailbleApi("idle.onStateChanged"); return bridgeHelper.fakeEvent; } + queryState(detectionIntervalInSeconds, callback) { + bridgeLog.LogUnavailbleApi("idle.queryState"); + } + setDetectionInterval(intervalInSeconds) { + bridgeLog.LogUnavailbleApi("idle.setDetectionInterval"); + } +} +class EdgeNotificationBridge { + get onButtonClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.notifications.onButtonClicked; }, "notifications.onButtonClicked"); } + get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.notifications.onClicked; }, "notifications.onClicked"); } + get onClosed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.notifications.onClosed; }, "notifications.onClosed"); } + get onPermissionLevelChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.notifications.onPermissionLevelChanged; }, "notifications.onPermissionLevelChanged"); } + get onShowSettings() { bridgeLog.LogUnavailbleApi("notifications.onShowSettings"); return bridgeHelper.fakeEvent; } + clear(notificationId, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.notifications.clear.apply(null, arguments); + }, "notifications.clear"); + } + create(notificationId, options, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.notifications.create.apply(null, arguments); + }, "notifications.create"); + } + getAll(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.notifications.getAll.apply(null, arguments); + }, "notifications.getAll"); + } + getPermissionLevel(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.notifications.getPermissionLevel.apply(null, arguments); + }, "notifications.getPermissionLevel"); + } + update(notificationId, options, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.notifications.update.apply(null, arguments); + }, "notifications.update"); + } +} +class EdgePageActionBridge { + get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.pageAction.onClicked; }, "pageAction.onClicked"); } + getPopup(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.getPopup.apply(null, arguments); + }, "pageAction.getPopup"); + } + getTitle(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.getTitle.apply(null, arguments); + }, "pageAction.getTitle"); + } + hide(tabId) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.hide.apply(null, arguments); + }, "pageAction.hide"); + } + setTitle(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.setTitle.apply(null, arguments); + }, "pageAction.setTitle"); + } + setIcon(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.setIcon.apply(null, arguments); + }, "pageAction.setIcon"); + } + setPopup(details) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.setPopup.apply(null, arguments); + }, "pageAction.setPopup"); + } + show(tabId) { + bridgeLog.DoActionAndLog(() => { + myBrowser.pageAction.show.apply(null, arguments); + }, "pageAction.show"); + } +} +class EdgePermissionsBridge { + get onAdded() { bridgeLog.LogUnavailbleApi("permissions.onAdded"); return bridgeHelper.fakeEvent; } + get onRemoved() { bridgeLog.LogUnavailbleApi("permissions.onRemoved"); return bridgeHelper.fakeEvent; } + contains(permissions, callback) { + bridgeLog.LogUnavailbleApi("permissions.contains"); + } + getAll(callback) { + bridgeLog.LogUnavailbleApi("permissions.getAll"); + } + remove(permissions, callback) { + bridgeLog.LogUnavailbleApi("permissions.remove"); + } + request(permissions, callback) { + bridgeLog.LogUnavailbleApi("permissions.request"); + } +} +class EdgeRuntimeBridge { + get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); } + get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); } + get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); } + get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.connect.apply(null, arguments); + }, "runtime.connect"); + } + connectNative(application) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.connectNative.apply(null, arguments); + }, "runtime.connectNative"); + } + getBackgroundPage(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.getBackgroundPage.apply(null, arguments); + }, "runtime.getBackgroundPage"); + } + getManifest() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getManifest.apply(null, arguments); + }, "runtime.getManifest"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getURL.apply(null, arguments); + }, "runtime.getURL"); + } + reload() { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.reload.apply(null, arguments); + }, "runtime.reload"); + } + sendMessage(extensionId, message, options, responseCallback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.sendMessage.apply(null, arguments); + }, "runtime.sendMessage"); + } + sendNativeMessage(application, message, responseCallback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.sendNativeMessage.apply(null, arguments); + }, "runtime.sendNativeMessage"); + } + setUninstallURL(url, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.setUninstallURL.apply(null, arguments); + }, "runtime.setUninstallURL"); + } +} +class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge { + get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; } + get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; } + get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; } + get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; } + get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; } + get onStartup() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onCreated; }, "runtime.onStartup", undefined, "windows.onCreated"); } + openOptionsPage(callback) { + bridgeLog.DoActionAndLog(() => { + var optionsPage = myBrowser.runtime.getManifest()["options_page"]; + var optionsPageUrl = myBrowser.runtime.getURL(optionsPage); + if (typeof callback !== "undefined") { + myBrowser.tabs.create({ url: optionsPageUrl }, callback); + } + else { + myBrowser.tabs.create({ url: optionsPageUrl }); + } + }, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })"); + } + setUninstallURL(url, callback) { + if (myBrowser.runtime.setUninstallURL) { + EdgeRuntimeBridge.prototype.setUninstallURL.apply(null, arguments); + } + else { + bridgeLog.LogUnavailbleApi("runtime.setUninstallURL"); + } + } + getPackageDirectoryEntry(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry"); + } + getPlatformInfo(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo"); + } + requestUpdateCheck(callback) { + bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck"); + } + restart() { + bridgeLog.LogUnavailbleApi("runtime.restart"); + } +} +class EdgeStorageBridge { + get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); } + get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.sync; }, "storage.sync"); } + get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); } +} +class EdgeChromeStorageBridge extends EdgeStorageBridge { + get sync() { + if (myBrowser.storage.sync) { + return EdgeStorageBridge.prototype.sync; + } + else { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.storage.local; + }, "storage.sync", undefined, "storage.local"); + } + } + get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); } +} +class EdgeTabsBridge { + get onActivated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onActivated; }, "tabs.onActivated"); } + get onAttached() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onAttached; }, "tabs.onAttached"); } + get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onCreated; }, "tabs.onCreated"); } + get onDetached() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onDetached; }, "tabs.onDetached"); } + get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onRemoved; }, "tabs.onRemoved"); } + get onReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onReplaced; }, "tabs.onReplaced"); } + get onUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onUpdated; }, "tabs.onUpdated"); } + captureVisibleTab(windowId, options, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.captureVisibleTab.apply(null, arguments); + }, "tabs.captureVisibleTab"); + } + create(createProperties, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.create.apply(null, arguments); + }, "tabs.create"); + } + detectLanguage(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.detectLanguage.apply(null, arguments); + }, "tabs.detectLanguage"); + } + executeScript(tabId, details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.executeScript.apply(null, arguments); + }, "tabs.executeScript"); + } + get(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.get.apply(null, arguments); + }, "tabs.get"); + } + getCurrent(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.getCurrent.apply(null, arguments); + }, "tabs.getCurrent"); + } + insertCSS(tabId, details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.insertCSS.apply(null, arguments); + }, "tabs.insertCSS"); + } + query(queryInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.query.apply(null, arguments); + }, "tabs.query"); + } + reload(tabId, reloadProperties, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.reload.apply(null, arguments); + }, "tabs.reload"); + } + remove(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.remove.apply(null, arguments); + }, "tabs.remove"); + } + sendMessage(tabId, message, responseCallback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.sendMessage.apply(null, arguments); + }, "tabs.sendMessage"); + } + update(tabId, updateProperties, callback) { + var updatePropertiesBridged = false; + for (var index = 0; index < arguments.length; index++) { + var argument = arguments[index]; + if (typeof argument === "object") { + if (!argument.active && (argument.highlighted || argument.selected)) { + argument.active = argument.highlighted || argument.selected; + updatePropertiesBridged = true; + } + } + } + bridgeLog.DoActionAndLog(() => { + myBrowser.tabs.update.apply(null, arguments); + }, "tabs.update", undefined, updatePropertiesBridged ? "tabs.update with UpdateProperties modified" : undefined); + } +} +class EdgeChromeTabsBridge extends EdgeTabsBridge { + get onHighlighted() { bridgeLog.LogUnavailbleApi("tabs.onHighlighted"); return bridgeHelper.fakeEvent; } + get onMoved() { bridgeLog.LogUnavailbleApi("tabs.onMoved"); return bridgeHelper.fakeEvent; } + get onSelectionChanged() { + return bridgeLog.DoActionAndLog(() => { + var fakeEvent = bridgeHelper.fakeEvent; + fakeEvent.addListener = (callback) => { + myBrowser.tabs.onActivated.addListener((activeInfo) => { + callback(activeInfo.tabId, { windowId: activeInfo.windowId }); + }); + }; + return fakeEvent; + }, "tabs.onSelectionChanged", "tabs.onActivated", "tabs.onActivated"); + } + duplicate(tabId, callback) { + bridgeLog.DoActionAndLog(() => { + var tabGetCallback = function (tab) { + if (typeof callback !== "undefined") { + myBrowser.tabs.create({ url: tab.url }, callback); + } + else { + myBrowser.tabs.create({ url: tab.url }); + } + }; + EdgeTabsBridge.prototype.get(tabId, tabGetCallback); + }, "tabs.duplicate", undefined, "tabs.create"); + } + getAllInWindow(windowId, callback) { + bridgeLog.DoActionAndLog(() => { + EdgeTabsBridge.prototype.query({ windowId: windowId }, callback); + }, "tabs.getAllInWindow", "tabs.query", "tabs.query"); + } + getSelected(windowId, callback) { + bridgeLog.DoActionAndLog(() => { + EdgeTabsBridge.prototype.query({ active: true }, (tabs) => callback(tabs[0])); + }, "tabs.getSelected", "tabs.query", "tabs.query"); + } + sendRequest(tabId, request, responseCallback) { + bridgeLog.DoActionAndLog(() => { + EdgeTabsBridge.prototype.sendMessage.apply(null, arguments); + }, "tabs.sendRequest", "tabs.sendMessage", "tabs.sendMessage"); + } + connect(tabId, connectInfo) { + bridgeLog.LogUnavailbleApi("tabs.connect"); + return null; + } + highlight(highlightInfo, callback) { + bridgeLog.LogUnavailbleApi("tabs.highlight"); + } + move(tabId, moveProperties, callback) { + bridgeLog.LogUnavailbleApi("tabs.move"); + } +} +class EdgeWebNavigationBridge { + get onBeforeNavigate() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onBeforeNavigate; }, "webNavigation.onBeforeNavigate"); } + get onCommitted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCommitted; }, "webNavigation.onCommitted"); } + get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCompleted; }, "webNavigation.onCompleted"); } + get onCreatedNavigationTarget() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCreatedNavigationTarget; }, "webNavigation.onCreatedNavigationTarget"); } + get onDOMContentLoaded() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onDOMContentLoaded; }, "webNavigation.onDOMContentLoaded"); } + get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onErrorOccurred; }, "webNavigation.onErrorOccurred"); } + get onHistoryStateUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onHistoryStateUpdated; }, "webNavigation.onHistoryStateUpdated"); } + get onReferenceFragmentUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onReferenceFragmentUpdated; }, "webNavigation.onReferenceFragmentUpdated"); } + get onTabReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onTabReplaced; }, "webNavigation.onTabReplaced"); } + getAllFrames(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.webNavigation.getAllFrames.apply(null, arguments); + }, "webNavigation.getAllFrames"); + } + getFrame(details, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.webNavigation.getFrame.apply(null, arguments); + }, "webNavigation.getFrame"); + } +} +class EdgeWebRequestBridge { + get MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES; }, "webNavigation.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES"); } + get onAuthRequired() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onAuthRequired; }, "webRequest.onAuthRequired"); } + get onBeforeRedirect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRedirect; }, "webRequest.onBeforeRedirect"); } + get onBeforeRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRequest; }, "webRequest.onBeforeRequest"); } + get onBeforeSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeSendHeaders; }, "webRequest.onBeforeSendHeaders"); } + get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onCompleted; }, "webRequest.onCompleted"); } + get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onErrorOccurred; }, "webRequest.onErrorOccurred"); } + get onHeadersReceived() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onHeadersReceived; }, "webRequest.onHeadersReceived"); } + get onResponseStarted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onResponseStarted; }, "webRequest.onResponseStarted"); } + get onSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onSendHeaders; }, "webRequest.onSendHeaders"); } + handlerBehaviorChanged(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.webRequest.handlerBehaviorChanged.apply(null, arguments); + }, "webRequest.handlerBehaviorChanged"); + } +} +class EdgeWindowsBridge { + get WINDOW_ID_CURRENT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_CURRENT; }, "windows.WINDOW_ID_CURRENT"); } + get WINDOW_ID_NONE() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_NONE; }, "windows.WINDOW_ID_NONE"); } + get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onCreated; }, "windows.onCreated"); } + get onFocusChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onFocusChanged; }, "windows.onFocusChanged"); } + get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onRemoved; }, "windows.onRemoved"); } + create(createData, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.create.apply(null, arguments); + }, "windows.create"); + } + get(windowId, getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.get.apply(null, arguments); + }, "windows.get"); + } + getAll(getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.getAll.apply(null, arguments); + }, "windows.getAll"); + } + getCurrent(getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.getCurrent.apply(null, arguments); + }, "windows.getCurrent"); + } + getLastFocused(getInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.getLastFocused.apply(null, arguments); + }, "windows.getLastFocused"); + } + update(windowId, updateInfo, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.windows.update.apply(null, arguments); + }, "windows.update"); + } +} +class EdgeChromeWindowsBridge extends EdgeWindowsBridge { + remove(windowId, callback) { + bridgeLog.LogUnavailbleApi("windows.remove"); + } +} +class EdgeBackgroundBridge { + constructor() { + this.alarms = new EdgeChromeAlarmBridge(); + this.app = new EdgeChromeAppBridge(); + this.commands = new EdgeChromeCommandsBridge(); + this.idle = new EdgeChromeIdleBridge(); + this.notifications = new EdgeNotificationBridge(); + this.bookmarks = typeof browser["bookmarks"] !== "undefined" ? new EdgeChromeBookmarksBridge() : undefined; + this.browserAction = typeof browser.browserAction !== "undefined" ? new EdgeChromeBrowserActionBridge() : undefined; + this.contextMenus = typeof browser.contextMenus !== "undefined" ? new EdgeContextMenusBridge() : undefined; + this.cookies = typeof browser.cookies !== "undefined" ? new EdgeChromeCookiesBridge() : undefined; + this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined; + this.history = typeof browser.history !== "undefined" ? new EdgeHistoryBridge() : undefined; + this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined; + this.pageAction = typeof browser.pageAction !== "undefined" ? new EdgePageActionBridge() : undefined; + this.permissions = typeof browser.permissions !== "undefined" ? new EdgePermissionsBridge() : undefined; + this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined; + this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined; + this.tabs = typeof browser.tabs !== "undefined" ? new EdgeChromeTabsBridge() : undefined; + this.webNavigation = typeof browser.webNavigation !== "undefined" ? new EdgeWebNavigationBridge() : undefined; + this.webRequest = typeof browser.webRequest !== "undefined" ? new EdgeWebRequestBridge() : undefined; + this.windows = typeof browser.windows !== "undefined" ? new EdgeChromeWindowsBridge() : undefined; + } +} +var myBrowser = browser; +var chrome = new EdgeBackgroundBridge(); diff --git a/edge-files/contentScriptsAPIBridge.js b/edge-files/contentScriptsAPIBridge.js new file mode 100644 index 000000000..0a84c346b --- /dev/null +++ b/edge-files/contentScriptsAPIBridge.js @@ -0,0 +1,484 @@ +try { + if (!Range.prototype.hasOwnProperty("intersectsNode")) { + Range.prototype["intersectsNode"] = function (node) { + let range = document.createRange(); + range.selectNode(node); + return 0 > this.compareBoundaryPoints(Range.END_TO_START, range) + && 0 < this.compareBoundaryPoints(Range.START_TO_END, range); + }; + } +} +catch (e) { } +try { + if (!Navigator.prototype.hasOwnProperty("languages")) { + Navigator.prototype["languages"] = [navigator.language]; + } +} +catch (e) { } +var getExtensionProtocol = function () { + if (typeof browser == "undefined") { + if (typeof chrome !== "undefined") + return "chrome-extension://"; + } + else { + return "ms-browser-extension://"; + } +}; +class BridgeAlarmEvent { + constructor() { + this.listeners = new Array(); + } + addListener(callback) { + this.listeners.push(callback); + } + addRules(rules, callback) { } + getRules(ruleIdentifiers, callback) { } + hasListener(callback) { return false; } + hasListeners() { return this.listeners.length > 0; } + removeRules(ruleIdentifiers, callback) { } + removeListener(callback) { } +} +class EdgeBridgeAlarms { + constructor() { + this.alarms = {}; + this.onAlarm = new BridgeAlarmEvent(); + } + create(name, alarmInfo) { + if (arguments.length < 1 || arguments.length > 2) { + throw "Unexpected set of arguments. Expecting (alarmInfo) or (name, alarmInfo)"; + } + var alarmName = ""; + var startMilliseconds = 0; + var startSet = false; + if (typeof name === "string") { + alarmName = name; + } + else if (typeof name === "object") { + alarmInfo = name; + } + else + throw "Unexpected set of arguments. Expecting (alarmInfo) or (name, alarmInfo)"; + if (!alarmInfo) { + throw "You must specify an alarmInfo argument!!"; + } + if (!alarmInfo.when && !alarmInfo.delayInMinutes && !alarmInfo.periodInMinutes) { + throw "Invalid alarmInfo argument!!"; + } + else if (alarmInfo.when && alarmInfo.delayInMinutes) { + throw "Invalid alarmInfo argument!! Either 'when' or 'delayInMinutes' but not both!!"; + } + else if (alarmInfo.when) { + startMilliseconds = alarmInfo.when; + startSet = true; + } + else if (alarmInfo.delayInMinutes) { + startMilliseconds = alarmInfo.delayInMinutes * 60 * 1000; + startSet = true; + } + else if (alarmInfo.periodInMinutes) { + startMilliseconds = alarmInfo.periodInMinutes * 60 * 1000; + startSet = true; + } + else + throw "Invalid alarmInfo argument!!"; + var timerHandle; + if (startSet) { + if (this.alarms[alarmName]) { + this.clearAlarm(alarmName); + } + var alarm = { name: alarmName, scheduledTime: Date.now() + startMilliseconds }; + var alarmAndHandle = { alarm: alarm, timerHandle: 0, startedInterval: false }; + this.alarms[alarmName] = alarmAndHandle; + if (alarmInfo.periodInMinutes) { + this.alarms[alarmName].alarm.periodInMinutes = alarmInfo.periodInMinutes; + this.alarms[alarmName].timerHandle = window.setTimeout(function (alarmName, that) { + that.soundAlarm(alarmName, that); + that.alarms[alarmName].timerHandle = window.setInterval(that.soundAlarm, alarmInfo.periodInMinutes * 60 * 1000, alarmName, that); + that.alarms[alarmName].startedInterval = true; + }, startMilliseconds, alarmName, this); + } + else { + this.alarms[alarmName].timerHandle = window.setTimeout(this.soundAlarm, startMilliseconds, alarmName, this); + } + } + } + getAll(callback) { + for (var key in this.alarms) { + if (this.alarms.hasOwnProperty(key)) { + var alarm = this.alarms[key].alarm; + callback(alarm); + } + } + } + clearAll(callback) { + var clearedAll = true; + for (var key in this.alarms) { + if (this.alarms.hasOwnProperty(key)) { + var alarm = this.alarms[key].alarm; + if (!this.clearAlarm(alarm.name)) { + clearedAll = false; + } + } + } + if (callback) { + callback(clearedAll); + } + } + clear(name, callback) { + var alarmName = ""; + if (typeof name === "string") { + alarmName = name; + } + else if (typeof name === "function") { + callback = name; + } + var wasCleared = this.clearAlarm(alarmName); + if (callback) { + callback(wasCleared); + } + } + get(name, callback) { + if (this.alarms.hasOwnProperty(name)) { + var alarm = this.alarms[name].alarm; + callback(alarm); + } + } + clearAlarm(name) { + var wasCleared = false; + if (this.alarms[name]) { + if (this.alarms[name].alarm.startedInterval) { + window.clearInterval(this.alarms[name].timerHandle); + } + else { + window.clearTimeout(this.alarms[name].timerHandle); + } + delete this.alarms[name]; + wasCleared = true; + } + return wasCleared; + } + soundAlarm(name, that) { + for (var index = 0; index < that.onAlarm.listeners.length; index++) { + var listener = that.onAlarm.listeners[index]; + listener({ name: name }); + } + } +} +class FakeEvent { + addListener(callback) { } + addRules(rules, callback) { } + getRules(ruleIdentifiers, callback) { } + hasListener(callback) { return false; } + hasListeners() { return false; } + removeRules(ruleIdentifiers, callback) { } + removeListener(callback) { } +} +class EdgeBridgeHelper { + constructor() { + this.fakeEvent = new FakeEvent(); + this.alarms = new EdgeBridgeAlarms(); + } + toAbsolutePath(relativePath) { + if (relativePath.indexOf("ms-browser-extension://") == 0) { + return relativePath.replace(myBrowser.runtime.getURL(""), ""); + } + else if (relativePath.indexOf("/") != 0) { + var absolutePath = ""; + var documentPath = document.location.pathname; + absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1); + absolutePath += relativePath; + return absolutePath; + } + return relativePath; + } +} +var bridgeHelper = new EdgeBridgeHelper(); +class EdgeBridgeDebugLog { + constructor() { + this.CatchOnException = true; + this.VerboseLogging = true; + this.FailedCalls = {}; + this.SuccededCalls = {}; + this.DeprecatedCalls = {}; + this.BridgedCalls = {}; + this.UnavailableApis = {}; + this.EdgeIssues = {}; + } + log(message) { + try { + if (this.VerboseLogging) { + console.log(message); + } + } + catch (e) { + } + } + info(message) { + try { + if (this.VerboseLogging) { + console.info(message); + } + } + catch (e) { + } + } + warn(message) { + try { + if (this.VerboseLogging) { + console.warn(message); + } + } + catch (e) { + } + } + error(message) { + try { + if (this.VerboseLogging) { + console.error(message); + } + } + catch (e) { + } + } + DoActionAndLog(action, name, deprecatedTo, bridgedTo) { + var result; + try { + result = action(); + this.AddToCalledDictionary(this.SuccededCalls, name); + if (typeof deprecatedTo !== "undefined") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + if (typeof bridgedTo !== "undefined") { + this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo); + this.AddToCalledDictionary(this.BridgedCalls, name); + } + this.info("API Call: '" + name + "'"); + return result; + } + catch (ex) { + this.AddToCalledDictionary(this.FailedCalls, name); + if (this.CatchOnException) + this.error("API Call Failed: " + name + " - " + ex); + else + throw ex; + } + } + LogEdgeIssue(name, message) { + this.warn(message); + this.AddToCalledDictionary(this.EdgeIssues, name); + } + LogUnavailbleApi(name, deprecatedTo) { + this.warn("API Call '" + name + "' is not supported in Edge"); + this.AddToCalledDictionary(this.UnavailableApis, name); + if (typeof deprecatedTo !== "undefined") { + this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!"); + this.AddToCalledDictionary(this.DeprecatedCalls, name); + } + } + AddToCalledDictionary(dictionary, name) { + if (typeof dictionary[name] !== "undefined") { + dictionary[name]++; + } + else { + dictionary[name] = 1; + } + } +} +var bridgeLog = new EdgeBridgeDebugLog(); +class EdgeExtensionBridge { + get inIncognitoContext() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.inIncognitoContext; + }, "extension.inIncognitoContext"); + } + getBackgroundPage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getBackgroundPage.apply(null, arguments); + }, "extension.getBackgroundPage"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getURL.apply(null, arguments); + }, "extension.getURL"); + } + getViews(fetchProperties) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.getViews.apply(null, arguments); + }, "extension.getViews"); + } + isAllowedIncognitoAccess(callback) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.extension.isAllowedIncognitoAccess.apply(null, arguments); + }, "extension.isAllowedIncognitoAccess"); + } +} +class EdgeChromeExtensionBridge extends EdgeExtensionBridge { + get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); } + get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); } + get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.connect.apply(null, arguments); + }, "extension.connect", "runtime.connect", "runtime.connect"); + } + sendMessage(message, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage.apply(null, arguments); + }, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage"); + } + sendRequest(extensionId, message, options, responseCallback) { + return bridgeLog.DoActionAndLog(() => { + return EdgeRuntimeBridge.prototype.sendMessage.apply(null, arguments); + }, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage"); + } + isAllowedFileSchemeAccess(callback) { + bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess"); + } + setUpdateUrlData(data) { + bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData"); + } +} +class EdgeI18nBridge { + getAcceptLanguages(callback) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getAcceptLanguages.apply(null, arguments); + }, "i18n.getAcceptLanguages"); + } + getMessage(messageName, substitutions) { + return bridgeLog.DoActionAndLog(() => { + if (messageName.indexOf("@@extension_id") > -1) { + return myBrowser.runtime.id; + } + return myBrowser.i18n.getMessage.apply(null, arguments); + }, "i18n.getMessage"); + } + getUILanguage() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.i18n.getUILanguage.apply(null, arguments); + }, "i18n.getUILanguage"); + } +} +class EdgeRuntimeBridge { + get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); } + get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); } + get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); } + get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); } + get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); } + get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); } + connect(extensionId, connectInfo) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.connect.apply(null, arguments); + }, "runtime.connect"); + } + connectNative(application) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.connectNative.apply(null, arguments); + }, "runtime.connectNative"); + } + getBackgroundPage(callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.getBackgroundPage.apply(null, arguments); + }, "runtime.getBackgroundPage"); + } + getManifest() { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getManifest.apply(null, arguments); + }, "runtime.getManifest"); + } + getURL(path) { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.runtime.getURL.apply(null, arguments); + }, "runtime.getURL"); + } + reload() { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.reload.apply(null, arguments); + }, "runtime.reload"); + } + sendMessage(extensionId, message, options, responseCallback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.sendMessage.apply(null, arguments); + }, "runtime.sendMessage"); + } + sendNativeMessage(application, message, responseCallback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.sendNativeMessage.apply(null, arguments); + }, "runtime.sendNativeMessage"); + } + setUninstallURL(url, callback) { + bridgeLog.DoActionAndLog(() => { + myBrowser.runtime.setUninstallURL.apply(null, arguments); + }, "runtime.setUninstallURL"); + } +} +class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge { + get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; } + get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; } + get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; } + get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; } + get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; } + get onStartup() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onCreated; }, "runtime.onStartup", undefined, "windows.onCreated"); } + openOptionsPage(callback) { + bridgeLog.DoActionAndLog(() => { + var optionsPage = myBrowser.runtime.getManifest()["options_page"]; + var optionsPageUrl = myBrowser.runtime.getURL(optionsPage); + if (typeof callback !== "undefined") { + myBrowser.tabs.create({ url: optionsPageUrl }, callback); + } + else { + myBrowser.tabs.create({ url: optionsPageUrl }); + } + }, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })"); + } + setUninstallURL(url, callback) { + if (myBrowser.runtime.setUninstallURL) { + EdgeRuntimeBridge.prototype.setUninstallURL.apply(null, arguments); + } + else { + bridgeLog.LogUnavailbleApi("runtime.setUninstallURL"); + } + } + getPackageDirectoryEntry(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry"); + } + getPlatformInfo(callback) { + bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo"); + } + requestUpdateCheck(callback) { + bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck"); + } + restart() { + bridgeLog.LogUnavailbleApi("runtime.restart"); + } +} +class EdgeStorageBridge { + get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); } + get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.sync; }, "storage.sync"); } + get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); } +} +class EdgeChromeStorageBridge extends EdgeStorageBridge { + get sync() { + if (myBrowser.storage.sync) { + return EdgeStorageBridge.prototype.sync; + } + else { + return bridgeLog.DoActionAndLog(() => { + return myBrowser.storage.local; + }, "storage.sync", undefined, "storage.local"); + } + } + get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); } +} +class EdgeContentBridge { + constructor() { + this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined; + this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined; + this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined; + this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined; + } +} +var myBrowser = browser; +var chrome = new EdgeContentBridge(); diff --git a/edge-files/icon_150.png b/edge-files/icon_150.png new file mode 100644 index 0000000000000000000000000000000000000000..177f3ea80350a93bc6c981dbafdcdf0ad7361482 GIT binary patch literal 15971 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 literal 0 HcmV?d00001 diff --git a/edge-files/icon_44.png b/edge-files/icon_44.png new file mode 100644 index 0000000000000000000000000000000000000000..50e53f41e0e6ab7ce28499051bcd975b852add5a GIT binary patch literal 5467 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 RTkik>002ovPDHLkV1n^GiOK)~ literal 0 HcmV?d00001 diff --git a/edge-files/icon_50.png b/edge-files/icon_50.png new file mode 100644 index 0000000000000000000000000000000000000000..c23c7d0ea46456460c560ee24fa0b45bd18e199d GIT binary patch literal 5622 zcmV004&%004{+008|`004nN004b?008NW002DY000@xb3BE2000U( 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 QF8}}l07*qoM6N<$g1}AQP5=M^ literal 0 HcmV?d00001 diff --git a/manifest-edge.json b/manifest-edge.json new file mode 100644 index 000000000..392de2620 --- /dev/null +++ b/manifest-edge.json @@ -0,0 +1,70 @@ +{ + "author": "Authenticator Extension", + "background": { + "scripts": [ + "js/jsqrcode/grid.js", + "js/jsqrcode/version.js", + "js/jsqrcode/detector.js", + "js/jsqrcode/formatinf.js", + "js/jsqrcode/errorlevel.js", + "js/jsqrcode/bitmat.js", + "js/jsqrcode/datablock.js", + "js/jsqrcode/bmparser.js", + "js/jsqrcode/datamask.js", + "js/jsqrcode/rsdecoder.js", + "js/jsqrcode/gf256poly.js", + "js/jsqrcode/gf256.js", + "js/jsqrcode/decoder.js", + "js/jsqrcode/qrcode.js", + "js/jsqrcode/findpat.js", + "js/jsqrcode/alignpat.js", + "js/jsqrcode/databr.js", + "js/md5.js", + "js/aes.js", + "js/sha.js", + "js/qrcode.js", + "build/models/encryption.js", + "build/models/interface.js", + "build/models/otp.js", + "build/models/storage.js", + "build/background.js" + ], + "persistent": false + }, + "browser_action": { + "default_icon": { + "19": "images/icon19.png", + "38": "images/icon38.png" + }, + "default_title": "__MSG_extShortName__", + "default_popup": "view/popup.html" + }, + "content_security_policy": "script-src 'self'; font-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; connect-src https://www.google.com/ https://*.dropboxapi.com; default-src 'none'", + "default_locale": "en", + "description": "__MSG_extDesc__", + "icons": { + "16": "images/icon16.png", + "48": "images/icon48.png", + "128": "images/icon128.png" + }, + "manifest_version": 2, + "name": "__MSG_extName__", + "offline_enabled": true, + "permissions": [ + "", + "storage" + ], + "optional_permissions": [ + "clipboardWrite" + ], + "short_name": "__MSG_extShortName__", + "version": "5.1.0", + "web_accessible_resources": [ + "view/qr.html", + "images/scan.gif" + ], + "-ms-preload": { + "backgroundScript": "edge-files/backgroundScriptsAPIBridge.js", + "contentScript": "edge-files/contentScriptsAPIBridge.js" + } +} \ No newline at end of file diff --git a/package.json b/package.json index 4baf4575e..12aeaa9e6 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,17 @@ "clean": "gts clean", "copyChrome": "cp -r src build css images js _locales LICENSE view chrome", "copyFirefox": "cp -r src build css images js _locales LICENSE view firefox", + "copyEdge": "cp -r src build css images js _locales LICENSE view edge-files edge/Extension && mv edge/Extension/edge-files/AppXManifest.xml edge && mv edge/Extension/edge-files/icon*.png edge/Assets", + "packageEdge": "cmd /C \"\"C:\\Program Files (x86)\\Windows Kits\\10\\App Certification Kit\\makeappx.exe\" pack /h SHA256 /d edge /p edge/Authenticator.appx\"", + "installEdge": "npm run edge && powershell -Command \"Add-AppxPackage -Path edge\\AppxManifest.xml -Register\"", "compile": "gts clean && tsc -p .", "fix": "gts fix", "prepare": "npm run compile", "pretest": "npm run compile", "posttest": "npm run check", "chrome": "node ensureDir.js chrome && npm run compile && npm run copyChrome && cp manifest-chrome.json chrome/manifest.json", - "firefox": "node ensureDir.js firefox && npm run compile && npm run copyFirefox && cp manifest-firefox.json firefox/manifest.json" + "firefox": "node ensureDir.js firefox && npm run compile && npm run copyFirefox && cp manifest-firefox.json firefox/manifest.json", + "edge": "node ensureDir.js edge && node ensureDir.js edge/Extension && node ensureDir.js edge/Assets && npm run compile && npm run copyEdge && cp manifest-edge.json edge/Extension/manifest.json" }, "repository": { "type": "git", @@ -33,5 +37,6 @@ "fs-extra": "^5.0.0", "gts": "^0.5.2", "typescript": "^2.6.1" - } + }, + "dependencies": {} } diff --git a/src/background.ts b/src/background.ts index 9e167bdb3..c1116a4d1 100644 --- a/src/background.ts +++ b/src/background.ts @@ -208,6 +208,9 @@ chrome.runtime.onInstalled.addListener((details) => { } else if (navigator.userAgent.indexOf('Firefox') !== -1) { url = 'https://github.com/Authenticator-Extension/Authenticator/wiki/Firefox-Issues'; + } else if (navigator.userAgent.indexOf('Edge') !== -1) { + url = + 'https://github.com/Authenticator-Extension/Authenticator/wiki/Edge-Issues'; } if (url) { diff --git a/src/popup.ts b/src/popup.ts index 50df55cf6..a3fadf618 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -116,11 +116,15 @@ async function init() { return; } -chrome.permissions.contains( - {origins: ['https://www.google.com/']}, (hasPermission) => { - if (hasPermission) { - syncTimeWithGoogle(); - } - }); +if (navigator.userAgent.indexOf('Edge') !== -1) { + syncTimeWithGoogle(); +} else { + chrome.permissions.contains( + {origins: ['https://www.google.com/']}, (hasPermission) => { + if (hasPermission) { + syncTimeWithGoogle(); + } + }); +} init(); diff --git a/src/ui/entry.ts b/src/ui/entry.ts index 7523d0f48..d015fb900 100644 --- a/src/ui/entry.ts +++ b/src/ui/entry.ts @@ -490,47 +490,87 @@ async function entry(_ui: UI) { return; } - chrome.permissions.request( - {permissions: ['clipboardWrite']}, async (granted) => { - if (granted) { - const codeClipboard = document.getElementById( - 'codeClipboard') as HTMLInputElement; - if (!codeClipboard) { - return; - } + if (navigator.userAgent.indexOf('Edge') !== -1) { + const codeClipboard = + document.getElementById('codeClipboard') as HTMLInputElement; + if (!codeClipboard) { + return; + } - if (_ui.instance.useAutofill) { - await insertContentScript(); + if (_ui.instance.useAutofill) { + await insertContentScript(); - chrome.tabs.query( - {active: true, lastFocusedWindow: true}, (tabs) => { - const tab = tabs[0]; - if (!tab || !tab.id) { - return; - } + chrome.tabs.query( + {active: true, lastFocusedWindow: true}, (tabs) => { + const tab = tabs[0]; + if (!tab || !tab.id) { + return; + } - chrome.tabs.sendMessage( - tab.id, {action: 'pastecode', code: entry.code}); - }); - } + chrome.tabs.sendMessage( + tab.id, {action: 'pastecode', code: entry.code}); + }); + } - codeClipboard.value = entry.code; - codeClipboard.focus(); - codeClipboard.select(); - document.execCommand('Copy'); - _ui.instance.notification = _ui.instance.i18n.copied; - clearTimeout(_ui.instance.notificationTimeout); - _ui.instance.class.notificationFadein = true; - _ui.instance.class.notificationFadeout = false; - _ui.instance.notificationTimeout = setTimeout(() => { - _ui.instance.class.notificationFadein = false; - _ui.instance.class.notificationFadeout = true; - setTimeout(() => { - _ui.instance.class.notificationFadeout = false; - }, 200); - }, 1000); - } - }); + codeClipboard.value = entry.code; + codeClipboard.focus(); + codeClipboard.select(); + document.execCommand('Copy'); + _ui.instance.notification = _ui.instance.i18n.copied; + clearTimeout(_ui.instance.notificationTimeout); + _ui.instance.class.notificationFadein = true; + _ui.instance.class.notificationFadeout = false; + _ui.instance.notificationTimeout = setTimeout(() => { + _ui.instance.class.notificationFadein = false; + _ui.instance.class.notificationFadeout = true; + setTimeout(() => { + _ui.instance.class.notificationFadeout = false; + }, 200); + }, 1000); + } else { + chrome.permissions.request( + {permissions: ['clipboardWrite']}, async (granted) => { + if (granted) { + const codeClipboard = + document.getElementById('codeClipboard') as + HTMLInputElement; + if (!codeClipboard) { + return; + } + + if (_ui.instance.useAutofill) { + await insertContentScript(); + + chrome.tabs.query( + {active: true, lastFocusedWindow: true}, (tabs) => { + const tab = tabs[0]; + if (!tab || !tab.id) { + return; + } + + chrome.tabs.sendMessage( + tab.id, {action: 'pastecode', code: entry.code}); + }); + } + + codeClipboard.value = entry.code; + codeClipboard.focus(); + codeClipboard.select(); + document.execCommand('Copy'); + _ui.instance.notification = _ui.instance.i18n.copied; + clearTimeout(_ui.instance.notificationTimeout); + _ui.instance.class.notificationFadein = true; + _ui.instance.class.notificationFadeout = false; + _ui.instance.notificationTimeout = setTimeout(() => { + _ui.instance.class.notificationFadein = false; + _ui.instance.class.notificationFadeout = true; + setTimeout(() => { + _ui.instance.class.notificationFadeout = false; + }, 200); + }, 1000); + } + }); + } return; }, } diff --git a/src/ui/menu.ts b/src/ui/menu.ts index f9bccefe1..2c0c4eec9 100644 --- a/src/ui/menu.ts +++ b/src/ui/menu.ts @@ -56,12 +56,12 @@ function openHelp() { let url = 'https://github.com/Authenticator-Extension/Authenticator/wiki/Chrome-Issues'; - if (navigator.userAgent.indexOf('Chrome') !== -1) { - url = - 'https://github.com/Authenticator-Extension/Authenticator/wiki/Chrome-Issues'; - } else if (navigator.userAgent.indexOf('Firefox') !== -1) { + if (navigator.userAgent.indexOf('Firefox') !== -1) { url = 'https://github.com/Authenticator-Extension/Authenticator/wiki/Firefox-Issues'; + } else if (navigator.userAgent.indexOf('Edge') !== -1) { + url = + 'https://github.com/Authenticator-Extension/Authenticator/wiki/Edge-Issues'; } window.open(url, '_blank'); @@ -116,20 +116,27 @@ async function menu(_ui: UI) { return; }, syncClock: async () => { - chrome.permissions.request( - {origins: ['https://www.google.com/']}, async (granted) => { - if (granted) { - const message = await syncTimeWithGoogle(); - _ui.instance.alert(_ui.instance.i18n[message]); - } - return; - }); + if (navigator.userAgent.indexOf('Edge') !== -1) { + const message = await syncTimeWithGoogle(); + _ui.instance.alert(_ui.instance.i18n[message]); + } else { + chrome.permissions.request( + {origins: ['https://www.google.com/']}, async (granted) => { + if (granted) { + const message = await syncTimeWithGoogle(); + _ui.instance.alert(_ui.instance.i18n[message]); + } + return; + }); + } return; }, popOut: () => { let windowType; if (navigator.userAgent.indexOf('Firefox') !== -1) { windowType = 'detached_panel'; + } else if (navigator.userAgent.indexOf('Edge') !== -1) { + windowType = 'popup'; } else { windowType = 'panel'; } diff --git a/view/popup.html b/view/popup.html index 2127b114e..23554336e 100644 --- a/view/popup.html +++ b/view/popup.html @@ -77,7 +77,7 @@
From 5b721702c5d4f9de941a12a2082d7add89fa9869 Mon Sep 17 00:00:00 2001 From: Brendan Date: Sun, 29 Jul 2018 11:12:07 -0500 Subject: [PATCH 3/7] Remove pointless permission --- manifest-edge.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/manifest-edge.json b/manifest-edge.json index 4dc410f23..a12b5c427 100644 --- a/manifest-edge.json +++ b/manifest-edge.json @@ -53,9 +53,6 @@ "", "storage" ], - "optional_permissions": [ - "clipboardWrite" - ], "short_name": "__MSG_extShortName__", "version": "5.1.0", "web_accessible_resources": [ From 37fed154f4bd2b7bd652ab1b4c4f600e986dcb7b Mon Sep 17 00:00:00 2001 From: Brendan Date: Sun, 29 Jul 2018 11:20:42 -0500 Subject: [PATCH 4/7] Add edge bug warning --- src/ui/menu.ts | 3 +++ view/popup.html | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ui/menu.ts b/src/ui/menu.ts index 64ddd0ec0..cce7a4785 100644 --- a/src/ui/menu.ts +++ b/src/ui/menu.ts @@ -115,6 +115,9 @@ async function menu(_ui: UI) { return false; } }, + showEdgeBugWarning: () => { + _ui.instance.alert("Due to a bug in Edge, downloading backups is not supported at this time. More info on feedback page."); + }, saveAutofill: () => { localStorage.autofill = _ui.instance.useAutofill; useAutofill = diff --git a/view/popup.html b/view/popup.html index e3c73db35..314ee1215 100644 --- a/view/popup.html +++ b/view/popup.html @@ -157,7 +157,8 @@
{{ i18n.export_info }}
- {{ i18n.download_backup }} + {{ i18n.download_backup }} + {{ i18n.download_backup }} {{ i18n.download_enc_backup }} {{ i18n.import_backup }} From 537eb8600eeb694ab9e1fb7a31c1cbca72435fcb Mon Sep 17 00:00:00 2001 From: Brendan Date: Sun, 29 Jul 2018 11:21:32 -0500 Subject: [PATCH 5/7] gts fix --- src/ui/menu.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/menu.ts b/src/ui/menu.ts index cce7a4785..c98200ef1 100644 --- a/src/ui/menu.ts +++ b/src/ui/menu.ts @@ -81,7 +81,7 @@ async function menu(_ui: UI) { return; }, createWindow: (url: string) => { - chrome.windows.create({type: "normal", url: url}); + chrome.windows.create({type: 'normal', url}); return; }, showMenu: () => { @@ -116,7 +116,8 @@ async function menu(_ui: UI) { } }, showEdgeBugWarning: () => { - _ui.instance.alert("Due to a bug in Edge, downloading backups is not supported at this time. More info on feedback page."); + _ui.instance.alert( + 'Due to a bug in Edge, downloading backups is not supported at this time. More info on feedback page.'); }, saveAutofill: () => { localStorage.autofill = _ui.instance.useAutofill; From 08a96e86f24e980cb4f5fd0071cdefc171ba1a97 Mon Sep 17 00:00:00 2001 From: Brendan Date: Sun, 29 Jul 2018 11:35:36 -0500 Subject: [PATCH 6/7] gts fix --- manifest-edge.json | 2 +- src/ui/menu.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/manifest-edge.json b/manifest-edge.json index a12b5c427..edf884e9b 100644 --- a/manifest-edge.json +++ b/manifest-edge.json @@ -63,4 +63,4 @@ "backgroundScript": "edge-files/backgroundScriptsAPIBridge.js", "contentScript": "edge-files/contentScriptsAPIBridge.js" } -} \ No newline at end of file +} diff --git a/src/ui/menu.ts b/src/ui/menu.ts index cce7a4785..c98200ef1 100644 --- a/src/ui/menu.ts +++ b/src/ui/menu.ts @@ -81,7 +81,7 @@ async function menu(_ui: UI) { return; }, createWindow: (url: string) => { - chrome.windows.create({type: "normal", url: url}); + chrome.windows.create({type: 'normal', url}); return; }, showMenu: () => { @@ -116,7 +116,8 @@ async function menu(_ui: UI) { } }, showEdgeBugWarning: () => { - _ui.instance.alert("Due to a bug in Edge, downloading backups is not supported at this time. More info on feedback page."); + _ui.instance.alert( + 'Due to a bug in Edge, downloading backups is not supported at this time. More info on feedback page.'); }, saveAutofill: () => { localStorage.autofill = _ui.instance.useAutofill; From 13055c1a4335903a1216ac8a17904273f5f72973 Mon Sep 17 00:00:00 2001 From: Brendan Date: Sun, 29 Jul 2018 12:02:09 -0500 Subject: [PATCH 7/7] Declare localization in AppXManifest --- edge-files/AppXManifest.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/edge-files/AppXManifest.xml b/edge-files/AppXManifest.xml index 5e5594711..acd5d1490 100644 --- a/edge-files/AppXManifest.xml +++ b/edge-files/AppXManifest.xml @@ -24,7 +24,21 @@ - + + + + + + + + + + + + + + +