1. Add subdomains auto support for conditions. #50

2. Supports customizing the colors of built-in profiles. #56
3. Add reload extension context menu on action button icon. #54 #62
This commit is contained in:
proxy.zeroomega 2024-11-25 16:38:48 +08:00
parent 8bf613ae35
commit af343d6af0
19 changed files with 242 additions and 27 deletions

View File

@ -455,6 +455,10 @@ msgstr "Enable Syncing"
msgid "options_useBuiltInSyncEnhance"
msgstr "Enhance your Gist sync experience with built-in browser sync"
msgid "options_useBuiltInSyncEnhanceTip"
msgstr "<li>After the user logs in to the browser account, the extension will be automatically downloaded and all synchronized settings will be restored</li>"
"<li>When the configuration items are changed, they will be synchronized to other browsers immediately. (When this feature is not turned on, the application will only check whether the configuration has changed every 5 minutes)</li>"
msgid "options_syncEnableForce"
msgstr "Download from Syncing"
@ -492,6 +496,12 @@ msgstr ""
"Options syncing is not supported on your platform or browser. For now, only "
"Chrome browser on desktop is supported."
msgid "options_builtin"
msgstr "Builtin"
msgid "options_builtinProfile"
msgstr "Builtin Profiles"
msgid "options_profileTabPrefix"
msgstr "Profile :: "

View File

@ -416,6 +416,10 @@ msgstr "启用同步"
msgid "options_useBuiltInSyncEnhance"
msgstr "使用浏览器内置同步功能增强 Gist 同步使用体验"
msgid "options_useBuiltInSyncEnhanceTip"
msgstr "<li>用户登录浏览器账号后就自动下载扩展,并恢复所有已同步的设置</li>"
"<li>配置项有变化时,会立即同步到其他浏览器下.(没有打开该功能时,应用只会每隔 5 分钟检查配置是否变化)</li>"
msgid "options_syncEnableForce"
msgstr "下载云端版本"
@ -443,6 +447,12 @@ msgstr "您可以将云端的选项下载到此设备使用。<br>一旦选择
msgid "options_syncUnsupportedHelp"
msgstr "选项同步暂不支持您的平台或浏览器。目前只支持桌面版Chrome的浏览器的同步请谅解。"
msgid "options_builtin"
msgstr "系统"
msgid "options_builtinProfile"
msgstr "内置情境模式"
msgid "options_profileTabPrefix"
msgstr "情景模式: "

View File

@ -402,6 +402,15 @@ msgstr "選項同步 (測試中)"
msgid "options_syncEnable"
msgstr "啟用同步"
msgid "options_useBuiltInSyncEnhance"
msgstr "使用瀏覽器內建同步功能增強 Gist 同步使用體驗"
msgid "options_useBuiltInSyncEnhanceTip"
msgstr "<li>用戶登入瀏覽器帳號後就自動下載擴展,並恢復所有已同步的設定</li>"
"<li>配置項目有變化時,會立即同步到其他瀏覽器下. (沒有開啟功能時,應用程式只會每隔 5 分鐘檢查配置是否變化)</li>"
msgid "options_syncEnableForce"
msgstr "下載雲端版本"
@ -429,6 +438,12 @@ msgstr "您可以將雲端的選項下載到此裝置使用。<br>一旦選擇
msgid "options_syncUnsupportedHelp"
msgstr "選項同步暫不支援您的平臺或瀏覽器。目前只支援桌面版Chrome的瀏覽器的同步請諒解。"
msgid "options_builtin"
msgstr "内建"
msgid "options_builtinProfile"
msgstr "內建情境模式"
msgid "options_profileTabPrefix"
msgstr "情境模式: "

View File

