migrate from mv2 to mv3
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
node_modules
|
||||
bower_components
|
||||
package-lock.json
|
||||
|
@ -111,7 +111,7 @@ To build the project:
|
||||
grunt
|
||||
# After building, a folder will be generated:
|
||||
cd .. # Return to project root.
|
||||
ls omega-chromium-extension/build/
|
||||
ls omega-target-chromium-extension/build/
|
||||
# The folder above can be loaded as an unpacked extension in Chromium now.
|
||||
|
||||
To enable `grunt watch`, run `grunt watch` once in the `omega-build` directory.
|
||||
|
2
omega-pac/uglifyjs.js
vendored
@ -1,5 +1,5 @@
|
||||
(function(exports, global) {
|
||||
global["UglifyJS"] = exports;
|
||||
globalThis["UglifyJS"] = exports;
|
||||
"use strict";
|
||||
function array_to_hash(a) {
|
||||
var ret = Object.create(null);
|
||||
|
1
omega-target-chromium-extension/.gitignore
vendored
@ -3,5 +3,6 @@
|
||||
|
||||
/tmp
|
||||
/build
|
||||
/build*
|
||||
/release.zip
|
||||
/web-ext-artifacts
|
||||
|
5
omega-target-chromium-extension/b.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
. ~/.nvm/nvm.sh
|
||||
nvm use 11.9.0
|
||||
minify-all-js ./build -j
|
||||
cd build && zip -r ../release.zip ./*
|
1
omega-target-chromium-extension/overlay/idb-keyval.js
Normal file
@ -0,0 +1 @@
|
||||
function _slicedToArray(t,n){return _arrayWithHoles(t)||_iterableToArrayLimit(t,n)||_unsupportedIterableToArray(t,n)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(t,n){if(t){if("string"==typeof t)return _arrayLikeToArray(t,n);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(t,n):void 0}}function _arrayLikeToArray(t,n){(null==n||n>t.length)&&(n=t.length);for(var r=0,e=new Array(n);r<n;r++)e[r]=t[r];return e}function _iterableToArrayLimit(t,n){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var e,o,u=[],i=!0,a=!1;try{for(r=r.call(t);!(i=(e=r.next()).done)&&(u.push(e.value),!n||u.length!==n);i=!0);}catch(t){a=!0,o=t}finally{try{i||null==r.return||r.return()}finally{if(a)throw o}}return u}}function _arrayWithHoles(t){if(Array.isArray(t))return t}function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}!function(t,n){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).idbKeyval={})}(this,(function(t){"use strict";function n(t){return new Promise((function(n,r){t.oncomplete=t.onsuccess=function(){return n(t.result)},t.onabort=t.onerror=function(){return r(t.error)}}))}function r(t,r){var e=indexedDB.open(t);e.onupgradeneeded=function(){return e.result.createObjectStore(r)};var o=n(e);return function(t,n){return o.then((function(e){return n(e.transaction(r,t).objectStore(r))}))}}var e;function o(){return e||(e=r("keyval-store","keyval")),e}function u(t,r){return t.openCursor().onsuccess=function(){this.result&&(r(this.result),this.result.continue())},n(t.transaction)}t.clear=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:o();return t("readwrite",(function(t){return t.clear(),n(t.transaction)}))},t.createStore=r,t.del=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:o();return r("readwrite",(function(r){return r.delete(t),n(r.transaction)}))},t.delMany=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:o();return r("readwrite",(function(r){return t.forEach((function(t){return r.delete(t)})),n(r.transaction)}))},t.entries=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:o();return t("readonly",(function(r){if(r.getAll&&r.getAllKeys)return Promise.all([n(r.getAllKeys()),n(r.getAll())]).then((function(t){var n=_slicedToArray(t,2),r=n[0],e=n[1];return r.map((function(t,n){return[t,e[n]]}))}));var e=[];return t("readonly",(function(t){return u(t,(function(t){return e.push([t.key,t.value])})).then((function(){return e}))}))}))},t.get=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:o();return r("readonly",(function(r){return n(r.get(t))}))},t.getMany=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:o();return r("readonly",(function(r){return Promise.all(t.map((function(t){return n(r.get(t))})))}))},t.keys=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:o();return t("readonly",(function(t){if(t.getAllKeys)return n(t.getAllKeys());var r=[];return u(t,(function(t){return r.push(t.key)})).then((function(){return r}))}))},t.promisifyRequest=n,t.set=function(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:o();return e("readwrite",(function(e){return e.put(r,t),n(e.transaction)}))},t.setMany=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:o();return r("readwrite",(function(r){return t.forEach((function(t){return r.put(t[1],t[0])})),n(r.transaction)}))},t.update=function(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:o();return e("readwrite",(function(e){return new Promise((function(o,u){e.get(t).onsuccess=function(){try{e.put(r(this.result),t),o(n(e.transaction))}catch(t){u(t)}}}))}))},t.values=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:o();return t("readonly",(function(t){if(t.getAll)return n(t.getAll());var r=[];return u(t,(function(t){return r.push(t.value)})).then((function(){return r}))}))},Object.defineProperty(t,"__esModule",{value:!0})}));
|
@ -0,0 +1,62 @@
|
||||
'use strict'
|
||||
let valuesMap = new Map()
|
||||
|
||||
class LocalStorage {
|
||||
getItem (key) {
|
||||
const stringKey = String(key)
|
||||
if (valuesMap.has(key)) {
|
||||
return String(valuesMap.get(stringKey))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
setItem (key, val) {
|
||||
valuesMap.set(String(key), String(val))
|
||||
}
|
||||
|
||||
removeItem (key) {
|
||||
valuesMap.delete(key)
|
||||
}
|
||||
|
||||
clear () {
|
||||
valuesMap.clear()
|
||||
}
|
||||
|
||||
key (i) {
|
||||
if (arguments.length === 0) {
|
||||
throw new TypeError("Failed to execute 'key' on 'Storage': 1 argument required, but only 0 present.") // this is a TypeError implemented on Chrome, Firefox throws Not enough arguments to Storage.key.
|
||||
}
|
||||
var arr = Array.from(valuesMap.keys())
|
||||
return arr[i]
|
||||
}
|
||||
|
||||
get length () {
|
||||
return valuesMap.size
|
||||
}
|
||||
initValuesMap (_valuesMap){
|
||||
valuesMap = new Map(Object.entries(_valuesMap || {}))
|
||||
}
|
||||
getValuesMap (){
|
||||
return Object.fromEntries(valuesMap);
|
||||
}
|
||||
}
|
||||
const instance = new LocalStorage()
|
||||
|
||||
globalThis.localStorage = new Proxy(instance, {
|
||||
set: function (obj, prop, value) {
|
||||
if (LocalStorage.prototype.hasOwnProperty(prop)) {
|
||||
instance[prop] = value
|
||||
} else {
|
||||
instance.setItem(prop, value)
|
||||
}
|
||||
return true
|
||||
},
|
||||
get: function (target, name) {
|
||||
if (LocalStorage.prototype.hasOwnProperty(name)) {
|
||||
return instance[name]
|
||||
}
|
||||
if (valuesMap.has(name)) {
|
||||
return instance.getItem(name)
|
||||
}
|
||||
}
|
||||
})
|
@ -1,9 +1,8 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "__MSG_manifest_app_name__",
|
||||
"version": "2.5.21",
|
||||
"manifest_version": 3,
|
||||
"name": "ZeroOmega--Proxy Switchy manifest v3 version",
|
||||
"version": "3.0.0",
|
||||
"description": "__MSG_manifest_app_description__",
|
||||
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkhwZJT76btQ04EEMOFtZPLESD1TmSVjbLjs0OyesD9Ht8YllFPfJ3qmtbSQGVuvmxH1GK/jUO2QcEWb8bHuOjoRlq20fi5j5Aq90O8FKET+y5D8PxCyi3WmnquiEwaE5cNmaCsw/G2JlO+bZOtdQ/QKOvMxBAegABYimEGfSvCMVUEvpymys0gBhLoch72zPAiJUBkf0z8BtjYTueMRcRXkrSeRPLygUDQnZ1TkQWMYYBp/zqpD5ggxytAklEMQzR9Hn0lqu5s7iuUAgihbysPn/8Wh00Zj5FySpK//KcpG3JS7UWxC28oSt8z5ZR3YimnX+HX3P36V0mC1pgM4o7wIDAQAB",
|
||||
"icons": {
|
||||
"16": "img/icons/omega-action-16.png",
|
||||
"24": "img/icons/omega-action-24.png",
|
||||
@ -13,8 +12,7 @@
|
||||
"128": "img/icons/omega-128.png"
|
||||
},
|
||||
"default_locale": "en",
|
||||
"browser_action": {
|
||||
"browser_style": false,
|
||||
"action": {
|
||||
"default_icon": {
|
||||
"16": "img/icons/omega-action-16.png",
|
||||
"19": "img/icons/omega-action-19.png",
|
||||
@ -25,40 +23,27 @@
|
||||
"default_popup": "popup/index.html"
|
||||
},
|
||||
"background": {
|
||||
"page": "background.html"
|
||||
"service_worker": "x-background.js",
|
||||
"type": "module"
|
||||
},
|
||||
"minimum_chrome_version": "22.0.0",
|
||||
"minimum_chrome_version": "111",
|
||||
"options_page": "options.html",
|
||||
"options_ui": {
|
||||
"page": "options.html",
|
||||
"browser_style": false,
|
||||
"open_in_tab": true
|
||||
},
|
||||
"commands": {
|
||||
"_execute_action": { "suggested_key": { "default": "Alt+Shift+O" } }
|
||||
},
|
||||
"permissions": [
|
||||
"proxy",
|
||||
"tabs",
|
||||
"alarms",
|
||||
"storage",
|
||||
"webRequest",
|
||||
"downloads",
|
||||
"webRequestBlocking",
|
||||
"contextMenus",
|
||||
|
||||
"http://*/*",
|
||||
"https://*/*",
|
||||
"<all_urls>"
|
||||
"webRequestAuthProvider",
|
||||
"contextMenus"
|
||||
],
|
||||
"commands": {
|
||||
"_execute_browser_action": {
|
||||
"suggested_key": {
|
||||
"default": "Alt+Shift+O"
|
||||
}
|
||||
}
|
||||
},
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "switchyomega@feliscatus.addons.mozilla.org",
|
||||
"strict_min_version": "55.0a1"
|
||||
}
|
||||
}
|
||||
"host_permissions": ["<all_urls>"]
|
||||
}
|
||||
|
11
omega-target-chromium-extension/overlay/x-background.js
Normal file
@ -0,0 +1,11 @@
|
||||
import "./js/background_preload.js"
|
||||
import "./idb-keyval.js"
|
||||
import "./localstorage-polyfill.js"
|
||||
import "./js/log_error.js"
|
||||
//import "./lib/FileSaver/FileSaver.min.js"
|
||||
import "./js/omega_debug.js"
|
||||
import "./js/omega_pac.min.js"
|
||||
import "./js/omega_target.min.js"
|
||||
import "./js/omega_target_chromium_extension.min.js"
|
||||
import "./img/icons/draw_omega.js"
|
||||
import "./js/background.js"
|
@ -45,7 +45,8 @@ drawIcon = (resultColor, profileColor) ->
|
||||
return icon if icon
|
||||
try
|
||||
if not drawContext?
|
||||
drawContext = document.getElementById('canvas-icon').getContext('2d')
|
||||
canvas = new OffscreenCanvas(300, 300)
|
||||
drawContext = canvas.getContext('2d', { willReadFrequently: true })
|
||||
|
||||
icon = {}
|
||||
for size in [16, 19, 24, 32, 38]
|
||||
@ -186,7 +187,7 @@ options = new OmegaTargetCurrent.Options(null, storage, state, Log, sync,
|
||||
options.externalApi = new OmegaTargetCurrent.ExternalApi(options)
|
||||
options.externalApi.listen()
|
||||
|
||||
if chrome.runtime.id != OmegaTargetCurrent.SwitchySharp.extId
|
||||
if chrome.runtime.id != OmegaTargetCurrent.SwitchySharp.extId and false
|
||||
options.switchySharp = new OmegaTargetCurrent.SwitchySharp()
|
||||
options.switchySharp.monitor()
|
||||
|
||||
@ -212,7 +213,7 @@ options._inspect = new OmegaTargetCurrent.Inspect (url, tab) ->
|
||||
|
||||
title = chrome.i18n.getMessage('browserAction_titleInspect', urlDisp) + '\n'
|
||||
title += action.title
|
||||
chrome.browserAction.setTitle(title: title, tabId: tab.id)
|
||||
chrome.action.setTitle(title: title, tabId: tab.id)
|
||||
tabs.setTabBadge(tab, {
|
||||
text: '#'
|
||||
color: action.resultColor
|
||||
@ -320,11 +321,14 @@ encodeError = (obj) ->
|
||||
refreshActivePageIfEnabled = ->
|
||||
return if localStorage['omega.local.refreshOnProfileChange'] == 'false'
|
||||
chrome.tabs.query {active: true, lastFocusedWindow: true}, (tabs) ->
|
||||
url = tabs[0].url
|
||||
url = tabs[0].url or tabs[0].url
|
||||
return if not url
|
||||
return if url.substr(0, 6) == 'chrome'
|
||||
return if url.substr(0, 6) == 'about:'
|
||||
return if url.substr(0, 4) == 'moz-'
|
||||
if tabs[0].pendingUrl
|
||||
chrome.tabs.update(tabs[0].id, {url: url})
|
||||
else
|
||||
chrome.tabs.reload(tabs[0].id, {bypassCache: true})
|
||||
|
||||
chrome.runtime.onMessage.addListener (request, sender, respond) ->
|
||||
@ -333,6 +337,9 @@ chrome.runtime.onMessage.addListener (request, sender, respond) ->
|
||||
if request.method == 'getState'
|
||||
target = state
|
||||
method = state.get
|
||||
else if request.method == 'setState'
|
||||
target = state
|
||||
method = state.set
|
||||
else
|
||||
target = options
|
||||
method = target[request.method]
|
||||
|
@ -1,32 +1,25 @@
|
||||
globalThis.window = globalThis
|
||||
globalThis.global = globalThis
|
||||
window.UglifyJS_NoUnsafeEval = true
|
||||
localStorage['log'] = ''
|
||||
localStorage['logLastError'] = ''
|
||||
|
||||
window.OmegaContextMenuQuickSwitchHandler = -> null
|
||||
|
||||
chrome.runtime.onInstalled.addListener( ->
|
||||
if chrome.contextMenus?
|
||||
# We don't need this API. However its presence indicates that Chrome >= 35
|
||||
# which provides info.checked we need in contextMenu callback.
|
||||
# https://developer.chrome.com/extensions/contextMenus
|
||||
if chrome.i18n.getUILanguage?
|
||||
# We must create the menu item here before others to make it first in menu.
|
||||
chrome.contextMenus.create({
|
||||
id: 'enableQuickSwitch'
|
||||
title: chrome.i18n.getMessage('contextMenu_enableQuickSwitch')
|
||||
type: 'checkbox'
|
||||
checked: false
|
||||
contexts: ["browser_action"]
|
||||
onclick: (info) -> window.OmegaContextMenuQuickSwitchHandler(info)
|
||||
})
|
||||
|
||||
chrome.contextMenus.create({
|
||||
title: chrome.i18n.getMessage('popup_reportIssues')
|
||||
contexts: ["browser_action"]
|
||||
onclick: OmegaDebug.reportIssue
|
||||
})
|
||||
|
||||
chrome.contextMenus.create({
|
||||
title: chrome.i18n.getMessage('popup_errorLog')
|
||||
contexts: ["browser_action"]
|
||||
onclick: OmegaDebug.downloadLog
|
||||
contexts: ["action"]
|
||||
})
|
||||
chrome.contextMenus.onClicked.addListener((info, tab) ->
|
||||
switch info.menuItemId
|
||||
when 'enableQuickSwitch'
|
||||
globalThis.OmegaContextMenuQuickSwitchHandler(info)
|
||||
)
|
||||
)
|
||||
|
@ -6,11 +6,6 @@ window.OmegaDebug =
|
||||
downloadLog: ->
|
||||
blob = new Blob [localStorage['log']], {type: "text/plain;charset=utf-8"}
|
||||
filename = "OmegaLog_#{Date.now()}.txt"
|
||||
|
||||
if browser?.downloads?.download?
|
||||
url = URL.createObjectURL(blob)
|
||||
browser.downloads.download({url: url, filename: filename})
|
||||
else
|
||||
saveAs(blob, filename)
|
||||
resetOptions: ->
|
||||
localStorage.clear()
|
||||
|
@ -50,19 +50,27 @@ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) ->
|
||||
omegaTarget =
|
||||
options: null
|
||||
state: (name, value) ->
|
||||
d = $q.defer()
|
||||
if arguments.length == 1
|
||||
getValue = (key) -> try JSON.parse(localStorage[prefix + key])
|
||||
if Array.isArray(name)
|
||||
return $q.when(name.map(getValue))
|
||||
callBackground('getState', name).then((values) ->
|
||||
d.resolve(name.map((key) -> values[key]))
|
||||
)
|
||||
else
|
||||
value = getValue(name)
|
||||
callBackground('getState', [name]).then( (values) ->
|
||||
d.resolve(values[name])
|
||||
)
|
||||
else
|
||||
localStorage[prefix + name] = JSON.stringify(value)
|
||||
return $q.when(value)
|
||||
newItem = {}
|
||||
newItem[name] = value
|
||||
callBackground('setState', newItem).then( ->
|
||||
d.resolve(value)
|
||||
)
|
||||
return d.promise
|
||||
lastUrl: (url) ->
|
||||
name = 'web.last_url'
|
||||
if url
|
||||
omegaTarget.state(name, url)
|
||||
localStorage[prefix + name] = url
|
||||
url
|
||||
else
|
||||
try JSON.parse(localStorage[prefix + name])
|
||||
@ -91,7 +99,7 @@ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) ->
|
||||
getMessage: chrome.i18n.getMessage.bind(chrome.i18n)
|
||||
openOptions: (hash) ->
|
||||
d = $q['defer']()
|
||||
options_url = chrome.extension.getURL('options.html')
|
||||
options_url = chrome.runtime.getURL('options.html')
|
||||
chrome.tabs.query url: options_url, (tabs) ->
|
||||
url = if hash
|
||||
urlParser.href = tabs[0]?.url || options_url
|
||||
@ -124,10 +132,10 @@ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) ->
|
||||
clearBadge = true
|
||||
d = $q['defer']()
|
||||
chrome.tabs.query {active: true, lastFocusedWindow: true}, (tabs) ->
|
||||
if not tabs[0]?.url
|
||||
if tabs.length == 0 or not (tabs[0].pendingUrl || tabs[0].url)
|
||||
d.resolve(null)
|
||||
return
|
||||
args = {tabId: tabs[0].id, url: tabs[0].url}
|
||||
args = {tabId: tabs[0].id, url: tabs[0].pendingUrl || tabs[0].url}
|
||||
if tabs[0].id and requestInfoCallback
|
||||
connectBackground('tabRequestInfo', args,
|
||||
requestInfoCallback)
|
||||
@ -136,7 +144,11 @@ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) ->
|
||||
refreshActivePage: ->
|
||||
d = $q['defer']()
|
||||
chrome.tabs.query {active: true, lastFocusedWindow: true}, (tabs) ->
|
||||
if tabs[0].url and not isChromeUrl(tabs[0].url)
|
||||
url = tabs[0].pendingUrl || tabs[0].url
|
||||
if url and not isChromeUrl(url)
|
||||
if tabs[0].pendingUrl
|
||||
chrome.tabs.update(tabs[0].id, {url})
|
||||
else
|
||||
chrome.tabs.reload(tabs[0].id, {bypassCache: true})
|
||||
d.resolve()
|
||||
return d.promise
|
||||
|
@ -24,25 +24,15 @@ var requestInfoCallback = null;
|
||||
|
||||
OmegaTargetPopup = {
|
||||
getState: function (keys, cb) {
|
||||
if (typeof localStorage === 'undefined' || !localStorage.length) {
|
||||
callBackground('getState', [keys], cb);
|
||||
return;
|
||||
}
|
||||
var results = {};
|
||||
keys.forEach(function(key) {
|
||||
try {
|
||||
results[key] = JSON.parse(localStorage['omega.local.' + key]);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (cb) cb(null, results);
|
||||
},
|
||||
applyProfile: function (name, cb) {
|
||||
callBackgroundNoReply('applyProfile', [name], cb);
|
||||
},
|
||||
openOptions: function (hash, cb) {
|
||||
var options_url = chrome.extension.getURL('options.html');
|
||||
var options_url = chrome.runtime.getURL('options.html');
|
||||
console.log('open options.....')
|
||||
|
||||
chrome.tabs.query({
|
||||
url: options_url
|
||||
@ -66,8 +56,8 @@ OmegaTargetPopup = {
|
||||
},
|
||||
getActivePageInfo: function(cb) {
|
||||
chrome.tabs.query({active: true, lastFocusedWindow: true}, function (tabs) {
|
||||
if (tabs.length === 0 || !tabs[0].url) return cb();
|
||||
var args = {tabId: tabs[0].id, url: tabs[0].url};
|
||||
if (tabs.length === 0 || !(tabs[0].pendingUrl || tabs[0].url)) return cb();
|
||||
var args = {tabId: tabs[0].id, url: tabs[0].pendingUrl || tabs[0].url};
|
||||
callBackground('getPageInfo', [args], cb)
|
||||
});
|
||||
},
|
||||
|
@ -22,7 +22,7 @@ module.exports = class ExternalApi
|
||||
return unless @disabled
|
||||
|
||||
@options.setProxyNotControllable(null)
|
||||
chrome.browserAction.setPopup?({popup: 'popup/index.html'})
|
||||
chrome.action.setPopup?({popup: 'popup/index.html'})
|
||||
@options.reloadQuickSwitch()
|
||||
@disabled = false
|
||||
@options.clearBadge()
|
||||
@ -49,7 +49,7 @@ module.exports = class ExternalApi
|
||||
if @knownExts[port.sender.id] >= 32
|
||||
reason = 'upgrade'
|
||||
@options.setProxyNotControllable reason, {text: 'X', color: '#5ab432'}
|
||||
chrome.browserAction.setPopup?({popup: 'popup/index.html'})
|
||||
chrome.action.setPopup?({popup: 'popup/index.html'})
|
||||
port.postMessage({action: 'state', state: 'disabled'})
|
||||
when 'enable'
|
||||
@reenable()
|
||||
|
@ -1,10 +1,14 @@
|
||||
Promise = OmegaTarget.Promise
|
||||
xhr = Promise.promisify(require('xhr'))
|
||||
#xhr = Promise.promisify(require('xhr'))
|
||||
Url = require('url')
|
||||
ContentTypeRejectedError = OmegaTarget.ContentTypeRejectedError
|
||||
|
||||
xhrWrapper = (args...) ->
|
||||
xhr(args...).catch (err) ->
|
||||
fetch(args...).then((response) ->
|
||||
response.text().then((body) ->
|
||||
return [response, body]
|
||||
)
|
||||
).catch (err) ->
|
||||
throw err unless err.isOperational
|
||||
if not err.statusCode
|
||||
throw new OmegaTarget.NetworkError(err)
|
||||
|
@ -15,6 +15,7 @@ module.exports = class Inspect
|
||||
return unless chrome.i18n.getUILanguage?
|
||||
|
||||
return if @_enabled
|
||||
return
|
||||
|
||||
webResource = [
|
||||
"http://*/*"
|
||||
|
@ -51,11 +51,11 @@ class ChromeOptions extends OmegaTarget.Options
|
||||
else
|
||||
text: '?'
|
||||
color: '#49afcd'
|
||||
chrome.browserAction.setBadgeText(text: options.text)
|
||||
chrome.browserAction.setBadgeBackgroundColor(color: options.color)
|
||||
chrome.action.setBadgeText(text: options.text)
|
||||
chrome.action.setBadgeBackgroundColor(color: options.color)
|
||||
if options.title
|
||||
@_badgeTitle = options.title
|
||||
chrome.browserAction.setTitle(title: options.title)
|
||||
chrome.action.setTitle(title: options.title)
|
||||
else
|
||||
@_badgeTitle = null
|
||||
clearBadge: ->
|
||||
@ -65,7 +65,7 @@ class ChromeOptions extends OmegaTarget.Options
|
||||
if @_proxyNotControllable
|
||||
@setBadge()
|
||||
else
|
||||
chrome.browserAction.setBadgeText?(text: '')
|
||||
chrome.action.setBadgeText?(text: '')
|
||||
return
|
||||
|
||||
_quickSwitchInit: false
|
||||
@ -82,14 +82,14 @@ class ChromeOptions extends OmegaTarget.Options
|
||||
if info.checked and not @_quickSwitchCanEnable
|
||||
setOptions.then ->
|
||||
chrome.tabs.create(
|
||||
url: chrome.extension.getURL('options.html#/ui')
|
||||
url: chrome.runtime.getURL('options.html#/ui')
|
||||
)
|
||||
|
||||
if quickSwitch or not chrome.browserAction.setPopup?
|
||||
chrome.browserAction.setPopup?({popup: ''})
|
||||
if quickSwitch or not chrome.action.setPopup?
|
||||
chrome.action.setPopup?({popup: ''})
|
||||
if not @_quickSwitchInit
|
||||
@_quickSwitchInit = true
|
||||
chrome.browserAction.onClicked.addListener (tab) =>
|
||||
chrome.action.onClicked.addListener (tab) =>
|
||||
@clearBadge()
|
||||
if not @_options['-enableQuickSwitch']
|
||||
# If we reach here, then the browser does not support popup.
|
||||
@ -101,14 +101,17 @@ class ChromeOptions extends OmegaTarget.Options
|
||||
index = (index + 1) % profiles.length
|
||||
@applyProfile(profiles[index]).then =>
|
||||
if @_options['-refreshOnProfileChange']
|
||||
url = tab.url
|
||||
url = tab.pendingUrl or tab.url
|
||||
return if not url
|
||||
return if url.substr(0, 6) == 'chrome'
|
||||
return if url.substr(0, 6) == 'about:'
|
||||
return if url.substr(0, 4) == 'moz-'
|
||||
if tab.pendingUrl
|
||||
chrome.tabs.update(tab.id, {url: url})
|
||||
else
|
||||
chrome.tabs.reload(tab.id)
|
||||
else
|
||||
chrome.browserAction.setPopup({popup: 'popup/index.html'})
|
||||
chrome.action.setPopup({popup: 'popup/index.html'})
|
||||
|
||||
chrome.contextMenus?.update('enableQuickSwitch', {checked: !!quickSwitch})
|
||||
Promise.resolve()
|
||||
@ -135,14 +138,22 @@ class ChromeOptions extends OmegaTarget.Options
|
||||
if info.errorCount > 0
|
||||
info.badgeSet = true
|
||||
badge = {text: info.errorCount.toString(), color: '#f0ad4e'}
|
||||
chrome.browserAction.setBadgeText(text: badge.text, tabId: tabId)
|
||||
chrome.browserAction.setBadgeBackgroundColor(
|
||||
chrome.action.setBadgeText(text: badge.text, tabId: tabId)
|
||||
.catch((e) ->
|
||||
console.log('error:',e)
|
||||
)
|
||||
chrome.action.setBadgeBackgroundColor(
|
||||
color: badge.color
|
||||
tabId: tabId
|
||||
).catch((e) ->
|
||||
console.log('error:',e)
|
||||
)
|
||||
else if info.badgeSet
|
||||
info.badgeSet = false
|
||||
chrome.browserAction.setBadgeText(text: '', tabId: tabId)
|
||||
chrome.action.setBadgeText(text: '', tabId: tabId)
|
||||
.catch((e) ->
|
||||
console.log('error:',e)
|
||||
)
|
||||
@_tabRequestInfoPorts[tabId]?.postMessage({
|
||||
errorCount: info.errorCount
|
||||
summary: info.summary
|
||||
@ -210,10 +221,7 @@ class ChromeOptions extends OmegaTarget.Options
|
||||
upgrade: (options, changes) ->
|
||||
super(options).catch (err) =>
|
||||
return Promise.reject err if options?['schemaVersion']
|
||||
getOldOptions = if @switchySharp
|
||||
@switchySharp.getOptions().timeout(1000)
|
||||
else
|
||||
Promise.reject()
|
||||
getOldOptions = Promise.reject()
|
||||
|
||||
getOldOptions = getOldOptions.catch ->
|
||||
if options?['config']
|
||||
@ -239,16 +247,17 @@ class ChromeOptions extends OmegaTarget.Options
|
||||
return this && super(upgraded, upgraded)
|
||||
|
||||
onFirstRun: (reason) ->
|
||||
chrome.tabs.create url: chrome.extension.getURL('options.html')
|
||||
console.log('first run ....')
|
||||
chrome.tabs.create url: chrome.runtime.getURL('options.html')
|
||||
|
||||
getPageInfo: ({tabId, url}) ->
|
||||
errorCount = @_requestMonitor?.tabInfo[tabId]?.errorCount
|
||||
result = if errorCount then {errorCount: errorCount} else null
|
||||
getBadge = new Promise (resolve, reject) ->
|
||||
if not chrome.browserAction.getBadgeText?
|
||||
if not chrome.action.getBadgeText?
|
||||
resolve('')
|
||||
return
|
||||
chrome.browserAction.getBadgeText {tabId: tabId}, (result) ->
|
||||
chrome.action.getBadgeText {tabId: tabId}, (result) ->
|
||||
resolve(result)
|
||||
|
||||
getInspectUrl = @_state.get({inspectUrl: ''})
|
||||
|
@ -25,10 +25,10 @@ class ChromeTabs
|
||||
tabs.forEach (tab) =>
|
||||
@_dirtyTabs[tab.id] = tab.id
|
||||
@onUpdated tab.id, {}, tab if tab.active
|
||||
if chrome.browserAction.setPopup?
|
||||
chrome.browserAction.setTitle({title: action.title})
|
||||
if chrome.action.setPopup?
|
||||
chrome.action.setTitle({title: action.title})
|
||||
else
|
||||
chrome.browserAction.setTitle({title: action.shortTitle})
|
||||
chrome.action.setTitle({title: action.shortTitle})
|
||||
@setIcon(action.icon)
|
||||
|
||||
onUpdated: (tabId, changeInfo, tab) ->
|
||||
@ -42,32 +42,35 @@ class ChromeTabs
|
||||
processTab: (tab, changeInfo) ->
|
||||
if @_badgeTab
|
||||
for own id of @_badgeTab
|
||||
try chrome.browserAction.setBadgeText?(text: '', tabId: id)
|
||||
try chrome.action.setBadgeText?(text: '', tabId: id)
|
||||
@_badgeTab = null
|
||||
|
||||
if not tab.url? or tab.url.indexOf("chrome") == 0
|
||||
if @_defaultAction
|
||||
chrome.browserAction.setTitle({
|
||||
chrome.action.setTitle({
|
||||
title: @_defaultAction.title
|
||||
tabId: tab.id
|
||||
})
|
||||
@clearIcon tab.id
|
||||
return
|
||||
@actionForUrl(tab.url).then (action) =>
|
||||
@actionForUrl(tab.url).then((action) =>
|
||||
if not action
|
||||
@clearIcon tab.id
|
||||
return
|
||||
@setIcon(action.icon, tab.id)
|
||||
if chrome.browserAction.setPopup?
|
||||
chrome.browserAction.setTitle({title: action.title, tabId: tab.id})
|
||||
if chrome.action.setPopup?
|
||||
chrome.action.setTitle({title: action.title, tabId: tab.id})
|
||||
else
|
||||
chrome.browserAction.setTitle({title: action.shortTitle, tabId: tab.id})
|
||||
chrome.action.setTitle({title: action.shortTitle, tabId: tab.id})
|
||||
).catch((e) ->
|
||||
console.log('error:', e)
|
||||
)
|
||||
|
||||
setTabBadge: (tab, badge) ->
|
||||
@_badgeTab ?= {}
|
||||
@_badgeTab[tab.id] = true
|
||||
chrome.browserAction.setBadgeText?(text: badge.text, tabId: tab.id)
|
||||
chrome.browserAction.setBadgeBackgroundColor?(
|
||||
chrome.action.setBadgeText?(text: badge.text, tabId: tab.id)
|
||||
chrome.action.setBadgeBackgroundColor?(
|
||||
color: badge.color
|
||||
tabId: tab.id
|
||||
)
|
||||
@ -87,11 +90,11 @@ class ChromeTabs
|
||||
|
||||
_chromeSetIcon: (params) ->
|
||||
try
|
||||
chrome.browserAction.setIcon?(params, @ignoreError)
|
||||
chrome.action.setIcon?(params, @ignoreError)
|
||||
catch _
|
||||
# Some legacy Chrome versions will panic if there are other icon sizes.
|
||||
params.imageData = {19: params.imageData[19], 38: params.imageData[38]}
|
||||
chrome.browserAction.setIcon?(params, @ignoreError)
|
||||
chrome.action.setIcon?(params, @ignoreError)
|
||||
|
||||
clearIcon: (tabId) ->
|
||||
return unless @_defaultAction?.icon?
|
||||
|
@ -128,8 +128,8 @@ module.exports = class WebRequestMonitor
|
||||
chrome.tabs.onCreated.addListener (tab) =>
|
||||
return unless tab.id
|
||||
@tabInfo[tab.id] = @_newTabInfo()
|
||||
chrome.tabs.onRemoved.addListener (tab) =>
|
||||
delete @tabInfo[tab.id]
|
||||
chrome.tabs.onRemoved.addListener (tabId) =>
|
||||
delete @tabInfo[tabId]
|
||||
chrome.tabs.onReplaced?.addListener (added, removed) =>
|
||||
@tabInfo[added] ?= @_newTabInfo()
|
||||
delete @tabInfo[removed]
|
||||
|
@ -1,11 +1,17 @@
|
||||
Storage = require('./storage')
|
||||
Promise = require('bluebird')
|
||||
|
||||
_globalLocalStorageCache = null
|
||||
|
||||
class BrowserStorage extends Storage
|
||||
constructor: (@storage, @prefix = '') ->
|
||||
@proto = Object.getPrototypeOf(@storage)
|
||||
|
||||
get: (keys) ->
|
||||
promiseResult = idbKeyval.get('localStorage').then((initValuesMap) =>
|
||||
if !_globalLocalStorageCache
|
||||
@proto.initValuesMap(initValuesMap)
|
||||
_globalLocalStorageCache = true
|
||||
map = {}
|
||||
if typeof keys == 'string'
|
||||
map[keys] = undefined
|
||||
@ -20,15 +26,32 @@ class BrowserStorage extends Storage
|
||||
map[key] = value if value?
|
||||
if typeof map[key] == 'undefined'
|
||||
delete map[key]
|
||||
Promise.resolve map
|
||||
return map
|
||||
)
|
||||
Promise.resolve promiseResult
|
||||
|
||||
set: (items) ->
|
||||
promiseResult = idbKeyval.get('localStorage').then((initValuesMap) =>
|
||||
if !_globalLocalStorageCache
|
||||
@proto.initValuesMap(initValuesMap)
|
||||
_globalLocalStorageCache = true
|
||||
for own key, value of items
|
||||
value = JSON.stringify(value)
|
||||
@proto.setItem.call(@storage, @prefix + key, value)
|
||||
Promise.resolve items
|
||||
return items
|
||||
).then((items) =>
|
||||
initValuesMap = @proto.getValuesMap()
|
||||
idbKeyval.set('localStorage', initValuesMap).then( ->
|
||||
return items
|
||||
)
|
||||
)
|
||||
Promise.resolve promiseResult
|
||||
|
||||
remove: (keys) ->
|
||||
promiseResult = idbKeyval.get('localStorage').then((initValuesMap) =>
|
||||
if !_globalLocalStorageCache
|
||||
@proto.initValuesMap(initValuesMap)
|
||||
_globalLocalStorageCache = true
|
||||
if not keys?
|
||||
if not @prefix
|
||||
@proto.clear.call(@storage)
|
||||
@ -46,6 +69,12 @@ class BrowserStorage extends Storage
|
||||
for key in keys
|
||||
@proto.removeItem.call(@storage, @prefix + key)
|
||||
|
||||
Promise.resolve()
|
||||
).then( =>
|
||||
initValuesMap = @proto.getValuesMap()
|
||||
idbKeyval.set('localStorage', initValuesMap).then( ->
|
||||
return
|
||||
)
|
||||
)
|
||||
Promise.resolve promiseResult
|
||||
|
||||
module.exports = BrowserStorage
|
||||
|
@ -34,7 +34,7 @@
|
||||
"ngprogress": "~1.0.4",
|
||||
"angular-ui-sortable": "~0.13.3",
|
||||
"jsondiffpatch": "~0.1.7",
|
||||
"angular-spectrum-colorpicker": "~1.3.5",
|
||||
"angular-spectrum-colorpicker": "git://github.com/suziwen/angular-spectrum-colorpicker.git#main",
|
||||
"blob": "*",
|
||||
"FileSaver": "=1.3.3",
|
||||
"angular-ui-utils": "bower-validate",
|
||||
|
@ -1,4 +1,4 @@
|
||||
var drawOmega = function (ctx, outerCircleColor, innerCircleColor) {
|
||||
globalThis.drawOmega = function (ctx, outerCircleColor, innerCircleColor) {
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.fillStyle = outerCircleColor;
|
||||
ctx.beginPath();
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.3 KiB |
@ -1,12 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="128"
|
||||
height="128"
|
||||
version="1.1">
|
||||
<path
|
||||
d="M 64 64 m -56 0 a 56 56 0 1 0 112 0 a 56 56 0 1 0 -112 0 M 64 64 m -28 0 a 28 28 0 1 0 56 0 a 28 28 0 1 0 -56 0"
|
||||
fill-rule="evenodd"
|
||||
fill="#31afec"
|
||||
stroke="none" />
|
||||
</svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1708946463856" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10155" width="128" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M704 896h256L1024 768v256H640V809.7792c131.106133-56.490667 224-197.154133 224-361.7792 0-214.4256-157.5936-382.2592-352-382.2592S160 233.5744 160 448c0 164.625067 92.893867 305.3056 224 361.7792V1024H0V768l64 128h256v-32.597333C132.369067 796.945067 0 636.0064 0 448 0 200.567467 229.2224 0 512 0s512 200.567467 512 448c0 188.0064-132.369067 348.945067-320 415.402667v32.597333z" p-id="10156" fill="#31afec"></path></svg>
|
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 756 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 870 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 692 B After Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 737 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 613 B |
@ -1,12 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="32"
|
||||
height="32"
|
||||
version="1.1">
|
||||
<path
|
||||
d="M 16 16 m -16 0 a 16 16 0 1 0 32 0 a 16 16 0 1 0 -32 0 M 16 16 m -8 0 a 8 8 0 1 0 16 0 a 8 8 0 1 0 -16 0"
|
||||
fill-rule="evenodd"
|
||||
fill="#31afec"
|
||||
stroke="none" />
|
||||
</svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1708946463856" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10155" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M704 896h256L1024 768v256H640V809.7792c131.106133-56.490667 224-197.154133 224-361.7792 0-214.4256-157.5936-382.2592-352-382.2592S160 233.5744 160 448c0 164.625067 92.893867 305.3056 224 361.7792V1024H0V768l64 128h256v-32.597333C132.369067 796.945067 0 636.0064 0 448 0 200.567467 229.2224 0 512 0s512 200.567467 512 448c0 188.0064-132.369067 348.945067-320 415.402667v32.597333z" p-id="10156" fill="#31afec"></path></svg>
|
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 754 B |
@ -96,14 +96,6 @@ angular.module('omega').factory 'omegaDebug', ($window, $rootScope,
|
||||
omegaDebug
|
||||
|
||||
angular.module('omega').factory 'downloadFile', ->
|
||||
if browser?.downloads?.download?
|
||||
return (blob, filename) ->
|
||||
url = URL.createObjectURL(blob)
|
||||
if filename
|
||||
browser.downloads.download({url: url, filename: filename})
|
||||
else
|
||||
browser.downloads.download({url: url})
|
||||
else
|
||||
return (blob, filename) ->
|
||||
noAutoBom = true
|
||||
saveAs(blob, filename, noAutoBom)
|
||||
|
@ -13,7 +13,7 @@ html(lang='en' ng-controller='MasterCtrl' ng-csp)
|
||||
.container-fluid
|
||||
header.col-lg-2.col-sm-3.side-nav
|
||||
h1
|
||||
a(ui-sref='about' title='{{"about_title" | tr}}') {{'appNameShort' | tr}}
|
||||
a(ui-sref='about' title='{{"about_title" | tr}}') Zero Omega
|
||||
sup.om-experimental.text-danger(ng-show='isExperimental')
|
||||
| {{'options_experimental_badge' | tr}}
|
||||
nav.nav.nav-pills.nav-stacked
|
||||
|
@ -1,7 +1,4 @@
|
||||
(function() {
|
||||
$script.ready('om-state', updateMenuByState);
|
||||
$script.ready('om-page-info', updateMenuByPageInfo);
|
||||
$script.ready(['om-state', 'om-page-info'], updateMenuByStateAndPageInfo);
|
||||
|
||||
var profileTemplate = document.getElementById('js-profile-tpl')
|
||||
.cloneNode(true);
|
||||
@ -25,6 +22,10 @@
|
||||
'RuleListProfile': 3000,
|
||||
};
|
||||
|
||||
$script.ready('om-state', updateMenuByState);
|
||||
$script.ready('om-page-info', updateMenuByPageInfo);
|
||||
$script.ready(['om-state', 'om-page-info'], updateMenuByStateAndPageInfo);
|
||||
|
||||
return;
|
||||
|
||||
function updateMenuByState() {
|
||||
|