Show profile details tooltip for popup menu and browserAction.

This commit is contained in:
FelisCatus 2014-11-07 15:38:34 +08:00
parent 862c7b141f
commit e988fa7c1c
12 changed files with 149 additions and 35 deletions

View File

@ -667,6 +667,21 @@
"popup_errorLog": {
"message": "Error log"
},
"browserAction_profileDetails_PacProfile": {
"message": "(PAC script)"
},
"browserAction_profileDetails_SystemProfile": {
"message": "(controlled by other extensions or environment)"
},
"browserAction_profileDetails_DirectProfile": {
"message": "(not using any proxy)"
},
"browserAction_profileDetails_SwitchProfile": {
"message": "(switching based on conditions)"
},
"browserAction_profileDetails_RuleListProfile": {
"message": "(switching based on rule list)"
},
"browserAction_titleNormal": {
"message": "SwitchyOmega:: $PROFILE$",
"placeholders": {

View File

@ -492,6 +492,9 @@
}
}
},
"options_replaceProfileSuccess": {
"message": "更改选项成功。"
},
"options_modalHeader_deleteProfile": {
"message": "删除情景模式"
},
@ -664,6 +667,21 @@
"popup_errorLog": {
"message": "错误日志"
},
"browserAction_profileDetails_PacProfile": {
"message": "(PAC 脚本)"
},
"browserAction_profileDetails_SystemProfile": {
"message": "(由其他扩展或系统环境控制)"
},
"browserAction_profileDetails_DirectProfile": {
"message": "(不使用任何代理)"
},
"browserAction_profileDetails_SwitchProfile": {
"message": "(根据条件切换)"
},
"browserAction_profileDetails_RuleListProfile": {
"message": "(根据规则列表切换)"
},
"browserAction_titleNormal": {
"message": "SwitchyOmega:: $PROFILE$",
"placeholders": {

View File

@ -492,6 +492,9 @@
}
}
},
"options_replaceProfileSuccess": {
"message": "更改選項成功。"
},
"options_modalHeader_deleteProfile": {
"message": "刪除情景模式"
},
@ -664,6 +667,21 @@
"popup_errorLog": {
"message": "錯誤日誌"
},
"browserAction_profileDetails_PacProfile": {
"message": "(PAC 指令碼)"
},
"browserAction_profileDetails_SystemProfile": {
"message": "(由其他擴展或系統環境控制)"
},
"browserAction_profileDetails_DirectProfile": {
"message": "(不使用任何代理)"
},
"browserAction_profileDetails_SwitchProfile": {
"message": "(根據條件切換)"
},
"browserAction_profileDetails_RuleListProfile": {
"message": "(根據規則列表切換)"
},
"browserAction_titleNormal": {
"message": "SwitchyOmega:: $PROFILE$",
"placeholders": {

View File

@ -492,6 +492,9 @@
}
}
},
"options_replaceProfileSuccess": {
"message": "更改選項成功。"
},
"options_modalHeader_deleteProfile": {
"message": "刪除情景模式"
},
@ -664,6 +667,21 @@
"popup_errorLog": {
"message": "錯誤日誌"
},
"browserAction_profileDetails_PacProfile": {
"message": "(PAC 指令碼)"
},
"browserAction_profileDetails_SystemProfile": {
"message": "(由其他擴展或系統環境控制)"
},
"browserAction_profileDetails_DirectProfile": {
"message": "(不使用任何代理)"
},
"browserAction_profileDetails_SwitchProfile": {
"message": "(根據條件切換)"
},
"browserAction_profileDetails_RuleListProfile": {
"message": "(根據規則列表切換)"
},
"browserAction_titleNormal": {
"message": "SwitchyOmega:: $PROFILE$",
"placeholders": {

View File

@ -139,7 +139,9 @@ module.exports = exports =
handler = exports._handler(profile)
cache.directReferenceSet = handler.directReferenceSet.call(exports, profile)
allReferenceSet: (profile, options, opt_out) ->
o_profile = profile
profile = exports.byName(profile, options)
throw new Error("Profile #{o_profile} does not exist!") if not profile?
result = opt_out ? {}
result[exports.nameAsKey(profile.name)] = profile.name
for key, name of exports.directReferenceSet(profile)

View File

@ -127,10 +127,9 @@ options.setProxyNotControllable(null)
timeout = null
options.watchProxyChange (details) ->
lastProxyChangeAt = Date.now()
notControllableBefore = options.proxyNotControllable()
internal = false
switch details['levelOfControl']
when "controllable_by_this_extension"
break
when "controlled_by_other_extensions", "not_controllable"
reason =
if details['levelOfControl'] == 'not_controllable'
@ -141,7 +140,9 @@ options.watchProxyChange (details) ->
else
options.setProxyNotControllable(null)
return if details['levelOfControl'] == 'controlled_by_this_extension'
if details['levelOfControl'] == 'controlled_by_this_extension'
internal = true
return if not notControllableBefore
Log.log('external proxy: ', details)
# Chromium will send chrome.proxy.settings.onChange on extension unload,
@ -151,16 +152,16 @@ options.watchProxyChange (details) ->
# To workaround this issue, wait for some time before setting the proxy.
# However this will cause some delay before the settings are processed.
clearTimeout(timeout) if timeout?
parsed = null
timeout = setTimeout (->
options.setExternalProfile(
options.parseExternalProfile(details),
noRevert: true)
options.setExternalProfile(parsed, {noRevert: true, internal: internal})
), 500
parsed = options.parseExternalProfile(details)
return
external = false
options.currentProfileChanged = (reason) ->
profile = options.currentProfile()
iconCache = {}
if reason == 'external'
@ -176,19 +177,21 @@ options.currentProfileChanged = (reason) ->
realCurrentName = current.defaultProfileName
currentName += " [#{dispName(realCurrentName)}]"
current = options.profile(realCurrentName)
title =
if profile.name == ''
details = profile.pacUrl ? options.printFixedProfile(profile)
details = details ? profile.profileType
else
chrome.i18n.getMessage('browserAction_titleNormal', [currentName])
if external and profile.profileType != 'SystemProfile'
details = options.printProfile(current)
if currentName
title = chrome.i18n.getMessage('browserAction_titleWithResult', [
currentName, '', details])
else
title = details
if external and current.profileType != 'SystemProfile'
message = chrome.i18n.getMessage('browserAction_titleExternalProxy')
title = message + '\n' + title
options.setBadge()
tabs.resetAll(
icon: drawIcon(profile.color)
icon: drawIcon(current.color)
title: title
)

View File

@ -35,7 +35,7 @@ class ChromeOptions extends OmegaTarget.Options
return results
_proxyNotControllable: null
proxyNotControllable: => @_proxyNotControllable
proxyNotControllable: -> @_proxyNotControllable
setProxyNotControllable: (reason) ->
@_proxyNotControllable = reason
if reason
@ -110,7 +110,8 @@ class ChromeOptions extends OmegaTarget.Options
watcher(details)
chrome.proxy.settings.onChange.addListener @_proxyChangeListener
@_proxyChangeWatchers.push(callback)
applyProfileProxy: (profile) ->
applyProfileProxy: (profile, meta) ->
meta ?= profile
if profile.profileType == 'SystemProfile'
# Clear proxy settings, returning proxy control to Chromium.
return proxySettings.clearAsync({}).then =>
@ -135,10 +136,10 @@ class ChromeOptions extends OmegaTarget.Options
data: null
mandatory: true
setPacScript = @pacForProfile(profile).then (script) ->
profileName = OmegaPac.PacGenerator.ascii(JSON.stringify(profile.name))
profileName = OmegaPac.PacGenerator.ascii(JSON.stringify(meta.name))
profileName = profileName.replace(/\*/g, '\\u002a')
profileName = profileName.replace(/\\/g, '\\u002f')
prefix = "/*OmegaProfile*#{profileName}*#{profile.revision}*/"
prefix = "/*OmegaProfile*#{profileName}*#{meta.revision}*/"
config['pacScript'].data = prefix + script
return
setPacScript ?= Promise.resolve()
@ -193,8 +194,22 @@ class ChromeOptions extends OmegaTarget.Options
result += "#{scheme.scheme}: #{pacResult}\n"
else
result += "#{pacResult}\n"
result ||= chrome.i18n.getMessage(
'browserAction_profileDetails_DirectProfile')
return result
printProfile: (profile) ->
type = profile.profileType
if type.indexOf('RuleListProfile') >= 0
type = 'RuleListProfile'
if type == 'FixedProfile'
@printFixedProfile(profile)
else if type == 'PacProfile' and profile.pacUrl
profile.pacUrl
else
chrome.i18n.getMessage('browserAction_profileDetails_' + type) || null
upgrade: (options, changes) ->
super(options).catch (err) =>
if not options?['schemaVersion']

View File

@ -63,7 +63,7 @@ module.exports = (details, options, fixedProfileConfig) ->
proxies = {}
for prop in props
result = OmegaPac.Profiles.pacResult(details.value.rules[prop])
if prop == 'singleProxy'
if prop == 'singleProxy' and details.value.rules[prop]?
proxies['fallbackProxy'] = result
else
proxies[prop] = result

View File

@ -86,6 +86,14 @@ class Options
toString: -> "<Options>"
###*
# Return a localized, human-readable description of the given profile.
# In base class, this method is not implemented and will always return null.
# @param {?{}} profile The profile to print
# @returns {string} Description of the profile with details
###
printProfile: (profile) -> null
###*
# Upgrade options from previous versions.
# For now, this method only supports schemaVersion 1 and 2. If so, it upgrades
@ -268,7 +276,7 @@ class Options
# Get PAC script for profile.
# @param {?string|Object} profile The name of the profile, or the profile.
# @param {bool=false} compress Compress the script if true.
# @returns {String} The compiled
# @returns {string} The compiled
###
pacForProfile: (profile, compress = false) ->
ast = OmegaPac.PacGenerator.script(@_options, profile)
@ -288,11 +296,16 @@ class Options
name: p.name
profileType: p.profileType
color: p.color
desc: @printProfile(p)
builtin: if p.builtin then true
if p.profileType == 'VirtualProfile'
profiles[key].defaultProfileName = p.defaultProfileName
if not allReferenceSet?
allReferenceSet = OmegaPac.Profiles.allReferenceSet profile, @_options
allReferenceSet =
if profile
OmegaPac.Profiles.allReferenceSet profile, @_options
else
{}
if allReferenceSet[key]
profiles[key].validResultProfiles =
OmegaPac.Profiles.validResultProfilesFor(p, @_options)
@ -357,7 +370,7 @@ class Options
@_watchingProfiles = OmegaPac.Profiles.allReferenceSet(@_tempProfile,
@_options)
@applyProfileProxy(@_tempProfile)
@applyProfileProxy(@_tempProfile, profile)
else
@applyProfileProxy(profile)
@ -381,9 +394,10 @@ class Options
# Set proxy settings based on the given profile.
# In base class, this method is not implemented and will always reject.
# @param {{}} profile The profile to apply
# @param {{}=profile} meta The metadata of the profile, like name and revision
# @returns {Promise} A promise which is fulfilled when the proxy is set.
###
applyProfileProxy: (profile) ->
applyProfileProxy: (profile, meta) ->
Promise.reject new Error('not implemented')
###*
@ -707,6 +721,8 @@ class Options
# @param {{}} profile The external profile
# @param {?{}} args Extra arguments
# @param {boolean=false} args.noRevert If true, do not revert changes.
# @param {boolean=false} args.internal If true, treat the profile change as
# caused by the options itself instead of external reasons.
# @returns {Promise} A promise which is fulfilled when the profile is set
###
setExternalProfile: (profile, args) ->
@ -717,8 +733,11 @@ class Options
return
p = OmegaPac.Profiles.byName(profile.name, @_options)
if p
@applyProfile(p.name,
{proxy: false, system: @_isSystem, reason: 'external'})
if args?.internal
@applyProfile(p.name, {proxy: false})
else
@applyProfile(p.name,
{proxy: false, system: @_isSystem, reason: 'external'})
else
@_currentProfileName = null
@_externalProfile = profile

View File

@ -98,7 +98,7 @@ angular.module('omegaDecoration', []).value('profileIcons', {
scope.profileIcon = profileIcons[profile.profileType]
break
scope.$watch(scope.profiles, ((profiles) ->
scope.currentProfiles = profiles
scope.currentProfiles = profiles || []
if scope.dispProfiles?
scope.dispProfiles = currentProfiles
updateView()

View File

@ -9,7 +9,7 @@ module.filter 'dispName', (omegaTarget) ->
omegaTarget.getMessage('profile_' + name) || name
module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
profileIcons, profileOrder, dispNameFilter) ->
profileIcons, profileOrder, dispNameFilter, getVirtualTarget) ->
refreshOnProfileChange = false
refresh = ->
@ -33,6 +33,12 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
'glyphicon-ok'
else
undefined
$scope.getProfileTitle = (profile, normal) ->
desc = ''
while profile
desc = profile.desc
profile = getVirtualTarget(profile, $scope.availableProfiles)
desc || profile?.name || ''
$scope.openOptions = (hash) ->
omegaTarget.openOptions(hash).then ->
$window.close()

View File

@ -26,10 +26,10 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp)
body(ng-class='{"with-condition-form": showConditionForm}')
ul.nav.nav-pills.nav-stacked(ng-hide='showConditionForm || proxyNotControllable')
li.profile(ng-repeat='profile in builtinProfiles' ng-class='{active: isActive(profile.name), "bg-info": isEffective(profile.name)}')
a(ng-click='applyProfile(profile)')
a(ng-click='applyProfile(profile)' title='{{getProfileTitle(profile)}}')
span(omega-profile-inline='profile' icon='getIcon(profile)' options='availableProfiles' disp-name='dispNameFilter')
li.profile.external-profile(ng-show='!!externalProfile' ng-class='{active: isActive(""), "bg-info": isEffective("")}')
a(ng-click='nameExternal.open = true')
a(ng-click='nameExternal.open = true' title='{{getProfileTitle(externalProfile)}}')
form(name='nameExternalForm' ng-submit='nameExternalForm.$valid && saveExternal()')
span(omega-profile-icon='externalProfile' icon='getIcon(externalProfile, "normal")' options='availableProfiles' disp-name='dispNameFilter')
= ' '
@ -39,9 +39,9 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp)
li.divider
li.profile(ng-repeat='profile in customProfiles' ng-class='{active: isActive(profile.name), "bg-info": isEffective(profile.name)}'
dropdown)
a(ng-click='applyProfile(profile)' ng-if='!profile.validResultProfiles')
a(ng-click='applyProfile(profile)' ng-if='!profile.validResultProfiles' title='{{getProfileTitle(profile)}}')
span(omega-profile-inline='profile' icon='getIcon(profile)' options='availableProfiles' disp-name='dispNameFilter')
a.profile-with-default-edit(ng-click='applyProfile(profile)' ng-if='!!profile.validResultProfiles')
a.profile-with-default-edit(ng-click='applyProfile(profile)' ng-if='!!profile.validResultProfiles' title='{{getProfileTitle(profile)}}')
span(omega-profile-inline='profile' icon='getIcon(profile)' options='availableProfiles' disp-name='dispNameFilter')
= ' '
| [{{profile.defaultProfileName}}]
@ -49,7 +49,7 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp)
span.glyphicon.glyphicon-chevron-down
ul.dropdown-menu(ng-if='!!profile.validResultProfiles')
li(ng-repeat='p in profile.validResultProfiles' ng-class='{active: p.name == profile.defaultProfileName}')
a(ng-click='setDefaultProfile(profile.name, p.name)')
a(ng-click='setDefaultProfile(profile.name, p.name)' title='{{getProfileTitle(profile)}}')
span(omega-profile-inline='p' options='availableProfiles' disp-name='dispNameFilter')
li.divider(ng-show='!!currentDomain && validResultProfiles.length')
li(ng-show='!!currentProfileCanAddRule')
@ -66,7 +66,7 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp)
ul.dropdown-menu
li(ng-repeat='profile in validResultProfiles' ng-class='{active: profile.name == currentTempRuleProfile}'
ng-show='!!currentTempRuleProfile || validResultProfiles.length == 1 || profile.name != currentProfileName')
a(ng-click='addTempRule(currentDomain, profile.name)')
a(ng-click='addTempRule(currentDomain, profile.name)' title='{{getProfileTitle(profile)}}')
span(omega-profile-inline='profile' options='availableProfiles' disp-name='dispNameFilter')
li.divider
li