@ -11,6 +11,14 @@ class AST_Raw extends U2.AST_SymbolRef
U2.AST_SymbolRef.call(this, name: raw)
@aborts = -> false
decorateCustomBuiltinProfiles = (profile, options = {}) ->
key = exports.nameAsKey(profile)
if exports.builtinProfiles[key]
customBuiltinProfiles = Object.assign(
{}, exports.builtinProfiles, options['-builtinProfiles']
)
profile.color = customBuiltinProfiles[key].color
module.exports = exports =
builtinProfiles:
'+direct':
@ -76,14 +84,18 @@ module.exports = exports =
profileName = profileName.name
'+' + profileName
byName: (profileName, options) ->
profile = profileName
if typeof profileName == 'string'
key = exports.nameAsKey(profileName)
profileName = exports.builtinProfiles[key] ? options[key]
profileName
profile = exports.builtinProfiles[key] ? options[key]
decorateCustomBuiltinProfiles(profile, options)
profile
byKey: (key, options) ->
profile = key
if typeof key == 'string'
key = exports.builtinProfiles[key] ? options[key]
key
profile = exports.builtinProfiles[key] ? options[key]
decorateCustomBuiltinProfiles(profile, options)
profile
each: (options, callback) ->
charCodePlus = '+'.charCodeAt(0)
@ -91,6 +103,7 @@ module.exports = exports =
callback(key, profile)
for key, profile of exports.builtinProfiles
if key.charCodeAt(0) == charCodePlus
decorateCustomBuiltinProfiles(profile, options)
callback(key, profile)
profileResult: (profileName) ->

View File

@ -51,6 +51,9 @@ exports.getBaseDomain = (domain) ->
return domain if exports.isIp(domain)
return tld.getDomain(domain) ? domain
exports.getSubdomain = (url) ->
return tld.getSubdomain(url)
exports.wildcardForDomain = (domain) ->
return domain if exports.isIp(domain)
return '*.' + exports.getBaseDomain(domain)
@ -58,4 +61,5 @@ exports.wildcardForDomain = (domain) ->
Url = require('url')
exports.wildcardForUrl = (url) ->
domain = Url.parse(url).hostname
return exports.wildcardForDomain(domain)
return domain if exports.isIp(domain)
return '*.' + domain

View File

@ -21,11 +21,18 @@ initContextMenu = ->
title: chrome.i18n.getMessage('popup_reportIssues')
contexts: ["action"]
})
chrome.contextMenus.create({
id: 'reload'
title: 'Reload'
contexts: ["action"]
})
initContextMenu()
chrome.contextMenus?.onClicked.addListener((info, tab) ->
switch info.menuItemId
when 'reload'
chrome.runtime.reload()
when 'reportIssue'
OmegaDebug.reportIssue()
)

View File

@ -9,9 +9,6 @@ Url = require('url')
TEMPPROFILEKEY = 'tempProfileState'
chrome.runtime.onStartup.addListener ->
idbKeyval.del(TEMPPROFILEKEY)
class ChromeOptions extends OmegaTarget.Options
_inspect: null
@ -69,7 +66,10 @@ class ChromeOptions extends OmegaTarget.Options
init: (startupCheck) ->
super(startupCheck)
@ready.then =>
idbKeyval.get(TEMPPROFILEKEY).then (tempProfileState) =>
chrome.storage.session
.get(TEMPPROFILEKEY).then((tempProfileState = {}) =>
tempProfileState = if globalThis.hasStartupCheck
then tempProfileState[TEMPPROFILEKEY] else null
# tempProfileState =
# { _tempProfile,
# _tempProfileActive}
@ -89,15 +89,19 @@ class ChromeOptions extends OmegaTarget.Options
# tempProfileState._tempProfileRulesByProfile
@_tempProfileActive = tempProfileState._tempProfileActive
OmegaPac.Profiles.updateRevision(@_tempProfile)
console.log('apply temp state profile', @_currentProfileName)
@applyProfile(@_currentProfileName)
)
@ready
addTempRule: (domain, profileName) ->
super(domain, profileName).then =>
idbKeyval.set(TEMPPROFILEKEY, {
_zeroState = {}
_zeroState[TEMPPROFILEKEY] = {
_tempProfile: @_tempProfile
_tempProfileActive: @_tempProfileActive
})
}
chrome.storage.session.set(_zeroState)
updateProfile: (args...) ->
super(args...).then (results) ->
error = false
@ -296,10 +300,12 @@ class ChromeOptions extends OmegaTarget.Options
return result if url.substr(0, 6) == 'about:'
return result if url.substr(0, 4) == 'moz-'
domain = OmegaPac.getBaseDomain(Url.parse(url).hostname)
subdomain = OmegaPac.getSubdomain(url)
return {
url: url
domain: domain
subdomain: subdomain
tempRuleProfileName: @queryTempRule(domain)
errorCount: errorCount
}

