From 3b9ddfc6c514ad42340489974c3fc69243de094f Mon Sep 17 00:00:00 2001 From: FelisCatus Date: Thu, 25 Sep 2014 21:18:17 +0800 Subject: [PATCH] Support PAC profiles with file: URLs. Fix #29. --- omega-i18n/en/messages.json | 6 +++++ omega-i18n/zh_CN/messages.json | 6 +++++ omega-pac/src/profiles.coffee | 22 ++++++++++++++----- omega-pac/test/profiles.coffee | 6 +++++ .../background.coffee | 1 - .../src/options.coffee | 6 ++--- .../src/omega/controllers/pac_profile.coffee | 20 +++++++++++++++++ omega-web/src/omega/directives.coffee | 9 +++++++- omega-web/src/partials/input_group_clear.jade | 2 +- omega-web/src/partials/profile_pac.jade | 10 +++++++-- 10 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 omega-web/src/omega/controllers/pac_profile.coffee diff --git a/omega-i18n/en/messages.json b/omega-i18n/en/messages.json index 535b704..eab46ad 100644 --- a/omega-i18n/en/messages.json +++ b/omega-i18n/en/messages.json @@ -286,6 +286,12 @@ "options_pacUrlHelp": { "message": "The PAC script will be updated from this URL. If it is left blank, the following scripts will be used directly instead." }, + "options_pacUrlFile": { + "message": "PAC profiles with file: URLs can only be applied directly. They cannot be used as result profiles because local files cannot be accessed due to browser limitation." + }, + "options_pacUrlFileDisabled": { + "message": "Therefore, you cannot use local PAC file for this profile. You can create a new PAC profile for that if you really want that." + }, "options_group_pacScript": { "message": "PAC Script" }, diff --git a/omega-i18n/zh_CN/messages.json b/omega-i18n/zh_CN/messages.json index c73d726..040edc8 100644 --- a/omega-i18n/zh_CN/messages.json +++ b/omega-i18n/zh_CN/messages.json @@ -286,6 +286,12 @@ "options_pacUrlHelp": { "message": "应用将从此网址下载PAC脚本。如果网址留空,则直接使用下方的脚本内容。" }, + "options_pacUrlFile": { + "message": "如果您使用本地PAC文件,则该情景模式只能单独使用,无法作为自动切换的结果。这是因为浏览器不允许读取本地文件。" + }, + "options_pacUrlFileDisabled": { + "message": "此情景模式已被引用,所以不能使用本地PAC文件。如果您真的需要使用本地文件,请另外新建一个PAC情景模式。" + }, "options_group_pacScript": { "message": "PAC 脚本" }, diff --git a/omega-pac/src/profiles.coffee b/omega-pac/src/profiles.coffee index 518289c..6262290 100644 --- a/omega-pac/src/profiles.coffee +++ b/omega-pac/src/profiles.coffee @@ -64,6 +64,8 @@ module.exports = exports = else 'DIRECT' + isFileUrl: (url) -> !!(url?.substr(0, 5).toUpperCase() == 'FILE:') + nameAsKey: (profileName) -> if typeof profileName != 'string' profileName = profileName.name @@ -92,11 +94,17 @@ module.exports = exports = key = exports.pacResult() new U2.AST_String value: key - isIncludable: (profile) -> !!exports._handler(profile).includable + isIncludable: (profile) -> + includable = exports._handler(profile).includable + if typeof includable == 'function' + includable = includable.call(exports, profile) + !!includable isInclusive: (profile) -> !!exports._handler(profile).inclusive - updateUrl: (profile) -> exports._handler(profile).updateUrl?(profile) - update: (profile, data) -> exports._handler(profile).update(profile, data) + updateUrl: (profile) -> + exports._handler(profile).updateUrl?.call(exports, profile) + update: (profile, data) -> + exports._handler(profile).update.call(exports, profile, data) tag: (profile) -> exports._profileCache.tag(profile) create: (profile, opt_profileType) -> @@ -259,7 +267,7 @@ module.exports = exports = body: body ) 'PacProfile': - includable: true + includable: (profile) -> !@isFileUrl(profile.pacUrl) create: (profile) -> profile.pacScript ?= ''' function FindProxyForURL(url, host) { @@ -277,7 +285,11 @@ module.exports = exports = new U2.AST_SymbolRef name: 'FindProxyForURL' ] ) - updateUrl: (profile) -> profile.pacUrl + updateUrl: (profile) -> + if @isFileUrl(profile.pacUrl) + undefined + else + profile.pacUrl update: (profile, data) -> profile.pacScript = data 'AutoDetectProfile': 'PacProfile' diff --git a/omega-pac/test/profiles.coffee b/omega-pac/test/profiles.coffee index 953034a..204628c 100644 --- a/omega-pac/test/profiles.coffee +++ b/omega-pac/test/profiles.coffee @@ -107,6 +107,12 @@ describe 'Profiles', -> it 'should return the result of the pac script', -> testProfile(profile, 'ftp://www.example.com:9999/abc', null, 'PROXY www.example.com:8080') + it 'should return includable for non-file pacUrl', -> + Profiles.isIncludable(profile).should.be.true + it 'should return not includable for file: pacUrl', -> + profile = Profiles.create('test', 'PacProfile') + profile.pacUrl = 'file:///proxy.pac' + Profiles.isIncludable(profile).should.be.false describe 'SwitchProfile', -> profile = Profiles.create('test', 'SwitchProfile') profile.rules = [ diff --git a/omega-target-chromium-extension/background.coffee b/omega-target-chromium-extension/background.coffee index c240ede..c06b27d 100644 --- a/omega-target-chromium-extension/background.coffee +++ b/omega-target-chromium-extension/background.coffee @@ -88,7 +88,6 @@ actionForUrl = (url) -> storage = new OmegaTargetCurrent.Storage(chrome.storage.local, 'local') state = new OmegaTargetCurrent.BrowserStorage(localStorage, 'omega.local.') options = new OmegaTargetCurrent.Options(null, storage, state, Log) -console.log(options.log) tabs = new OmegaTargetCurrent.ChromeTabs(actionForUrl) tabs.watch() diff --git a/omega-target-chromium-extension/src/options.coffee b/omega-target-chromium-extension/src/options.coffee index f0e5dc1..092cd31 100644 --- a/omega-target-chromium-extension/src/options.coffee +++ b/omega-target-chromium-extension/src/options.coffee @@ -121,11 +121,11 @@ class ChromeOptions extends OmegaTarget.Options config['mode'] = 'direct' else if profile.profileType == 'PacProfile' config['mode'] = 'pac_script' - config['pacScript'] = if profile.pacScript - data: profile.pacScript + config['pacScript'] = if profile.pacUrl + url: profile.pacUrl mandatory: true else - url: profile.pacUrl + data: profile.pacScript mandatory: true else if profile.profileType == 'FixedProfile' config = @_fixedProfileConfig(profile) diff --git a/omega-web/src/omega/controllers/pac_profile.coffee b/omega-web/src/omega/controllers/pac_profile.coffee new file mode 100644 index 0000000..f1cd60d --- /dev/null +++ b/omega-web/src/omega/controllers/pac_profile.coffee @@ -0,0 +1,20 @@ +angular.module('omega').controller 'PacProfileCtrl', ($scope) -> + # coffeelint: disable=max_line_length + + # https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L13 + $scope.urlRegex = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/ + # With the file: scheme added to the pattern: + $scope.urlWithFile = /^(ftp|http|https|file):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/ + + # coffeelint: enable=max_line_length + + $scope.isFileUrl = OmegaPac.Profiles.isFileUrl + $scope.pacUrlCtrl = {ctrl: null} + $scope.$watch 'pacUrlCtrl.ctrl', console.log.bind(console) + + set = OmegaPac.Profiles.referencedBySet($scope.profile, $scope.options) + $scope.referenced = Object.keys(set).length > 0 + + onProfileChange = (profile) -> + $scope.pacUrlIsFile = $scope.isFileUrl(profile.pacUrl) + $scope.$watch 'profile', onProfileChange, true diff --git a/omega-web/src/omega/directives.coffee b/omega-web/src/omega/directives.coffee index f0ff3cd..30cdf7a 100644 --- a/omega-web/src/omega/directives.coffee +++ b/omega-web/src/omega/directives.coffee @@ -1,12 +1,19 @@ -angular.module('omega').directive 'inputGroupClear', -> +angular.module('omega').directive 'inputGroupClear', ($timeout) -> restrict: 'A' templateUrl: 'partials/input_group_clear.html' scope: 'model': '=model' 'type': '@type' + 'ngPattern': '=?ngPattern' 'placeholder': '@placeholder' + 'controller': '=controller' link: (scope, element, attrs) -> + scope.catchAll = new RegExp('') + $timeout -> + scope.controller = element.find('input').controller('ngModel') + scope.oldModel = '' + scope.controller = scope.input scope.modelChange = -> if scope.model scope.oldModel = '' diff --git a/omega-web/src/partials/input_group_clear.jade b/omega-web/src/partials/input_group_clear.jade index 14ba1da..ebaeeae 100644 --- a/omega-web/src/partials/input_group_clear.jade +++ b/omega-web/src/partials/input_group_clear.jade @@ -1,5 +1,5 @@ .input-group - input.form-control(ng-model='model' ng-attr-type='{{type}}' + input.form-control(ng-model='model' ng-attr-type='{{type}}' ng-pattern='ngPattern || catchAll' placeholder='{{placeholder}}' ng-change='modelChange()') span.input-group-btn button.btn.btn-default.input-group-clear-btn(ng-click='toggleClear()' ng-disabled='!model && !oldModel' diff --git a/omega-web/src/partials/profile_pac.jade b/omega-web/src/partials/profile_pac.jade index 3df4033..f9d053d 100644 --- a/omega-web/src/partials/profile_pac.jade +++ b/omega-web/src/partials/profile_pac.jade @@ -1,7 +1,13 @@ -section.settings-group +section.settings-group(ng-controller='PacProfileCtrl') h3 {{'options_group_pacUrl' | tr}} - .width-limit(input-group-clear type='url' model='profile.pacUrl') + .width-limit(input-group-clear type='text' model='profile.pacUrl' + ng-pattern='referenced ? urlRegex : urlWithFile' controller='pacUrlCtrl.ctrl') p.help-block {{'options_pacUrlHelp' | tr}} + .has-warning(ng-show='isFileUrl(profile.pacUrl) && !referenced') + p.help-block #[span.glyphicon.glyphicon-warning-sign] {{'options_pacUrlFile' | tr}} + .has-error(ng-show='isFileUrl(pacUrlCtrl.ctrl.$viewValue) && referenced') + p.help-block #[span.glyphicon.glyphicon-remove-sign] {{'options_pacUrlFile' | tr}} + p.help-block {{'options_pacUrlFileDisabled' | tr}} section.settings-group h3 {{'options_group_pacScript' | tr}} p