diff --git a/omega-i18n/en/messages.json b/omega-i18n/en/messages.json index 309f25a7..c56aed0a 100644 --- a/omega-i18n/en/messages.json +++ b/omega-i18n/en/messages.json @@ -649,6 +649,15 @@ "options_formInvalid": { "message": "Please correct the errors in this page." }, + "options_profileNotFound": { + "message": "Profile $PROFILE$ does not exist! The options may be corrupted.", + "placeholders": { + "profile": { + "content": "$1", + "example": "Example" + } + } + }, "options_resetSuccess": { "message": "Options reset." }, diff --git a/omega-i18n/zh_CN/messages.json b/omega-i18n/zh_CN/messages.json index bcbd32bf..814e2090 100644 --- a/omega-i18n/zh_CN/messages.json +++ b/omega-i18n/zh_CN/messages.json @@ -649,6 +649,15 @@ "options_formInvalid": { "message": "请更正这个页面中的错误。" }, + "options_profileNotFound": { + "message": "情景模式 $PROFILE$ 不存在!选项可能已经损坏。", + "placeholders": { + "profile": { + "content": "$1", + "example": "Example" + } + } + }, "options_resetSuccess": { "message": "选项已经重置。" }, diff --git a/omega-i18n/zh_HK/messages.json b/omega-i18n/zh_HK/messages.json index 03a3f8ab..a1b0cf74 100644 --- a/omega-i18n/zh_HK/messages.json +++ b/omega-i18n/zh_HK/messages.json @@ -649,6 +649,15 @@ "options_formInvalid": { "message": "請更正這個頁面中的錯誤。" }, + "options_profileNotFound": { + "message": "情景模式 $PROFILE$ 不存在!選項可能已經損壞。", + "placeholders": { + "profile": { + "content": "$1", + "example": "Example" + } + } + }, "options_resetSuccess": { "message": "選項已經重置。" }, diff --git a/omega-i18n/zh_TW/messages.json b/omega-i18n/zh_TW/messages.json index d91d25e4..b7f888e9 100644 --- a/omega-i18n/zh_TW/messages.json +++ b/omega-i18n/zh_TW/messages.json @@ -649,6 +649,15 @@ "options_formInvalid": { "message": "請更正這個頁面中的錯誤。" }, + "options_profileNotFound": { + "message": "情景模式 $PROFILE$ 不存在!選項可能已經損壞。", + "placeholders": { + "profile": { + "content": "$1", + "example": "Example" + } + } + }, "options_resetSuccess": { "message": "選項已經重置。" }, diff --git a/omega-pac/src/pac_generator.coffee b/omega-pac/src/pac_generator.coffee index 78166f24..55a1dcde 100644 --- a/omega-pac/src/pac_generator.coffee +++ b/omega-pac/src/pac_generator.coffee @@ -22,16 +22,21 @@ module.exports = compressed_ast.mangle_names() compressed_ast - script: (options, profile) -> + script: (options, profile, args) -> if typeof profile == 'string' profile = Profiles.byName(profile, options) - refs = Profiles.allReferenceSet(profile, options) + refs = Profiles.allReferenceSet(profile, options, + profileNotFound: args?.profileNotFound) + profiles = new U2.AST_Object properties: for key, name of refs when key != '+direct' - new U2.AST_ObjectKeyVal( - key: key - value: Profiles.compile(Profiles.byName(name, options) ? profile), - ) + p = if typeof profile == 'object' and profile.name == name + profile + else + Profiles.byName(name, options) + if not p? + p = Profiles.profileNotFound(name, args?.profileNotFound) + new U2.AST_ObjectKeyVal(key: key, value: Profiles.compile(p)) factory = new U2.AST_Function( argnames: [ diff --git a/omega-pac/src/profiles.coffee b/omega-pac/src/profiles.coffee index ae4dc219..ca0720cb 100644 --- a/omega-pac/src/profiles.coffee +++ b/omega-pac/src/profiles.coffee @@ -138,22 +138,48 @@ module.exports = exports = return cache.directReferenceSet if cache.directReferenceSet handler = exports._handler(profile) cache.directReferenceSet = handler.directReferenceSet.call(exports, profile) - allReferenceSet: (profile, options, opt_out) -> + + profileNotFound: (name, action) -> + if not action? + throw new Error("Profile #{name} does not exist!") + if typeof action == 'function' + action = action(name) + if typeof action == 'object' and action.profileType + return action + switch action + when 'ignore' + return null + when 'dumb' + return exports.create({ + name: name + profileType: 'VirtualProfile' + defaultProfileName: 'direct' + }) + throw action + + allReferenceSet: (profile, options, opt_args) -> 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) - exports.allReferenceSet(name, options, result) + profile ?= exports.profileNotFound?(o_profile, opt_args.profileNotFound) + opt_args ?= {} + has_out = opt_args.out? + result = opt_args.out ?= {} + if profile + result[exports.nameAsKey(profile.name)] = profile.name + for key, name of exports.directReferenceSet(profile) + exports.allReferenceSet(name, options, opt_args) + delete opt_args.out if not has_out result - referencedBySet: (profile, options, opt_out) -> + referencedBySet: (profile, options, opt_args) -> profileKey = exports.nameAsKey(profile) - result = opt_out ? {} + opt_args ?= {} + has_out = opt_args.out? + result = opt_args.out ?= {} exports.each options, (key, prof) -> if exports.directReferenceSet(prof)[profileKey] result[key] = prof.name - exports.referencedBySet(prof, options, result) + exports.referencedBySet(prof, options, opt_args) + delete opt_args.out if not has_out result validResultProfilesFor: (profile, options) -> profile = exports.byName(profile, options) diff --git a/omega-pac/test/profiles.coffee b/omega-pac/test/profiles.coffee index 444e2c3d..21d04714 100644 --- a/omega-pac/test/profiles.coffee +++ b/omega-pac/test/profiles.coffee @@ -55,6 +55,18 @@ describe 'Profiles', -> profile = {} profile = Profiles.byName('profile', {"+profile": profile}) profile.should.equal(profile) + describe '#allReferenceSet', -> + profile = Profiles.create('test', 'VirtualProfile') + profile.defaultProfileName = 'bogus' + it 'should throw if referenced profile does not exist', -> + getAllReferenceSet = -> + Profiles.allReferenceSet(profile, {}) + getAllReferenceSet.should.throw(Error) + it 'should process a dumb profile for each missing profile if requested', -> + profile.defaultProfileName = 'bogus' + refs = Profiles.allReferenceSet profile, {}, profileNotFound: 'dumb' + refs['+bogus'].should.equal('bogus') + describe 'SystemProfile', -> it 'should be builtin with the name "system"', -> profile = Profiles.byName('system') diff --git a/omega-target/src/options.coffee b/omega-target/src/options.coffee index 3b83fbe3..d7235cdc 100644 --- a/omega-target/src/options.coffee +++ b/omega-target/src/options.coffee @@ -293,6 +293,14 @@ class Options ### watch: (callback) -> @_storage.watch null, callback + _profileNotFound: (name) -> + @log.error("Profile #{name} not found! Things may go very, very wrong.") + return OmegaPac.Profiles.create({ + name: name + profileType: 'VirtualProfile' + defaultProfileName: 'direct' + }) + ###* # Get PAC script for profile. # @param {?string|Object} profile The name of the profile, or the profile. @@ -300,7 +308,8 @@ class Options # @returns {string} The compiled ### pacForProfile: (profile, compress = false) -> - ast = OmegaPac.PacGenerator.script(@_options, profile) + ast = OmegaPac.PacGenerator.script(@_options, profile, + profileNotFound: @_profileNotFound.bind(this)) if compress ast = OmegaPac.PacGenerator.compress(ast) Promise.resolve OmegaPac.PacGenerator.ascii(ast.print_to_string()) @@ -324,7 +333,8 @@ class Options if not allReferenceSet? allReferenceSet = if profile - OmegaPac.Profiles.allReferenceSet profile, @_options + OmegaPac.Profiles.allReferenceSet(profile, @_options, + profileNotFound: @_profileNotFound.bind(this)) else {} if allReferenceSet[key] @@ -358,7 +368,8 @@ class Options @_currentProfileName = profile.name @_isSystem = options?.system || (profile.profileType == 'SystemProfile') - @_watchingProfiles = OmegaPac.Profiles.allReferenceSet(profile, @_options) + @_watchingProfiles = OmegaPac.Profiles.allReferenceSet(profile, @_options, + profileNotFound: @_profileNotFound.bind(this)) @_state.set({ 'currentProfileName': @_currentProfileName @@ -390,7 +401,7 @@ class Options OmegaPac.Profiles.updateRevision(@_tempProfile) @_watchingProfiles = OmegaPac.Profiles.allReferenceSet(@_tempProfile, - @_options) + @_options, profileNotFound: @_profileNotFound.bind(this)) @applyProfileProxy(@_tempProfile, profile) else @applyProfileProxy(profile) diff --git a/omega-web/src/omega/controllers/master.coffee b/omega-web/src/omega/controllers/master.coffee index 65d13027..0a51aec5 100644 --- a/omega-web/src/omega/controllers/master.coffee +++ b/omega-web/src/omega/controllers/master.coffee @@ -27,12 +27,23 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window, return unless profileName profile = $rootScope.profileByName(profileName) return if profile.profileType in ['DirectProfile', 'SystemProfile'] - ast = OmegaPac.PacGenerator.script($rootScope.options, profileName) + missingProfile = null + profileNotFound = (name) -> + missingProfile = name + return 'dumb' + ast = OmegaPac.PacGenerator.script($rootScope.options, profileName, + profileNotFound: profileNotFound) pac = ast.print_to_string(beautify: true, comments: true) pac = OmegaPac.PacGenerator.ascii(pac) blob = new Blob [pac], {type: "text/plain;charset=utf-8"} fileName = profileName.replace(/\W+/g, '_') saveAs(blob, "OmegaProfile_#{fileName}.pac") + if missingProfile + $timeout -> + $rootScope.showAlert( + type: 'error' + message: tr('options_profileNotFound', [missingProfile]) + ) diff = jsondiffpatch.create( objectHash: (obj) -> JSON.stringify(obj)