View File

@ -176,7 +176,11 @@ module.exports = class WebRequestMonitor
if @eventCategory[oldStatus] != 'error'
summaryItem = info.summary[id]
if not summaryItem?
summaryItem = info.summary[id] = {errorCount: 0}
hostname = Url.parse(req.url).hostname
summaryItem = info.summary[id] = {
baseDomain: OmegaPac.wildcardForDomain(hostname)
errorCount: 0
}
summaryItem.errorCount++
else if @eventCategory[oldStatus] == 'error'
summaryItem = info.summary[id]

View File

@ -384,6 +384,8 @@ class Options
value.revision)
continue if result >= 0
profilesChanged = true
if key is '-builtinProfiles'
currentProfileAffected = 'changed'
@_options[key] = value
if not currentProfileAffected and @_watchingProfiles[key]
currentProfileAffected = 'changed'

View File

@ -33,6 +33,9 @@ shortcutKeys =
for i in [1..9]
shortcutKeys[48 + i] = i
subdomainLevel = 0
summaryDetail = false
customProfiles = do ->
_customProfiles = null
return ->
@ -81,8 +84,8 @@ jQuery(document).on 'keydown', (e) ->
return false
module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
profileIcons, profileOrder, dispNameFilter, getVirtualTarget) ->
profileIcons, profileOrder, dispNameFilter, getVirtualTarget
) ->
omegaTarget.state('customCss').then (customCss = '') ->
$scope.customCss = customCss
@ -219,7 +222,8 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
'proxyNotControllable', 'lastProfileNameForCondition'
]).then ([availableProfiles, currentProfileName, isSystemProfile,
validResultProfiles, refresh, externalProfile,
proxyNotControllable, lastProfileNameForCondition]) ->
proxyNotControllable, lastProfileNameForCondition]
) ->
$scope.proxyNotControllable = proxyNotControllable
return if proxyNotControllable
$scope.availableProfiles = availableProfiles
@ -261,12 +265,43 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
$scope.domainsForCondition = {}
$scope.requestInfoProvided = null
omegaTarget.setRequestInfoCallback (info) ->
info.domains = []
for own domain, domainInfo of info.summary
generateDomainInfos = (info) ->
domains = []
summary = info.summary
unless summaryDetail
summary = {}
for own domain, domainInfo of info.summary
summaryItem = summary[domainInfo.baseDomain]
unless summaryItem
summaryItem = {
errorCount: domainInfo.errorCount
domain: domainInfo.baseDomain
baseDomain: domainInfo.baseDomain
}
summary[domainInfo.baseDomain] = summaryItem
else
summaryItem.errorCount += domainInfo.errorCount
for own domain, domainInfo of summary
domainInfo.domain = domain
info.domains.push(domainInfo)
info.domains.sort (a, b) -> b.errorCount - a.errorCount
domains.push(domainInfo)
domains.sort (a, b) -> b.errorCount - a.errorCount
return domains
$scope.toggleSummarDetail = (event) ->
event.preventDefault()
event.stopPropagation()
$scope.domainsForCondition = {}
$scope.requestInfoProvided = null
summaryDetail = !summaryDetail
info = $scope.requestInfo
info.domains = generateDomainInfos(info)
$scope.requestInfo = info
$scope.requestInfoProvided ?= (info?.domains.length > 0)
for domain in info.domains
$scope.domainsForCondition[domain.domain] ?= true
omegaTarget.setRequestInfoCallback (info) ->
info.domains = generateDomainInfos(info)
$scope.$apply ->
$scope.requestInfo = info
$scope.requestInfoProvided ?= (info?.domains.length > 0)
@ -284,11 +319,12 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
if $scope.currentTempRuleProfile
preselectedProfileNameForCondition = $scope.currentTempRuleProfile
$scope.currentDomain = info.domain
$scope.subdomain = info.subdomain
if $window.location.hash == '#!addRule'
$scope.prepareConditionForm()
$scope.prepareConditionForm = ->
generateConditionSuggestion = ->
currentDomain = $scope.currentDomain
subdomain = $scope.subdomain
currentDomainEscaped = currentDomain.replace(/\./g, '\\.')
domainLooksLikeIp = false
if currentDomain.indexOf(':') >= 0
@ -308,6 +344,14 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
'UrlRegexCondition': '://' + currentDomainEscaped + '(:\\d+)?/'
'KeywordCondition': currentDomain
else
if subdomain
subdomains = subdomain.split('.')
subdomainLevel = subdomainLevel % ( subdomains.length + 1 )
if subdomainLevel > 0
subdomains = subdomains.splice(subdomainLevel - 1)
subdomains.push(currentDomain)
currentDomain = subdomains.join('.')
currentDomainEscaped = currentDomain.replace(/\./g, '\\.')
conditionSuggestion =
'HostWildcardCondition': '*.' + currentDomain
'HostRegexCondition': '(^|\\.)' + currentDomainEscaped + '$'
@ -315,7 +359,12 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
'UrlRegexCondition':
'://([^/.]+\\.)*' + currentDomainEscaped + '(:\\d+)?/'
'KeywordCondition': currentDomain
return conditionSuggestion
$scope.prepareConditionForm = ->
conditionSuggestion = generateConditionSuggestion()
$scope.rule =
condition:
conditionType: 'HostWildcardCondition'
@ -323,5 +372,15 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
profileName: preselectedProfileNameForCondition
$scope.$watch 'rule.condition.conditionType', (type) ->
$scope.rule.condition.pattern = conditionSuggestion[type]
$scope.toggleSubDomainLevel = (domain) ->
domain = domain or $scope.currentDomain
if $window.location.hash == '#!addRule'
subdomainLevel++
conditionSuggestion = generateConditionSuggestion()
$scope.rule.condition.pattern =
conditionSuggestion[$scope.rule.condition.conditionType]
else
console.log('change domain....')
$scope.showConditionForm = true

