1. Improve the performance of a large number of Rule Lists

2. Fix the pop-up window issue in Edge for Android #93
This commit is contained in:
proxy.zeroomega 2025-02-15 08:32:40 +08:00
parent bd8187800a
commit fa756d806a
8 changed files with 124 additions and 6 deletions

View File

@ -73,6 +73,18 @@ module.exports =
]
new U2.AST_Do(
body: new U2.AST_BlockStatement body: [
new U2.AST_If(
condition: new U2.AST_UnaryPrefix(
operator: "!",
expression: new U2.AST_Sub(
expression: new U2.AST_SymbolRef name: 'profiles'
property: new U2.AST_SymbolRef name: 'result'
)
)
body: new U2.AST_Return(
value: new U2.AST_SymbolRef name: "result"
)
)
new U2.AST_SimpleStatement body: new U2.AST_Assign(
left: new U2.AST_SymbolRef name: 'result'
operator: '='

View File

@ -472,6 +472,12 @@ module.exports = exports =
match: (profile, request) ->
result = exports.match(profile, request, 'SwitchProfile')
compile: (profile) ->
if profile.isTempPacProfile
exports.compile(profile, 'SwitchProfile')
else
if profile.pacScript
exports.compile(profile, 'PacProfile')
else
exports.compile(profile, 'SwitchProfile')
updateUrl: (profile) -> profile.sourceUrl
updateContentTypeHints: -> [
@ -497,6 +503,8 @@ module.exports = exports =
if formatHandler.preprocess?
data = formatHandler.preprocess(data)
return false if profile.ruleList == data
# regenerator pacScript
profile.pacScript = ''
profile.ruleList = data
return true
'SwitchyRuleListProfile': 'RuleListProfile'

View File

@ -24,6 +24,16 @@ import "./js/background.js" // zeroBackground
const isFirefox = !!globalThis.localStorage
const zcb = globalThis.zeroDetectModeCB
globalThis.POPUPHTMLURL = './popup-iframe.html'
//if android, (eg. edge canary for android), use default popup/index.html
//https://github.com/zero-peak/ZeroOmega/issues/93
if (globalThis.navigator && /Android/i.test(globalThis.navigator.userAgent)){
globalThis.POPUPHTMLURL = './popup/index.html'
}
// keepAlive
setInterval(chrome.runtime.getPlatformInfo, 25 * 1000) //https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers
function detectPrivateMode(cb) {
var db, tempMode,on, off;
if (zcb) {

View File

@ -23,7 +23,7 @@ module.exports = class ExternalApi
@options.setProxyNotControllable(null)
#chrome.action.setPopup?({popup: 'popup/index.html'})
chrome.action.setPopup?({popup: 'popup-iframe.html'})
chrome.action.setPopup?({popup: globalThis.POPUPHTMLURL})
@options.reloadQuickSwitch()
@disabled = false
@options.clearBadge()

View File

@ -164,8 +164,7 @@ class ChromeOptions extends OmegaTarget.Options
if quickSwitch
chrome.action.setPopup({popup: ''})
else
#chrome.action.setPopup({popup: 'popup/index.html'})
chrome.action.setPopup({popup: 'popup-iframe.html'})
chrome.action.setPopup({popup: globalThis.POPUPHTMLURL})
chrome.contextMenus?.update('enableQuickSwitch', {checked: !!quickSwitch})
Promise.resolve()

View File

@ -2,6 +2,10 @@ OmegaTarget = require('omega-target')
Promise = OmegaTarget.Promise
ProxyAuth = require('./proxy_auth')
# TODO temp profile will always create new cache.
profilePacCache = new Map()
class ProxyImpl
constructor: (log) ->
@log = log
@ -31,6 +35,25 @@ class ProxyImpl
)
getProfilePacScript: (profile, meta, options) ->
meta ?= profile
referenced_profiles = []
ref_set = OmegaPac.Profiles.allReferenceSet(profile,
options, profileNotFound: @_profileNotFound.bind(this))
for own _, name of ref_set
_profile = OmegaPac.Profiles.byName(name, options)
if _profile
referenced_profiles.push(_profile)
cachedProfiles = profilePacCache.keys().toArray()
allProfiles = Object.values(options)
cachedProfiles.forEach((cachedProfile) ->
if allProfiles.indexOf(cachedProfile) < 0
profilePacCache.delete(cachedProfile)
)
profilePac = profilePacCache.get(profile)
profilePacKey = referenced_profiles.map(
(_profile) -> _profile.name + '_' + (_profile.revision or 1)
).join(',')
if profilePac?[profilePacKey]
return profilePac[profilePacKey]
ast = OmegaPac.PacGenerator.script(options, profile,
profileNotFound: @_profileNotFound.bind(this))
ast = OmegaPac.PacGenerator.compress(ast)
@ -39,6 +62,10 @@ class ProxyImpl
profileName = profileName.replace(/\*/g, '\\u002a')
profileName = profileName.replace(/\\/g, '\\u002f')
prefix = "/*OmegaProfile*#{profileName}*#{meta.revision}*/"
return prefix + script
pacScript = prefix + script
profilePac = {}
profilePac[profilePacKey] = pacScript
profilePacCache.set(profile, profilePac)
return pacScript
module.exports = ProxyImpl

View File

@ -4,6 +4,29 @@ Promise = OmegaTarget.Promise
chromeApiPromisify = require('../chrome_api').chromeApiPromisify
ProxyImpl = require('./proxy_impl')
notExistentWebsite = "preflight-auth.non-existent-website.zzzzzzzzeroomega.zero"
getFirstAuthProfile = (profile, options) ->
for rule in profile.rules
profileName = rule.profileName
_profile = OmegaPac.Profiles.byName(profileName, options)
return _profile if _profile.auth
addAuthPreflightRule = (profile, options) ->
return unless profile.profileType is 'SwitchProfile'
return unless profile.rules or profile.rules.length is 0
authProfile = getFirstAuthProfile(profile, options)
return unless authProfile
profile.rules.unshift({
"condition": {
"conditionType": "HostWildcardCondition"
"pattern": notExistentWebsite
}
"isPreflightRule": true
"profileName": authProfile.name
})
return authProfile
class SettingsProxyImpl extends ProxyImpl
@isSupported: -> chrome?.proxy?.settings?
features: ['fullUrlHttp', 'pacScript', 'watchProxyChange']
@ -14,6 +37,7 @@ class SettingsProxyImpl extends ProxyImpl
return chromeApiPromisify(chrome.proxy.settings, 'clear')({}).then =>
chrome.proxy.settings.get {}, @_proxyChangeListener
return
authProfile = null
config = {}
if profile.profileType == 'DirectProfile'
config['mode'] = 'direct'
@ -31,14 +55,24 @@ class SettingsProxyImpl extends ProxyImpl
config = @_fixedProfileConfig(profile)
else
config['mode'] = 'pac_script'
authProfile = addAuthPreflightRule(profile, options)
config['pacScript'] =
mandatory: true
data: @getProfilePacScript(profile, meta, options)
return @setProxyAuth(profile, options).then(->
return chromeApiPromisify(chrome.proxy.settings, 'set')({value: config})
).then(=>
if authProfile
fetch("https://" + notExistentWebsite).catch(-> authProfile)
chrome.proxy.settings.get {}, @_proxyChangeListener
return
).finally(->
if authProfile
profile.rules.forEach((rule, index) ->
if rule.isPreflightRule
profile.rules.splice(index, 1)
)
profile.rules
)
_fixedProfileConfig: (profile) ->
config = {}

View File

@ -5,6 +5,31 @@ Storage = require './storage'
OmegaPac = require 'omega-pac'
jsondiffpatch = require 'jsondiffpatch'
PROFILETEMPPACKEY = '__tempZeroRuleListPac'
generateProfileTempPac = (profile) ->
tempProfile = OmegaPac.Profiles.create(PROFILETEMPPACKEY, profile.profileType)
tempProfile.defaultProfileName = profile.defaultProfileName
tempProfile.format = profile.format
tempProfile.matchProfileName = profile.matchProfileName
tempProfile.ruleList = profile.ruleList
tempProfile.isTempPacProfile = true
options = {}
nameKey = OmegaPac.Profiles.nameAsKey(tempProfile.name)
options[nameKey] = tempProfile
profileNotFound = -> 'ignore'
ast = OmegaPac.PacGenerator.script(options, tempProfile.name,
profileNotFound: profileNotFound)
pac = ast.print_to_string(beautify: true, comments: true)
pac = OmegaPac.PacGenerator.ascii(pac)
return pac
class Options
###*
# The entire set of options including profiles and other settings.
@ -109,7 +134,7 @@ class Options
@_storage.get(null)
else
@sync.init({gistId, gistToken}).catch((e) ->
console.error('sync init fail::', e)
console.log('sync init fail::', e)
)
@_syncWatchStop = @sync.watchAndPull(@_storage)
@sync.copyTo(@_storage).catch(Storage.StorageUnavailableError, =>
@ -384,6 +409,8 @@ class Options
value.revision)
continue if result >= 0
profilesChanged = true
if value.profileType is 'RuleListProfile'
value.pacScript = generateProfileTempPac(value)
if key is '-builtinProfiles'
currentProfileAffected = 'changed'
@_options[key] = value
@ -722,6 +749,7 @@ class Options
profile.lastUpdate = new Date().toISOString()
if OmegaPac.Profiles.update(profile, data)
OmegaPac.Profiles.dropCache(profile)
OmegaPac.Profiles.updateRevision(profile)
changes = {}
changes[key] = profile
@_setOptions(changes).return(profile)