View File

@ -544,3 +544,7 @@ main {
.modal-body .well:last-child {
margin-bottom: 0;
}
.use-built-in-sync-enhance-tip {
display: inline-block;
}

View File

@ -58,6 +58,10 @@ $httpProvider, $animateProvider, $compileProvider) ->
url: '/io'
templateUrl: 'partials/io.html'
controller: 'IoCtrl'
).state('builtin',
url: '/builtin'
templateUrl: 'partials/builtin.html'
controller: 'BuiltinCtrl'
).state('theme',
url: '/theme'
templateUrl: 'partials/theme.html'

View File

@ -0,0 +1,29 @@
angular.module('omega').controller 'BuiltinCtrl', ($scope, $stateParams,
$location, $rootScope,
$timeout, $state, $modal,
builtinProfiles, profileColorPalette,
getAttachedName, getParentName, getVirtualTarget
) ->
customBuiltinProfiles = Object.assign(
{}, builtinProfiles, $rootScope.options['-builtinProfiles']
)
#$rootScope.options['-builtinProfiles'] = customBuiltinProfiles
$scope.systemProfile = customBuiltinProfiles['+system']
$scope.directProfile = customBuiltinProfiles['+direct']
$scope.moveColor = (color, key) ->
customBuiltinProfiles[key].color = color
# make sure options watcher watch value changed
$rootScope.options['-builtinProfiles'] =
JSON.parse(JSON.stringify(customBuiltinProfiles))
$scope.changeColor = (color) ->
console.log('change color::::', color)
$scope.spectrumOptions =
localStorageKey: 'spectrum.profileColor'
palette: profileColorPalette
preferredFormat: 'hex'
showButtons: false
showInitial: true
showInput: true
showPalette: true
showSelectionPalette: true
maxSelectionSize: 5

View File

@ -1,7 +1,8 @@
angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window,
$q, $modal, $state, profileColors, profileIcons, omegaTarget,
$timeout, $location, $filter, getAttachedName, isProfileNameReserved,
isProfileNameHidden, dispNameFilter, downloadFile, themes) ->
isProfileNameHidden, dispNameFilter, downloadFile, themes
) ->
if browser?.proxy?.register? or browser?.proxy?.registerProxyScript?
$scope.isExperimental = true

View File

@ -38,6 +38,10 @@ html(lang='en' ng-controller='MasterCtrl' ng-csp)
| {{'Theme'}}
li.divider
li.nav-header {{'options_navHeader_profiles' | tr}}
li(ui-sref-active='active'): a(ui-sref='builtin')
span.glyphicon.glyphicon-globe
= ' '
| {{'options_builtin' | tr}}
li.nav-profile(ng-repeat='profile in options | profiles:"sorted"' ui-sref-active='active'
data-profile-type="{{profile.profileType}}")
a(ui-sref='profile({name: profile.name})')

View File

@ -0,0 +1,21 @@
.page-header
h2 {{'options_builtinProfile' | tr}}
section.settings-group
span.profile-color-editor
.profile-color-editor-fake
x-spectrum-colorpicker(
ng-model='systemProfile.color'
options='spectrumOptions'
on-change='changeColor(color)'
on-move='moveColor(color, "+system")'
)
h2.profile-name {{'options_profileTabPrefix' | tr}}{{'System'}}
section.settings-group
span.profile-color-editor
.profile-color-editor-fake
x-spectrum-colorpicker(
ng-model='directProfile.color'
options='spectrumOptions'
on-move='moveColor(color, "+direct")'
)
h2.profile-name {{'options_profileTabPrefix' | tr}}{{'Direct'}}

View File

@ -63,6 +63,11 @@ section.settings-group
label
input#use-built-in-sync-enhance(type='checkbox' ng-model='useBuiltInSync')
span {{'options_useBuiltInSyncEnhance' | tr}}
details.use-built-in-sync-enhance-tip
summary
span.glyphicon.glyphicon-question-sign
ol(omega-html='"options_useBuiltInSyncEnhanceTip" | tr')
p.help-block(omega-html='"options_syncPristineHelp" | tr')
p
button.btn.btn-default(ng-click='enableOptionsSync()' ladda='enableOptionsSyncing' data-spinner-color="currentColor")

View File

@ -108,7 +108,11 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp)
option(value='KeywordCondition') {{'condition_KeywordCondition' | tr}}
div.form-group
label {{'options_conditionDetails' | tr}}
input.form-control.condition-details(type='text' required ng-model='rule.condition.pattern' autofocus)
span.input-group
input.form-control.condition-details(type='text' required ng-model='rule.condition.pattern' autofocus)
span.input-group-btn
button.btn.btn-default(type='button' ng-click='toggleSubDomainLevel()')
i.glyphicon.glyphicon-transfer
div.form-group
label {{'options_resultProfile' | tr}}
div(omega-profile-select='validResultProfiles' ng-model='rule.profileName'
@ -138,6 +142,9 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp)
.text-warning {{'popup_requestErrorWarning' | tr}}
p.help-block {{'popup_requestErrorWarningHelp' | tr}}
p.help-block(ng-show='!!currentProfileCanAddRule') {{'popup_requestErrorAddCondition' | tr}}
div
button.btn.btn-default.btn-xs.btn-link(ng-click='toggleSummarDetail($event)')
i.glyphicon.glyphicon-transfer
.checkbox(ng-repeat='domain in requestInfo.domains track by domain.domain')
label
input(type='checkbox' ng-model='domainsForCondition[domain.domain]' autofocus ng-if='$index === 0')

View File

@ -120,9 +120,18 @@
isValidResultProfile['+' + name] = true;
});
function createGlobeIcon(targetEl, color){
var el = document.createElement('span')
el.className = 'glyphicon glyphicon-globe'
el.style.color = color
targetEl.appendChild(el)
}
function addProfilesItems(state) {
var systemProfileDisp = document.getElementById('js-system');
var directProfileDisp = document.getElementById('js-direct');
var systemProfile = state.availableProfiles['+system']
var directProfile = state.availableProfiles['+direct']
var currentProfileClass = 'om-active';
if (state.isSystemProfile) {
systemProfileDisp.parentElement.classList.add('om-active');
@ -131,11 +140,12 @@
if (state.currentProfileName === 'direct') {
directProfileDisp.parentElement.classList.add(currentProfileClass);
}
createGlobeIcon(systemProfileDisp, systemProfile.color)
systemProfileDisp.setAttribute('title',
state.availableProfiles['+system'].desc);
systemProfile.desc);
createGlobeIcon(directProfileDisp, directProfile.color)
directProfileDisp.setAttribute('title',
state.availableProfiles['+direct'].desc);
directProfile.desc);
var profilesEnd = document.getElementById('js-profiles-end');
var profilesContainer = profilesEnd.parentElement;